This patch-series aims at enabling Nested stage translation in guests
using virtio-iommu as the paravirtualized iommu. The backend is supported
with Arm SMMU-v3 that provides nested stage-1 and stage-2 translation.
This series derives its purpose from various efforts happening to add
support for Shared Virtual Addressing (SVA) in host and guest. On Arm,
most of the support for SVA has already landed. The support for nested
stage translation and fault reporting to guest has been proposed [1].
The related changes required in VFIO [2] framework have also been put
forward.
This series proposes changes in virtio-iommu to program PASID tables
and related stage-1 page tables. A simple iommu-pasid-table library
is added for this purpose that interacts with vendor drivers to
allocate and populate PASID tables.
In Arm SMMUv3 we propose to pull the Context Descriptor (CD) management
code out of the arm-smmu-v3 driver and add that as a glue vendor layer
to support allocating CD tables, and populating them with right values.
These CD tables are essentially the PASID tables and contain stage-1
page table configurations too.
A request to setup these CD tables come from virtio-iommu driver using
the iommu-pasid-table library when running on Arm. The virtio-iommu
then pass these PASID tables to the host using the right virtio backend
and support in VMM.
For testing we have added necessary support in kvmtool. The changes in
kvmtool are based on virtio-iommu development branch by Jean-Philippe
Brucker [3].
The tested kernel branch contains following in the order bottom to top
on the git hash -
a) v5.11-rc3
b) arm-smmu-v3 [1] and vfio [2] changes from Eric to add nested page
table support for Arm.
c) Smmu test engine patches from Jean-Philippe's branch [4]
d) This series
e) Domain nesting info patches [5][6][7].
f) Changes to add arm-smmu-v3 specific nesting info (to be sent to
the list).
This kernel is tested on Neoverse reference software stack with
Fixed virtual platform. Public version of the software stack and
FVP is available here[8][9].
A big thanks to Jean-Philippe for his contributions towards this work
and for his valuable guidance.
[1] https://lore.kernel.org/linux-iommu/20201118112151.25412-1-eric.auger@redhat.com/T/
[2] https://lore.kernel.org/kvmarm/20201116110030.32335-12-eric.auger@redhat.com/T/
[3] https://jpbrucker.net/git/kvmtool/log/?h=virtio-iommu/devel
[4] https://jpbrucker.net/git/linux/log/?h=sva/smmute
[5] https://lore.kernel.org/kvm/1599734733-6431-2-git-send-email-yi.l.liu@intel.com/
[6] https://lore.kernel.org/kvm/1599734733-6431-3-git-send-email-yi.l.liu@intel.com/
[7] https://lore.kernel.org/kvm/1599734733-6431-4-git-send-email-yi.l.liu@intel.com/
[8] https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps
[9] https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/rdn1edge/user-guide.rst
Jean-Philippe Brucker (6):
iommu/virtio: Add headers for table format probing
iommu/virtio: Add table format probing
iommu/virtio: Add headers for binding pasid table in iommu
iommu/virtio: Add support for INVALIDATE request
iommu/virtio: Attach Arm PASID tables when available
iommu/virtio: Add support for Arm LPAE page table format
Vivek Gautam (9):
iommu/arm-smmu-v3: Create a Context Descriptor library
iommu: Add a simple PASID table library
iommu/arm-smmu-v3: Update drivers to work with iommu-pasid-table
iommu/arm-smmu-v3: Update CD base address info for user-space
iommu/arm-smmu-v3: Set sync op from consumer driver of cd-lib
iommu: Add asid_bits to arm smmu-v3 stage1 table info
iommu/virtio: Update table format probing header
iommu/virtio: Prepare to add attach pasid table infrastructure
iommu/virtio: Update fault type and reason info for viommu fault
drivers/iommu/arm/arm-smmu-v3/Makefile | 2 +-
.../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 283 +++++++
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 16 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 268 +------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 4 +-
drivers/iommu/iommu-pasid-table.h | 140 ++++
drivers/iommu/virtio-iommu.c | 692 +++++++++++++++++-
include/uapi/linux/iommu.h | 2 +-
include/uapi/linux/virtio_iommu.h | 158 +++-
9 files changed, 1303 insertions(+), 262 deletions(-)
create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c
create mode 100644 drivers/iommu/iommu-pasid-table.h
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Para-virtualized iommu drivers in guest may require to create and manage
context descriptor (CD) tables as part of PASID table allocations.
The PASID tables are passed to host to configure stage-1 tables in
hardware.
Make way for a library driver for CD management to allow para-
virtualized iommu driver call such code.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/arm/arm-smmu-v3/Makefile | 2 +-
.../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 223 ++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 216 +----------------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 +
4 files changed, 228 insertions(+), 216 deletions(-)
create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c
@@ -0,0 +1,223 @@+// SPDX-License-Identifier: GPL-2.0+/*+*arm-smmu-v3contextdescriptorhandlinglibrarydriver+*+*Copyright(C)2021ArmLtd.+*/++#include<linux/dma-iommu.h>++#include"arm-smmu-v3.h"++staticintarm_smmu_alloc_cd_leaf_table(structarm_smmu_device*smmu,+structarm_smmu_l1_ctx_desc*l1_desc)+{+size_tsize=CTXDESC_L2_ENTRIES*(CTXDESC_CD_DWORDS<<3);++l1_desc->l2ptr=dmam_alloc_coherent(smmu->dev,size,+&l1_desc->l2ptr_dma,GFP_KERNEL);+if(!l1_desc->l2ptr){+dev_warn(smmu->dev,+"failed to allocate context descriptor table\n");+return-ENOMEM;+}+return0;+}++staticvoidarm_smmu_write_cd_l1_desc(__le64*dst,+structarm_smmu_l1_ctx_desc*l1_desc)+{+u64val=(l1_desc->l2ptr_dma&CTXDESC_L1_DESC_L2PTR_MASK)|+CTXDESC_L1_DESC_V;++/* See comment in arm_smmu_write_ctx_desc() */+WRITE_ONCE(*dst,cpu_to_le64(val));+}++static__le64*arm_smmu_get_cd_ptr(structarm_smmu_domain*smmu_domain,+u32ssid)+{+__le64*l1ptr;+unsignedintidx;+structarm_smmu_l1_ctx_desc*l1_desc;+structarm_smmu_device*smmu=smmu_domain->smmu;+structarm_smmu_ctx_desc_cfg*cdcfg=&smmu_domain->s1_cfg.cdcfg;++if(smmu_domain->s1_cfg.s1fmt==STRTAB_STE_0_S1FMT_LINEAR)+returncdcfg->cdtab+ssid*CTXDESC_CD_DWORDS;++idx=ssid>>CTXDESC_SPLIT;+l1_desc=&cdcfg->l1_desc[idx];+if(!l1_desc->l2ptr){+if(arm_smmu_alloc_cd_leaf_table(smmu,l1_desc))+returnNULL;++l1ptr=cdcfg->cdtab+idx*CTXDESC_L1_DESC_DWORDS;+arm_smmu_write_cd_l1_desc(l1ptr,l1_desc);+/* An invalid L1CD can be cached */+arm_smmu_sync_cd(smmu_domain,ssid,false);+}+idx=ssid&(CTXDESC_L2_ENTRIES-1);+returnl1_desc->l2ptr+idx*CTXDESC_CD_DWORDS;+}++intarm_smmu_write_ctx_desc(structarm_smmu_domain*smmu_domain,intssid,+structarm_smmu_ctx_desc*cd)+{+/*+*Thisfunctionhandlesthefollowingcases:+*+*(1)InstallprimaryCD,fornormalDMAtraffic(SSID=0).+*(2)InstallasecondaryCD,forSID+SSIDtraffic.+*(3)UpdateASIDofaCD.Atomicallywritethefirst64bitsofthe+*CD,theninvalidatetheoldentryandmappings.+*(4)Quiescethecontextwithoutclearingthevalidbit.Disable+*translation,andignoreanytranslationfault.+*(5)RemoveasecondaryCD.+*/+u64val;+boolcd_live;+__le64*cdptr;+structarm_smmu_device*smmu=smmu_domain->smmu;++if(WARN_ON(ssid>=(1<<smmu_domain->s1_cfg.s1cdmax)))+return-E2BIG;++cdptr=arm_smmu_get_cd_ptr(smmu_domain,ssid);+if(!cdptr)+return-ENOMEM;++val=le64_to_cpu(cdptr[0]);+cd_live=!!(val&CTXDESC_CD_0_V);++if(!cd){/* (5) */+val=0;+}elseif(cd==&quiet_cd){/* (4) */+val|=CTXDESC_CD_0_TCR_EPD0;+}elseif(cd_live){/* (3) */+val&=~CTXDESC_CD_0_ASID;+val|=FIELD_PREP(CTXDESC_CD_0_ASID,cd->asid);+/*+*UntilCD+TLBinvalidation,bothASIDsmaybeusedfortagging+*thissubstream'straffic+*/+}else{/* (1) and (2) */+cdptr[1]=cpu_to_le64(cd->ttbr&CTXDESC_CD_1_TTB0_MASK);+cdptr[2]=0;+cdptr[3]=cpu_to_le64(cd->mair);++/*+*STEislive,andtheSMMUmightreaddwordsofthisCDinany+*order.Ensurethatitobservesvalidvaluesbeforereading+*V=1.+*/+arm_smmu_sync_cd(smmu_domain,ssid,true);++val=cd->tcr|+#ifdef __BIG_ENDIAN+CTXDESC_CD_0_ENDI|+#endif+CTXDESC_CD_0_R|CTXDESC_CD_0_A|+(cd->mm?0:CTXDESC_CD_0_ASET)|+CTXDESC_CD_0_AA64|+FIELD_PREP(CTXDESC_CD_0_ASID,cd->asid)|+CTXDESC_CD_0_V;++/* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */+if(smmu->features&ARM_SMMU_FEAT_STALL_FORCE)+val|=CTXDESC_CD_0_S;+}++/*+*TheSMMUaccesses64-bitvaluesatomically.SeeIHI0070Ca3.21.3+*"Configuration structures and configuration invalidation completion"+*+*Thesizeofsingle-copyatomicreadsmadebytheSMMUis+*IMPLEMENTATIONDEFINEDbutmustbeatleast64bits.Anysingle+*fieldwithinanaligned64-bitspanofastructurecanbealtered+*withoutfirstmakingthestructureinvalid.+*/+WRITE_ONCE(cdptr[0],cpu_to_le64(val));+arm_smmu_sync_cd(smmu_domain,ssid,true);+return0;+}++intarm_smmu_alloc_cd_tables(structarm_smmu_domain*smmu_domain)+{+intret;+size_tl1size;+size_tmax_contexts;+structarm_smmu_device*smmu=smmu_domain->smmu;+structarm_smmu_s1_cfg*cfg=&smmu_domain->s1_cfg;+structarm_smmu_ctx_desc_cfg*cdcfg=&cfg->cdcfg;++max_contexts=1<<cfg->s1cdmax;++if(!(smmu->features&ARM_SMMU_FEAT_2_LVL_CDTAB)||+max_contexts<=CTXDESC_L2_ENTRIES){+cfg->s1fmt=STRTAB_STE_0_S1FMT_LINEAR;+cdcfg->num_l1_ents=max_contexts;++l1size=max_contexts*(CTXDESC_CD_DWORDS<<3);+}else{+cfg->s1fmt=STRTAB_STE_0_S1FMT_64K_L2;+cdcfg->num_l1_ents=DIV_ROUND_UP(max_contexts,+CTXDESC_L2_ENTRIES);++cdcfg->l1_desc=devm_kcalloc(smmu->dev,cdcfg->num_l1_ents,+sizeof(*cdcfg->l1_desc),+GFP_KERNEL);+if(!cdcfg->l1_desc)+return-ENOMEM;++l1size=cdcfg->num_l1_ents*(CTXDESC_L1_DESC_DWORDS<<3);+}++cdcfg->cdtab=dmam_alloc_coherent(smmu->dev,l1size,&cdcfg->cdtab_dma,+GFP_KERNEL);+if(!cdcfg->cdtab){+dev_warn(smmu->dev,"failed to allocate context descriptor\n");+ret=-ENOMEM;+gotoerr_free_l1;+}++return0;++err_free_l1:+if(cdcfg->l1_desc){+devm_kfree(smmu->dev,cdcfg->l1_desc);+cdcfg->l1_desc=NULL;+}+returnret;+}++voidarm_smmu_free_cd_tables(structarm_smmu_domain*smmu_domain)+{+inti;+size_tsize,l1size;+structarm_smmu_device*smmu=smmu_domain->smmu;+structarm_smmu_ctx_desc_cfg*cdcfg=&smmu_domain->s1_cfg.cdcfg;++if(cdcfg->l1_desc){+size=CTXDESC_L2_ENTRIES*(CTXDESC_CD_DWORDS<<3);++for(i=0;i<cdcfg->num_l1_ents;i++){+if(!cdcfg->l1_desc[i].l2ptr)+continue;++dmam_free_coherent(smmu->dev,size,+cdcfg->l1_desc[i].l2ptr,+cdcfg->l1_desc[i].l2ptr_dma);+}+devm_kfree(smmu->dev,cdcfg->l1_desc);+cdcfg->l1_desc=NULL;++l1size=cdcfg->num_l1_ents*(CTXDESC_L1_DESC_DWORDS<<3);+}else{+l1size=cdcfg->num_l1_ents*(CTXDESC_CD_DWORDS<<3);+}++dmam_free_coherent(smmu->dev,l1size,cdcfg->cdtab,cdcfg->cdtab_dma);+cdcfg->cdtab_dma=0;+cdcfg->cdtab=NULL;+}
Add a small API in iommu subsystem to handle PASID table allocation
requests from different consumer drivers, such as a paravirtualized
iommu driver. The API provides ops for allocating and freeing PASID
table, writing to it and managing the table caches.
This library also provides for registering a vendor API that attaches
to these ops. The vendor APIs would eventually perform arch level
implementations for these PASID tables.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/iommu-pasid-table.h | 134 ++++++++++++++++++++++++++++++
1 file changed, 134 insertions(+)
create mode 100644 drivers/iommu/iommu-pasid-table.h
Update base address information in vendor pasid table info to pass that
to user-space for stage1 table management.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 6 ++++++
1 file changed, 6 insertions(+)
Update arm-smmu-v3 context descriptor (CD) library driver to work
with iommu-pasid-table APIs. These APIs are then used in arm-smmu-v3
drivers to manage CD tables.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
.../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 127 +++++++++++++-----
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 16 ++-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 47 ++++---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 7 +-
drivers/iommu/iommu-pasid-table.h | 10 +-
5 files changed, 144 insertions(+), 63 deletions(-)
@@ -8,17 +8,17 @@#include<linux/dma-iommu.h>#include"arm-smmu-v3.h"+#include"../../iommu-pasid-table.h"-staticintarm_smmu_alloc_cd_leaf_table(structarm_smmu_device*smmu,+staticintarm_smmu_alloc_cd_leaf_table(structdevice*dev,structarm_smmu_l1_ctx_desc*l1_desc){size_tsize=CTXDESC_L2_ENTRIES*(CTXDESC_CD_DWORDS<<3);-l1_desc->l2ptr=dmam_alloc_coherent(smmu->dev,size,+l1_desc->l2ptr=dmam_alloc_coherent(dev,size,&l1_desc->l2ptr_dma,GFP_KERNEL);if(!l1_desc->l2ptr){-dev_warn(smmu->dev,-"failed to allocate context descriptor table\n");+dev_warn(dev,"failed to allocate context descriptor table\n");return-ENOMEM;}return0;
@@ -34,35 +34,39 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,WRITE_ONCE(*dst,cpu_to_le64(val));}-static__le64*arm_smmu_get_cd_ptr(structarm_smmu_domain*smmu_domain,+static__le64*arm_smmu_get_cd_ptr(structiommu_vendor_psdtable_cfg*pst_cfg,u32ssid){__le64*l1ptr;unsignedintidx;+structdevice*dev=pst_cfg->iommu_dev;+structarm_smmu_cfg_info*cfgi=&pst_cfg->vendor.cfg;+structarm_smmu_s1_cfg*s1cfg=cfgi->s1_cfg;+structarm_smmu_ctx_desc_cfg*cdcfg=&s1cfg->cdcfg;structarm_smmu_l1_ctx_desc*l1_desc;-structarm_smmu_device*smmu=smmu_domain->smmu;-structarm_smmu_ctx_desc_cfg*cdcfg=&smmu_domain->s1_cfg.cdcfg;+structiommu_pasid_table*tbl=pasid_table_cfg_to_table(pst_cfg);-if(smmu_domain->s1_cfg.s1fmt==STRTAB_STE_0_S1FMT_LINEAR)+if(s1cfg->s1fmt==STRTAB_STE_0_S1FMT_LINEAR)returncdcfg->cdtab+ssid*CTXDESC_CD_DWORDS;idx=ssid>>CTXDESC_SPLIT;l1_desc=&cdcfg->l1_desc[idx];if(!l1_desc->l2ptr){-if(arm_smmu_alloc_cd_leaf_table(smmu,l1_desc))+if(arm_smmu_alloc_cd_leaf_table(dev,l1_desc))returnNULL;l1ptr=cdcfg->cdtab+idx*CTXDESC_L1_DESC_DWORDS;arm_smmu_write_cd_l1_desc(l1ptr,l1_desc);/* An invalid L1CD can be cached */-arm_smmu_sync_cd(smmu_domain,ssid,false);+if(iommu_psdtable_sync(tbl,tbl->cookie,ssid,false))+returnNULL;}idx=ssid&(CTXDESC_L2_ENTRIES-1);returnl1_desc->l2ptr+idx*CTXDESC_CD_DWORDS;}-intarm_smmu_write_ctx_desc(structarm_smmu_domain*smmu_domain,intssid,-structarm_smmu_ctx_desc*cd)+staticintarm_smmu_write_ctx_desc(structiommu_vendor_psdtable_cfg*pst_cfg,+intssid,void*cookie){/**Thisfunctionhandlesthefollowingcases:
@@ -78,12 +82,15 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,u64val;boolcd_live;__le64*cdptr;-structarm_smmu_device*smmu=smmu_domain->smmu;+structarm_smmu_cfg_info*cfgi=&pst_cfg->vendor.cfg;+structarm_smmu_s1_cfg*s1cfg=cfgi->s1_cfg;+structiommu_pasid_table*tbl=pasid_table_cfg_to_table(pst_cfg);+structarm_smmu_ctx_desc*cd=cookie;-if(WARN_ON(ssid>=(1<<smmu_domain->s1_cfg.s1cdmax)))+if(WARN_ON(ssid>=(1<<s1cfg->s1cdmax)))return-E2BIG;-cdptr=arm_smmu_get_cd_ptr(smmu_domain,ssid);+cdptr=arm_smmu_get_cd_ptr(pst_cfg,ssid);if(!cdptr)return-ENOMEM;
@@ -111,7 +118,8 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,*order.Ensurethatitobservesvalidvaluesbeforereading*V=1.*/-arm_smmu_sync_cd(smmu_domain,ssid,true);+if(iommu_psdtable_sync(tbl,tbl->cookie,ssid,true))+return-ENOSYS;val=cd->tcr|#ifdef __BIG_ENDIAN
@@ -124,7 +132,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,CTXDESC_CD_0_V;/* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */-if(smmu->features&ARM_SMMU_FEAT_STALL_FORCE)+if(cfgi->feat_flag&ARM_SMMU_FEAT_STALL_FORCE)val|=CTXDESC_CD_0_S;}
@@ -138,33 +146,55 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,*withoutfirstmakingthestructureinvalid.*/WRITE_ONCE(cdptr[0],cpu_to_le64(val));-arm_smmu_sync_cd(smmu_domain,ssid,true);+if(iommu_psdtable_sync(tbl,tbl->cookie,ssid,true))+return-ENOSYS;+return0;}-intarm_smmu_alloc_cd_tables(structarm_smmu_domain*smmu_domain)+staticvoidarm_smmu_prepare_cd(structiommu_vendor_psdtable_cfg*pst_cfg,+structio_pgtable_cfg*pgtbl_cfg,u32asid)+{+structarm_smmu_cfg_info*cfgi=&pst_cfg->vendor.cfg;+structarm_smmu_s1_cfg*s1cfg=cfgi->s1_cfg;+typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr)tcr=&pgtbl_cfg->arm_lpae_s1_cfg.tcr;++s1cfg->cd.asid=(u16)asid;+s1cfg->cd.ttbr=pgtbl_cfg->arm_lpae_s1_cfg.ttbr;+s1cfg->cd.tcr=FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ,tcr->tsz)|+FIELD_PREP(CTXDESC_CD_0_TCR_TG0,tcr->tg)|+FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0,tcr->irgn)|+FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0,tcr->orgn)|+FIELD_PREP(CTXDESC_CD_0_TCR_SH0,tcr->sh)|+FIELD_PREP(CTXDESC_CD_0_TCR_IPS,tcr->ips)|+CTXDESC_CD_0_TCR_EPD1|CTXDESC_CD_0_AA64;+s1cfg->cd.mair=pgtbl_cfg->arm_lpae_s1_cfg.mair;+}++staticintarm_smmu_alloc_cd_tables(structiommu_vendor_psdtable_cfg*pst_cfg){intret;size_tl1size;size_tmax_contexts;-structarm_smmu_device*smmu=smmu_domain->smmu;-structarm_smmu_s1_cfg*cfg=&smmu_domain->s1_cfg;-structarm_smmu_ctx_desc_cfg*cdcfg=&cfg->cdcfg;+structdevice*dev=pst_cfg->iommu_dev;+structarm_smmu_cfg_info*cfgi=&pst_cfg->vendor.cfg;+structarm_smmu_s1_cfg*s1cfg=cfgi->s1_cfg;+structarm_smmu_ctx_desc_cfg*cdcfg=&s1cfg->cdcfg;-max_contexts=1<<cfg->s1cdmax;+max_contexts=1<<s1cfg->s1cdmax;-if(!(smmu->features&ARM_SMMU_FEAT_2_LVL_CDTAB)||+if(!(cfgi->feat_flag&ARM_SMMU_FEAT_2_LVL_CDTAB)||max_contexts<=CTXDESC_L2_ENTRIES){-cfg->s1fmt=STRTAB_STE_0_S1FMT_LINEAR;+s1cfg->s1fmt=STRTAB_STE_0_S1FMT_LINEAR;cdcfg->num_l1_ents=max_contexts;l1size=max_contexts*(CTXDESC_CD_DWORDS<<3);}else{-cfg->s1fmt=STRTAB_STE_0_S1FMT_64K_L2;+s1cfg->s1fmt=STRTAB_STE_0_S1FMT_64K_L2;cdcfg->num_l1_ents=DIV_ROUND_UP(max_contexts,CTXDESC_L2_ENTRIES);-cdcfg->l1_desc=devm_kcalloc(smmu->dev,cdcfg->num_l1_ents,+cdcfg->l1_desc=devm_kcalloc(dev,cdcfg->num_l1_ents,sizeof(*cdcfg->l1_desc),GFP_KERNEL);if(!cdcfg->l1_desc)
@@ -173,10 +203,10 @@ int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)l1size=cdcfg->num_l1_ents*(CTXDESC_L1_DESC_DWORDS<<3);}-cdcfg->cdtab=dmam_alloc_coherent(smmu->dev,l1size,&cdcfg->cdtab_dma,+cdcfg->cdtab=dmam_alloc_coherent(dev,l1size,&cdcfg->cdtab_dma,GFP_KERNEL);if(!cdcfg->cdtab){-dev_warn(smmu->dev,"failed to allocate context descriptor\n");+dev_warn(dev,"failed to allocate context descriptor\n");ret=-ENOMEM;gotoerr_free_l1;}
@@ -185,18 +215,20 @@ int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)err_free_l1:if(cdcfg->l1_desc){-devm_kfree(smmu->dev,cdcfg->l1_desc);+devm_kfree(dev,cdcfg->l1_desc);cdcfg->l1_desc=NULL;}returnret;}-voidarm_smmu_free_cd_tables(structarm_smmu_domain*smmu_domain)+staticvoidarm_smmu_free_cd_tables(structiommu_vendor_psdtable_cfg*pst_cfg){inti;size_tsize,l1size;-structarm_smmu_device*smmu=smmu_domain->smmu;-structarm_smmu_ctx_desc_cfg*cdcfg=&smmu_domain->s1_cfg.cdcfg;+structdevice*dev=pst_cfg->iommu_dev;+structarm_smmu_cfg_info*cfgi=&pst_cfg->vendor.cfg;+structarm_smmu_s1_cfg*s1cfg=cfgi->s1_cfg;+structarm_smmu_ctx_desc_cfg*cdcfg=&s1cfg->cdcfg;if(cdcfg->l1_desc){size=CTXDESC_L2_ENTRIES*(CTXDESC_CD_DWORDS<<3);
@@ -1806,7 +1809,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)/* Prevent SVA from touching the CD while we're freeing it */mutex_lock(&arm_smmu_asid_lock);if(s1_cfg->cdcfg.cdtab)-arm_smmu_free_cd_tables(smmu_domain);+iommu_psdtable_free(tbl,&tbl->cfg);arm_smmu_free_asid(&s1_cfg->cd);mutex_unlock(&arm_smmu_asid_lock);}
@@ -1826,7 +1829,8 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,u32asid;structarm_smmu_device*smmu=smmu_domain->smmu;structarm_smmu_s1_cfg*cfg=&smmu_domain->s1_cfg;-typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr)tcr=&pgtbl_cfg->arm_lpae_s1_cfg.tcr;+structiommu_vendor_psdtable_cfg*pst_cfg;+structiommu_pasid_table*tbl;refcount_set(&cfg->cd.refs,1);
@@ -1837,29 +1841,40 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,if(ret)gotoout_unlock;+tbl=iommu_register_pasid_table(PASID_TABLE_ARM_SMMU_V3,smmu->dev,smmu_domain);+if(!tbl){+ret=-ENOMEM;+gotoout_free_asid;+}++pst_cfg=&tbl->cfg;++pst_cfg->iommu_dev=smmu->dev;+pst_cfg->fmt=PASID_TABLE_ARM_SMMU_V3;+pst_cfg->vendor.cfg.s1_cfg=&smmu_domain->s1_cfg;++if(smmu->features&ARM_SMMU_FEAT_2_LVL_CDTAB)+pst_cfg->vendor.cfg.feat_flag|=ARM_SMMU_FEAT_2_LVL_CDTAB;+if(smmu->features&ARM_SMMU_FEAT_STALL_FORCE)+pst_cfg->vendor.cfg.feat_flag|=ARM_SMMU_FEAT_STALL_FORCE;+cfg->s1cdmax=master->ssid_bits;-ret=arm_smmu_alloc_cd_tables(smmu_domain);+smmu_domain->tbl=tbl;+ret=iommu_psdtable_alloc(tbl,pst_cfg);if(ret)gotoout_free_asid;-cfg->cd.asid=(u16)asid;-cfg->cd.ttbr=pgtbl_cfg->arm_lpae_s1_cfg.ttbr;-cfg->cd.tcr=FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ,tcr->tsz)|-FIELD_PREP(CTXDESC_CD_0_TCR_TG0,tcr->tg)|-FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0,tcr->irgn)|-FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0,tcr->orgn)|-FIELD_PREP(CTXDESC_CD_0_TCR_SH0,tcr->sh)|-FIELD_PREP(CTXDESC_CD_0_TCR_IPS,tcr->ips)|-CTXDESC_CD_0_TCR_EPD1|CTXDESC_CD_0_AA64;-cfg->cd.mair=pgtbl_cfg->arm_lpae_s1_cfg.mair;+ret=iommu_psdtable_prepare(tbl,pst_cfg,pgtbl_cfg,asid);+if(ret)+gotoout_free_cd_tables;/**Notethatthiswillendupcallingarm_smmu_sync_cd()before*themasterhasbeenaddedtothedeviceslistforthisdomain.*Thisisn'tanissuebecausetheSTEhasn'tbeeninstalledyet.*/-ret=arm_smmu_write_ctx_desc(smmu_domain,0,&cfg->cd);+ret=iommu_psdtable_write(tbl,pst_cfg,0,&cfg->cd);if(ret)gotoout_free_cd_tables;
@@ -1867,7 +1882,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,return0;out_free_cd_tables:-arm_smmu_free_cd_tables(smmu_domain);+iommu_psdtable_free(tbl,pst_cfg);out_free_asid:arm_smmu_free_asid(&cfg->cd);out_unlock:
Te change allows different consumers of arm-smmu-v3-cd-lib to set
their respective sync op for pasid entries.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 1 -
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 7 +++++++
2 files changed, 7 insertions(+), 1 deletion(-)
From: Jean-Philippe Brucker <redacted>
Add required UAPI defines for probing table format for underlying
iommu hardware. The device may provide information about hardware
tables and additional capabilities for each device.
This allows guest to correctly fabricate stage-1 page tables.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Use a single "struct virtio_iommu_probe_table_format" rather
than separate structures for page table and pasid table format.
Also update commit message.]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/virtio_iommu.h | 44 ++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
@@ -130,6 +136,42 @@ struct virtio_iommu_probe_resv_mem {__le64end;};+structvirtio_iommu_probe_page_size_mask{+structvirtio_iommu_probe_propertyhead;+__u8reserved[4];+__le64mask;+};++structvirtio_iommu_probe_input_range{+structvirtio_iommu_probe_propertyhead;+__u8reserved[4];+__le64start;+__le64end;+};++structvirtio_iommu_probe_output_size{+structvirtio_iommu_probe_propertyhead;+__u8bits;+__u8reserved[3];+};++structvirtio_iommu_probe_pasid_size{+structvirtio_iommu_probe_propertyhead;+__u8bits;+__u8reserved[3];+};++/* Arm LPAE page table format */+#define VIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE 1+/* Arm smmu-v3 type PASID table format */+#define VIRTIO_IOMMU_FORMAT_PSTF_ARM_SMMU_V3 2++structvirtio_iommu_probe_table_format{+structvirtio_iommu_probe_propertyhead;+__le16format;+__u8reserved[2];+};+structvirtio_iommu_req_probe{structvirtio_iommu_req_headhead;__le32endpoint;
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Jean-Philippe Brucker <redacted>
The device may provide information about hardware tables and additional
capabilities for each device. Parse the new probe fields.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Refactor to use "struct virtio_iommu_probe_table_format" rather
than separate structures for page table and pasid table format.]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 102 ++++++++++++++++++++++++++++++++++-
1 file changed, 101 insertions(+), 1 deletion(-)
@@ -78,6 +78,17 @@ struct viommu_endpoint {structviommu_dev*viommu;structviommu_domain*vdomain;structlist_headresv_regions;++/* properties of the physical IOMMU */+u64pgsize_mask;+u64input_start;+u64input_end;+u8output_bits;+u8pasid_bits;+/* Preferred PASID table format */+void*pstf;+/* Preferred page table format */+void*pgtf;};structviommu_request{
@@ -457,6 +468,72 @@ static int viommu_add_resv_mem(struct viommu_endpoint *vdev,return0;}+staticintviommu_add_pgsize_mask(structviommu_endpoint*vdev,+structvirtio_iommu_probe_page_size_mask*prop,+size_tlen)+{+if(len<sizeof(*prop))+return-EINVAL;+vdev->pgsize_mask=le64_to_cpu(prop->mask);+return0;+}++staticintviommu_add_input_range(structviommu_endpoint*vdev,+structvirtio_iommu_probe_input_range*prop,+size_tlen)+{+if(len<sizeof(*prop))+return-EINVAL;+vdev->input_start=le64_to_cpu(prop->start);+vdev->input_end=le64_to_cpu(prop->end);+return0;+}++staticintviommu_add_output_size(structviommu_endpoint*vdev,+structvirtio_iommu_probe_output_size*prop,+size_tlen)+{+if(len<sizeof(*prop))+return-EINVAL;+vdev->output_bits=prop->bits;+return0;+}++staticintviommu_add_pasid_size(structviommu_endpoint*vdev,+structvirtio_iommu_probe_pasid_size*prop,+size_tlen)+{+if(len<sizeof(*prop))+return-EINVAL;+vdev->pasid_bits=prop->bits;+return0;+}++staticintviommu_add_pgtf(structviommu_endpoint*vdev,void*pgtf,size_tlen)+{+/* Select the first page table format available */+if(len<sizeof(structvirtio_iommu_probe_table_format)||vdev->pgtf)+return-EINVAL;++vdev->pgtf=kmemdup(pgtf,len,GFP_KERNEL);+if(!vdev->pgtf)+return-ENOMEM;++return0;+}++staticintviommu_add_pstf(structviommu_endpoint*vdev,void*pstf,size_tlen)+{+if(len<sizeof(structvirtio_iommu_probe_table_format)||vdev->pstf)+return-EINVAL;++vdev->pstf=kmemdup(pstf,len,GFP_KERNEL);+if(!vdev->pstf)+return-ENOMEM;++return0;+}+staticintviommu_probe_endpoint(structviommu_dev*viommu,structdevice*dev){intret;
In preparation to add attach pasid table op, separate out the
existing attach request code to a separate method.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 73 +++++++++++++++++++++++++-----------
1 file changed, 51 insertions(+), 22 deletions(-)
@@ -67,12 +74,20 @@ struct viommu_domain {unsignedintid;u32map_flags;+/* Default address space when a table is bound */+structviommu_mmmm;++/* When no table is bound, use generic mappings */spinlock_tmappings_lock;structrb_root_cachedmappings;unsignedlongnr_endpoints;};+#define vdev_for_each_id(i, eid, vdev) \+for(i=0;i<vdev->dev->iommu->fwspec->num_ids&&\+({eid=vdev->dev->iommu->fwspec->ids[i];1;});i++)+structviommu_endpoint{structdevice*dev;structviommu_dev*viommu;
@@ -790,25 +833,9 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)if(vdev->vdomain)vdev->vdomain->nr_endpoints--;-req=(structvirtio_iommu_req_attach){-.head.type=VIRTIO_IOMMU_T_ATTACH,-.domain=cpu_to_le32(vdomain->id),-};--for(i=0;i<fwspec->num_ids;i++){-req.endpoint=cpu_to_le32(fwspec->ids[i]);--ret=viommu_send_req_sync(vdomain->viommu,&req,sizeof(req));-if(ret)-returnret;-}--if(!vdomain->nr_endpoints){-/*-*Thisendpointisthefirsttobeattachedtothedomain.-*Replayexistingmappings(e.g.SWMSI).-*/-ret=viommu_replay_mappings(vdomain);+if(!vdomain->mm.ops){+/* If we couldn't bind any table, use the mapping tree */+ret=viommu_simple_attach(vdomain,vdev);if(ret)returnret;}
@@ -1142,6 +1169,8 @@ static int viommu_probe(struct virtio_device *vdev)structvirtio_iommu_config,probe_size,&viommu->probe_size);+viommu->has_map=virtio_has_feature(vdev,VIRTIO_IOMMU_F_MAP_UNMAP);+viommu->geometry=(structiommu_domain_geometry){.aperture_start=input_start,.aperture_end=input_end,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Add info about asid_bits and additional flags to table format
probing header.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/virtio_iommu.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
From: Jean-Philippe Brucker <redacted>
Add support for tlb invalidation ops that can send invalidation
requests to back-end virtio-iommu when stage-1 page tables are
supported.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Refactoring the iommu_flush_ops, and adding only one pasid sync
op that's needed with current iommu-pasid-table infrastructure.
Also updating uapi defines as required by latest changes]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 95 ++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
From: Jean-Philippe Brucker <redacted>
When the ARM PASID table format is reported in a probe, send an attach
request and install the page tables for iommu_map/iommu_unmap use.
Architecture-specific components are already abstracted to libraries. We
just need to pass config bits around and setup an alternative mechanism to
the mapping tree.
We reuse the convention already adopted by other IOMMU architectures (ARM
SMMU and AMD IOMMU), that entry 0 in the PASID table is reserved for
non-PASID traffic. Bind the PASID table, and setup entry 0 to be modified
with iommu_map/unmap.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Bunch of refactoring and clean-ups to use iommu-pasid-table APIs,
creating iommu_pasid_table, and configuring based on reported
pasid format. Couple of additional methods have also been created
to configure vendor specific pasid configuration]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 314 +++++++++++++++++++++++++++++++++++
1 file changed, 314 insertions(+)
@@ -33,6 +34,9 @@#define VIOMMU_EVENT_VQ 1#define VIOMMU_NR_VQS 2+/* Some architectures need an Address Space ID for each page table */+staticDEFINE_IDA(asid_ida);+structviommu_dev{structiommu_deviceiommu;structdevice*dev;
@@ -76,6 +81,7 @@ struct viommu_domain {structmutexmutex;/* protects viommu pointer */unsignedintid;u32map_flags;+structiommu_pasid_table*pasid_tbl;/* Default address space when a table is bound */structviommu_mmmm;
@@ -891,6 +897,285 @@ static int viommu_simple_attach(struct viommu_domain *vdomain,returnret;}+staticintviommu_teardown_pgtable(structviommu_domain*vdomain)+{+structiommu_vendor_psdtable_cfg*pst_cfg;+structarm_smmu_cfg_info*cfgi;+u32asid;++if(!vdomain->mm.ops)+return0;++free_io_pgtable_ops(vdomain->mm.ops);+vdomain->mm.ops=NULL;++if(vdomain->pasid_tbl){+pst_cfg=&vdomain->pasid_tbl->cfg;+cfgi=&pst_cfg->vendor.cfg;+asid=cfgi->s1_cfg->cd.asid;++iommu_psdtable_write(vdomain->pasid_tbl,pst_cfg,0,NULL);+ida_simple_remove(&asid_ida,asid);+}++return0;+}++staticintviommu_setup_pgtable(structviommu_endpoint*vdev,+structviommu_domain*vdomain)+{+intret,id;+u32asid;+enumio_pgtable_fmtfmt;+structio_pgtable_ops*ops=NULL;+structviommu_dev*viommu=vdev->viommu;+structvirtio_iommu_probe_table_format*desc=vdev->pgtf;+structiommu_pasid_table*tbl=vdomain->pasid_tbl;+structiommu_vendor_psdtable_cfg*pst_cfg;+structarm_smmu_cfg_info*cfgi;+structio_pgtable_cfgcfg={+.iommu_dev=viommu->dev->parent,+.tlb=&viommu_flush_ops,+.pgsize_bitmap=vdev->pgsize_mask?vdev->pgsize_mask:+vdomain->domain.pgsize_bitmap,+.ias=(vdev->input_end?ilog2(vdev->input_end):+ilog2(vdomain->domain.geometry.aperture_end))+1,+.oas=vdev->output_bits,+};++if(!desc)+return-EINVAL;++if(!vdev->output_bits)+return-ENODEV;++switch(le16_to_cpu(desc->format)){+caseVIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE:+fmt=ARM_64_LPAE_S1;+break;+default:+dev_err(vdev->dev,"unsupported page table format 0x%x\n",+le16_to_cpu(desc->format));+return-EINVAL;+}++if(vdomain->mm.ops){+/*+*TODO:attachadditionalendpointtothedomain.Checkthat+*theconfigissane.+*/+return-EEXIST;+}++vdomain->mm.domain=vdomain;+ops=alloc_io_pgtable_ops(fmt,&cfg,&vdomain->mm);+if(!ops)+return-ENOMEM;++pst_cfg=&tbl->cfg;+cfgi=&pst_cfg->vendor.cfg;+id=ida_simple_get(&asid_ida,1,1<<desc->asid_bits,GFP_KERNEL);+if(id<0){+ret=id;+gotoerr_free_pgtable;+}++asid=id;+ret=iommu_psdtable_prepare(tbl,pst_cfg,&cfg,asid);+if(ret)+gotoerr_free_asid;++/*+*Strangetosetupanophere?+*cd-libistheactualuserofsyncop,andthereforetheplatform+*driversshouldassignthissync/maintenanceopsasperneed.+*/+tbl->ops->sync=viommu_flush_pasid;++/* Right now only PASID 0 supported ?? */+ret=iommu_psdtable_write(tbl,pst_cfg,0,&cfgi->s1_cfg->cd);+if(ret)+gotoerr_free_asid;++vdomain->mm.ops=ops;+dev_dbg(vdev->dev,"using page table format 0x%x\n",fmt);++return0;++err_free_asid:+ida_simple_remove(&asid_ida,asid);+err_free_pgtable:+free_io_pgtable_ops(ops);+returnret;+}++staticintviommu_config_arm_pst(structiommu_vendor_psdtable_cfg*pst_cfg,+structvirtio_iommu_req_attach_pst_arm*req)+{+structarm_smmu_s1_cfg*s1_cfg=pst_cfg->vendor.cfg.s1_cfg;++if(!s1_cfg)+return-ENODEV;++req->format=cpu_to_le16(VIRTIO_IOMMU_FORMAT_PSTF_ARM_SMMU_V3);+req->s1fmt=s1_cfg->s1fmt;+req->s1dss=VIRTIO_IOMMU_PSTF_ARM_SMMU_V3_DSS_0;+req->s1contextptr=cpu_to_le64(pst_cfg->base);+req->s1cdmax=cpu_to_le32(s1_cfg->s1cdmax);++return0;+}++staticintviommu_config_pst(structiommu_vendor_psdtable_cfg*pst_cfg,+void*req,enumpasid_table_fmtfmt)+{+intret;++switch(fmt){+casePASID_TABLE_ARM_SMMU_V3:+ret=viommu_config_arm_pst(pst_cfg,req);+break;+default:+ret=-EINVAL;+WARN_ON(1);+}++returnret;+}++staticintviommu_prepare_arm_pst(structviommu_endpoint*vdev,+structiommu_vendor_psdtable_cfg*pst_cfg)+{+structvirtio_iommu_probe_table_format*pgtf=vdev->pgtf;+structarm_smmu_cfg_info*cfgi=&pst_cfg->vendor.cfg;+structarm_smmu_s1_cfg*cfg;++/* Some sanity checks */+if(pgtf->asid_bits!=8&&pgtf->asid_bits!=16)+return-EINVAL;++cfg=devm_kzalloc(pst_cfg->iommu_dev,sizeof(cfg),GFP_KERNEL);+if(!cfg)+return-ENOMEM;++cfgi->s1_cfg=cfg;+cfg->s1cdmax=vdev->pasid_bits;+cfg->cd.asid=pgtf->asid_bits;++pst_cfg->fmt=PASID_TABLE_ARM_SMMU_V3;+/* XXX HACK: set feature bit ARM_SMMU_FEAT_2_LVL_CDTAB */+pst_cfg->vendor.cfg.feat_flag|=(1<<1);++return0;+}++staticintviommu_prepare_pst(structviommu_endpoint*vdev,+structiommu_vendor_psdtable_cfg*pst_cfg,+enumpasid_table_fmtfmt)+{+intret;++switch(fmt){+casePASID_TABLE_ARM_SMMU_V3:+ret=viommu_prepare_arm_pst(vdev,pst_cfg);+break;+default:+dev_err(vdev->dev,"unsupported PASID table format 0x%x\n",fmt);+ret=-EINVAL;+}++returnret;+}++staticintviommu_attach_pasid_table(structviommu_endpoint*vdev,+structviommu_domain*vdomain)+{+intret;+inti,eid;+enumpasid_table_fmtfmt=-1;+structvirtio_iommu_probe_table_format*desc=vdev->pstf;+structvirtio_iommu_req_attach_tablereq={+.head.type=VIRTIO_IOMMU_T_ATTACH_TABLE,+.domain=cpu_to_le32(vdomain->id),+};+structviommu_dev*viommu=vdev->viommu;+structiommu_pasid_table*tbl;+structiommu_vendor_psdtable_cfg*pst_cfg;++if(!viommu->has_table)+return0;++if(!desc)+return-ENODEV;++/* Prepare PASID tables configuration */+switch(le16_to_cpu(desc->format)){+caseVIRTIO_IOMMU_FORMAT_PSTF_ARM_SMMU_V3:+fmt=PASID_TABLE_ARM_SMMU_V3;+break;+default:+dev_err(vdev->dev,"unsupported PASID table format 0x%x\n",+le16_to_cpu(desc->format));+return0;+}++if(!tbl){+tbl=iommu_register_pasid_table(fmt,viommu->dev->parent,vdomain);+if(!tbl)+return-ENOMEM;++vdomain->pasid_tbl=tbl;+pst_cfg=&tbl->cfg;++pst_cfg->iommu_dev=viommu->dev->parent;++/* Prepare PASID tables info to allocate a new table */+ret=viommu_prepare_pst(vdev,pst_cfg,fmt);+if(ret)+returnret;++ret=iommu_psdtable_alloc(tbl,pst_cfg);+if(ret)+returnret;++pst_cfg->iommu_dev=viommu->dev->parent;+pst_cfg->fmt=PASID_TABLE_ARM_SMMU_V3;++ret=viommu_setup_pgtable(vdev,vdomain);+if(ret){+dev_err(vdev->dev,"could not install page tables\n");+gotoerr_free_psdtable;+}++/* Add arch-specific configuration */+ret=viommu_config_pst(pst_cfg,(void*)&req,fmt);+if(ret)+gotoerr_free_ops;++vdev_for_each_id(i,eid,vdev){+req.endpoint=cpu_to_le32(eid);+ret=viommu_send_req_sync(viommu,&req,sizeof(req));+if(ret)+gotoerr_free_ops;+}+}else{+/* TODO: otherwise, check for compatibility with vdev. */+return-ENOSYS;+}++dev_dbg(vdev->dev,"uses PASID table format 0x%x\n",fmt);++return0;++err_free_ops:+if(vdomain->mm.ops)+viommu_teardown_pgtable(vdomain);+err_free_psdtable:+iommu_psdtable_free(tbl,&tbl->cfg);++returnret;+}+staticintviommu_attach_dev(structiommu_domain*domain,structdevice*dev){intret=0;
@@ -928,6 +1213,17 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)if(vdev->vdomain)vdev->vdomain->nr_endpoints--;+ret=viommu_attach_pasid_table(vdev,vdomain);+if(ret){+/*+*NoPASIDsupport,toobad.Perhapswecanbindasingleset+*ofpagetables?+*/+ret=viommu_setup_pgtable(vdev,vdomain);+if(ret)+dev_err(vdev->dev,"could not install tables\n");+}+if(!vdomain->mm.ops){/* If we couldn't bind any table, use the mapping tree */ret=viommu_simple_attach(vdomain,vdev);
@@ -948,6 +1244,10 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,u32flags;structvirtio_iommu_req_mapmap;structviommu_domain*vdomain=to_viommu_domain(domain);+structio_pgtable_ops*ops=vdomain->mm.ops;++if(ops)+returnops->map(ops,iova,paddr,size,prot,gfp);flags=(prot&IOMMU_READ?VIRTIO_IOMMU_MAP_F_READ:0)|(prot&IOMMU_WRITE?VIRTIO_IOMMU_MAP_F_WRITE:0)|
From: Jean-Philippe Brucker <redacted>
Add the required UAPI defines for binding pasid tables in virtio-iommu.
This mode allows to hand stage-1 page tables over to the guest.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Refactor to cleanup headers for invalidation]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/virtio_iommu.h | 68 +++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
aisd_bits data is required to prepare stage-1 tables for arm-smmu-v3.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/iommu.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Jean-Philippe Brucker <redacted>
When PASID isn't supported, we can still register one set of tables.
Add support to register Arm LPAE based page table.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Clean-ups to add right tcr definitions and accomodate
with parent patches]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 131 +++++++++++++++++++++++++-----
include/uapi/linux/virtio_iommu.h | 30 +++++++
2 files changed, 139 insertions(+), 22 deletions(-)
@@ -897,6 +904,76 @@ static int viommu_simple_attach(struct viommu_domain *vdomain,returnret;}+staticintviommu_config_arm_pgt(structviommu_endpoint*vdev,+structio_pgtable_cfg*cfg,+structvirtio_iommu_req_attach_pgt_arm*req,+u64*asid)+{+intid;+structvirtio_iommu_probe_table_format*pgtf=(void*)vdev->pgtf;+typeof(&cfg->arm_lpae_s1_cfg.tcr)tcr=&cfg->arm_lpae_s1_cfg.tcr;+u64__tcr;++if(pgtf->asid_bits!=8&&pgtf->asid_bits!=16)+return-EINVAL;++id=ida_simple_get(&asid_ida,1,1<<pgtf->asid_bits,GFP_KERNEL);+if(id<0)+return-ENOMEM;++__tcr=VIRTIO_FIELD_PREP(T0SZ_MASK,T0SZ_SHIFT,tcr->tsz)|+VIRTIO_FIELD_PREP(IRGN0_MASK,IRGN0_SHIFT,tcr->irgn)|+VIRTIO_FIELD_PREP(ORGN0_MASK,ORGN0_SHIFT,tcr->orgn)|+VIRTIO_FIELD_PREP(SH0_MASK,SH0_SHIFT,tcr->sh)|+VIRTIO_FIELD_PREP(TG0_MASK,TG0_SHIFT,tcr->tg)|+VIRTIO_IOMMU_PGTF_ARM_EPD1|VIRTIO_IOMMU_PGTF_ARM_HPD0|+VIRTIO_IOMMU_PGTF_ARM_HPD1;++req->format=cpu_to_le16(VIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE);+req->ttbr=cpu_to_le64(cfg->arm_lpae_s1_cfg.ttbr);+req->tcr=cpu_to_le64(__tcr);+req->mair=cpu_to_le64(cfg->arm_lpae_s1_cfg.mair);+req->asid=cpu_to_le16(id);++*asid=id;+return0;+}++staticintviommu_attach_pgtable(structviommu_endpoint*vdev,+structviommu_domain*vdomain,+enumio_pgtable_fmtfmt,+structio_pgtable_cfg*cfg,+u64*asid)+{+intret;+inti,eid;++structvirtio_iommu_req_attach_tablereq={+.head.type=VIRTIO_IOMMU_T_ATTACH_TABLE,+.domain=cpu_to_le32(vdomain->id),+};++switch(fmt){+caseARM_64_LPAE_S1:+ret=viommu_config_arm_pgt(vdev,cfg,(void*)&req,asid);+if(ret)+returnret;+break;+default:+WARN_ON(1);+return-EINVAL;+}++vdev_for_each_id(i,eid,vdev){+req.endpoint=cpu_to_le32(eid);+ret=viommu_send_req_sync(vdomain->viommu,&req,sizeof(req));+if(ret)+returnret;+}++return0;+}+staticintviommu_teardown_pgtable(structviommu_domain*vdomain){structiommu_vendor_psdtable_cfg*pst_cfg;
@@ -972,32 +1049,42 @@ static int viommu_setup_pgtable(struct viommu_endpoint *vdev,if(!ops)return-ENOMEM;-pst_cfg=&tbl->cfg;-cfgi=&pst_cfg->vendor.cfg;-id=ida_simple_get(&asid_ida,1,1<<desc->asid_bits,GFP_KERNEL);-if(id<0){-ret=id;-gotoerr_free_pgtable;-}+if(!tbl){+/* No PASID support, send attach_table */+ret=viommu_attach_pgtable(vdev,vdomain,fmt,&cfg,+&vdomain->mm.archid);+if(ret)+gotoerr_free_pgtable;+}else{+pst_cfg=&tbl->cfg;+cfgi=&pst_cfg->vendor.cfg;+id=ida_simple_get(&asid_ida,1,1<<desc->asid_bits,GFP_KERNEL);+if(id<0){+ret=id;+gotoerr_free_pgtable;+}-asid=id;-ret=iommu_psdtable_prepare(tbl,pst_cfg,&cfg,asid);-if(ret)-gotoerr_free_asid;+asid=id;+ret=iommu_psdtable_prepare(tbl,pst_cfg,&cfg,asid);+if(ret)+gotoerr_free_asid;-/*-*Strangetosetupanophere?-*cd-libistheactualuserofsyncop,andthereforetheplatform-*driversshouldassignthissync/maintenanceopsasperneed.-*/-tbl->ops->sync=viommu_flush_pasid;+/*+*Strangetosetupanophere?+*cd-libistheactualuserofsyncop,andthereforethe+*cd-libconsumerdriversshouldassignthissync/maintenance+*opsasperneed.+*/+tbl->ops->sync=viommu_flush_pasid;-/* Right now only PASID 0 supported ?? */-ret=iommu_psdtable_write(tbl,pst_cfg,0,&cfgi->s1_cfg->cd);-if(ret)-gotoerr_free_asid;+/* Right now only PASID 0 supported */+ret=iommu_psdtable_write(tbl,pst_cfg,0,&cfgi->s1_cfg->cd);+if(ret)+gotoerr_free_asid;++vdomain->mm.ops=ops;+}-vdomain->mm.ops=ops;dev_dbg(vdev->dev,"using page table format 0x%x\n",fmt);return0;
Fault type information can tell about a page request fault or
an unreceoverable fault, and further additions to fault reasons
and the related PASID information can help in handling faults
efficiently.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 27 +++++++++++++++++++++++++--
include/uapi/linux/virtio_iommu.h | 13 ++++++++++++-
2 files changed, 37 insertions(+), 3 deletions(-)
@@ -663,6 +670,21 @@ static int viommu_fault_handler(struct viommu_dev *viommu,caseVIRTIO_IOMMU_FAULT_R_MAPPING:reason_str="page";break;+caseVIRTIO_IOMMU_FAULT_R_WALK_EABT:+reason_str="page walk external abort";+break;+caseVIRTIO_IOMMU_FAULT_R_PTE_FETCH:+reason_str="pte fetch";+break;+caseVIRTIO_IOMMU_FAULT_R_PERMISSION:+reason_str="permission";+break;+caseVIRTIO_IOMMU_FAULT_R_ACCESS:+reason_str="access";+break;+caseVIRTIO_IOMMU_FAULT_R_OOR_ADDRESS:+reason_str="output address";+break;caseVIRTIO_IOMMU_FAULT_R_UNKNOWN:default:reason_str="unknown";
@@ -671,8 +693,9 @@ static int viommu_fault_handler(struct viommu_dev *viommu,/* TODO: find EP by ID and report_iommu_fault */if(flags&VIRTIO_IOMMU_FAULT_F_ADDRESS)-dev_err_ratelimited(viommu->dev,"%s fault from EP %u at %#llx [%s%s%s]\n",-reason_str,endpoint,address,+dev_err_ratelimited(viommu->dev,+"%s fault from EP %u PASID %u at %#llx [%s%s%s]\n",+reason_str,endpoint,pasid,address,flags&VIRTIO_IOMMU_FAULT_F_READ?"R":"",flags&VIRTIO_IOMMU_FAULT_F_WRITE?"W":"",flags&VIRTIO_IOMMU_FAULT_F_EXEC?"X":"");
From: Auger Eric <eric.auger@redhat.com> Date: 2021-01-19 09:08:25
Hi Vivek,
On 1/15/21 1:13 PM, Vivek Gautam wrote:
This patch-series aims at enabling Nested stage translation in guests
using virtio-iommu as the paravirtualized iommu. The backend is supported
with Arm SMMU-v3 that provides nested stage-1 and stage-2 translation.
This series derives its purpose from various efforts happening to add
support for Shared Virtual Addressing (SVA) in host and guest. On Arm,
most of the support for SVA has already landed. The support for nested
stage translation and fault reporting to guest has been proposed [1].
The related changes required in VFIO [2] framework have also been put
forward.
This series proposes changes in virtio-iommu to program PASID tables
and related stage-1 page tables. A simple iommu-pasid-table library
is added for this purpose that interacts with vendor drivers to
allocate and populate PASID tables.
In Arm SMMUv3 we propose to pull the Context Descriptor (CD) management
code out of the arm-smmu-v3 driver and add that as a glue vendor layer
to support allocating CD tables, and populating them with right values.
These CD tables are essentially the PASID tables and contain stage-1
page table configurations too.
A request to setup these CD tables come from virtio-iommu driver using
the iommu-pasid-table library when running on Arm. The virtio-iommu
then pass these PASID tables to the host using the right virtio backend
and support in VMM.
For testing we have added necessary support in kvmtool. The changes in
kvmtool are based on virtio-iommu development branch by Jean-Philippe
Brucker [3].
The tested kernel branch contains following in the order bottom to top
on the git hash -
a) v5.11-rc3
b) arm-smmu-v3 [1] and vfio [2] changes from Eric to add nested page
table support for Arm.
c) Smmu test engine patches from Jean-Philippe's branch [4]
d) This series
e) Domain nesting info patches [5][6][7].
f) Changes to add arm-smmu-v3 specific nesting info (to be sent to
the list).
This kernel is tested on Neoverse reference software stack with
Fixed virtual platform. Public version of the software stack and
FVP is available here[8][9].
A big thanks to Jean-Philippe for his contributions towards this work
and for his valuable guidance.
[1] https://lore.kernel.org/linux-iommu/20201118112151.25412-1-eric.auger@redhat.com/T/
[2] https://lore.kernel.org/kvmarm/20201116110030.32335-12-eric.auger@redhat.com/T/
[3] https://jpbrucker.net/git/kvmtool/log/?h=virtio-iommu/devel
[4] https://jpbrucker.net/git/linux/log/?h=sva/smmute
[5] https://lore.kernel.org/kvm/1599734733-6431-2-git-send-email-yi.l.liu@intel.com/
[6] https://lore.kernel.org/kvm/1599734733-6431-3-git-send-email-yi.l.liu@intel.com/
[7] https://lore.kernel.org/kvm/1599734733-6431-4-git-send-email-yi.l.liu@intel.com/
[8] https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps
[9] https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/rdn1edge/user-guide.rst
Could you share a public branch where we could find all the kernel pieces.
Thank you in advance
Best Regards
Eric
Jean-Philippe Brucker (6):
iommu/virtio: Add headers for table format probing
iommu/virtio: Add table format probing
iommu/virtio: Add headers for binding pasid table in iommu
iommu/virtio: Add support for INVALIDATE request
iommu/virtio: Attach Arm PASID tables when available
iommu/virtio: Add support for Arm LPAE page table format
Vivek Gautam (9):
iommu/arm-smmu-v3: Create a Context Descriptor library
iommu: Add a simple PASID table library
iommu/arm-smmu-v3: Update drivers to work with iommu-pasid-table
iommu/arm-smmu-v3: Update CD base address info for user-space
iommu/arm-smmu-v3: Set sync op from consumer driver of cd-lib
iommu: Add asid_bits to arm smmu-v3 stage1 table info
iommu/virtio: Update table format probing header
iommu/virtio: Prepare to add attach pasid table infrastructure
iommu/virtio: Update fault type and reason info for viommu fault
drivers/iommu/arm/arm-smmu-v3/Makefile | 2 +-
.../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 283 +++++++
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 16 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 268 +------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 4 +-
drivers/iommu/iommu-pasid-table.h | 140 ++++
drivers/iommu/virtio-iommu.c | 692 +++++++++++++++++-
include/uapi/linux/iommu.h | 2 +-
include/uapi/linux/virtio_iommu.h | 158 +++-
9 files changed, 1303 insertions(+), 262 deletions(-)
create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c
create mode 100644 drivers/iommu/iommu-pasid-table.h
This patch-series aims at enabling Nested stage translation in guests
using virtio-iommu as the paravirtualized iommu. The backend is supported
with Arm SMMU-v3 that provides nested stage-1 and stage-2 translation.
This series derives its purpose from various efforts happening to add
support for Shared Virtual Addressing (SVA) in host and guest. On Arm,
most of the support for SVA has already landed. The support for nested
stage translation and fault reporting to guest has been proposed [1].
The related changes required in VFIO [2] framework have also been put
forward.
This series proposes changes in virtio-iommu to program PASID tables
and related stage-1 page tables. A simple iommu-pasid-table library
is added for this purpose that interacts with vendor drivers to
allocate and populate PASID tables.
In Arm SMMUv3 we propose to pull the Context Descriptor (CD) management
code out of the arm-smmu-v3 driver and add that as a glue vendor layer
to support allocating CD tables, and populating them with right values.
These CD tables are essentially the PASID tables and contain stage-1
page table configurations too.
A request to setup these CD tables come from virtio-iommu driver using
the iommu-pasid-table library when running on Arm. The virtio-iommu
then pass these PASID tables to the host using the right virtio backend
and support in VMM.
For testing we have added necessary support in kvmtool. The changes in
kvmtool are based on virtio-iommu development branch by Jean-Philippe
Brucker [3].
The tested kernel branch contains following in the order bottom to top
on the git hash -
a) v5.11-rc3
b) arm-smmu-v3 [1] and vfio [2] changes from Eric to add nested page
table support for Arm.
c) Smmu test engine patches from Jean-Philippe's branch [4]
d) This series
e) Domain nesting info patches [5][6][7].
f) Changes to add arm-smmu-v3 specific nesting info (to be sent to
the list).
This kernel is tested on Neoverse reference software stack with
Fixed virtual platform. Public version of the software stack and
FVP is available here[8][9].
A big thanks to Jean-Philippe for his contributions towards this work
and for his valuable guidance.
[1] https://lore.kernel.org/linux-iommu/20201118112151.25412-1-eric.auger@redhat.com/T/
[2] https://lore.kernel.org/kvmarm/20201116110030.32335-12-eric.auger@redhat.com/T/
[3] https://jpbrucker.net/git/kvmtool/log/?h=virtio-iommu/devel
[4] https://jpbrucker.net/git/linux/log/?h=sva/smmute
[5] https://lore.kernel.org/kvm/1599734733-6431-2-git-send-email-yi.l.liu@intel.com/
[6] https://lore.kernel.org/kvm/1599734733-6431-3-git-send-email-yi.l.liu@intel.com/
[7] https://lore.kernel.org/kvm/1599734733-6431-4-git-send-email-yi.l.liu@intel.com/
[8] https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps
[9] https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/rdn1edge/user-guide.rst
Could you share a public branch where we could find all the kernel pieces.
Thank you in advance
Jean-Philippe Brucker (6):
iommu/virtio: Add headers for table format probing
iommu/virtio: Add table format probing
iommu/virtio: Add headers for binding pasid table in iommu
iommu/virtio: Add support for INVALIDATE request
iommu/virtio: Attach Arm PASID tables when available
iommu/virtio: Add support for Arm LPAE page table format
Vivek Gautam (9):
iommu/arm-smmu-v3: Create a Context Descriptor library
iommu: Add a simple PASID table library
iommu/arm-smmu-v3: Update drivers to work with iommu-pasid-table
iommu/arm-smmu-v3: Update CD base address info for user-space
iommu/arm-smmu-v3: Set sync op from consumer driver of cd-lib
iommu: Add asid_bits to arm smmu-v3 stage1 table info
iommu/virtio: Update table format probing header
iommu/virtio: Prepare to add attach pasid table infrastructure
iommu/virtio: Update fault type and reason info for viommu fault
drivers/iommu/arm/arm-smmu-v3/Makefile | 2 +-
.../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 283 +++++++
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 16 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 268 +------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 4 +-
drivers/iommu/iommu-pasid-table.h | 140 ++++
drivers/iommu/virtio-iommu.c | 692 +++++++++++++++++-
include/uapi/linux/iommu.h | 2 +-
include/uapi/linux/virtio_iommu.h | 158 +++-
9 files changed, 1303 insertions(+), 262 deletions(-)
create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c
create mode 100644 drivers/iommu/iommu-pasid-table.h
-----Original Message-----
From: Vivek Kumar Gautam [mailto:vivek.gautam@arm.com]
Sent: 21 January 2021 17:34
To: Auger Eric <eric.auger@redhat.com>; linux-kernel@vger.kernel.org;
linux-arm-kernel@lists.infradead.org; iommu@lists.linux-foundation.org;
virtualization@lists.linux-foundation.org
Cc: joro@8bytes.org; will.deacon@arm.com; mst@redhat.com;
robin.murphy@arm.com; jean-philippe@linaro.org;
alex.williamson@redhat.com; kevin.tian@intel.com;
jacob.jun.pan@linux.intel.com; yi.l.liu@intel.com; lorenzo.pieralisi@arm.com;
Shameerali Kolothum Thodi [off-list ref]
Subject: Re: [PATCH RFC v1 00/15] iommu/virtio: Nested stage support with
Arm
Hi Eric,
On 1/19/21 2:33 PM, Auger Eric wrote:
quoted
Hi Vivek,
On 1/15/21 1:13 PM, Vivek Gautam wrote:
quoted
This patch-series aims at enabling Nested stage translation in guests
using virtio-iommu as the paravirtualized iommu. The backend is
supported with Arm SMMU-v3 that provides nested stage-1 and stage-2
translation.
quoted
quoted
This series derives its purpose from various efforts happening to add
support for Shared Virtual Addressing (SVA) in host and guest. On
Arm, most of the support for SVA has already landed. The support for
nested stage translation and fault reporting to guest has been proposed [1].
The related changes required in VFIO [2] framework have also been put
forward.
This series proposes changes in virtio-iommu to program PASID tables
and related stage-1 page tables. A simple iommu-pasid-table library
is added for this purpose that interacts with vendor drivers to
allocate and populate PASID tables.
In Arm SMMUv3 we propose to pull the Context Descriptor (CD)
management code out of the arm-smmu-v3 driver and add that as a glue
vendor layer to support allocating CD tables, and populating them with right
values.
quoted
quoted
These CD tables are essentially the PASID tables and contain stage-1
page table configurations too.
A request to setup these CD tables come from virtio-iommu driver
using the iommu-pasid-table library when running on Arm. The
virtio-iommu then pass these PASID tables to the host using the right
virtio backend and support in VMM.
For testing we have added necessary support in kvmtool. The changes
in kvmtool are based on virtio-iommu development branch by
Jean-Philippe Brucker [3].
The tested kernel branch contains following in the order bottom to
top on the git hash -
a) v5.11-rc3
b) arm-smmu-v3 [1] and vfio [2] changes from Eric to add nested page
table support for Arm.
c) Smmu test engine patches from Jean-Philippe's branch [4]
d) This series
e) Domain nesting info patches [5][6][7].
f) Changes to add arm-smmu-v3 specific nesting info (to be sent to
the list).
This kernel is tested on Neoverse reference software stack with Fixed
virtual platform. Public version of the software stack and FVP is
available here[8][9].
A big thanks to Jean-Philippe for his contributions towards this work
and for his valuable guidance.
[1]
https://lore.kernel.org/linux-iommu/20201118112151.25412-1-eric.auger
@redhat.com/T/ [2]
Thanks for this. Do you have a corresponding kvmtool branch mentioned above as public?
Thanks,
Shameer
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Auger Eric <eric.auger@redhat.com> Date: 2021-01-26 05:06:42
Hi Vivek,
On 1/21/21 6:34 PM, Vivek Kumar Gautam wrote:
Hi Eric,
On 1/19/21 2:33 PM, Auger Eric wrote:
quoted
Hi Vivek,
On 1/15/21 1:13 PM, Vivek Gautam wrote:
quoted
This patch-series aims at enabling Nested stage translation in guests
using virtio-iommu as the paravirtualized iommu. The backend is
supported
with Arm SMMU-v3 that provides nested stage-1 and stage-2 translation.
This series derives its purpose from various efforts happening to add
support for Shared Virtual Addressing (SVA) in host and guest. On Arm,
most of the support for SVA has already landed. The support for nested
stage translation and fault reporting to guest has been proposed [1].
The related changes required in VFIO [2] framework have also been put
forward.
This series proposes changes in virtio-iommu to program PASID tables
and related stage-1 page tables. A simple iommu-pasid-table library
is added for this purpose that interacts with vendor drivers to
allocate and populate PASID tables.
In Arm SMMUv3 we propose to pull the Context Descriptor (CD) management
code out of the arm-smmu-v3 driver and add that as a glue vendor layer
to support allocating CD tables, and populating them with right values.
These CD tables are essentially the PASID tables and contain stage-1
page table configurations too.
A request to setup these CD tables come from virtio-iommu driver using
the iommu-pasid-table library when running on Arm. The virtio-iommu
then pass these PASID tables to the host using the right virtio backend
and support in VMM.
For testing we have added necessary support in kvmtool. The changes in
kvmtool are based on virtio-iommu development branch by Jean-Philippe
Brucker [3].
The tested kernel branch contains following in the order bottom to top
on the git hash -
a) v5.11-rc3
b) arm-smmu-v3 [1] and vfio [2] changes from Eric to add nested page
table support for Arm.
c) Smmu test engine patches from Jean-Philippe's branch [4]
d) This series
e) Domain nesting info patches [5][6][7].
f) Changes to add arm-smmu-v3 specific nesting info (to be sent to
the list).
This kernel is tested on Neoverse reference software stack with
Fixed virtual platform. Public version of the software stack and
FVP is available here[8][9].
A big thanks to Jean-Philippe for his contributions towards this work
and for his valuable guidance.
[1]
https://lore.kernel.org/linux-iommu/20201118112151.25412-1-eric.auger@redhat.com/T/
[2]
https://lore.kernel.org/kvmarm/20201116110030.32335-12-eric.auger@redhat.com/T/
[3] https://jpbrucker.net/git/kvmtool/log/?h=virtio-iommu/devel
[4] https://jpbrucker.net/git/linux/log/?h=sva/smmute
[5]
https://lore.kernel.org/kvm/1599734733-6431-2-git-send-email-yi.l.liu@intel.com/
[6]
https://lore.kernel.org/kvm/1599734733-6431-3-git-send-email-yi.l.liu@intel.com/
[7]
https://lore.kernel.org/kvm/1599734733-6431-4-git-send-email-yi.l.liu@intel.com/
[8]
https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps
[9]
https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/rdn1edge/user-guide.rst
Could you share a public branch where we could find all the kernel
pieces.
Thank you in advance
no problem. Thank you for the link.
Best Regards
Eric
Thanks and regards
Vivek
quoted
Best Regards
Eric
quoted
Jean-Philippe Brucker (6):
iommu/virtio: Add headers for table format probing
iommu/virtio: Add table format probing
iommu/virtio: Add headers for binding pasid table in iommu
iommu/virtio: Add support for INVALIDATE request
iommu/virtio: Attach Arm PASID tables when available
iommu/virtio: Add support for Arm LPAE page table format
Vivek Gautam (9):
iommu/arm-smmu-v3: Create a Context Descriptor library
iommu: Add a simple PASID table library
iommu/arm-smmu-v3: Update drivers to work with iommu-pasid-table
iommu/arm-smmu-v3: Update CD base address info for user-space
iommu/arm-smmu-v3: Set sync op from consumer driver of cd-lib
iommu: Add asid_bits to arm smmu-v3 stage1 table info
iommu/virtio: Update table format probing header
iommu/virtio: Prepare to add attach pasid table infrastructure
iommu/virtio: Update fault type and reason info for viommu fault
drivers/iommu/arm/arm-smmu-v3/Makefile | 2 +-
.../arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 283 +++++++
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 16 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 268 +------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 4 +-
drivers/iommu/iommu-pasid-table.h | 140 ++++
drivers/iommu/virtio-iommu.c | 692 +++++++++++++++++-
include/uapi/linux/iommu.h | 2 +-
include/uapi/linux/virtio_iommu.h | 158 +++-
9 files changed, 1303 insertions(+), 262 deletions(-)
create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c
create mode 100644 drivers/iommu/iommu-pasid-table.h
Hi Shameer,
On 1/22/21 9:19 PM, Shameerali Kolothum Thodi wrote:
Hi Vivek,
quoted
-----Original Message-----
From: Vivek Kumar Gautam [mailto:vivek.gautam@arm.com]
Sent: 21 January 2021 17:34
To: Auger Eric <eric.auger@redhat.com>; linux-kernel@vger.kernel.org;
linux-arm-kernel@lists.infradead.org; iommu@lists.linux-foundation.org;
virtualization@lists.linux-foundation.org
Cc: joro@8bytes.org; will.deacon@arm.com; mst@redhat.com;
robin.murphy@arm.com; jean-philippe@linaro.org;
alex.williamson@redhat.com; kevin.tian@intel.com;
jacob.jun.pan@linux.intel.com; yi.l.liu@intel.com; lorenzo.pieralisi@arm.com;
Shameerali Kolothum Thodi [off-list ref]
Subject: Re: [PATCH RFC v1 00/15] iommu/virtio: Nested stage support with
Arm
Hi Eric,
On 1/19/21 2:33 PM, Auger Eric wrote:
quoted
Hi Vivek,
On 1/15/21 1:13 PM, Vivek Gautam wrote:
quoted
This patch-series aims at enabling Nested stage translation in guests
using virtio-iommu as the paravirtualized iommu. The backend is
supported with Arm SMMU-v3 that provides nested stage-1 and stage-2
translation.
quoted
quoted
This series derives its purpose from various efforts happening to add
support for Shared Virtual Addressing (SVA) in host and guest. On
Arm, most of the support for SVA has already landed. The support for
nested stage translation and fault reporting to guest has been proposed [1].
The related changes required in VFIO [2] framework have also been put
forward.
This series proposes changes in virtio-iommu to program PASID tables
and related stage-1 page tables. A simple iommu-pasid-table library
is added for this purpose that interacts with vendor drivers to
allocate and populate PASID tables.
In Arm SMMUv3 we propose to pull the Context Descriptor (CD)
management code out of the arm-smmu-v3 driver and add that as a glue
vendor layer to support allocating CD tables, and populating them with right
values.
quoted
quoted
These CD tables are essentially the PASID tables and contain stage-1
page table configurations too.
A request to setup these CD tables come from virtio-iommu driver
using the iommu-pasid-table library when running on Arm. The
virtio-iommu then pass these PASID tables to the host using the right
virtio backend and support in VMM.
For testing we have added necessary support in kvmtool. The changes
in kvmtool are based on virtio-iommu development branch by
Jean-Philippe Brucker [3].
The tested kernel branch contains following in the order bottom to
top on the git hash -
a) v5.11-rc3
b) arm-smmu-v3 [1] and vfio [2] changes from Eric to add nested page
table support for Arm.
c) Smmu test engine patches from Jean-Philippe's branch [4]
d) This series
e) Domain nesting info patches [5][6][7].
f) Changes to add arm-smmu-v3 specific nesting info (to be sent to
the list).
This kernel is tested on Neoverse reference software stack with Fixed
virtual platform. Public version of the software stack and FVP is
available here[8][9].
A big thanks to Jean-Philippe for his contributions towards this work
and for his valuable guidance.
[1]
https://lore.kernel.org/linux-iommu/20201118112151.25412-1-eric.auger
@redhat.com/T/ [2]
> Thanks for this. Do you have a corresponding kvmtool branch mentioned
above as public?
Thanks for showing interest. I will publish the kvmtool branch asap.
Though the current development is based on Jean's branch for
virtio-iommu [1], I plan to rebase the changes to master soon.
Thanks & regards
Vivek
[1] https://jpbrucker.net/git/kvmtool/log/?h=virtio-iommu/devel
Hi Vivek,
Thanks again for working on this. I have a few comments but it looks
sensible overall.
Regarding the overall design, I was initially assigning page directories
instead of whole PASID tables, which would simplify the driver and host
implementation. A major complication, however, is SMMUv3 accesses PASID
tables using a guest-physical address, so there is a messy negotiation
needed between host and guest when the host needs to allocate PASID
tables. Plus vSMMU needs PASID table assignment, so that's what the host
driver will implement.
On Fri, Jan 15, 2021 at 05:43:29PM +0530, Vivek Gautam wrote:
Add a small API in iommu subsystem to handle PASID table allocation
requests from different consumer drivers, such as a paravirtualized
iommu driver. The API provides ops for allocating and freeing PASID
table, writing to it and managing the table caches.
This library also provides for registering a vendor API that attaches
to these ops. The vendor APIs would eventually perform arch level
implementations for these PASID tables.
Although Arm might be the only vendor to ever use this, I think the
abstraction makes sense and isn't too invasive. Even if we called directly
into the SMMU driver from the virtio one, we'd still need patch 3 and
separate TLB invalidations ops.
quoted hunk
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/iommu-pasid-table.h | 134 ++++++++++++++++++++++++++++++
1 file changed, 134 insertions(+)
create mode 100644 drivers/iommu/iommu-pasid-table.h
On Fri, Jan 15, 2021 at 05:43:31PM +0530, Vivek Gautam wrote:
quoted hunk
Update base address information in vendor pasid table info to pass that
to user-space for stage1 table management.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 6 ++++++
1 file changed, 6 insertions(+)
This isn't the right place, because this path allocates second-level
tables for two-level tables. I don't think we need pst_cfg->base at all,
because for both linear and two-level tables, the base pointer is in
cdcfg->cdtab_dma, which can be read directly.
Thanks,
Jean
quoted hunk
l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
arm_smmu_write_cd_l1_desc(l1ptr, l1_desc);
/* An invalid L1CD can be cached */
On Fri, Jan 15, 2021 at 05:43:32PM +0530, Vivek Gautam wrote:
quoted hunk
Te change allows different consumers of arm-smmu-v3-cd-lib to set
their respective sync op for pasid entries.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 1 -
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 7 +++++++
2 files changed, 7 insertions(+), 1 deletion(-)
@@ -1869,6 +1869,13 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,if(ret)gotoout_free_cd_tables;+/*+*Strangetosetupanophere?+*cd-libistheactualuserofsyncop,andthereforetheplatform+*driversshouldassignthissync/maintenanceopsasperneed.+*/+tbl->ops->sync=arm_smmu_sync_cd;+
Modifying a static struct from here doesn't feel right. I think the
interface should be roughly similar to io-pgtable since the principle is
the same. So the sync() op should be separate from arm_cd_table_ops since
it's a callback into the driver. Maybe pass it to
iommu_register_pasid_table().
Thanks,
Jean
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 05:43:33PM +0530, Vivek Gautam wrote:
From: Jean-Philippe Brucker <redacted>
Add required UAPI defines for probing table format for underlying
iommu hardware. The device may provide information about hardware
tables and additional capabilities for each device.
This allows guest to correctly fabricate stage-1 page tables.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Use a single "struct virtio_iommu_probe_table_format" rather
than separate structures for page table and pasid table format.
On Fri, Jan 15, 2021 at 05:43:35PM +0530, Vivek Gautam wrote:
quoted hunk
aisd_bits data is required to prepare stage-1 tables for arm-smmu-v3.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/iommu.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Is this used anywhere? This struct is passed from host userspace to host
kernel to attach the PASID table, so I don't think it needs an asid_bits
field.
Thanks,
Jean
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 05:43:36PM +0530, Vivek Gautam wrote:
quoted hunk
Add info about asid_bits and additional flags to table format
probing header.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/virtio_iommu.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
This struct should only contain the head and format fields. asid and flags
should go in a specialized structure - virtio_iommu_probe_pgt_arm64 in the
latest spec draft, where I dropped the asid_bits field in favor of an
"ASID16" flag.
Thanks,
Jean
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 05:43:40PM +0530, Vivek Gautam wrote:
[...]
+static int viommu_setup_pgtable(struct viommu_endpoint *vdev,
+ struct viommu_domain *vdomain)
+{
+ int ret, id;
+ u32 asid;
+ enum io_pgtable_fmt fmt;
+ struct io_pgtable_ops *ops = NULL;
+ struct viommu_dev *viommu = vdev->viommu;
+ struct virtio_iommu_probe_table_format *desc = vdev->pgtf;
+ struct iommu_pasid_table *tbl = vdomain->pasid_tbl;
+ struct iommu_vendor_psdtable_cfg *pst_cfg;
+ struct arm_smmu_cfg_info *cfgi;
+ struct io_pgtable_cfg cfg = {
+ .iommu_dev = viommu->dev->parent,
+ .tlb = &viommu_flush_ops,
+ .pgsize_bitmap = vdev->pgsize_mask ? vdev->pgsize_mask :
+ vdomain->domain.pgsize_bitmap,
+ .ias = (vdev->input_end ? ilog2(vdev->input_end) :
+ ilog2(vdomain->domain.geometry.aperture_end)) + 1,
+ .oas = vdev->output_bits,
+ };
+
+ if (!desc)
+ return -EINVAL;
+
+ if (!vdev->output_bits)
+ return -ENODEV;
+
+ switch (le16_to_cpu(desc->format)) {
+ case VIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE:
+ fmt = ARM_64_LPAE_S1;
+ break;
+ default:
+ dev_err(vdev->dev, "unsupported page table format 0x%x\n",
+ le16_to_cpu(desc->format));
+ return -EINVAL;
+ }
+
+ if (vdomain->mm.ops) {
+ /*
+ * TODO: attach additional endpoint to the domain. Check that
+ * the config is sane.
+ */
+ return -EEXIST;
+ }
+
+ vdomain->mm.domain = vdomain;
+ ops = alloc_io_pgtable_ops(fmt, &cfg, &vdomain->mm);
+ if (!ops)
+ return -ENOMEM;
+
+ pst_cfg = &tbl->cfg;
+ cfgi = &pst_cfg->vendor.cfg;
+ id = ida_simple_get(&asid_ida, 1, 1 << desc->asid_bits, GFP_KERNEL);
+ if (id < 0) {
+ ret = id;
+ goto err_free_pgtable;
+ }
+
+ asid = id;
+ ret = iommu_psdtable_prepare(tbl, pst_cfg, &cfg, asid);
+ if (ret)
+ goto err_free_asid;
+
+ /*
+ * Strange to setup an op here?
+ * cd-lib is the actual user of sync op, and therefore the platform
+ * drivers should assign this sync/maintenance ops as per need.
+ */
+ tbl->ops->sync = viommu_flush_pasid;
But this function deals with page tables, not pasid tables. As said on an
earlier patch, the TLB flush ops should probably be passed during table
registration - those ops are global so should really be const.
That doesn't look right, cfg->cd.asid takes the ASID value of context 0
but here we're writing a limit. viommu_setup_pgtable() probably needs to
set this field to the allocated ASID, since viommu_teardown_pgtable() uses
it.
+
+ pst_cfg->fmt = PASID_TABLE_ARM_SMMU_V3;
Parent function can set this
+ /* XXX HACK: set feature bit ARM_SMMU_FEAT_2_LVL_CDTAB */
+ pst_cfg->vendor.cfg.feat_flag |= (1 << 1);
Oh right, this flag is missing. I'll add
#define VIRTIO_IOMMU_PST_ARM_SMMU3_F_CD2L (1ULL << 1)
to the spec.
Already set by iommu_register_pasid_table() (and needed for DMA
allocations in iommu_psdtable_alloc())
+ pst_cfg->fmt = PASID_TABLE_ARM_SMMU_V3;
Already set above
quoted hunk
+
+ ret = viommu_setup_pgtable(vdev, vdomain);
+ if (ret) {
+ dev_err(vdev->dev, "could not install page tables\n");
+ goto err_free_psdtable;
+ }
+
+ /* Add arch-specific configuration */
+ ret = viommu_config_pst(pst_cfg, (void *)&req, fmt);
+ if (ret)
+ goto err_free_ops;
+
+ vdev_for_each_id(i, eid, vdev) {
+ req.endpoint = cpu_to_le32(eid);
+ ret = viommu_send_req_sync(viommu, &req, sizeof(req));
+ if (ret)
+ goto err_free_ops;
+ }
+ } else {
+ /* TODO: otherwise, check for compatibility with vdev. */
+ return -ENOSYS;
+ }
+
+ dev_dbg(vdev->dev, "uses PASID table format 0x%x\n", fmt);
+
+ return 0;
+
+err_free_ops:
+ if (vdomain->mm.ops)
+ viommu_teardown_pgtable(vdomain);
+err_free_psdtable:
+ iommu_psdtable_free(tbl, &tbl->cfg);
+
+ return ret;
+}
+
static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
int ret = 0;
@@ -928,6 +1213,17 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) if (vdev->vdomain) vdev->vdomain->nr_endpoints--;+ ret = viommu_attach_pasid_table(vdev, vdomain);+ if (ret) {+ /*+ * No PASID support, too bad. Perhaps we can bind a single set+ * of page tables?+ */+ ret = viommu_setup_pgtable(vdev, vdomain);
This cannot work at the moment because viommu_setup_pgtable() writes to
the non-existing pasid table. Probably best to leave this call for next
patch.
Thanks,
Jean
quoted hunk
+ if (ret)
+ dev_err(vdev->dev, "could not install tables\n");
+ }
+
if (!vdomain->mm.ops) {
/* If we couldn't bind any table, use the mapping tree */
ret = viommu_simple_attach(vdomain, vdev);
On Fri, Jan 15, 2021 at 05:43:42PM +0530, Vivek Gautam wrote:
quoted hunk
Fault type information can tell about a page request fault or
an unreceoverable fault, and further additions to fault reasons
and the related PASID information can help in handling faults
efficiently.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 27 +++++++++++++++++++++++++--
include/uapi/linux/virtio_iommu.h | 13 ++++++++++++-
2 files changed, 37 insertions(+), 3 deletions(-)
@@ -663,6 +670,21 @@ static int viommu_fault_handler(struct viommu_dev *viommu,caseVIRTIO_IOMMU_FAULT_R_MAPPING:reason_str="page";break;+caseVIRTIO_IOMMU_FAULT_R_WALK_EABT:+reason_str="page walk external abort";+break;+caseVIRTIO_IOMMU_FAULT_R_PTE_FETCH:+reason_str="pte fetch";+break;+caseVIRTIO_IOMMU_FAULT_R_PERMISSION:+reason_str="permission";+break;+caseVIRTIO_IOMMU_FAULT_R_ACCESS:+reason_str="access";+break;+caseVIRTIO_IOMMU_FAULT_R_OOR_ADDRESS:+reason_str="output address";+break;caseVIRTIO_IOMMU_FAULT_R_UNKNOWN:default:reason_str="unknown";
@@ -671,8 +693,9 @@ static int viommu_fault_handler(struct viommu_dev *viommu,/* TODO: find EP by ID and report_iommu_fault */if(flags&VIRTIO_IOMMU_FAULT_F_ADDRESS)-dev_err_ratelimited(viommu->dev,"%s fault from EP %u at %#llx [%s%s%s]\n",-reason_str,endpoint,address,+dev_err_ratelimited(viommu->dev,+"%s fault from EP %u PASID %u at %#llx [%s%s%s]\n",+reason_str,endpoint,pasid,address,flags&VIRTIO_IOMMU_FAULT_F_READ?"R":"",flags&VIRTIO_IOMMU_FAULT_F_WRITE?"W":"",flags&VIRTIO_IOMMU_FAULT_F_EXEC?"X":"");
Currently all reported faults are unrecoverable, so to be consistent
DMA_UNRECOV should be 0. But I'd prefer having just a new "page request"
flag in the flags field, instead of the flt_type field.
For page requests we'll also need a 16-bit fault ID field to store the PRI
"page request group index" or the stall "stag". "last" and "privileged"
flags as well, to match the PRI page request. And a new command to
complete a page fault.
From: Jacob Pan <hidden> Date: 2021-03-03 20:58:18
Hi Vivek,
On Fri, 15 Jan 2021 17:43:39 +0530, Vivek Gautam [off-list ref]
wrote:
From: Jean-Philippe Brucker <redacted>
Add support for tlb invalidation ops that can send invalidation
requests to back-end virtio-iommu when stage-1 page tables are
supported.
Just curious if it possible to reuse the iommu uapi for invalidation and others.
When we started out designing the iommu uapi, the intention was to support
both emulated and virtio iommu.
quoted hunk
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Refactoring the iommu_flush_ops, and adding only one pasid sync
op that's needed with current iommu-pasid-table infrastructure.
Also updating uapi defines as required by latest changes]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 95 ++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
From: Jacob Pan <redacted>
Sent: Thursday, March 4, 2021 2:29 AM
Hi Vivek,
On Fri, 15 Jan 2021 17:43:39 +0530, Vivek Gautam [off-list ref]
wrote:
quoted
From: Jean-Philippe Brucker <redacted>
Add support for tlb invalidation ops that can send invalidation
requests to back-end virtio-iommu when stage-1 page tables are
supported.
Just curious if it possible to reuse the iommu uapi for invalidation and others.
When we started out designing the iommu uapi, the intention was to support
both emulated and virtio iommu.
IIUC this patch is about the protocol between virtio-iommu frontend and backend.
After the virtio-iommu backend receives invalidation ops, it then needs to
forward the request to the host IOMMU driver through the existing iommu
uapi that you referred to, as a emulated VT-d or SMMU would do.
Thanks
Kevin
quoted
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Refactoring the iommu_flush_ops, and adding only one pasid sync
op that's needed with current iommu-pasid-table infrastructure.
Also updating uapi defines as required by latest changes]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 95
Hi Jacob, Kevin,
On 3/4/21 11:28 AM, Tian, Kevin wrote:
quoted
From: Jacob Pan <redacted>
Sent: Thursday, March 4, 2021 2:29 AM
Hi Vivek,
On Fri, 15 Jan 2021 17:43:39 +0530, Vivek Gautam [off-list ref]
wrote:
quoted
From: Jean-Philippe Brucker <redacted>
Add support for tlb invalidation ops that can send invalidation
requests to back-end virtio-iommu when stage-1 page tables are
supported.
Just curious if it possible to reuse the iommu uapi for invalidation and others.
When we started out designing the iommu uapi, the intention was to support
both emulated and virtio iommu.
IIUC this patch is about the protocol between virtio-iommu frontend and backend.
After the virtio-iommu backend receives invalidation ops, it then needs to
forward the request to the host IOMMU driver through the existing iommu
uapi that you referred to, as a emulated VT-d or SMMU would do.
Thanks a lot for looking at the patch.
Yes this patch is to provide the front-end virtio interface for
invalidation requests during map/unmap and when flushing the pasid
tables when virtio-iommu requested pasid table (in other words cd tables
for arm-smmu-v3) from the iommu-pasid-table library.
The kvmtool back-end virtio driver forwards these requests to vfio
driver which then makes use of iommu uapi to finally request host iommu
driver for handling these invalidations.
Regards
Vivek
Thanks
Kevin
quoted
quoted
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Refactoring the iommu_flush_ops, and adding only one pasid sync
op that's needed with current iommu-pasid-table infrastructure.
Also updating uapi defines as required by latest changes]
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 95
Hi Jean,
On 3/3/21 10:44 PM, Jean-Philippe Brucker wrote:
On Fri, Jan 15, 2021 at 05:43:31PM +0530, Vivek Gautam wrote:
quoted
Update base address information in vendor pasid table info to pass that
to user-space for stage1 table management.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 6 ++++++
1 file changed, 6 insertions(+)
This isn't the right place, because this path allocates second-level
tables for two-level tables. I don't think we need pst_cfg->base at all,
because for both linear and two-level tables, the base pointer is in
cdcfg->cdtab_dma, which can be read directly.
Sure, will remove this.
Thanks,
Jean
quoted
l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
arm_smmu_write_cd_l1_desc(l1ptr, l1_desc);
/* An invalid L1CD can be cached */
Hi Jean,
On 3/3/21 10:41 PM, Jean-Philippe Brucker wrote:
Hi Vivek,
Thanks again for working on this. I have a few comments but it looks
sensible overall.
Thanks a lot for reviewing the patch-series. Please find my responses
inline below.
Regarding the overall design, I was initially assigning page directories
instead of whole PASID tables, which would simplify the driver and host
implementation. A major complication, however, is SMMUv3 accesses PASID
tables using a guest-physical address, so there is a messy negotiation
needed between host and guest when the host needs to allocate PASID
tables. Plus vSMMU needs PASID table assignment, so that's what the host
driver will implement.
By assigning the page directories, you mean setting up just the stage-1
page table ops, and passing that information to the host using ATTACH_TABLE?
Right now when using kvmtool, the struct iommu_pasid_table_config is
populated with the correct information, and this whole memory is mapped
between host and guest by creating a mem bank using
kvm__for_each_mem_bank().
Did I get you or did I fail terribly in understanding the point you are
making here?
If it helps, I will publish my kvmtool branch.
On Fri, Jan 15, 2021 at 05:43:29PM +0530, Vivek Gautam wrote:
quoted
Add a small API in iommu subsystem to handle PASID table allocation
requests from different consumer drivers, such as a paravirtualized
iommu driver. The API provides ops for allocating and freeing PASID
table, writing to it and managing the table caches.
This library also provides for registering a vendor API that attaches
to these ops. The vendor APIs would eventually perform arch level
implementations for these PASID tables.
Although Arm might be the only vendor to ever use this, I think the
abstraction makes sense and isn't too invasive. Even if we called directly
into the SMMU driver from the virtio one, we'd still need patch 3 and
separate TLB invalidations ops.
Right, the idea was to make users of iommu-pasid-table - virtio-iommu or
the arm-smmu-v3 - consistent. I also noticed that the whole process of
allocating the pasid tables (or cd tables) and populating them with
stage-1 page tables in viommu is also in-line with how things are in
arm-smmu-v3 or atleast that's how the design can be in general -
allocate pasid_table, and program stage-1 information into it, and then
pass it across to host.
quoted
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/iommu-pasid-table.h | 134 ++++++++++++++++++++++++++++++
1 file changed, 134 insertions(+)
create mode 100644 drivers/iommu/iommu-pasid-table.h
On Fri, Jan 15, 2021 at 05:43:32PM +0530, Vivek Gautam wrote:
quoted
Te change allows different consumers of arm-smmu-v3-cd-lib to set
their respective sync op for pasid entries.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-cd-lib.c | 1 -
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 7 +++++++
2 files changed, 7 insertions(+), 1 deletion(-)
@@ -1869,6 +1869,13 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,if(ret)gotoout_free_cd_tables;+/*+*Strangetosetupanophere?+*cd-libistheactualuserofsyncop,andthereforetheplatform+*driversshouldassignthissync/maintenanceopsasperneed.+*/+tbl->ops->sync=arm_smmu_sync_cd;+
Modifying a static struct from here doesn't feel right. I think the
interface should be roughly similar to io-pgtable since the principle is
the same. So the sync() op should be separate from arm_cd_table_ops since
it's a callback into the driver. Maybe pass it to
iommu_register_pasid_table().
On Fri, Jan 15, 2021 at 05:43:33PM +0530, Vivek Gautam wrote:
quoted
From: Jean-Philippe Brucker <redacted>
Add required UAPI defines for probing table format for underlying
iommu hardware. The device may provide information about hardware
tables and additional capabilities for each device.
This allows guest to correctly fabricate stage-1 page tables.
Signed-off-by: Jean-Philippe Brucker <redacted>
[Vivek: Use a single "struct virtio_iommu_probe_table_format" rather
than separate structures for page table and pasid table format.
+/* Arm smmu-v3 type PASID table format */
+#define VIRTIO_IOMMU_FORMAT_PSTF_ARM_SMMU_V3 2
These should be with the Arm-specific definitions patches 11 and 14
Right, will add these definitions with Arm specific patches.
Best regards
Vivek
[snip]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 05:43:35PM +0530, Vivek Gautam wrote:
quoted
aisd_bits data is required to prepare stage-1 tables for arm-smmu-v3.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/iommu.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Is this used anywhere? This struct is passed from host userspace to host
kernel to attach the PASID table, so I don't think it needs an asid_bits
field.
Yea, must have missed removing it from the WIP work. Will remove it.
Thanks
Vivek
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 05:43:36PM +0530, Vivek Gautam wrote:
quoted
Add info about asid_bits and additional flags to table format
probing header.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
include/uapi/linux/virtio_iommu.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
This struct should only contain the head and format fields. asid and flags
should go in a specialized structure - virtio_iommu_probe_pgt_arm64 in the
latest spec draft, where I dropped the asid_bits field in favor of an
"ASID16" flag.
Right, will take care of this looking at the spec draft.
Best regards
Vivek
On Fri, Jan 15, 2021 at 05:43:42PM +0530, Vivek Gautam wrote:
quoted
Fault type information can tell about a page request fault or
an unreceoverable fault, and further additions to fault reasons
and the related PASID information can help in handling faults
efficiently.
Signed-off-by: Vivek Gautam <redacted>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Will Deacon <redacted>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Jean-Philippe Brucker <redacted>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Alex Williamson <redacted>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <redacted>
Cc: Liu Yi L <redacted>
Cc: Lorenzo Pieralisi <redacted>
Cc: Shameerali Kolothum Thodi <redacted>
---
drivers/iommu/virtio-iommu.c | 27 +++++++++++++++++++++++++--
include/uapi/linux/virtio_iommu.h | 13 ++++++++++++-
2 files changed, 37 insertions(+), 3 deletions(-)
@@ -663,6 +670,21 @@ static int viommu_fault_handler(struct viommu_dev *viommu,caseVIRTIO_IOMMU_FAULT_R_MAPPING:reason_str="page";break;+caseVIRTIO_IOMMU_FAULT_R_WALK_EABT:+reason_str="page walk external abort";+break;+caseVIRTIO_IOMMU_FAULT_R_PTE_FETCH:+reason_str="pte fetch";+break;+caseVIRTIO_IOMMU_FAULT_R_PERMISSION:+reason_str="permission";+break;+caseVIRTIO_IOMMU_FAULT_R_ACCESS:+reason_str="access";+break;+caseVIRTIO_IOMMU_FAULT_R_OOR_ADDRESS:+reason_str="output address";+break;caseVIRTIO_IOMMU_FAULT_R_UNKNOWN:default:reason_str="unknown";
@@ -671,8 +693,9 @@ static int viommu_fault_handler(struct viommu_dev *viommu,/* TODO: find EP by ID and report_iommu_fault */if(flags&VIRTIO_IOMMU_FAULT_F_ADDRESS)-dev_err_ratelimited(viommu->dev,"%s fault from EP %u at %#llx [%s%s%s]\n",-reason_str,endpoint,address,+dev_err_ratelimited(viommu->dev,+"%s fault from EP %u PASID %u at %#llx [%s%s%s]\n",+reason_str,endpoint,pasid,address,flags&VIRTIO_IOMMU_FAULT_F_READ?"R":"",flags&VIRTIO_IOMMU_FAULT_F_WRITE?"W":"",flags&VIRTIO_IOMMU_FAULT_F_EXEC?"X":"");
Currently all reported faults are unrecoverable, so to be consistent
DMA_UNRECOV should be 0. But I'd prefer having just a new "page request"
flag in the flags field, instead of the flt_type field.
Yea, looking at what I am currently trying as well - handle page-request
and leave all other faults as unrecoverable - I will add the page
request flag in the structure.
For page requests we'll also need a 16-bit fault ID field to store the PRI
"page request group index" or the stall "stag". "last" and "privileged"
flags as well, to match the PRI page request. And a new command to
complete a page fault.
Right, will add the fields as suggested.
To complete the page request we would also need to send the response
back to the host from virtio backend when handling page request. So the
virtio command should also be accompanied with a vfio api to send the
page request response back to the host. Isn't it?
This is where the host smmuv3 can send PRI_RESP command to the device to
complete the page fault.
On Fri, Jan 15, 2021 at 05:43:40PM +0530, Vivek Gautam wrote:
[...]
quoted
+static int viommu_setup_pgtable(struct viommu_endpoint *vdev,
+ struct viommu_domain *vdomain)
+{
+ int ret, id;
+ u32 asid;
+ enum io_pgtable_fmt fmt;
+ struct io_pgtable_ops *ops = NULL;
+ struct viommu_dev *viommu = vdev->viommu;
+ struct virtio_iommu_probe_table_format *desc = vdev->pgtf;
+ struct iommu_pasid_table *tbl = vdomain->pasid_tbl;
+ struct iommu_vendor_psdtable_cfg *pst_cfg;
+ struct arm_smmu_cfg_info *cfgi;
+ struct io_pgtable_cfg cfg = {
+ .iommu_dev = viommu->dev->parent,
+ .tlb = &viommu_flush_ops,
+ .pgsize_bitmap = vdev->pgsize_mask ? vdev->pgsize_mask :
+ vdomain->domain.pgsize_bitmap,
+ .ias = (vdev->input_end ? ilog2(vdev->input_end) :
+ ilog2(vdomain->domain.geometry.aperture_end)) + 1,
+ .oas = vdev->output_bits,
+ };
+
+ if (!desc)
+ return -EINVAL;
+
+ if (!vdev->output_bits)
+ return -ENODEV;
+
+ switch (le16_to_cpu(desc->format)) {
+ case VIRTIO_IOMMU_FOMRAT_PGTF_ARM_LPAE:
+ fmt = ARM_64_LPAE_S1;
+ break;
+ default:
+ dev_err(vdev->dev, "unsupported page table format 0x%x\n",
+ le16_to_cpu(desc->format));
+ return -EINVAL;
+ }
+
+ if (vdomain->mm.ops) {
+ /*
+ * TODO: attach additional endpoint to the domain. Check that
+ * the config is sane.
+ */
+ return -EEXIST;
+ }
+
+ vdomain->mm.domain = vdomain;
+ ops = alloc_io_pgtable_ops(fmt, &cfg, &vdomain->mm);
+ if (!ops)
+ return -ENOMEM;
+
+ pst_cfg = &tbl->cfg;
+ cfgi = &pst_cfg->vendor.cfg;
+ id = ida_simple_get(&asid_ida, 1, 1 << desc->asid_bits, GFP_KERNEL);
+ if (id < 0) {
+ ret = id;
+ goto err_free_pgtable;
+ }
+
+ asid = id;
+ ret = iommu_psdtable_prepare(tbl, pst_cfg, &cfg, asid);
+ if (ret)
+ goto err_free_asid;
+
+ /*
+ * Strange to setup an op here?
+ * cd-lib is the actual user of sync op, and therefore the platform
+ * drivers should assign this sync/maintenance ops as per need.
+ */
+ tbl->ops->sync = viommu_flush_pasid;
But this function deals with page tables, not pasid tables. As said on an
earlier patch, the TLB flush ops should probably be passed during table
registration - those ops are global so should really be const.
That doesn't look right, cfg->cd.asid takes the ASID value of context 0
but here we're writing a limit. viommu_setup_pgtable() probably needs to
set this field to the allocated ASID, since viommu_teardown_pgtable() uses
it.
Yea, this isn't right. The asid should be assigned to the one that we
are allocating. I think this is getting over-written when
iommu_psdtable_prepare() calls into arm_smmu_prepare_cd() where the
correct asid value is assigned. I will remove this.
quoted
+
+ pst_cfg->fmt = PASID_TABLE_ARM_SMMU_V3;
Parent function can set this
Sure.
quoted
+ /* XXX HACK: set feature bit ARM_SMMU_FEAT_2_LVL_CDTAB */
+ pst_cfg->vendor.cfg.feat_flag |= (1 << 1);
Oh right, this flag is missing. I'll add
#define VIRTIO_IOMMU_PST_ARM_SMMU3_F_CD2L (1ULL << 1)
to the spec.
Regarding this Eric pointed out [1] in my other patch about the
scalability of the approach where we keep adding flags in
'iommu_nesting_info' corresponding to the arm-smmu-v3 capabilities. I
guess the same goes to these flags in virtio.
May be the 'iommu_nesting_info' can have a bitmap with the caps for
vendor specific features, and here we can add the related flags?
Already set by iommu_register_pasid_table() (and needed for DMA
allocations in iommu_psdtable_alloc())
Right.
quoted
+ pst_cfg->fmt = PASID_TABLE_ARM_SMMU_V3;
Already set above
Right.
quoted
+
+ ret = viommu_setup_pgtable(vdev, vdomain);
+ if (ret) {
+ dev_err(vdev->dev, "could not install page tables\n");
+ goto err_free_psdtable;
+ }
+
+ /* Add arch-specific configuration */
+ ret = viommu_config_pst(pst_cfg, (void *)&req, fmt);
+ if (ret)
+ goto err_free_ops;
+
+ vdev_for_each_id(i, eid, vdev) {
+ req.endpoint = cpu_to_le32(eid);
+ ret = viommu_send_req_sync(viommu, &req, sizeof(req));
+ if (ret)
+ goto err_free_ops;
+ }
+ } else {
+ /* TODO: otherwise, check for compatibility with vdev. */
+ return -ENOSYS;
+ }
+
+ dev_dbg(vdev->dev, "uses PASID table format 0x%x\n", fmt);
+
+ return 0;
+
+err_free_ops:
+ if (vdomain->mm.ops)
+ viommu_teardown_pgtable(vdomain);
+err_free_psdtable:
+ iommu_psdtable_free(tbl, &tbl->cfg);
+
+ return ret;
+}
+
static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
int ret = 0;
@@ -928,6 +1213,17 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) if (vdev->vdomain) vdev->vdomain->nr_endpoints--;+ ret = viommu_attach_pasid_table(vdev, vdomain);+ if (ret) {+ /*+ * No PASID support, too bad. Perhaps we can bind a single set+ * of page tables?+ */+ ret = viommu_setup_pgtable(vdev, vdomain);
This cannot work at the moment because viommu_setup_pgtable() writes to
the non-existing pasid table. Probably best to leave this call for next
patch.
Yea, will move it to the next patch.
Thanks & regards
Vivek
Thanks,
Jean
quoted
+ if (ret)
+ dev_err(vdev->dev, "could not install tables\n");
+ }
+
if (!vdomain->mm.ops) {
/* If we couldn't bind any table, use the mapping tree */
ret = viommu_simple_attach(vdomain, vdev);
On Fri, Mar 12, 2021 at 06:59:17PM +0530, Vivek Kumar Gautam wrote:
quoted
quoted
+ /* XXX HACK: set feature bit ARM_SMMU_FEAT_2_LVL_CDTAB */
+ pst_cfg->vendor.cfg.feat_flag |= (1 << 1);
Oh right, this flag is missing. I'll add
#define VIRTIO_IOMMU_PST_ARM_SMMU3_F_CD2L (1ULL << 1)
to the spec.
Regarding this Eric pointed out [1] in my other patch about the scalability
of the approach where we keep adding flags in 'iommu_nesting_info'
corresponding to the arm-smmu-v3 capabilities. I guess the same goes to
these flags in virtio.
May be the 'iommu_nesting_info' can have a bitmap with the caps for vendor
specific features, and here we can add the related flags?
Something like that, but I'd keep separate arch-specific structs. Vt-d
reports the capability registers directly through iommu_nesting_info [2].
We could do the same for Arm, copy sanitized values of IDR0..5 into
struct iommu_nesting_info_arm_smmuv3.
I've avoided doing that for virtio-iommu because every field needs a
description in the spec. So where possible I used generic properties that
apply to any architecture, such as page, PASID and address size. What's
left is the minimum arch-specific information to get nested translation
going, leaving out a lot of properties such as big-endian and 32-bit,
which can be added later if needed. The Arm specific properties are split
into page table and pasid table information. Page table info should work
for both SMMUv2 and v3 (where they correspond to an SMMU_IDRx field that
constrains a context descriptor field.) I should move BTM in there since
it's supported by SMMUv2.
Thanks,
Jean
[2] https://lore.kernel.org/linux-iommu/20210302203545.436623-11-yi.l.liu@intel.com/
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Mar 12, 2021 at 06:39:05PM +0530, Vivek Kumar Gautam wrote:
To complete the page request we would also need to send the response back to
the host from virtio backend when handling page request. So the virtio
command should also be accompanied with a vfio api to send the page request
response back to the host. Isn't it?
This is where the host smmuv3 can send PRI_RESP command to the device to
complete the page fault.
On Fri, Mar 12, 2021 at 06:17:55PM +0530, Vivek Kumar Gautam wrote:
quoted
Regarding the overall design, I was initially assigning page directories
instead of whole PASID tables, which would simplify the driver and host
implementation. A major complication, however, is SMMUv3 accesses PASID
tables using a guest-physical address, so there is a messy negotiation
needed between host and guest when the host needs to allocate PASID
tables. Plus vSMMU needs PASID table assignment, so that's what the host
driver will implement.
By assigning the page directories, you mean setting up just the stage-1 page
table ops, and passing that information to the host using ATTACH_TABLE?
Yes. And we can support nested translation with SMMUv2 that way. But with
SMMUv3 the guest has to manage the whole PASID table.
Right now when using kvmtool, the struct iommu_pasid_table_config is
populated with the correct information, and this whole memory is mapped
between host and guest by creating a mem bank using
kvm__for_each_mem_bank().
Did I get you or did I fail terribly in understanding the point you are
making here?
On Fri, Mar 12, 2021 at 06:39:05PM +0530, Vivek Kumar Gautam wrote:
quoted
To complete the page request we would also need to send the response back to
the host from virtio backend when handling page request. So the virtio
command should also be accompanied with a vfio api to send the page request
response back to the host. Isn't it?
This is where the host smmuv3 can send PRI_RESP command to the device to
complete the page fault.
Right, I have taken this change to work on getting the vSVA with
virtio-iommu.
For this I am adding a new request for virtio-iomm -
VIRTIO_IOMMU_T_PAGE_RESP, and related struct virtio_iommu_req_page_resp
that would contain information such as, pasid, grpid, response_code,
flags, and endpoint. This is inline with struct iommu_page_response.
I will post out the patches for this soon.
Thanks & regards
Vivek