* [PATCH v3 0/9] Initial support for SMMUv3 nested translation
@ 2024-10-09 16:23 Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 1/9] vfio: Remove VFIO_TYPE1_NESTING_IOMMU Jason Gunthorpe
` (11 more replies)
0 siblings, 12 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
This brings support for the IOMMFD ioctls:
- IOMMU_GET_HW_INFO
- IOMMU_HWPT_ALLOC_NEST_PARENT
- IOMMU_DOMAIN_NESTED
- ops->enforce_cache_coherency()
This is quite straightforward as the nested STE can just be built in the
special NESTED domain op and fed through the generic update machinery.
The design allows the user provided STE fragment to control several
aspects of the translation, including putting the STE into a "virtual
bypass" or a aborting state. This duplicates functionality available by
other means, but it allows trivially preserving the VMID in the STE as we
eventually move towards the vIOMMU owning the VMID.
Nesting support requires the system to either support S2FWB or the
stronger CANWBS ACPI flag. This is to ensure the VM cannot bypass the
cache and view incoherent data, currently VFIO lacks any cache flushing
that would make this safe.
Yan has a series to add some of the needed infrastructure for VFIO cache
flushing here:
https://lore.kernel.org/linux-iommu/20240507061802.20184-1-yan.y.zhao@intel.com/
Which may someday allow relaxing this further.
Remove VFIO_TYPE1_NESTING_IOMMU since it was never used and superseded by
this.
This is the first series in what will be several to complete nesting
support. At least:
- IOMMU_RESV_SW_MSI related fixups
https://lore.kernel.org/linux-iommu/cover.1722644866.git.nicolinc@nvidia.com/
- vIOMMU object support to allow ATS and CD invalidations
https://lore.kernel.org/linux-iommu/cover.1723061377.git.nicolinc@nvidia.com/
- vCMDQ hypervisor support for direct invalidation queue assignment
https://lore.kernel.org/linux-iommu/cover.1712978212.git.nicolinc@nvidia.com/
- KVM pinned VMID using vIOMMU for vBTM
https://lore.kernel.org/linux-iommu/20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com/
- Cross instance S2 sharing
- Virtual Machine Structure using vIOMMU (for vMPAM?)
- Fault forwarding support through IOMMUFD's fault fd for vSVA
The vIOMMU series is essential to allow the invalidations to be processed
for the CD as well.
It is enough to allow qemu work to progress.
This is on github: https://github.com/jgunthorpe/linux/commits/smmuv3_nesting
v3:
- Rebase on v6.12-rc2
- Revise commit messages
- Consolidate CANWB checks into arm_smmu_master_canwbs()
- Add CONFIG_ARM_SMMU_V3_IOMMUFD to compile out iommufd only features
like nesting
- Shift code into arm-smmu-v3-iommufd.c
- Add missed IS_ERR check
- Add S2FWB to arm_smmu_get_ste_used()
- Fixup quirks checks
- Drop ARM_SMMU_FEAT_COHERENCY checks for S2FWB
- Limit S2FWB to S2 Nesting Parent domains "just in case"
v2: https://patch.msgid.link/r/0-v2-621370057090+91fec-smmuv3_nesting_jgg@nvidia.com
- Revise commit messages
- Guard S2FWB support with ARM_SMMU_FEAT_COHERENCY, since it doesn't make
sense to use S2FWB to enforce coherency on inherently non-coherent hardware.
- Add missing IO_PGTABLE_QUIRK_ARM_S2FWB validation
- Include formal ACPIA commit for IORT built using
generate/linux/gen-patch.sh
- Use FEAT_NESTING to block creating a NESTING_PARENT
- Use an abort STE instead of non-valid if the user requests a non-valid
vSTE
- Consistently use 'nest_parent' for naming variables
- Use the right domain for arm_smmu_remove_master_domain() when it
removes the master
- Join bitfields together
- Drop arm_smmu_cache_invalidate_user patch, invalidation will
exclusively go via viommu
v1: https://patch.msgid.link/r/0-v1-54e734311a7f+14f72-smmuv3_nesting_jgg@nvidia.com
Jason Gunthorpe (6):
vfio: Remove VFIO_TYPE1_NESTING_IOMMU
iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS
iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT
iommu/arm-smmu-v3: Expose the arm_smmu_attach interface
iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
iommu/arm-smmu-v3: Use S2FWB for NESTED domains
Nicolin Chen (3):
ACPICA: IORT: Update for revision E.f
ACPI/IORT: Support CANWBS memory access flag
iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct
arm_smmu_hw_info
drivers/acpi/arm64/iort.c | 13 ++
drivers/iommu/Kconfig | 9 +
drivers/iommu/arm/arm-smmu-v3/Makefile | 1 +
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 204 ++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 114 ++++++----
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 83 ++++++-
drivers/iommu/arm/arm-smmu/arm-smmu.c | 16 --
drivers/iommu/io-pgtable-arm.c | 27 ++-
drivers/iommu/iommu.c | 10 -
drivers/iommu/iommufd/vfio_compat.c | 7 +-
drivers/vfio/vfio_iommu_type1.c | 12 +-
include/acpi/actbl2.h | 3 +-
include/linux/io-pgtable.h | 2 +
include/linux/iommu.h | 5 +-
include/uapi/linux/iommufd.h | 55 +++++
include/uapi/linux/vfio.h | 2 +-
16 files changed, 465 insertions(+), 98 deletions(-)
create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
base-commit: 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b
--
2.46.2
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v3 1/9] vfio: Remove VFIO_TYPE1_NESTING_IOMMU
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 2/9] ACPICA: IORT: Update for revision E.f Jason Gunthorpe
` (10 subsequent siblings)
11 siblings, 0 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
This control causes the ARM SMMU drivers to choose a stage 2
implementation for the IO pagetable (vs the stage 1 usual default),
however this choice has no significant visible impact to the VFIO
user. Further qemu never implemented this and no other userspace user is
known.
The original description in commit f5c9ecebaf2a ("vfio/iommu_type1: add
new VFIO_TYPE1_NESTING_IOMMU IOMMU type") suggested this was to "provide
SMMU translation services to the guest operating system" however the rest
of the API to set the guest table pointer for the stage 1 and manage
invalidation was never completed, or at least never upstreamed, rendering
this part useless dead code.
Upstream has now settled on iommufd as the uAPI for controlling nested
translation. Choosing the stage 2 implementation should be done by through
the IOMMU_HWPT_ALLOC_NEST_PARENT flag during domain allocation.
Remove VFIO_TYPE1_NESTING_IOMMU and everything under it including the
enable_nesting iommu_domain_op.
Just in-case there is some userspace using this continue to treat
requesting it as a NOP, but do not advertise support any more.
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Mostafa Saleh <smostafa@google.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 16 ----------------
drivers/iommu/arm/arm-smmu/arm-smmu.c | 16 ----------------
drivers/iommu/iommu.c | 10 ----------
drivers/iommu/iommufd/vfio_compat.c | 7 +------
drivers/vfio/vfio_iommu_type1.c | 12 +-----------
include/linux/iommu.h | 3 ---
include/uapi/linux/vfio.h | 2 +-
7 files changed, 3 insertions(+), 63 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 737c5b88235510..acf250aeb18b27 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3378,21 +3378,6 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
return group;
}
-static int arm_smmu_enable_nesting(struct iommu_domain *domain)
-{
- struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
- int ret = 0;
-
- mutex_lock(&smmu_domain->init_mutex);
- if (smmu_domain->smmu)
- ret = -EPERM;
- else
- smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
- mutex_unlock(&smmu_domain->init_mutex);
-
- return ret;
-}
-
static int arm_smmu_of_xlate(struct device *dev,
const struct of_phandle_args *args)
{
@@ -3514,7 +3499,6 @@ static struct iommu_ops arm_smmu_ops = {
.flush_iotlb_all = arm_smmu_flush_iotlb_all,
.iotlb_sync = arm_smmu_iotlb_sync,
.iova_to_phys = arm_smmu_iova_to_phys,
- .enable_nesting = arm_smmu_enable_nesting,
.free = arm_smmu_domain_free_paging,
}
};
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8321962b37148b..12b173eec4540d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1558,21 +1558,6 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
return group;
}
-static int arm_smmu_enable_nesting(struct iommu_domain *domain)
-{
- struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
- int ret = 0;
-
- mutex_lock(&smmu_domain->init_mutex);
- if (smmu_domain->smmu)
- ret = -EPERM;
- else
- smmu_domain->stage = ARM_SMMU_DOMAIN_NESTED;
- mutex_unlock(&smmu_domain->init_mutex);
-
- return ret;
-}
-
static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
unsigned long quirks)
{
@@ -1656,7 +1641,6 @@ static struct iommu_ops arm_smmu_ops = {
.flush_iotlb_all = arm_smmu_flush_iotlb_all,
.iotlb_sync = arm_smmu_iotlb_sync,
.iova_to_phys = arm_smmu_iova_to_phys,
- .enable_nesting = arm_smmu_enable_nesting,
.set_pgtable_quirks = arm_smmu_set_pgtable_quirks,
.free = arm_smmu_domain_free,
}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 83c8e617a2c588..dbd70d5a4702cc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2723,16 +2723,6 @@ static int __init iommu_init(void)
}
core_initcall(iommu_init);
-int iommu_enable_nesting(struct iommu_domain *domain)
-{
- if (domain->type != IOMMU_DOMAIN_UNMANAGED)
- return -EINVAL;
- if (!domain->ops->enable_nesting)
- return -EINVAL;
- return domain->ops->enable_nesting(domain);
-}
-EXPORT_SYMBOL_GPL(iommu_enable_nesting);
-
int iommu_set_pgtable_quirks(struct iommu_domain *domain,
unsigned long quirk)
{
diff --git a/drivers/iommu/iommufd/vfio_compat.c b/drivers/iommu/iommufd/vfio_compat.c
index a3ad5f0b6c59dd..514aacd6400949 100644
--- a/drivers/iommu/iommufd/vfio_compat.c
+++ b/drivers/iommu/iommufd/vfio_compat.c
@@ -291,12 +291,7 @@ static int iommufd_vfio_check_extension(struct iommufd_ctx *ictx,
case VFIO_DMA_CC_IOMMU:
return iommufd_vfio_cc_iommu(ictx);
- /*
- * This is obsolete, and to be removed from VFIO. It was an incomplete
- * idea that got merged.
- * https://lore.kernel.org/kvm/0-v1-0093c9b0e345+19-vfio_no_nesting_jgg@nvidia.com/
- */
- case VFIO_TYPE1_NESTING_IOMMU:
+ case __VFIO_RESERVED_TYPE1_NESTING_IOMMU:
return 0;
/*
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index bf391b40e576fc..50ebc9593c9d70 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -72,7 +72,6 @@ struct vfio_iommu {
uint64_t pgsize_bitmap;
uint64_t num_non_pinned_groups;
bool v2;
- bool nesting;
bool dirty_page_tracking;
struct list_head emulated_iommu_groups;
};
@@ -2195,12 +2194,6 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
goto out_free_domain;
}
- if (iommu->nesting) {
- ret = iommu_enable_nesting(domain->domain);
- if (ret)
- goto out_domain;
- }
-
ret = iommu_attach_group(domain->domain, group->iommu_group);
if (ret)
goto out_domain;
@@ -2541,9 +2534,7 @@ static void *vfio_iommu_type1_open(unsigned long arg)
switch (arg) {
case VFIO_TYPE1_IOMMU:
break;
- case VFIO_TYPE1_NESTING_IOMMU:
- iommu->nesting = true;
- fallthrough;
+ case __VFIO_RESERVED_TYPE1_NESTING_IOMMU:
case VFIO_TYPE1v2_IOMMU:
iommu->v2 = true;
break;
@@ -2638,7 +2629,6 @@ static int vfio_iommu_type1_check_extension(struct vfio_iommu *iommu,
switch (arg) {
case VFIO_TYPE1_IOMMU:
case VFIO_TYPE1v2_IOMMU:
- case VFIO_TYPE1_NESTING_IOMMU:
case VFIO_UNMAP_ALL:
return 1;
case VFIO_UPDATE_VADDR:
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index bd722f47363520..c88d18d2c9280d 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -635,7 +635,6 @@ struct iommu_ops {
* @enforce_cache_coherency: Prevent any kind of DMA from bypassing IOMMU_CACHE,
* including no-snoop TLPs on PCIe or other platform
* specific mechanisms.
- * @enable_nesting: Enable nesting
* @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)
* @free: Release the domain after use.
*/
@@ -663,7 +662,6 @@ struct iommu_domain_ops {
dma_addr_t iova);
bool (*enforce_cache_coherency)(struct iommu_domain *domain);
- int (*enable_nesting)(struct iommu_domain *domain);
int (*set_pgtable_quirks)(struct iommu_domain *domain,
unsigned long quirks);
@@ -844,7 +842,6 @@ extern void iommu_group_put(struct iommu_group *group);
extern int iommu_group_id(struct iommu_group *group);
extern struct iommu_domain *iommu_group_default_domain(struct iommu_group *);
-int iommu_enable_nesting(struct iommu_domain *domain);
int iommu_set_pgtable_quirks(struct iommu_domain *domain,
unsigned long quirks);
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 2b68e6cdf1902f..c8dbf8219c4fcb 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -35,7 +35,7 @@
#define VFIO_EEH 5
/* Two-stage IOMMU */
-#define VFIO_TYPE1_NESTING_IOMMU 6 /* Implies v2 */
+#define __VFIO_RESERVED_TYPE1_NESTING_IOMMU 6 /* Implies v2 */
#define VFIO_SPAPR_TCE_v2_IOMMU 7
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 2/9] ACPICA: IORT: Update for revision E.f
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 1/9] vfio: Remove VFIO_TYPE1_NESTING_IOMMU Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-10 1:48 ` Hanjun Guo
2024-10-09 16:23 ` [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag Jason Gunthorpe
` (9 subsequent siblings)
11 siblings, 1 reply; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
From: Nicolin Chen <nicolinc@nvidia.com>
ACPICA commit c4f5c083d24df9ddd71d5782c0988408cf0fc1ab
The IORT spec, Issue E.f (April 2024), adds a new CANWBS bit to the Memory
Access Flag field in the Memory Access Properties table, mainly for a PCI
Root Complex.
This CANWBS defines the coherency of memory accesses to be not marked IOWB
cacheable/shareable. Its value further implies the coherency impact from a
pair of mismatched memory attributes (e.g. in a nested translation case):
0x0: Use of mismatched memory attributes for accesses made by this
device may lead to a loss of coherency.
0x1: Coherency of accesses made by this device to locations in
Conventional memory are ensured as follows, even if the memory
attributes for the accesses presented by the device or provided by
the SMMU are different from Inner and Outer Write-back cacheable,
Shareable.
Link: https://github.com/acpica/acpica/commit/c4f5c083
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
include/acpi/actbl2.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index d3858eebc2553b..2e917a8f8bca82 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -453,7 +453,7 @@ struct acpi_table_ccel {
* IORT - IO Remapping Table
*
* Conforms to "IO Remapping Table System Software on ARM Platforms",
- * Document number: ARM DEN 0049E.e, Sep 2022
+ * Document number: ARM DEN 0049E.f, Apr 2024
*
******************************************************************************/
@@ -524,6 +524,7 @@ struct acpi_iort_memory_access {
#define ACPI_IORT_MF_COHERENCY (1)
#define ACPI_IORT_MF_ATTRIBUTES (1<<1)
+#define ACPI_IORT_MF_CANWBS (1<<2)
/*
* IORT node specific subtables
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 1/9] vfio: Remove VFIO_TYPE1_NESTING_IOMMU Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 2/9] ACPICA: IORT: Update for revision E.f Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-10 7:45 ` Hanjun Guo
2024-10-24 7:38 ` Tian, Kevin
2024-10-09 16:23 ` [PATCH v3 4/9] iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS Jason Gunthorpe
` (8 subsequent siblings)
11 siblings, 2 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
From: Nicolin Chen <nicolinc@nvidia.com>
The IORT spec, Issue E.f (April 2024), adds a new CANWBS bit to the Memory
Access Flag field in the Memory Access Properties table, mainly for a PCI
Root Complex.
This CANWBS defines the coherency of memory accesses to be not marked IOWB
cacheable/shareable. Its value further implies the coherency impact from a
pair of mismatched memory attributes (e.g. in a nested translation case):
0x0: Use of mismatched memory attributes for accesses made by this
device may lead to a loss of coherency.
0x1: Coherency of accesses made by this device to locations in
Conventional memory are ensured as follows, even if the memory
attributes for the accesses presented by the device or provided by
the SMMU are different from Inner and Outer Write-back cacheable,
Shareable.
Note that the loss of coherency on a CANWBS-unsupported HW typically could
occur to an SMMU that doesn't implement the S2FWB feature where additional
cache flush operations would be required to prevent that from happening.
Add a new ACPI_IORT_MF_CANWBS flag and set IOMMU_FWSPEC_PCI_RC_CANWBS upon
the presence of this new flag.
CANWBS and S2FWB are similar features, in that they both guarantee the VM
can not violate coherency, however S2FWB can be bypassed by PCI No Snoop
TLPs, while CANWBS cannot. Thus CANWBS meets the requirements to set
IOMMU_CAP_ENFORCE_CACHE_COHERENCY.
Architecturally ARM has expected that VFIO would disable No Snoop through
PCI Config space, if this is done then the two would have the same
protections.
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/acpi/arm64/iort.c | 13 +++++++++++++
include/linux/iommu.h | 2 ++
2 files changed, 15 insertions(+)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 4c745a26226b27..1f7e4c691d9ee3 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1218,6 +1218,17 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
}
+static bool iort_pci_rc_supports_canwbs(struct acpi_iort_node *node)
+{
+ struct acpi_iort_memory_access *memory_access;
+ struct acpi_iort_root_complex *pci_rc;
+
+ pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+ memory_access =
+ (struct acpi_iort_memory_access *)&pci_rc->memory_properties;
+ return memory_access->memory_flags & ACPI_IORT_MF_CANWBS;
+}
+
static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
u32 streamid)
{
@@ -1335,6 +1346,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
fwspec = dev_iommu_fwspec_get(dev);
if (fwspec && iort_pci_rc_supports_ats(node))
fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
+ if (fwspec && iort_pci_rc_supports_canwbs(node))
+ fwspec->flags |= IOMMU_FWSPEC_PCI_RC_CANWBS;
} else {
node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
iort_match_node_callback, dev);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c88d18d2c9280d..4ad9b9ec6c9b27 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -991,6 +991,8 @@ struct iommu_fwspec {
/* ATS is supported */
#define IOMMU_FWSPEC_PCI_RC_ATS (1 << 0)
+/* CANWBS is supported */
+#define IOMMU_FWSPEC_PCI_RC_CANWBS (1 << 1)
/*
* An iommu attach handle represents a relationship between an iommu domain
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 4/9] iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (2 preceding siblings ...)
2024-10-09 16:23 ` [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-24 7:41 ` Tian, Kevin
2024-10-09 16:23 ` [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info Jason Gunthorpe
` (7 subsequent siblings)
11 siblings, 1 reply; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
HW with CANWBS is always cache coherent and ignores PCI No Snoop requests
as well. This meets the requirement for IOMMU_CAP_ENFORCE_CACHE_COHERENCY,
so let's return it.
Implement the enforce_cache_coherency() op to reject attaching devices
that don't have CANWBS.
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa@google.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 31 +++++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 7 +++++
2 files changed, 38 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index acf250aeb18b27..38725810c14eeb 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2293,6 +2293,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
case IOMMU_CAP_CACHE_COHERENCY:
/* Assume that a coherent TCU implies coherent TBUs */
return master->smmu->features & ARM_SMMU_FEAT_COHERENCY;
+ case IOMMU_CAP_ENFORCE_CACHE_COHERENCY:
+ return arm_smmu_master_canwbs(master);
case IOMMU_CAP_NOEXEC:
case IOMMU_CAP_DEFERRED_FLUSH:
return true;
@@ -2303,6 +2305,26 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
}
}
+static bool arm_smmu_enforce_cache_coherency(struct iommu_domain *domain)
+{
+ struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ struct arm_smmu_master_domain *master_domain;
+ unsigned long flags;
+ bool ret = true;
+
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_for_each_entry(master_domain, &smmu_domain->devices,
+ devices_elm) {
+ if (!arm_smmu_master_canwbs(master_domain->master)) {
+ ret = false;
+ break;
+ }
+ }
+ smmu_domain->enforce_cache_coherency = ret;
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
+ return ret;
+}
+
struct arm_smmu_domain *arm_smmu_domain_alloc(void)
{
struct arm_smmu_domain *smmu_domain;
@@ -2731,6 +2753,14 @@ static int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
* one of them.
*/
spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ if (smmu_domain->enforce_cache_coherency &&
+ !arm_smmu_master_canwbs(master)) {
+ spin_unlock_irqrestore(&smmu_domain->devices_lock,
+ flags);
+ kfree(master_domain);
+ return -EINVAL;
+ }
+
if (state->ats_enabled)
atomic_inc(&smmu_domain->nr_ats_masters);
list_add(&master_domain->devices_elm, &smmu_domain->devices);
@@ -3493,6 +3523,7 @@ static struct iommu_ops arm_smmu_ops = {
.owner = THIS_MODULE,
.default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = arm_smmu_attach_dev,
+ .enforce_cache_coherency = arm_smmu_enforce_cache_coherency,
.set_dev_pasid = arm_smmu_s1_set_dev_pasid,
.map_pages = arm_smmu_map_pages,
.unmap_pages = arm_smmu_unmap_pages,
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 1e9952ca989f87..06e3d88932df12 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -811,6 +811,7 @@ struct arm_smmu_domain {
/* List of struct arm_smmu_master_domain */
struct list_head devices;
spinlock_t devices_lock;
+ bool enforce_cache_coherency : 1;
struct mmu_notifier mmu_notifier;
};
@@ -893,6 +894,12 @@ int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
int arm_smmu_cmdq_init(struct arm_smmu_device *smmu,
struct arm_smmu_cmdq *cmdq);
+static inline bool arm_smmu_master_canwbs(struct arm_smmu_master *master)
+{
+ return dev_iommu_fwspec_get(master->dev)->flags &
+ IOMMU_FWSPEC_PCI_RC_CANWBS;
+}
+
#ifdef CONFIG_ARM_SMMU_V3_SVA
bool arm_smmu_sva_supported(struct arm_smmu_device *smmu);
bool arm_smmu_master_sva_supported(struct arm_smmu_master *master);
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (3 preceding siblings ...)
2024-10-09 16:23 ` [PATCH v3 4/9] iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-30 16:24 ` Mostafa Saleh
2024-10-09 16:23 ` [PATCH v3 6/9] iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT Jason Gunthorpe
` (6 subsequent siblings)
11 siblings, 1 reply; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
From: Nicolin Chen <nicolinc@nvidia.com>
For virtualization cases the IDR/IIDR/AIDR values of the actual SMMU
instance need to be available to the VMM so it can construct an
appropriate vSMMUv3 that reflects the correct HW capabilities.
For userspace page tables these values are required to constrain the valid
values within the CD table and the IOPTEs.
The kernel does not sanitize these values. If building a VMM then
userspace is required to only forward bits into a VM that it knows it can
implement. Some bits will also require a VMM to detect if appropriate
kernel support is available such as for ATS and BTM.
Start a new file and kconfig for the advanced iommufd support. This lets
it be compiled out for kernels that are not intended to support
virtualization, and allows distros to leave it disabled until they are
shipping a matching qemu too.
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/iommu/Kconfig | 9 +++++
drivers/iommu/arm/arm-smmu-v3/Makefile | 1 +
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 31 ++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 9 +++++
include/uapi/linux/iommufd.h | 35 +++++++++++++++++++
6 files changed, 86 insertions(+)
create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index b3aa1f5d53218b..0c9bceb1653d5f 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -415,6 +415,15 @@ config ARM_SMMU_V3_SVA
Say Y here if your system supports SVA extensions such as PCIe PASID
and PRI.
+config ARM_SMMU_V3_IOMMUFD
+ bool "Enable IOMMUFD features for ARM SMMUv3 (EXPERIMENTAL)"
+ depends on IOMMUFD
+ help
+ Support for IOMMUFD features intended to support virtual machines
+ with accelerated virtual IOMMUs.
+
+ Say Y here if you are doing development and testing on this feature.
+
config ARM_SMMU_V3_KUNIT_TEST
tristate "KUnit tests for arm-smmu-v3 driver" if !KUNIT_ALL_TESTS
depends on KUNIT
diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
index dc98c88b48c827..493a659cc66bb2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/Makefile
+++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_ARM_SMMU_V3) += arm_smmu_v3.o
arm_smmu_v3-y := arm-smmu-v3.o
+arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_IOMMUFD) += arm-smmu-v3-iommufd.o
arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
arm_smmu_v3-$(CONFIG_TEGRA241_CMDQV) += tegra241-cmdqv.o
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
new file mode 100644
index 00000000000000..3d2671031c9bb5
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
+ */
+
+#include <uapi/linux/iommufd.h>
+
+#include "arm-smmu-v3.h"
+
+void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
+{
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+ struct iommu_hw_info_arm_smmuv3 *info;
+ u32 __iomem *base_idr;
+ unsigned int i;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ base_idr = master->smmu->base + ARM_SMMU_IDR0;
+ for (i = 0; i <= 5; i++)
+ info->idr[i] = readl_relaxed(base_idr + i);
+ info->iidr = readl_relaxed(master->smmu->base + ARM_SMMU_IIDR);
+ info->aidr = readl_relaxed(master->smmu->base + ARM_SMMU_AIDR);
+
+ *length = sizeof(*info);
+ *type = IOMMU_HW_INFO_TYPE_ARM_SMMUV3;
+
+ return info;
+}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 38725810c14eeb..996774d461aea2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3506,6 +3506,7 @@ static struct iommu_ops arm_smmu_ops = {
.identity_domain = &arm_smmu_identity_domain,
.blocked_domain = &arm_smmu_blocked_domain,
.capable = arm_smmu_capable,
+ .hw_info = arm_smmu_hw_info,
.domain_alloc_paging = arm_smmu_domain_alloc_paging,
.domain_alloc_sva = arm_smmu_sva_domain_alloc,
.domain_alloc_user = arm_smmu_domain_alloc_user,
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 06e3d88932df12..66261fd5bfb2d2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -81,6 +81,8 @@ struct arm_smmu_device;
#define IIDR_REVISION GENMASK(15, 12)
#define IIDR_IMPLEMENTER GENMASK(11, 0)
+#define ARM_SMMU_AIDR 0x1C
+
#define ARM_SMMU_CR0 0x20
#define CR0_ATSCHK (1 << 4)
#define CR0_CMDQEN (1 << 3)
@@ -956,4 +958,11 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
return ERR_PTR(-ENODEV);
}
#endif /* CONFIG_TEGRA241_CMDQV */
+
+#if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
+void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
+#else
+#define arm_smmu_hw_info NULL
+#endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
+
#endif /* _ARM_SMMU_V3_H */
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 72010f71c5e479..b5c94fecb94ca5 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -484,15 +484,50 @@ struct iommu_hw_info_vtd {
__aligned_u64 ecap_reg;
};
+/**
+ * struct iommu_hw_info_arm_smmuv3 - ARM SMMUv3 hardware information
+ * (IOMMU_HW_INFO_TYPE_ARM_SMMUV3)
+ *
+ * @flags: Must be set to 0
+ * @__reserved: Must be 0
+ * @idr: Implemented features for ARM SMMU Non-secure programming interface
+ * @iidr: Information about the implementation and implementer of ARM SMMU,
+ * and architecture version supported
+ * @aidr: ARM SMMU architecture version
+ *
+ * For the details of @idr, @iidr and @aidr, please refer to the chapters
+ * from 6.3.1 to 6.3.6 in the SMMUv3 Spec.
+ *
+ * User space should read the underlying ARM SMMUv3 hardware information for
+ * the list of supported features.
+ *
+ * Note that these values reflect the raw HW capability, without any insight if
+ * any required kernel driver support is present. Bits may be set indicating the
+ * HW has functionality that is lacking kernel software support, such as BTM. If
+ * a VMM is using this information to construct emulated copies of these
+ * registers it should only forward bits that it knows it can support.
+ *
+ * In future, presence of required kernel support will be indicated in flags.
+ */
+struct iommu_hw_info_arm_smmuv3 {
+ __u32 flags;
+ __u32 __reserved;
+ __u32 idr[6];
+ __u32 iidr;
+ __u32 aidr;
+};
+
/**
* enum iommu_hw_info_type - IOMMU Hardware Info Types
* @IOMMU_HW_INFO_TYPE_NONE: Used by the drivers that do not report hardware
* info
* @IOMMU_HW_INFO_TYPE_INTEL_VTD: Intel VT-d iommu info type
+ * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type
*/
enum iommu_hw_info_type {
IOMMU_HW_INFO_TYPE_NONE = 0,
IOMMU_HW_INFO_TYPE_INTEL_VTD = 1,
+ IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2,
};
/**
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 6/9] iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (4 preceding siblings ...)
2024-10-09 16:23 ` [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-30 16:26 ` Mostafa Saleh
2024-10-09 16:23 ` [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface Jason Gunthorpe
` (5 subsequent siblings)
11 siblings, 1 reply; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
For SMMUv3 the parent must be a S2 domain, which can be composed
into a IOMMU_DOMAIN_NESTED.
In future the S2 parent will also need a VMID linked to the VIOMMU and
even to KVM.
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 996774d461aea2..80847fa386fcd2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3114,7 +3114,8 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
const struct iommu_user_data *user_data)
{
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
- const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
+ const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
+ IOMMU_HWPT_ALLOC_NEST_PARENT;
struct arm_smmu_domain *smmu_domain;
int ret;
@@ -3127,6 +3128,14 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
if (IS_ERR(smmu_domain))
return ERR_CAST(smmu_domain);
+ if (flags & IOMMU_HWPT_ALLOC_NEST_PARENT) {
+ if (!(master->smmu->features & ARM_SMMU_FEAT_NESTING)) {
+ ret = -EOPNOTSUPP;
+ goto err_free;
+ }
+ smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
+ }
+
smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
smmu_domain->domain.ops = arm_smmu_ops.default_domain_ops;
ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, flags);
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (5 preceding siblings ...)
2024-10-09 16:23 ` [PATCH v3 6/9] iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-09 17:03 ` Nicolin Chen
` (2 more replies)
2024-10-09 16:23 ` [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED Jason Gunthorpe
` (4 subsequent siblings)
11 siblings, 3 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
The arm-smmuv3-iommufd.c file will need to call these functions too.
Remove statics and put them in the header file. Remove the kunit
visibility protections from arm_smmu_make_abort_ste() and
arm_smmu_make_s2_domain_ste().
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++-------------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 27 +++++++++++++++++----
2 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 80847fa386fcd2..b4b03206afbf48 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1549,7 +1549,6 @@ static void arm_smmu_write_ste(struct arm_smmu_master *master, u32 sid,
}
}
-VISIBLE_IF_KUNIT
void arm_smmu_make_abort_ste(struct arm_smmu_ste *target)
{
memset(target, 0, sizeof(*target));
@@ -1632,7 +1631,6 @@ void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
}
EXPORT_SYMBOL_IF_KUNIT(arm_smmu_make_cdtable_ste);
-VISIBLE_IF_KUNIT
void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
struct arm_smmu_master *master,
struct arm_smmu_domain *smmu_domain,
@@ -2505,8 +2503,8 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
}
}
-static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
- const struct arm_smmu_ste *target)
+void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
+ const struct arm_smmu_ste *target)
{
int i, j;
struct arm_smmu_device *smmu = master->smmu;
@@ -2671,16 +2669,6 @@ static void arm_smmu_remove_master_domain(struct arm_smmu_master *master,
spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
}
-struct arm_smmu_attach_state {
- /* Inputs */
- struct iommu_domain *old_domain;
- struct arm_smmu_master *master;
- bool cd_needs_ats;
- ioasid_t ssid;
- /* Resulting state */
- bool ats_enabled;
-};
-
/*
* Start the sequence to attach a domain to a master. The sequence contains three
* steps:
@@ -2701,8 +2689,8 @@ struct arm_smmu_attach_state {
* new_domain can be a non-paging domain. In this case ATS will not be enabled,
* and invalidations won't be tracked.
*/
-static int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
- struct iommu_domain *new_domain)
+int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
+ struct iommu_domain *new_domain)
{
struct arm_smmu_master *master = state->master;
struct arm_smmu_master_domain *master_domain;
@@ -2784,7 +2772,7 @@ static int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
* completes synchronizing the PCI device's ATC and finishes manipulating the
* smmu_domain->devices list.
*/
-static void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
+void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
{
struct arm_smmu_master *master = state->master;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 66261fd5bfb2d2..c9e5290e995a64 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -830,21 +830,22 @@ struct arm_smmu_entry_writer_ops {
void (*sync)(struct arm_smmu_entry_writer *writer);
};
+void arm_smmu_make_abort_ste(struct arm_smmu_ste *target);
+void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
+ struct arm_smmu_master *master,
+ struct arm_smmu_domain *smmu_domain,
+ bool ats_enabled);
+
#if IS_ENABLED(CONFIG_KUNIT)
void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits);
void arm_smmu_write_entry(struct arm_smmu_entry_writer *writer, __le64 *cur,
const __le64 *target);
void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits);
-void arm_smmu_make_abort_ste(struct arm_smmu_ste *target);
void arm_smmu_make_bypass_ste(struct arm_smmu_device *smmu,
struct arm_smmu_ste *target);
void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
struct arm_smmu_master *master, bool ats_enabled,
unsigned int s1dss);
-void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
- struct arm_smmu_master *master,
- struct arm_smmu_domain *smmu_domain,
- bool ats_enabled);
void arm_smmu_make_sva_cd(struct arm_smmu_cd *target,
struct arm_smmu_master *master, struct mm_struct *mm,
u16 asid);
@@ -902,6 +903,22 @@ static inline bool arm_smmu_master_canwbs(struct arm_smmu_master *master)
IOMMU_FWSPEC_PCI_RC_CANWBS;
}
+struct arm_smmu_attach_state {
+ /* Inputs */
+ struct iommu_domain *old_domain;
+ struct arm_smmu_master *master;
+ bool cd_needs_ats;
+ ioasid_t ssid;
+ /* Resulting state */
+ bool ats_enabled;
+};
+
+int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
+ struct iommu_domain *new_domain);
+void arm_smmu_attach_commit(struct arm_smmu_attach_state *state);
+void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
+ const struct arm_smmu_ste *target);
+
#ifdef CONFIG_ARM_SMMU_V3_SVA
bool arm_smmu_sva_supported(struct arm_smmu_device *smmu);
bool arm_smmu_master_sva_supported(struct arm_smmu_master *master);
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (6 preceding siblings ...)
2024-10-09 16:23 ` [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-09 17:27 ` Nicolin Chen
` (2 more replies)
2024-10-09 16:23 ` [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains Jason Gunthorpe
` (3 subsequent siblings)
11 siblings, 3 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
For SMMUv3 a IOMMU_DOMAIN_NESTED is composed of a S2 iommu_domain acting
as the parent and a user provided STE fragment that defines the CD table
and related data with addresses translated by the S2 iommu_domain.
The kernel only permits userspace to control certain allowed bits of the
STE that are safe for user/guest control.
IOTLB maintenance is a bit subtle here, the S1 implicitly includes the S2
translation, but there is no way of knowing which S1 entries refer to a
range of S2.
For the IOTLB we follow ARM's guidance and issue a CMDQ_OP_TLBI_NH_ALL to
flush all ASIDs from the VMID after flushing the S2 on any change to the
S2.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 172 ++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 25 ++-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 37 ++++
include/uapi/linux/iommufd.h | 20 ++
4 files changed, 250 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 3d2671031c9bb5..a9aa7514e65ce4 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -29,3 +29,175 @@ void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
return info;
}
+
+static void arm_smmu_make_nested_cd_table_ste(
+ struct arm_smmu_ste *target, struct arm_smmu_master *master,
+ struct arm_smmu_nested_domain *nested_domain, bool ats_enabled)
+{
+ arm_smmu_make_s2_domain_ste(target, master, nested_domain->s2_parent,
+ ats_enabled);
+
+ target->data[0] = cpu_to_le64(STRTAB_STE_0_V |
+ FIELD_PREP(STRTAB_STE_0_CFG,
+ STRTAB_STE_0_CFG_NESTED));
+ target->data[0] |= nested_domain->ste[0] &
+ ~cpu_to_le64(STRTAB_STE_0_CFG);
+ target->data[1] |= nested_domain->ste[1];
+}
+
+/*
+ * Create a physical STE from the virtual STE that userspace provided when it
+ * created the nested domain. Using the vSTE userspace can request:
+ * - Non-valid STE
+ * - Abort STE
+ * - Bypass STE (install the S2, no CD table)
+ * - CD table STE (install the S2 and the userspace CD table)
+ */
+static void arm_smmu_make_nested_domain_ste(
+ struct arm_smmu_ste *target, struct arm_smmu_master *master,
+ struct arm_smmu_nested_domain *nested_domain, bool ats_enabled)
+{
+ unsigned int cfg =
+ FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0]));
+
+ /*
+ * Userspace can request a non-valid STE through the nesting interface.
+ * We relay that into an abort physical STE with the intention that
+ * C_BAD_STE for this SID can be generated to userspace.
+ */
+ if (!(nested_domain->ste[0] & cpu_to_le64(STRTAB_STE_0_V)))
+ cfg = STRTAB_STE_0_CFG_ABORT;
+
+ switch (cfg) {
+ case STRTAB_STE_0_CFG_S1_TRANS:
+ arm_smmu_make_nested_cd_table_ste(target, master, nested_domain,
+ ats_enabled);
+ break;
+ case STRTAB_STE_0_CFG_BYPASS:
+ arm_smmu_make_s2_domain_ste(
+ target, master, nested_domain->s2_parent, ats_enabled);
+ break;
+ case STRTAB_STE_0_CFG_ABORT:
+ default:
+ arm_smmu_make_abort_ste(target);
+ break;
+ }
+}
+
+static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct arm_smmu_nested_domain *nested_domain =
+ to_smmu_nested_domain(domain);
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+ struct arm_smmu_attach_state state = {
+ .master = master,
+ .old_domain = iommu_get_domain_for_dev(dev),
+ .ssid = IOMMU_NO_PASID,
+ /* Currently invalidation of ATC is not supported */
+ .disable_ats = true,
+ };
+ struct arm_smmu_ste ste;
+ int ret;
+
+ if (nested_domain->s2_parent->smmu != master->smmu)
+ return -EINVAL;
+ if (arm_smmu_ssids_in_use(&master->cd_table))
+ return -EBUSY;
+
+ mutex_lock(&arm_smmu_asid_lock);
+ ret = arm_smmu_attach_prepare(&state, domain);
+ if (ret) {
+ mutex_unlock(&arm_smmu_asid_lock);
+ return ret;
+ }
+
+ arm_smmu_make_nested_domain_ste(&ste, master, nested_domain,
+ state.ats_enabled);
+ arm_smmu_install_ste_for_dev(master, &ste);
+ arm_smmu_attach_commit(&state);
+ mutex_unlock(&arm_smmu_asid_lock);
+ return 0;
+}
+
+static void arm_smmu_domain_nested_free(struct iommu_domain *domain)
+{
+ kfree(to_smmu_nested_domain(domain));
+}
+
+static const struct iommu_domain_ops arm_smmu_nested_ops = {
+ .attach_dev = arm_smmu_attach_dev_nested,
+ .free = arm_smmu_domain_nested_free,
+};
+
+static int arm_smmu_validate_vste(struct iommu_hwpt_arm_smmuv3 *arg)
+{
+ unsigned int cfg;
+
+ if (!(arg->ste[0] & cpu_to_le64(STRTAB_STE_0_V))) {
+ memset(arg->ste, 0, sizeof(arg->ste));
+ return 0;
+ }
+
+ /* EIO is reserved for invalid STE data. */
+ if ((arg->ste[0] & ~STRTAB_STE_0_NESTING_ALLOWED) ||
+ (arg->ste[1] & ~STRTAB_STE_1_NESTING_ALLOWED))
+ return -EIO;
+
+ cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(arg->ste[0]));
+ if (cfg != STRTAB_STE_0_CFG_ABORT && cfg != STRTAB_STE_0_CFG_BYPASS &&
+ cfg != STRTAB_STE_0_CFG_S1_TRANS)
+ return -EIO;
+ return 0;
+}
+
+struct iommu_domain *
+arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
+ struct iommu_domain *parent,
+ const struct iommu_user_data *user_data)
+{
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+ struct arm_smmu_nested_domain *nested_domain;
+ struct arm_smmu_domain *smmu_parent;
+ struct iommu_hwpt_arm_smmuv3 arg;
+ int ret;
+
+ if (flags || !(master->smmu->features & ARM_SMMU_FEAT_NESTING))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ /*
+ * Must support some way to prevent the VM from bypassing the cache
+ * because VFIO currently does not do any cache maintenance.
+ */
+ if (!arm_smmu_master_canwbs(master))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ /*
+ * The core code checks that parent was created with
+ * IOMMU_HWPT_ALLOC_NEST_PARENT
+ */
+ smmu_parent = to_smmu_domain(parent);
+ if (smmu_parent->smmu != master->smmu)
+ return ERR_PTR(-EINVAL);
+
+ ret = iommu_copy_struct_from_user(&arg, user_data,
+ IOMMU_HWPT_DATA_ARM_SMMUV3, ste);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = arm_smmu_validate_vste(&arg);
+ if (ret)
+ return ERR_PTR(ret);
+
+ nested_domain = kzalloc(sizeof(*nested_domain), GFP_KERNEL_ACCOUNT);
+ if (!nested_domain)
+ return ERR_PTR(-ENOMEM);
+
+ nested_domain->domain.type = IOMMU_DOMAIN_NESTED;
+ nested_domain->domain.ops = &arm_smmu_nested_ops;
+ nested_domain->s2_parent = smmu_parent;
+ nested_domain->ste[0] = arg.ste[0];
+ nested_domain->ste[1] = arg.ste[1] & ~cpu_to_le64(STRTAB_STE_1_EATS);
+
+ return &nested_domain->domain;
+}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index b4b03206afbf48..eb401a4adfedc8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -295,6 +295,7 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
case CMDQ_OP_TLBI_NH_ASID:
cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
fallthrough;
+ case CMDQ_OP_TLBI_NH_ALL:
case CMDQ_OP_TLBI_S12_VMALL:
cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
break;
@@ -2230,6 +2231,15 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
}
__arm_smmu_tlb_inv_range(&cmd, iova, size, granule, smmu_domain);
+ if (smmu_domain->nest_parent) {
+ /*
+ * When the S2 domain changes all the nested S1 ASIDs have to be
+ * flushed too.
+ */
+ cmd.opcode = CMDQ_OP_TLBI_NH_ALL;
+ arm_smmu_cmdq_issue_cmd_with_sync(smmu_domain->smmu, &cmd);
+ }
+
/*
* Unfortunately, this can't be leaf-only since we may have
* zapped an entire table.
@@ -2614,8 +2624,7 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
static struct arm_smmu_master_domain *
arm_smmu_find_master_domain(struct arm_smmu_domain *smmu_domain,
- struct arm_smmu_master *master,
- ioasid_t ssid)
+ struct arm_smmu_master *master, ioasid_t ssid)
{
struct arm_smmu_master_domain *master_domain;
@@ -2644,6 +2653,8 @@ to_smmu_domain_devices(struct iommu_domain *domain)
if ((domain->type & __IOMMU_DOMAIN_PAGING) ||
domain->type == IOMMU_DOMAIN_SVA)
return to_smmu_domain(domain);
+ if (domain->type == IOMMU_DOMAIN_NESTED)
+ return to_smmu_nested_domain(domain)->s2_parent;
return NULL;
}
@@ -2716,7 +2727,8 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
* enabled if we have arm_smmu_domain, those always have page
* tables.
*/
- state->ats_enabled = arm_smmu_ats_supported(master);
+ state->ats_enabled = !state->disable_ats &&
+ arm_smmu_ats_supported(master);
}
if (smmu_domain) {
@@ -3107,9 +3119,13 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
struct arm_smmu_domain *smmu_domain;
int ret;
+ if (parent)
+ return arm_smmu_domain_alloc_nesting(dev, flags, parent,
+ user_data);
+
if (flags & ~PAGING_FLAGS)
return ERR_PTR(-EOPNOTSUPP);
- if (parent || user_data)
+ if (user_data)
return ERR_PTR(-EOPNOTSUPP);
smmu_domain = arm_smmu_domain_alloc();
@@ -3122,6 +3138,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
goto err_free;
}
smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
+ smmu_domain->nest_parent = true;
}
smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index c9e5290e995a64..b5dbf5acbfc4db 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -243,6 +243,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
#define STRTAB_STE_0_CFG_BYPASS 4
#define STRTAB_STE_0_CFG_S1_TRANS 5
#define STRTAB_STE_0_CFG_S2_TRANS 6
+#define STRTAB_STE_0_CFG_NESTED 7
#define STRTAB_STE_0_S1FMT GENMASK_ULL(5, 4)
#define STRTAB_STE_0_S1FMT_LINEAR 0
@@ -294,6 +295,15 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
#define STRTAB_STE_3_S2TTB_MASK GENMASK_ULL(51, 4)
+/* These bits can be controlled by userspace for STRTAB_STE_0_CFG_NESTED */
+#define STRTAB_STE_0_NESTING_ALLOWED \
+ cpu_to_le64(STRTAB_STE_0_V | STRTAB_STE_0_CFG | STRTAB_STE_0_S1FMT | \
+ STRTAB_STE_0_S1CTXPTR_MASK | STRTAB_STE_0_S1CDMAX)
+#define STRTAB_STE_1_NESTING_ALLOWED \
+ cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR | \
+ STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH | \
+ STRTAB_STE_1_S1STALLD)
+
/*
* Context descriptors.
*
@@ -513,6 +523,7 @@ struct arm_smmu_cmdq_ent {
};
} cfgi;
+ #define CMDQ_OP_TLBI_NH_ALL 0x10
#define CMDQ_OP_TLBI_NH_ASID 0x11
#define CMDQ_OP_TLBI_NH_VA 0x12
#define CMDQ_OP_TLBI_EL2_ALL 0x20
@@ -814,10 +825,18 @@ struct arm_smmu_domain {
struct list_head devices;
spinlock_t devices_lock;
bool enforce_cache_coherency : 1;
+ bool nest_parent : 1;
struct mmu_notifier mmu_notifier;
};
+struct arm_smmu_nested_domain {
+ struct iommu_domain domain;
+ struct arm_smmu_domain *s2_parent;
+
+ __le64 ste[2];
+};
+
/* The following are exposed for testing purposes. */
struct arm_smmu_entry_writer_ops;
struct arm_smmu_entry_writer {
@@ -862,6 +881,12 @@ static inline struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
return container_of(dom, struct arm_smmu_domain, domain);
}
+static inline struct arm_smmu_nested_domain *
+to_smmu_nested_domain(struct iommu_domain *dom)
+{
+ return container_of(dom, struct arm_smmu_nested_domain, domain);
+}
+
extern struct xarray arm_smmu_asid_xa;
extern struct mutex arm_smmu_asid_lock;
@@ -908,6 +933,7 @@ struct arm_smmu_attach_state {
struct iommu_domain *old_domain;
struct arm_smmu_master *master;
bool cd_needs_ats;
+ bool disable_ats;
ioasid_t ssid;
/* Resulting state */
bool ats_enabled;
@@ -978,8 +1004,19 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
#if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
+struct iommu_domain *
+arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
+ struct iommu_domain *parent,
+ const struct iommu_user_data *user_data);
#else
#define arm_smmu_hw_info NULL
+static inline struct iommu_domain *
+arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
+ struct iommu_domain *parent,
+ const struct iommu_user_data *user_data)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
#endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
#endif /* _ARM_SMMU_V3_H */
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index b5c94fecb94ca5..cd4920886ad05e 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -394,14 +394,34 @@ struct iommu_hwpt_vtd_s1 {
__u32 __reserved;
};
+/**
+ * struct iommu_hwpt_arm_smmuv3 - ARM SMMUv3 Context Descriptor Table info
+ * (IOMMU_HWPT_DATA_ARM_SMMUV3)
+ *
+ * @ste: The first two double words of the user space Stream Table Entry for
+ * a user stage-1 Context Descriptor Table. Must be little-endian.
+ * Allowed fields: (Refer to "5.2 Stream Table Entry" in SMMUv3 HW Spec)
+ * - word-0: V, Cfg, S1Fmt, S1ContextPtr, S1CDMax
+ * - word-1: S1DSS, S1CIR, S1COR, S1CSH, S1STALLD
+ *
+ * -EIO will be returned if @ste is not legal or contains any non-allowed field.
+ * Cfg can be used to select a S1, Bypass or Abort configuration. A Bypass
+ * nested domain will translate the same as the nesting parent.
+ */
+struct iommu_hwpt_arm_smmuv3 {
+ __aligned_le64 ste[2];
+};
+
/**
* enum iommu_hwpt_data_type - IOMMU HWPT Data Type
* @IOMMU_HWPT_DATA_NONE: no data
* @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table
+ * @IOMMU_HWPT_DATA_ARM_SMMUV3: ARM SMMUv3 Context Descriptor Table
*/
enum iommu_hwpt_data_type {
IOMMU_HWPT_DATA_NONE = 0,
IOMMU_HWPT_DATA_VTD_S1 = 1,
+ IOMMU_HWPT_DATA_ARM_SMMUV3 = 2,
};
/**
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (7 preceding siblings ...)
2024-10-09 16:23 ` [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED Jason Gunthorpe
@ 2024-10-09 16:23 ` Jason Gunthorpe
2024-10-09 17:42 ` Nicolin Chen
2024-10-24 7:54 ` Tian, Kevin
2024-10-09 17:46 ` [PATCH v3 0/9] Initial support for SMMUv3 nested translation Nicolin Chen
` (2 subsequent siblings)
11 siblings, 2 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-09 16:23 UTC (permalink / raw)
To: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
Force Write Back (FWB) changes how the S2 IOPTE's MemAttr field
works. When S2FWB is supported and enabled the IOPTE will force cachable
access to IOMMU_CACHE memory when nesting with a S1 and deny cachable
access otherwise.
When using a single stage of translation, a simple S2 domain, it doesn't
change things for PCI devices as it is just a different encoding for the
existing mapping of the IOMMU protection flags to cachability attributes.
For non-PCI it also changes the combining rules when incoming transactions
have inconsistent attributes.
However, when used with a nested S1, FWB has the effect of preventing the
guest from choosing a MemAttr in it's S1 that would cause ordinary DMA to
bypass the cache. Consistent with KVM we wish to deny the guest the
ability to become incoherent with cached memory the hypervisor believes is
cachable so we don't have to flush it.
Allow NESTED domains to be created if the SMMU has S2FWB support and use
S2FWB for NESTING_PARENTS. This is an additional option to CANWBS.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 3 ++-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 +++
drivers/iommu/io-pgtable-arm.c | 27 ++++++++++++++-----
include/linux/io-pgtable.h | 2 ++
5 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index a9aa7514e65ce4..44e1b9bef850d9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -169,7 +169,8 @@ arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
* Must support some way to prevent the VM from bypassing the cache
* because VFIO currently does not do any cache maintenance.
*/
- if (!arm_smmu_master_canwbs(master))
+ if (!arm_smmu_master_canwbs(master) &&
+ !(master->smmu->features & ARM_SMMU_FEAT_S2FWB))
return ERR_PTR(-EOPNOTSUPP);
/*
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index eb401a4adfedc8..4e559e02514983 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1046,7 +1046,8 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
/* S2 translates */
if (cfg & BIT(1)) {
used_bits[1] |=
- cpu_to_le64(STRTAB_STE_1_EATS | STRTAB_STE_1_SHCFG);
+ cpu_to_le64(STRTAB_STE_1_S2FWB | STRTAB_STE_1_EATS |
+ STRTAB_STE_1_SHCFG);
used_bits[2] |=
cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
@@ -1654,6 +1655,8 @@ void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
FIELD_PREP(STRTAB_STE_1_EATS,
ats_enabled ? STRTAB_STE_1_EATS_TRANS : 0));
+ if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_S2FWB)
+ target->data[1] |= cpu_to_le64(STRTAB_STE_1_S2FWB);
if (smmu->features & ARM_SMMU_FEAT_ATTR_TYPES_OVR)
target->data[1] |= cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
STRTAB_STE_1_SHCFG_INCOMING));
@@ -2472,6 +2475,9 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
pgtbl_cfg.oas = smmu->oas;
fmt = ARM_64_LPAE_S2;
finalise_stage_fn = arm_smmu_domain_finalise_s2;
+ if ((smmu->features & ARM_SMMU_FEAT_S2FWB) &&
+ (flags & IOMMU_HWPT_ALLOC_NEST_PARENT))
+ pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_S2FWB;
break;
default:
return -EINVAL;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index b5dbf5acbfc4db..e394943c0b4bfe 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -57,6 +57,7 @@ struct arm_smmu_device;
#define IDR1_SIDSIZE GENMASK(5, 0)
#define ARM_SMMU_IDR3 0xc
+#define IDR3_FWB (1 << 8)
#define IDR3_RIL (1 << 10)
#define ARM_SMMU_IDR5 0x14
@@ -265,6 +266,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
#define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6)
#define STRTAB_STE_1_S1STALLD (1UL << 27)
+#define STRTAB_STE_1_S2FWB (1UL << 25)
#define STRTAB_STE_1_EATS GENMASK_ULL(29, 28)
#define STRTAB_STE_1_EATS_ABT 0UL
@@ -739,6 +741,7 @@ struct arm_smmu_device {
#define ARM_SMMU_FEAT_ATTR_TYPES_OVR (1 << 20)
#define ARM_SMMU_FEAT_HA (1 << 21)
#define ARM_SMMU_FEAT_HD (1 << 22)
+#define ARM_SMMU_FEAT_S2FWB (1 << 23)
u32 features;
#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 0e67f1721a3d98..74f58c6ac30cbd 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -106,6 +106,18 @@
#define ARM_LPAE_PTE_HAP_FAULT (((arm_lpae_iopte)0) << 6)
#define ARM_LPAE_PTE_HAP_READ (((arm_lpae_iopte)1) << 6)
#define ARM_LPAE_PTE_HAP_WRITE (((arm_lpae_iopte)2) << 6)
+/*
+ * For !FWB these code to:
+ * 1111 = Normal outer write back cachable / Inner Write Back Cachable
+ * Permit S1 to override
+ * 0101 = Normal Non-cachable / Inner Non-cachable
+ * 0001 = Device / Device-nGnRE
+ * For S2FWB these code:
+ * 0110 Force Normal Write Back
+ * 0101 Normal* is forced Normal-NC, Device unchanged
+ * 0001 Force Device-nGnRE
+ */
+#define ARM_LPAE_PTE_MEMATTR_FWB_WB (((arm_lpae_iopte)0x6) << 2)
#define ARM_LPAE_PTE_MEMATTR_OIWB (((arm_lpae_iopte)0xf) << 2)
#define ARM_LPAE_PTE_MEMATTR_NC (((arm_lpae_iopte)0x5) << 2)
#define ARM_LPAE_PTE_MEMATTR_DEV (((arm_lpae_iopte)0x1) << 2)
@@ -458,12 +470,16 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
*/
if (data->iop.fmt == ARM_64_LPAE_S2 ||
data->iop.fmt == ARM_32_LPAE_S2) {
- if (prot & IOMMU_MMIO)
+ if (prot & IOMMU_MMIO) {
pte |= ARM_LPAE_PTE_MEMATTR_DEV;
- else if (prot & IOMMU_CACHE)
- pte |= ARM_LPAE_PTE_MEMATTR_OIWB;
- else
+ } else if (prot & IOMMU_CACHE) {
+ if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_S2FWB)
+ pte |= ARM_LPAE_PTE_MEMATTR_FWB_WB;
+ else
+ pte |= ARM_LPAE_PTE_MEMATTR_OIWB;
+ } else {
pte |= ARM_LPAE_PTE_MEMATTR_NC;
+ }
} else {
if (prot & IOMMU_MMIO)
pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV
@@ -1035,8 +1051,7 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
struct arm_lpae_io_pgtable *data;
typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;
- /* The NS quirk doesn't apply at stage 2 */
- if (cfg->quirks)
+ if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_S2FWB))
return NULL;
data = arm_lpae_alloc_pgtable(cfg);
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index b1ecfc3cd5bcc0..ce86b09ae80f18 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -87,6 +87,7 @@ struct io_pgtable_cfg {
* attributes set in the TCR for a non-coherent page-table walker.
*
* IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 pagetable.
+ * IO_PGTABLE_QUIRK_ARM_S2FWB: Use the FWB format for the MemAttrs bits
*/
#define IO_PGTABLE_QUIRK_ARM_NS BIT(0)
#define IO_PGTABLE_QUIRK_NO_PERMS BIT(1)
@@ -95,6 +96,7 @@ struct io_pgtable_cfg {
#define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5)
#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6)
#define IO_PGTABLE_QUIRK_ARM_HD BIT(7)
+ #define IO_PGTABLE_QUIRK_ARM_S2FWB BIT(8)
unsigned long quirks;
unsigned long pgsize_bitmap;
unsigned int ias;
--
2.46.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface
2024-10-09 16:23 ` [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface Jason Gunthorpe
@ 2024-10-09 17:03 ` Nicolin Chen
2024-10-24 7:47 ` Tian, Kevin
2024-10-30 16:26 ` Mostafa Saleh
2 siblings, 0 replies; 34+ messages in thread
From: Nicolin Chen @ 2024-10-09 17:03 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, patches, Rafael J. Wysocki,
Shameerali Kolothum Thodi, Mostafa Saleh
On Wed, Oct 09, 2024 at 01:23:13PM -0300, Jason Gunthorpe wrote:
> The arm-smmuv3-iommufd.c file will need to call these functions too.
> Remove statics and put them in the header file. Remove the kunit
> visibility protections from arm_smmu_make_abort_ste() and
> arm_smmu_make_s2_domain_ste().
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
2024-10-09 16:23 ` [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED Jason Gunthorpe
@ 2024-10-09 17:27 ` Nicolin Chen
2024-10-11 13:59 ` Jason Gunthorpe
2024-10-24 7:50 ` Tian, Kevin
2024-10-30 16:29 ` Mostafa Saleh
2 siblings, 1 reply; 34+ messages in thread
From: Nicolin Chen @ 2024-10-09 17:27 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, patches, Rafael J. Wysocki,
Shameerali Kolothum Thodi, Mostafa Saleh
On Wed, Oct 09, 2024 at 01:23:14PM -0300, Jason Gunthorpe wrote:
> For SMMUv3 a IOMMU_DOMAIN_NESTED is composed of a S2 iommu_domain acting
> as the parent and a user provided STE fragment that defines the CD table
> and related data with addresses translated by the S2 iommu_domain.
>
> The kernel only permits userspace to control certain allowed bits of the
> STE that are safe for user/guest control.
>
> IOTLB maintenance is a bit subtle here, the S1 implicitly includes the S2
> translation, but there is no way of knowing which S1 entries refer to a
> range of S2.
>
> For the IOTLB we follow ARM's guidance and issue a CMDQ_OP_TLBI_NH_ALL to
> flush all ASIDs from the VMID after flushing the S2 on any change to the
> S2.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index b4b03206afbf48..eb401a4adfedc8 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2614,8 +2624,7 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
>
> static struct arm_smmu_master_domain *
> arm_smmu_find_master_domain(struct arm_smmu_domain *smmu_domain,
> - struct arm_smmu_master *master,
> - ioasid_t ssid)
> + struct arm_smmu_master *master, ioasid_t ssid)
> {
> struct arm_smmu_master_domain *master_domain;
Looks like we mixed a cosmetic change :)
Thanks
Nicolin
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains
2024-10-09 16:23 ` [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains Jason Gunthorpe
@ 2024-10-09 17:42 ` Nicolin Chen
2024-10-11 14:00 ` Jason Gunthorpe
2024-10-24 7:54 ` Tian, Kevin
1 sibling, 1 reply; 34+ messages in thread
From: Nicolin Chen @ 2024-10-09 17:42 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, patches, Rafael J. Wysocki,
Shameerali Kolothum Thodi, Mostafa Saleh
On Wed, Oct 09, 2024 at 01:23:15PM -0300, Jason Gunthorpe wrote:
> Force Write Back (FWB) changes how the S2 IOPTE's MemAttr field
> works. When S2FWB is supported and enabled the IOPTE will force cachable
> access to IOMMU_CACHE memory when nesting with a S1 and deny cachable
> access otherwise.
>
> When using a single stage of translation, a simple S2 domain, it doesn't
> change things for PCI devices as it is just a different encoding for the
> existing mapping of the IOMMU protection flags to cachability attributes.
> For non-PCI it also changes the combining rules when incoming transactions
> have inconsistent attributes.
>
> However, when used with a nested S1, FWB has the effect of preventing the
> guest from choosing a MemAttr in it's S1 that would cause ordinary DMA to
> bypass the cache. Consistent with KVM we wish to deny the guest the
> ability to become incoherent with cached memory the hypervisor believes is
> cachable so we don't have to flush it.
>
> Allow NESTED domains to be created if the SMMU has S2FWB support and use
> S2FWB for NESTING_PARENTS. This is an additional option to CANWBS.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
My HW doesn't support this S2FWB for testing, but the patch LGTM.
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> @@ -265,6 +266,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
> #define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6)
>
> #define STRTAB_STE_1_S1STALLD (1UL << 27)
> +#define STRTAB_STE_1_S2FWB (1UL << 25)
Nit: seems that it should be in ascending order.
Thanks
Nicolin
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 0/9] Initial support for SMMUv3 nested translation
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (8 preceding siblings ...)
2024-10-09 16:23 ` [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains Jason Gunthorpe
@ 2024-10-09 17:46 ` Nicolin Chen
2024-10-26 20:26 ` Jerry Snitselaar
2024-10-30 4:06 ` Donald Dutile
11 siblings, 0 replies; 34+ messages in thread
From: Nicolin Chen @ 2024-10-09 17:46 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, patches, Rafael J. Wysocki,
Shameerali Kolothum Thodi, Mostafa Saleh
On Wed, Oct 09, 2024 at 01:23:06PM -0300, Jason Gunthorpe wrote:
> The vIOMMU series is essential to allow the invalidations to be processed
> for the CD as well.
>
> It is enough to allow qemu work to progress.
>
> This is on github: https://github.com/jgunthorpe/linux/commits/smmuv3_nesting
>
> v3:
> - Rebase on v6.12-rc2
> - Revise commit messages
> - Consolidate CANWB checks into arm_smmu_master_canwbs()
> - Add CONFIG_ARM_SMMU_V3_IOMMUFD to compile out iommufd only features
> like nesting
> - Shift code into arm-smmu-v3-iommufd.c
> - Add missed IS_ERR check
> - Add S2FWB to arm_smmu_get_ste_used()
> - Fixup quirks checks
> - Drop ARM_SMMU_FEAT_COHERENCY checks for S2FWB
> - Limit S2FWB to S2 Nesting Parent domains "just in case"
Verified SVA feature in a guest VM, with the vIOMMU part-1&2 series
applied on top and the pairing QEMU branch mentioned in the part-2
cover-letter:
https://lore.kernel.org/linux-iommu/cover.1728491532.git.nicolinc@nvidia.com/
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 2/9] ACPICA: IORT: Update for revision E.f
2024-10-09 16:23 ` [PATCH v3 2/9] ACPICA: IORT: Update for revision E.f Jason Gunthorpe
@ 2024-10-10 1:48 ` Hanjun Guo
0 siblings, 0 replies; 34+ messages in thread
From: Hanjun Guo @ 2024-10-10 1:48 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel, iommu, Joerg Roedel, Kevin Tian,
kvm, Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
On 2024/10/10 0:23, Jason Gunthorpe wrote:
> From: Nicolin Chen <nicolinc@nvidia.com>
>
> ACPICA commit c4f5c083d24df9ddd71d5782c0988408cf0fc1ab
>
> The IORT spec, Issue E.f (April 2024), adds a new CANWBS bit to the Memory
> Access Flag field in the Memory Access Properties table, mainly for a PCI
> Root Complex.
>
> This CANWBS defines the coherency of memory accesses to be not marked IOWB
> cacheable/shareable. Its value further implies the coherency impact from a
> pair of mismatched memory attributes (e.g. in a nested translation case):
> 0x0: Use of mismatched memory attributes for accesses made by this
> device may lead to a loss of coherency.
> 0x1: Coherency of accesses made by this device to locations in
> Conventional memory are ensured as follows, even if the memory
> attributes for the accesses presented by the device or provided by
> the SMMU are different from Inner and Outer Write-back cacheable,
> Shareable.
>
Acked-by: Hanjun Guo <guohanjun@huawei.com>
Thanks
Hanjun
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag
2024-10-09 16:23 ` [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag Jason Gunthorpe
@ 2024-10-10 7:45 ` Hanjun Guo
2024-10-24 7:38 ` Tian, Kevin
1 sibling, 0 replies; 34+ messages in thread
From: Hanjun Guo @ 2024-10-10 7:45 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel, iommu, Joerg Roedel, Kevin Tian,
kvm, Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
On 2024/10/10 0:23, Jason Gunthorpe wrote:
> From: Nicolin Chen<nicolinc@nvidia.com>
>
> The IORT spec, Issue E.f (April 2024), adds a new CANWBS bit to the Memory
> Access Flag field in the Memory Access Properties table, mainly for a PCI
> Root Complex.
>
> This CANWBS defines the coherency of memory accesses to be not marked IOWB
> cacheable/shareable. Its value further implies the coherency impact from a
> pair of mismatched memory attributes (e.g. in a nested translation case):
> 0x0: Use of mismatched memory attributes for accesses made by this
> device may lead to a loss of coherency.
> 0x1: Coherency of accesses made by this device to locations in
> Conventional memory are ensured as follows, even if the memory
> attributes for the accesses presented by the device or provided by
> the SMMU are different from Inner and Outer Write-back cacheable,
> Shareable.
>
> Note that the loss of coherency on a CANWBS-unsupported HW typically could
> occur to an SMMU that doesn't implement the S2FWB feature where additional
> cache flush operations would be required to prevent that from happening.
>
> Add a new ACPI_IORT_MF_CANWBS flag and set IOMMU_FWSPEC_PCI_RC_CANWBS upon
> the presence of this new flag.
>
> CANWBS and S2FWB are similar features, in that they both guarantee the VM
> can not violate coherency, however S2FWB can be bypassed by PCI No Snoop
> TLPs, while CANWBS cannot. Thus CANWBS meets the requirements to set
> IOMMU_CAP_ENFORCE_CACHE_COHERENCY.
>
> Architecturally ARM has expected that VFIO would disable No Snoop through
> PCI Config space, if this is done then the two would have the same
> protections.
Acked-by: Hanjun Guo <guohanjun@huawei.com>
Thanks
Hanjun
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
2024-10-09 17:27 ` Nicolin Chen
@ 2024-10-11 13:59 ` Jason Gunthorpe
0 siblings, 0 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-11 13:59 UTC (permalink / raw)
To: Nicolin Chen
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, patches, Rafael J. Wysocki,
Shameerali Kolothum Thodi, Mostafa Saleh
On Wed, Oct 09, 2024 at 10:27:42AM -0700, Nicolin Chen wrote:
> > static struct arm_smmu_master_domain *
> > arm_smmu_find_master_domain(struct arm_smmu_domain *smmu_domain,
> > - struct arm_smmu_master *master,
> > - ioasid_t ssid)
> > + struct arm_smmu_master *master, ioasid_t ssid)
> > {
> > struct arm_smmu_master_domain *master_domain;
>
> Looks like we mixed a cosmetic change :)
Ah, it is undone in a later patch from moving some code around I fixed
it
Thanks,
Jason
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains
2024-10-09 17:42 ` Nicolin Chen
@ 2024-10-11 14:00 ` Jason Gunthorpe
0 siblings, 0 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-11 14:00 UTC (permalink / raw)
To: Nicolin Chen
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, patches, Rafael J. Wysocki,
Shameerali Kolothum Thodi, Mostafa Saleh
On Wed, Oct 09, 2024 at 10:42:04AM -0700, Nicolin Chen wrote:
> > @@ -265,6 +266,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
> > #define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6)
> >
> > #define STRTAB_STE_1_S1STALLD (1UL << 27)
> > +#define STRTAB_STE_1_S2FWB (1UL << 25)
>
> Nit: seems that it should be in ascending order.
Done
Jason
^ permalink raw reply [flat|nested] 34+ messages in thread
* RE: [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag
2024-10-09 16:23 ` [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag Jason Gunthorpe
2024-10-10 7:45 ` Hanjun Guo
@ 2024-10-24 7:38 ` Tian, Kevin
1 sibling, 0 replies; 34+ messages in thread
From: Tian, Kevin @ 2024-10-24 7:38 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel@lists.linux.dev, Hanjun Guo,
iommu@lists.linux.dev, Joerg Roedel, kvm@vger.kernel.org,
Len Brown, linux-acpi@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Lorenzo Pieralisi,
Rafael J. Wysocki, Moore, Robert, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen,
patches@lists.linux.dev, Wysocki, Rafael J,
Shameerali Kolothum Thodi, Mostafa Saleh
> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Thursday, October 10, 2024 12:23 AM
>
> From: Nicolin Chen <nicolinc@nvidia.com>
>
> The IORT spec, Issue E.f (April 2024), adds a new CANWBS bit to the Memory
> Access Flag field in the Memory Access Properties table, mainly for a PCI
> Root Complex.
>
> This CANWBS defines the coherency of memory accesses to be not marked
> IOWB
> cacheable/shareable. Its value further implies the coherency impact from a
> pair of mismatched memory attributes (e.g. in a nested translation case):
> 0x0: Use of mismatched memory attributes for accesses made by this
> device may lead to a loss of coherency.
> 0x1: Coherency of accesses made by this device to locations in
> Conventional memory are ensured as follows, even if the memory
> attributes for the accesses presented by the device or provided by
> the SMMU are different from Inner and Outer Write-back cacheable,
> Shareable.
>
> Note that the loss of coherency on a CANWBS-unsupported HW typically
> could
> occur to an SMMU that doesn't implement the S2FWB feature where
> additional
> cache flush operations would be required to prevent that from happening.
>
> Add a new ACPI_IORT_MF_CANWBS flag and set
> IOMMU_FWSPEC_PCI_RC_CANWBS upon
> the presence of this new flag.
>
> CANWBS and S2FWB are similar features, in that they both guarantee the VM
> can not violate coherency, however S2FWB can be bypassed by PCI No Snoop
> TLPs, while CANWBS cannot. Thus CANWBS meets the requirements to set
> IOMMU_CAP_ENFORCE_CACHE_COHERENCY.
>
> Architecturally ARM has expected that VFIO would disable No Snoop through
> PCI Config space, if this is done then the two would have the same
> protections.
>
> Tested-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* RE: [PATCH v3 4/9] iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS
2024-10-09 16:23 ` [PATCH v3 4/9] iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS Jason Gunthorpe
@ 2024-10-24 7:41 ` Tian, Kevin
0 siblings, 0 replies; 34+ messages in thread
From: Tian, Kevin @ 2024-10-24 7:41 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel@lists.linux.dev, Hanjun Guo,
iommu@lists.linux.dev, Joerg Roedel, kvm@vger.kernel.org,
Len Brown, linux-acpi@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Lorenzo Pieralisi,
Rafael J. Wysocki, Moore, Robert, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen,
patches@lists.linux.dev, Wysocki, Rafael J,
Shameerali Kolothum Thodi, Mostafa Saleh
> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Thursday, October 10, 2024 12:23 AM
>
> HW with CANWBS is always cache coherent and ignores PCI No Snoop
> requests
> as well. This meets the requirement for
> IOMMU_CAP_ENFORCE_CACHE_COHERENCY,
> so let's return it.
>
> Implement the enforce_cache_coherency() op to reject attaching devices
> that don't have CANWBS.
>
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> Reviewed-by: Mostafa Saleh <smostafa@google.com>
> Tested-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* RE: [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface
2024-10-09 16:23 ` [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface Jason Gunthorpe
2024-10-09 17:03 ` Nicolin Chen
@ 2024-10-24 7:47 ` Tian, Kevin
2024-10-30 16:26 ` Mostafa Saleh
2 siblings, 0 replies; 34+ messages in thread
From: Tian, Kevin @ 2024-10-24 7:47 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel@lists.linux.dev, Hanjun Guo,
iommu@lists.linux.dev, Joerg Roedel, kvm@vger.kernel.org,
Len Brown, linux-acpi@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Lorenzo Pieralisi,
Rafael J. Wysocki, Moore, Robert, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen,
patches@lists.linux.dev, Wysocki, Rafael J,
Shameerali Kolothum Thodi, Mostafa Saleh
> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Thursday, October 10, 2024 12:23 AM
>
> The arm-smmuv3-iommufd.c file will need to call these functions too.
> Remove statics and put them in the header file. Remove the kunit
> visibility protections from arm_smmu_make_abort_ste() and
> arm_smmu_make_s2_domain_ste().
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* RE: [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
2024-10-09 16:23 ` [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED Jason Gunthorpe
2024-10-09 17:27 ` Nicolin Chen
@ 2024-10-24 7:50 ` Tian, Kevin
2024-10-30 16:29 ` Mostafa Saleh
2 siblings, 0 replies; 34+ messages in thread
From: Tian, Kevin @ 2024-10-24 7:50 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel@lists.linux.dev, Hanjun Guo,
iommu@lists.linux.dev, Joerg Roedel, kvm@vger.kernel.org,
Len Brown, linux-acpi@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Lorenzo Pieralisi,
Rafael J. Wysocki, Moore, Robert, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen,
patches@lists.linux.dev, Wysocki, Rafael J,
Shameerali Kolothum Thodi, Mostafa Saleh
> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Thursday, October 10, 2024 12:23 AM
>
> For SMMUv3 a IOMMU_DOMAIN_NESTED is composed of a S2
> iommu_domain acting
> as the parent and a user provided STE fragment that defines the CD table
> and related data with addresses translated by the S2 iommu_domain.
>
> The kernel only permits userspace to control certain allowed bits of the
> STE that are safe for user/guest control.
>
> IOTLB maintenance is a bit subtle here, the S1 implicitly includes the S2
> translation, but there is no way of knowing which S1 entries refer to a
> range of S2.
>
> For the IOTLB we follow ARM's guidance and issue a
> CMDQ_OP_TLBI_NH_ALL to
> flush all ASIDs from the VMID after flushing the S2 on any change to the
> S2.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* RE: [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains
2024-10-09 16:23 ` [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains Jason Gunthorpe
2024-10-09 17:42 ` Nicolin Chen
@ 2024-10-24 7:54 ` Tian, Kevin
2024-10-25 14:00 ` Jason Gunthorpe
1 sibling, 1 reply; 34+ messages in thread
From: Tian, Kevin @ 2024-10-24 7:54 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel@lists.linux.dev, Hanjun Guo,
iommu@lists.linux.dev, Joerg Roedel, kvm@vger.kernel.org,
Len Brown, linux-acpi@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Lorenzo Pieralisi,
Rafael J. Wysocki, Moore, Robert, Robin Murphy, Sudeep Holla,
Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen,
patches@lists.linux.dev, Wysocki, Rafael J,
Shameerali Kolothum Thodi, Mostafa Saleh
> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Thursday, October 10, 2024 12:23 AM
>
> Force Write Back (FWB) changes how the S2 IOPTE's MemAttr field
> works. When S2FWB is supported and enabled the IOPTE will force cachable
> access to IOMMU_CACHE memory when nesting with a S1 and deny cachable
> access otherwise.
didn't get the last part "deny cacheable access otherwise"
> @@ -169,7 +169,8 @@ arm_smmu_domain_alloc_nesting(struct device *dev,
> u32 flags,
> * Must support some way to prevent the VM from bypassing the
> cache
> * because VFIO currently does not do any cache maintenance.
> */
> - if (!arm_smmu_master_canwbs(master))
> + if (!arm_smmu_master_canwbs(master) &&
> + !(master->smmu->features & ARM_SMMU_FEAT_S2FWB))
> return ERR_PTR(-EOPNOTSUPP);
Probably can clarify the difference between CANWBS and S2FWB here
by copying some words from the previous commit message. especially
about the part of PCI nosnoop.
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains
2024-10-24 7:54 ` Tian, Kevin
@ 2024-10-25 14:00 ` Jason Gunthorpe
2024-10-28 2:25 ` Tian, Kevin
0 siblings, 1 reply; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-25 14:00 UTC (permalink / raw)
To: Tian, Kevin
Cc: acpica-devel@lists.linux.dev, Hanjun Guo, iommu@lists.linux.dev,
Joerg Roedel, kvm@vger.kernel.org, Len Brown,
linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Lorenzo Pieralisi, Rafael J. Wysocki, Moore, Robert, Robin Murphy,
Sudeep Holla, Will Deacon, Alex Williamson, Eric Auger,
Jean-Philippe Brucker, Moritz Fischer, Michael Shavit,
Nicolin Chen, patches@lists.linux.dev, Wysocki, Rafael J,
Shameerali Kolothum Thodi, Mostafa Saleh
On Thu, Oct 24, 2024 at 07:54:10AM +0000, Tian, Kevin wrote:
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > Sent: Thursday, October 10, 2024 12:23 AM
> >
> > Force Write Back (FWB) changes how the S2 IOPTE's MemAttr field
> > works. When S2FWB is supported and enabled the IOPTE will force cachable
> > access to IOMMU_CACHE memory when nesting with a S1 and deny cachable
> > access otherwise.
>
> didn't get the last part "deny cacheable access otherwise"
Force Write Back (FWB) changes how the S2 IOPTE's MemAttr field
works. When S2FWB is supported and enabled the IOPTE will force cachable
access to IOMMU_CACHE memory when nesting with a S1 and deny cachable
access when !IOMMU_CACHE.
?
> > @@ -169,7 +169,8 @@ arm_smmu_domain_alloc_nesting(struct device *dev,
> > u32 flags,
> > * Must support some way to prevent the VM from bypassing the
> > cache
> > * because VFIO currently does not do any cache maintenance.
> > */
> > - if (!arm_smmu_master_canwbs(master))
> > + if (!arm_smmu_master_canwbs(master) &&
> > + !(master->smmu->features & ARM_SMMU_FEAT_S2FWB))
> > return ERR_PTR(-EOPNOTSUPP);
>
> Probably can clarify the difference between CANWBS and S2FWB here
> by copying some words from the previous commit message. especially
> about the part of PCI nosnoop.
/*
* Must support some way to prevent the VM from bypassing the cache
* because VFIO currently does not do any cache maintenance. canwbs
* indicates the device is fully coherent and no cache maintenance is
* ever required, even for PCI No-Snoop. S2FWB means the S1 can't make
* things non-coherent using the memattr, but No-Snoop behavior is not
* effected.
*/
if (!arm_smmu_master_canwbs(master) &&
!(master->smmu->features & ARM_SMMU_FEAT_S2FWB))
return ERR_PTR(-EOPNOTSUPP);
?
Thanks,
Jason
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 0/9] Initial support for SMMUv3 nested translation
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (9 preceding siblings ...)
2024-10-09 17:46 ` [PATCH v3 0/9] Initial support for SMMUv3 nested translation Nicolin Chen
@ 2024-10-26 20:26 ` Jerry Snitselaar
2024-10-30 4:06 ` Donald Dutile
11 siblings, 0 replies; 34+ messages in thread
From: Jerry Snitselaar @ 2024-10-26 20:26 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
On Wed, Oct 09, 2024 at 01:23:06PM -0300, Jason Gunthorpe wrote:
> This brings support for the IOMMFD ioctls:
>
> - IOMMU_GET_HW_INFO
> - IOMMU_HWPT_ALLOC_NEST_PARENT
> - IOMMU_DOMAIN_NESTED
> - ops->enforce_cache_coherency()
>
> This is quite straightforward as the nested STE can just be built in the
> special NESTED domain op and fed through the generic update machinery.
>
> The design allows the user provided STE fragment to control several
> aspects of the translation, including putting the STE into a "virtual
> bypass" or a aborting state. This duplicates functionality available by
> other means, but it allows trivially preserving the VMID in the STE as we
> eventually move towards the vIOMMU owning the VMID.
>
> Nesting support requires the system to either support S2FWB or the
> stronger CANWBS ACPI flag. This is to ensure the VM cannot bypass the
> cache and view incoherent data, currently VFIO lacks any cache flushing
> that would make this safe.
>
> Yan has a series to add some of the needed infrastructure for VFIO cache
> flushing here:
>
> https://lore.kernel.org/linux-iommu/20240507061802.20184-1-yan.y.zhao@intel.com/
>
> Which may someday allow relaxing this further.
>
> Remove VFIO_TYPE1_NESTING_IOMMU since it was never used and superseded by
> this.
>
> This is the first series in what will be several to complete nesting
> support. At least:
> - IOMMU_RESV_SW_MSI related fixups
> https://lore.kernel.org/linux-iommu/cover.1722644866.git.nicolinc@nvidia.com/
> - vIOMMU object support to allow ATS and CD invalidations
> https://lore.kernel.org/linux-iommu/cover.1723061377.git.nicolinc@nvidia.com/
> - vCMDQ hypervisor support for direct invalidation queue assignment
> https://lore.kernel.org/linux-iommu/cover.1712978212.git.nicolinc@nvidia.com/
> - KVM pinned VMID using vIOMMU for vBTM
> https://lore.kernel.org/linux-iommu/20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com/
> - Cross instance S2 sharing
> - Virtual Machine Structure using vIOMMU (for vMPAM?)
> - Fault forwarding support through IOMMUFD's fault fd for vSVA
>
> The vIOMMU series is essential to allow the invalidations to be processed
> for the CD as well.
>
> It is enough to allow qemu work to progress.
>
> This is on github: https://github.com/jgunthorpe/linux/commits/smmuv3_nesting
>
> v3:
> - Rebase on v6.12-rc2
> - Revise commit messages
> - Consolidate CANWB checks into arm_smmu_master_canwbs()
> - Add CONFIG_ARM_SMMU_V3_IOMMUFD to compile out iommufd only features
> like nesting
> - Shift code into arm-smmu-v3-iommufd.c
> - Add missed IS_ERR check
> - Add S2FWB to arm_smmu_get_ste_used()
> - Fixup quirks checks
> - Drop ARM_SMMU_FEAT_COHERENCY checks for S2FWB
> - Limit S2FWB to S2 Nesting Parent domains "just in case"
> v2: https://patch.msgid.link/r/0-v2-621370057090+91fec-smmuv3_nesting_jgg@nvidia.com
> - Revise commit messages
> - Guard S2FWB support with ARM_SMMU_FEAT_COHERENCY, since it doesn't make
> sense to use S2FWB to enforce coherency on inherently non-coherent hardware.
> - Add missing IO_PGTABLE_QUIRK_ARM_S2FWB validation
> - Include formal ACPIA commit for IORT built using
> generate/linux/gen-patch.sh
> - Use FEAT_NESTING to block creating a NESTING_PARENT
> - Use an abort STE instead of non-valid if the user requests a non-valid
> vSTE
> - Consistently use 'nest_parent' for naming variables
> - Use the right domain for arm_smmu_remove_master_domain() when it
> removes the master
> - Join bitfields together
> - Drop arm_smmu_cache_invalidate_user patch, invalidation will
> exclusively go via viommu
> v1: https://patch.msgid.link/r/0-v1-54e734311a7f+14f72-smmuv3_nesting_jgg@nvidia.com
>
> Jason Gunthorpe (6):
> vfio: Remove VFIO_TYPE1_NESTING_IOMMU
> iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS
> iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT
> iommu/arm-smmu-v3: Expose the arm_smmu_attach interface
> iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
> iommu/arm-smmu-v3: Use S2FWB for NESTED domains
>
> Nicolin Chen (3):
> ACPICA: IORT: Update for revision E.f
> ACPI/IORT: Support CANWBS memory access flag
> iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct
> arm_smmu_hw_info
>
> drivers/acpi/arm64/iort.c | 13 ++
> drivers/iommu/Kconfig | 9 +
> drivers/iommu/arm/arm-smmu-v3/Makefile | 1 +
> .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 204 ++++++++++++++++++
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 114 ++++++----
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 83 ++++++-
> drivers/iommu/arm/arm-smmu/arm-smmu.c | 16 --
> drivers/iommu/io-pgtable-arm.c | 27 ++-
> drivers/iommu/iommu.c | 10 -
> drivers/iommu/iommufd/vfio_compat.c | 7 +-
> drivers/vfio/vfio_iommu_type1.c | 12 +-
> include/acpi/actbl2.h | 3 +-
> include/linux/io-pgtable.h | 2 +
> include/linux/iommu.h | 5 +-
> include/uapi/linux/iommufd.h | 55 +++++
> include/uapi/linux/vfio.h | 2 +-
> 16 files changed, 465 insertions(+), 98 deletions(-)
> create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
>
>
> base-commit: 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b
> --
> 2.46.2
>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* RE: [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains
2024-10-25 14:00 ` Jason Gunthorpe
@ 2024-10-28 2:25 ` Tian, Kevin
0 siblings, 0 replies; 34+ messages in thread
From: Tian, Kevin @ 2024-10-28 2:25 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel@lists.linux.dev, Hanjun Guo, iommu@lists.linux.dev,
Joerg Roedel, kvm@vger.kernel.org, Len Brown,
linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Lorenzo Pieralisi, Rafael J. Wysocki, Moore, Robert, Robin Murphy,
Sudeep Holla, Will Deacon, Alex Williamson, Eric Auger,
Jean-Philippe Brucker, Moritz Fischer, Michael Shavit,
Nicolin Chen, patches@lists.linux.dev, Wysocki, Rafael J,
Shameerali Kolothum Thodi, Mostafa Saleh
> From: Jason Gunthorpe <jgg@nvidia.com>
> Sent: Friday, October 25, 2024 10:01 PM
>
> On Thu, Oct 24, 2024 at 07:54:10AM +0000, Tian, Kevin wrote:
> > > From: Jason Gunthorpe <jgg@nvidia.com>
> > > Sent: Thursday, October 10, 2024 12:23 AM
> > >
> > > Force Write Back (FWB) changes how the S2 IOPTE's MemAttr field
> > > works. When S2FWB is supported and enabled the IOPTE will force
> cachable
> > > access to IOMMU_CACHE memory when nesting with a S1 and deny
> cachable
> > > access otherwise.
> >
> > didn't get the last part "deny cacheable access otherwise"
>
> Force Write Back (FWB) changes how the S2 IOPTE's MemAttr field
> works. When S2FWB is supported and enabled the IOPTE will force cachable
> access to IOMMU_CACHE memory when nesting with a S1 and deny
> cachable
> access when !IOMMU_CACHE.
>
> ?
Good. I read the original words as if cacheable access is denied
when S2FWB is not supported or disabled.
>
> > > @@ -169,7 +169,8 @@ arm_smmu_domain_alloc_nesting(struct device
> *dev,
> > > u32 flags,
> > > * Must support some way to prevent the VM from bypassing the
> > > cache
> > > * because VFIO currently does not do any cache maintenance.
> > > */
> > > - if (!arm_smmu_master_canwbs(master))
> > > + if (!arm_smmu_master_canwbs(master) &&
> > > + !(master->smmu->features & ARM_SMMU_FEAT_S2FWB))
> > > return ERR_PTR(-EOPNOTSUPP);
> >
> > Probably can clarify the difference between CANWBS and S2FWB here
> > by copying some words from the previous commit message. especially
> > about the part of PCI nosnoop.
>
> /*
> * Must support some way to prevent the VM from bypassing the
> cache
> * because VFIO currently does not do any cache maintenance.
> canwbs
> * indicates the device is fully coherent and no cache maintenance is
> * ever required, even for PCI No-Snoop. S2FWB means the S1 can't
> make
> * things non-coherent using the memattr, but No-Snoop behavior is
> not
> * effected.
> */
> if (!arm_smmu_master_canwbs(master) &&
> !(master->smmu->features & ARM_SMMU_FEAT_S2FWB))
> return ERR_PTR(-EOPNOTSUPP);
>
> ?
>
Looks good!
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 0/9] Initial support for SMMUv3 nested translation
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
` (10 preceding siblings ...)
2024-10-26 20:26 ` Jerry Snitselaar
@ 2024-10-30 4:06 ` Donald Dutile
11 siblings, 0 replies; 34+ messages in thread
From: Donald Dutile @ 2024-10-30 4:06 UTC (permalink / raw)
To: Jason Gunthorpe, acpica-devel, Hanjun Guo, iommu, Joerg Roedel,
Kevin Tian, kvm, Len Brown, linux-acpi, linux-arm-kernel,
Lorenzo Pieralisi, Rafael J. Wysocki, Robert Moore, Robin Murphy,
Sudeep Holla, Will Deacon
Cc: Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi, Mostafa Saleh
On 10/9/24 12:23 PM, Jason Gunthorpe wrote:
> This brings support for the IOMMFD ioctls:
>
> - IOMMU_GET_HW_INFO
> - IOMMU_HWPT_ALLOC_NEST_PARENT
> - IOMMU_DOMAIN_NESTED
> - ops->enforce_cache_coherency()
>
> This is quite straightforward as the nested STE can just be built in the
> special NESTED domain op and fed through the generic update machinery.
>
> The design allows the user provided STE fragment to control several
> aspects of the translation, including putting the STE into a "virtual
> bypass" or a aborting state. This duplicates functionality available by
> other means, but it allows trivially preserving the VMID in the STE as we
> eventually move towards the vIOMMU owning the VMID.
>
> Nesting support requires the system to either support S2FWB or the
> stronger CANWBS ACPI flag. This is to ensure the VM cannot bypass the
> cache and view incoherent data, currently VFIO lacks any cache flushing
> that would make this safe.
>
> Yan has a series to add some of the needed infrastructure for VFIO cache
> flushing here:
>
> https://lore.kernel.org/linux-iommu/20240507061802.20184-1-yan.y.zhao@intel.com/
>
> Which may someday allow relaxing this further.
>
> Remove VFIO_TYPE1_NESTING_IOMMU since it was never used and superseded by
> this.
>
> This is the first series in what will be several to complete nesting
> support. At least:
> - IOMMU_RESV_SW_MSI related fixups
> https://lore.kernel.org/linux-iommu/cover.1722644866.git.nicolinc@nvidia.com/
> - vIOMMU object support to allow ATS and CD invalidations
> https://lore.kernel.org/linux-iommu/cover.1723061377.git.nicolinc@nvidia.com/
> - vCMDQ hypervisor support for direct invalidation queue assignment
> https://lore.kernel.org/linux-iommu/cover.1712978212.git.nicolinc@nvidia.com/
> - KVM pinned VMID using vIOMMU for vBTM
> https://lore.kernel.org/linux-iommu/20240208151837.35068-1-shameerali.kolothum.thodi@huawei.com/
> - Cross instance S2 sharing
> - Virtual Machine Structure using vIOMMU (for vMPAM?)
> - Fault forwarding support through IOMMUFD's fault fd for vSVA
>
> The vIOMMU series is essential to allow the invalidations to be processed
> for the CD as well.
>
> It is enough to allow qemu work to progress.
>
> This is on github: https://github.com/jgunthorpe/linux/commits/smmuv3_nesting
>
> v3:
> - Rebase on v6.12-rc2
> - Revise commit messages
> - Consolidate CANWB checks into arm_smmu_master_canwbs()
> - Add CONFIG_ARM_SMMU_V3_IOMMUFD to compile out iommufd only features
> like nesting
> - Shift code into arm-smmu-v3-iommufd.c
> - Add missed IS_ERR check
> - Add S2FWB to arm_smmu_get_ste_used()
> - Fixup quirks checks
> - Drop ARM_SMMU_FEAT_COHERENCY checks for S2FWB
> - Limit S2FWB to S2 Nesting Parent domains "just in case"
> v2: https://patch.msgid.link/r/0-v2-621370057090+91fec-smmuv3_nesting_jgg@nvidia.com
> - Revise commit messages
> - Guard S2FWB support with ARM_SMMU_FEAT_COHERENCY, since it doesn't make
> sense to use S2FWB to enforce coherency on inherently non-coherent hardware.
> - Add missing IO_PGTABLE_QUIRK_ARM_S2FWB validation
> - Include formal ACPIA commit for IORT built using
> generate/linux/gen-patch.sh
> - Use FEAT_NESTING to block creating a NESTING_PARENT
> - Use an abort STE instead of non-valid if the user requests a non-valid
> vSTE
> - Consistently use 'nest_parent' for naming variables
> - Use the right domain for arm_smmu_remove_master_domain() when it
> removes the master
> - Join bitfields together
> - Drop arm_smmu_cache_invalidate_user patch, invalidation will
> exclusively go via viommu
> v1: https://patch.msgid.link/r/0-v1-54e734311a7f+14f72-smmuv3_nesting_jgg@nvidia.com
>
> Jason Gunthorpe (6):
> vfio: Remove VFIO_TYPE1_NESTING_IOMMU
> iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS
> iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT
> iommu/arm-smmu-v3: Expose the arm_smmu_attach interface
> iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
> iommu/arm-smmu-v3: Use S2FWB for NESTED domains
>
> Nicolin Chen (3):
> ACPICA: IORT: Update for revision E.f
> ACPI/IORT: Support CANWBS memory access flag
> iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct
> arm_smmu_hw_info
>
> drivers/acpi/arm64/iort.c | 13 ++
> drivers/iommu/Kconfig | 9 +
> drivers/iommu/arm/arm-smmu-v3/Makefile | 1 +
> .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 204 ++++++++++++++++++
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 114 ++++++----
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 83 ++++++-
> drivers/iommu/arm/arm-smmu/arm-smmu.c | 16 --
> drivers/iommu/io-pgtable-arm.c | 27 ++-
> drivers/iommu/iommu.c | 10 -
> drivers/iommu/iommufd/vfio_compat.c | 7 +-
> drivers/vfio/vfio_iommu_type1.c | 12 +-
> include/acpi/actbl2.h | 3 +-
> include/linux/io-pgtable.h | 2 +
> include/linux/iommu.h | 5 +-
> include/uapi/linux/iommufd.h | 55 +++++
> include/uapi/linux/vfio.h | 2 +-
> 16 files changed, 465 insertions(+), 98 deletions(-)
> create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
>
>
> base-commit: 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b
Apologies for the delay; quite a few spec bits to lookup, as well as some SMMU refresh-ing on my part.
Reviewed-by: Donald Dutile <ddutile@redhat.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info
2024-10-09 16:23 ` [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info Jason Gunthorpe
@ 2024-10-30 16:24 ` Mostafa Saleh
2024-10-30 17:56 ` Jason Gunthorpe
0 siblings, 1 reply; 34+ messages in thread
From: Mostafa Saleh @ 2024-10-30 16:24 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi
Hi Jason,
On Wed, Oct 09, 2024 at 01:23:11PM -0300, Jason Gunthorpe wrote:
> From: Nicolin Chen <nicolinc@nvidia.com>
>
> For virtualization cases the IDR/IIDR/AIDR values of the actual SMMU
> instance need to be available to the VMM so it can construct an
> appropriate vSMMUv3 that reflects the correct HW capabilities.
>
> For userspace page tables these values are required to constrain the valid
> values within the CD table and the IOPTEs.
>
> The kernel does not sanitize these values. If building a VMM then
> userspace is required to only forward bits into a VM that it knows it can
> implement. Some bits will also require a VMM to detect if appropriate
> kernel support is available such as for ATS and BTM.
>
> Start a new file and kconfig for the advanced iommufd support. This lets
> it be compiled out for kernels that are not intended to support
> virtualization, and allows distros to leave it disabled until they are
> shipping a matching qemu too.
>
> Tested-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
> drivers/iommu/Kconfig | 9 +++++
> drivers/iommu/arm/arm-smmu-v3/Makefile | 1 +
> .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 31 ++++++++++++++++
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 +
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 9 +++++
> include/uapi/linux/iommufd.h | 35 +++++++++++++++++++
> 6 files changed, 86 insertions(+)
> create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
>
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index b3aa1f5d53218b..0c9bceb1653d5f 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -415,6 +415,15 @@ config ARM_SMMU_V3_SVA
> Say Y here if your system supports SVA extensions such as PCIe PASID
> and PRI.
>
> +config ARM_SMMU_V3_IOMMUFD
> + bool "Enable IOMMUFD features for ARM SMMUv3 (EXPERIMENTAL)"
> + depends on IOMMUFD
> + help
> + Support for IOMMUFD features intended to support virtual machines
> + with accelerated virtual IOMMUs.
> +
> + Say Y here if you are doing development and testing on this feature.
> +
> config ARM_SMMU_V3_KUNIT_TEST
> tristate "KUnit tests for arm-smmu-v3 driver" if !KUNIT_ALL_TESTS
> depends on KUNIT
> diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
> index dc98c88b48c827..493a659cc66bb2 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/Makefile
> +++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
> @@ -1,6 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_ARM_SMMU_V3) += arm_smmu_v3.o
> arm_smmu_v3-y := arm-smmu-v3.o
> +arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_IOMMUFD) += arm-smmu-v3-iommufd.o
> arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
> arm_smmu_v3-$(CONFIG_TEGRA241_CMDQV) += tegra241-cmdqv.o
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
> new file mode 100644
> index 00000000000000..3d2671031c9bb5
> --- /dev/null
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
> @@ -0,0 +1,31 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
> + */
> +
> +#include <uapi/linux/iommufd.h>
> +
> +#include "arm-smmu-v3.h"
> +
> +void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
> +{
> + struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> + struct iommu_hw_info_arm_smmuv3 *info;
> + u32 __iomem *base_idr;
> + unsigned int i;
> +
> + info = kzalloc(sizeof(*info), GFP_KERNEL);
> + if (!info)
> + return ERR_PTR(-ENOMEM);
> +
> + base_idr = master->smmu->base + ARM_SMMU_IDR0;
> + for (i = 0; i <= 5; i++)
> + info->idr[i] = readl_relaxed(base_idr + i);
> + info->iidr = readl_relaxed(master->smmu->base + ARM_SMMU_IIDR);
> + info->aidr = readl_relaxed(master->smmu->base + ARM_SMMU_AIDR);
I wonder if passing the IDRs is enough for the VMM, for example in some
cases, firmware can override the coherency, also the IIDR can override
some features (as MMU700 and BTM), although, the VMM can deal with.
Also, PRI and ATS are gated by configs, I’d be worried if the VMM can make
ome assumptions just from the IDRs.
Maybe for those(coherency, ATS, PRI) we would need to keep the VMM view and
the kernel in sync?
Otherwise, LGTM.
Thanks,
Mostafa
> +
> + *length = sizeof(*info);
> + *type = IOMMU_HW_INFO_TYPE_ARM_SMMUV3;
> +
> + return info;
> +}
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 38725810c14eeb..996774d461aea2 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3506,6 +3506,7 @@ static struct iommu_ops arm_smmu_ops = {
> .identity_domain = &arm_smmu_identity_domain,
> .blocked_domain = &arm_smmu_blocked_domain,
> .capable = arm_smmu_capable,
> + .hw_info = arm_smmu_hw_info,
> .domain_alloc_paging = arm_smmu_domain_alloc_paging,
> .domain_alloc_sva = arm_smmu_sva_domain_alloc,
> .domain_alloc_user = arm_smmu_domain_alloc_user,
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 06e3d88932df12..66261fd5bfb2d2 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -81,6 +81,8 @@ struct arm_smmu_device;
> #define IIDR_REVISION GENMASK(15, 12)
> #define IIDR_IMPLEMENTER GENMASK(11, 0)
>
> +#define ARM_SMMU_AIDR 0x1C
> +
> #define ARM_SMMU_CR0 0x20
> #define CR0_ATSCHK (1 << 4)
> #define CR0_CMDQEN (1 << 3)
> @@ -956,4 +958,11 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
> return ERR_PTR(-ENODEV);
> }
> #endif /* CONFIG_TEGRA241_CMDQV */
> +
> +#if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
> +void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
> +#else
> +#define arm_smmu_hw_info NULL
> +#endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
> +
> #endif /* _ARM_SMMU_V3_H */
> diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
> index 72010f71c5e479..b5c94fecb94ca5 100644
> --- a/include/uapi/linux/iommufd.h
> +++ b/include/uapi/linux/iommufd.h
> @@ -484,15 +484,50 @@ struct iommu_hw_info_vtd {
> __aligned_u64 ecap_reg;
> };
>
> +/**
> + * struct iommu_hw_info_arm_smmuv3 - ARM SMMUv3 hardware information
> + * (IOMMU_HW_INFO_TYPE_ARM_SMMUV3)
> + *
> + * @flags: Must be set to 0
> + * @__reserved: Must be 0
> + * @idr: Implemented features for ARM SMMU Non-secure programming interface
> + * @iidr: Information about the implementation and implementer of ARM SMMU,
> + * and architecture version supported
> + * @aidr: ARM SMMU architecture version
> + *
> + * For the details of @idr, @iidr and @aidr, please refer to the chapters
> + * from 6.3.1 to 6.3.6 in the SMMUv3 Spec.
> + *
> + * User space should read the underlying ARM SMMUv3 hardware information for
> + * the list of supported features.
> + *
> + * Note that these values reflect the raw HW capability, without any insight if
> + * any required kernel driver support is present. Bits may be set indicating the
> + * HW has functionality that is lacking kernel software support, such as BTM. If
> + * a VMM is using this information to construct emulated copies of these
> + * registers it should only forward bits that it knows it can support.
> + *
> + * In future, presence of required kernel support will be indicated in flags.
> + */
> +struct iommu_hw_info_arm_smmuv3 {
> + __u32 flags;
> + __u32 __reserved;
> + __u32 idr[6];
> + __u32 iidr;
> + __u32 aidr;
> +};
> +
> /**
> * enum iommu_hw_info_type - IOMMU Hardware Info Types
> * @IOMMU_HW_INFO_TYPE_NONE: Used by the drivers that do not report hardware
> * info
> * @IOMMU_HW_INFO_TYPE_INTEL_VTD: Intel VT-d iommu info type
> + * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type
> */
> enum iommu_hw_info_type {
> IOMMU_HW_INFO_TYPE_NONE = 0,
> IOMMU_HW_INFO_TYPE_INTEL_VTD = 1,
> + IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2,
> };
>
> /**
> --
> 2.46.2
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 6/9] iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT
2024-10-09 16:23 ` [PATCH v3 6/9] iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT Jason Gunthorpe
@ 2024-10-30 16:26 ` Mostafa Saleh
0 siblings, 0 replies; 34+ messages in thread
From: Mostafa Saleh @ 2024-10-30 16:26 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi
On Wed, Oct 09, 2024 at 01:23:12PM -0300, Jason Gunthorpe wrote:
> For SMMUv3 the parent must be a S2 domain, which can be composed
> into a IOMMU_DOMAIN_NESTED.
>
> In future the S2 parent will also need a VMID linked to the VIOMMU and
> even to KVM.
>
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> Tested-by: Nicolin Chen <nicolinc@nvidia.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa@google.com>
Thanks,
Mostafa
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 996774d461aea2..80847fa386fcd2 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -3114,7 +3114,8 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
> const struct iommu_user_data *user_data)
> {
> struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> - const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
> + const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
> + IOMMU_HWPT_ALLOC_NEST_PARENT;
> struct arm_smmu_domain *smmu_domain;
> int ret;
>
> @@ -3127,6 +3128,14 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
> if (IS_ERR(smmu_domain))
> return ERR_CAST(smmu_domain);
>
> + if (flags & IOMMU_HWPT_ALLOC_NEST_PARENT) {
> + if (!(master->smmu->features & ARM_SMMU_FEAT_NESTING)) {
> + ret = -EOPNOTSUPP;
> + goto err_free;
> + }
> + smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
> + }
> +
> smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
> smmu_domain->domain.ops = arm_smmu_ops.default_domain_ops;
> ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, flags);
> --
> 2.46.2
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface
2024-10-09 16:23 ` [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface Jason Gunthorpe
2024-10-09 17:03 ` Nicolin Chen
2024-10-24 7:47 ` Tian, Kevin
@ 2024-10-30 16:26 ` Mostafa Saleh
2 siblings, 0 replies; 34+ messages in thread
From: Mostafa Saleh @ 2024-10-30 16:26 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi
On Wed, Oct 09, 2024 at 01:23:13PM -0300, Jason Gunthorpe wrote:
> The arm-smmuv3-iommufd.c file will need to call these functions too.
> Remove statics and put them in the header file. Remove the kunit
> visibility protections from arm_smmu_make_abort_ste() and
> arm_smmu_make_s2_domain_ste().
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa@google.com>
Thanks,
Mostafa
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++-------------
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 27 +++++++++++++++++----
> 2 files changed, 27 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 80847fa386fcd2..b4b03206afbf48 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1549,7 +1549,6 @@ static void arm_smmu_write_ste(struct arm_smmu_master *master, u32 sid,
> }
> }
>
> -VISIBLE_IF_KUNIT
> void arm_smmu_make_abort_ste(struct arm_smmu_ste *target)
> {
> memset(target, 0, sizeof(*target));
> @@ -1632,7 +1631,6 @@ void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
> }
> EXPORT_SYMBOL_IF_KUNIT(arm_smmu_make_cdtable_ste);
>
> -VISIBLE_IF_KUNIT
> void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
> struct arm_smmu_master *master,
> struct arm_smmu_domain *smmu_domain,
> @@ -2505,8 +2503,8 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
> }
> }
>
> -static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
> - const struct arm_smmu_ste *target)
> +void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
> + const struct arm_smmu_ste *target)
> {
> int i, j;
> struct arm_smmu_device *smmu = master->smmu;
> @@ -2671,16 +2669,6 @@ static void arm_smmu_remove_master_domain(struct arm_smmu_master *master,
> spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
> }
>
> -struct arm_smmu_attach_state {
> - /* Inputs */
> - struct iommu_domain *old_domain;
> - struct arm_smmu_master *master;
> - bool cd_needs_ats;
> - ioasid_t ssid;
> - /* Resulting state */
> - bool ats_enabled;
> -};
> -
> /*
> * Start the sequence to attach a domain to a master. The sequence contains three
> * steps:
> @@ -2701,8 +2689,8 @@ struct arm_smmu_attach_state {
> * new_domain can be a non-paging domain. In this case ATS will not be enabled,
> * and invalidations won't be tracked.
> */
> -static int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
> - struct iommu_domain *new_domain)
> +int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
> + struct iommu_domain *new_domain)
> {
> struct arm_smmu_master *master = state->master;
> struct arm_smmu_master_domain *master_domain;
> @@ -2784,7 +2772,7 @@ static int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
> * completes synchronizing the PCI device's ATC and finishes manipulating the
> * smmu_domain->devices list.
> */
> -static void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
> +void arm_smmu_attach_commit(struct arm_smmu_attach_state *state)
> {
> struct arm_smmu_master *master = state->master;
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 66261fd5bfb2d2..c9e5290e995a64 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -830,21 +830,22 @@ struct arm_smmu_entry_writer_ops {
> void (*sync)(struct arm_smmu_entry_writer *writer);
> };
>
> +void arm_smmu_make_abort_ste(struct arm_smmu_ste *target);
> +void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
> + struct arm_smmu_master *master,
> + struct arm_smmu_domain *smmu_domain,
> + bool ats_enabled);
> +
> #if IS_ENABLED(CONFIG_KUNIT)
> void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits);
> void arm_smmu_write_entry(struct arm_smmu_entry_writer *writer, __le64 *cur,
> const __le64 *target);
> void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits);
> -void arm_smmu_make_abort_ste(struct arm_smmu_ste *target);
> void arm_smmu_make_bypass_ste(struct arm_smmu_device *smmu,
> struct arm_smmu_ste *target);
> void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
> struct arm_smmu_master *master, bool ats_enabled,
> unsigned int s1dss);
> -void arm_smmu_make_s2_domain_ste(struct arm_smmu_ste *target,
> - struct arm_smmu_master *master,
> - struct arm_smmu_domain *smmu_domain,
> - bool ats_enabled);
> void arm_smmu_make_sva_cd(struct arm_smmu_cd *target,
> struct arm_smmu_master *master, struct mm_struct *mm,
> u16 asid);
> @@ -902,6 +903,22 @@ static inline bool arm_smmu_master_canwbs(struct arm_smmu_master *master)
> IOMMU_FWSPEC_PCI_RC_CANWBS;
> }
>
> +struct arm_smmu_attach_state {
> + /* Inputs */
> + struct iommu_domain *old_domain;
> + struct arm_smmu_master *master;
> + bool cd_needs_ats;
> + ioasid_t ssid;
> + /* Resulting state */
> + bool ats_enabled;
> +};
> +
> +int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
> + struct iommu_domain *new_domain);
> +void arm_smmu_attach_commit(struct arm_smmu_attach_state *state);
> +void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
> + const struct arm_smmu_ste *target);
> +
> #ifdef CONFIG_ARM_SMMU_V3_SVA
> bool arm_smmu_sva_supported(struct arm_smmu_device *smmu);
> bool arm_smmu_master_sva_supported(struct arm_smmu_master *master);
> --
> 2.46.2
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
2024-10-09 16:23 ` [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED Jason Gunthorpe
2024-10-09 17:27 ` Nicolin Chen
2024-10-24 7:50 ` Tian, Kevin
@ 2024-10-30 16:29 ` Mostafa Saleh
2024-10-30 23:59 ` Jason Gunthorpe
2 siblings, 1 reply; 34+ messages in thread
From: Mostafa Saleh @ 2024-10-30 16:29 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi
Hi Jason,
On Wed, Oct 09, 2024 at 01:23:14PM -0300, Jason Gunthorpe wrote:
> For SMMUv3 a IOMMU_DOMAIN_NESTED is composed of a S2 iommu_domain acting
> as the parent and a user provided STE fragment that defines the CD table
> and related data with addresses translated by the S2 iommu_domain.
>
> The kernel only permits userspace to control certain allowed bits of the
> STE that are safe for user/guest control.
>
> IOTLB maintenance is a bit subtle here, the S1 implicitly includes the S2
> translation, but there is no way of knowing which S1 entries refer to a
> range of S2.
>
> For the IOTLB we follow ARM's guidance and issue a CMDQ_OP_TLBI_NH_ALL to
> flush all ASIDs from the VMID after flushing the S2 on any change to the
> S2.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
> .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 172 ++++++++++++++++++
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 25 ++-
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 37 ++++
> include/uapi/linux/iommufd.h | 20 ++
> 4 files changed, 250 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
> index 3d2671031c9bb5..a9aa7514e65ce4 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
> @@ -29,3 +29,175 @@ void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
>
> return info;
> }
> +
> +static void arm_smmu_make_nested_cd_table_ste(
> + struct arm_smmu_ste *target, struct arm_smmu_master *master,
> + struct arm_smmu_nested_domain *nested_domain, bool ats_enabled)
> +{
> + arm_smmu_make_s2_domain_ste(target, master, nested_domain->s2_parent,
> + ats_enabled);
> +
> + target->data[0] = cpu_to_le64(STRTAB_STE_0_V |
> + FIELD_PREP(STRTAB_STE_0_CFG,
> + STRTAB_STE_0_CFG_NESTED));
> + target->data[0] |= nested_domain->ste[0] &
> + ~cpu_to_le64(STRTAB_STE_0_CFG);
> + target->data[1] |= nested_domain->ste[1];
> +}
> +
> +/*
> + * Create a physical STE from the virtual STE that userspace provided when it
> + * created the nested domain. Using the vSTE userspace can request:
> + * - Non-valid STE
> + * - Abort STE
> + * - Bypass STE (install the S2, no CD table)
> + * - CD table STE (install the S2 and the userspace CD table)
> + */
> +static void arm_smmu_make_nested_domain_ste(
> + struct arm_smmu_ste *target, struct arm_smmu_master *master,
> + struct arm_smmu_nested_domain *nested_domain, bool ats_enabled)
> +{
> + unsigned int cfg =
> + FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0]));
> +
> + /*
> + * Userspace can request a non-valid STE through the nesting interface.
> + * We relay that into an abort physical STE with the intention that
> + * C_BAD_STE for this SID can be generated to userspace.
> + */
> + if (!(nested_domain->ste[0] & cpu_to_le64(STRTAB_STE_0_V)))
> + cfg = STRTAB_STE_0_CFG_ABORT;
> +
> + switch (cfg) {
> + case STRTAB_STE_0_CFG_S1_TRANS:
> + arm_smmu_make_nested_cd_table_ste(target, master, nested_domain,
> + ats_enabled);
> + break;
> + case STRTAB_STE_0_CFG_BYPASS:
> + arm_smmu_make_s2_domain_ste(
> + target, master, nested_domain->s2_parent, ats_enabled);
> + break;
> + case STRTAB_STE_0_CFG_ABORT:
> + default:
> + arm_smmu_make_abort_ste(target);
> + break;
> + }
> +}
> +
> +static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
> + struct device *dev)
> +{
> + struct arm_smmu_nested_domain *nested_domain =
> + to_smmu_nested_domain(domain);
> + struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> + struct arm_smmu_attach_state state = {
> + .master = master,
> + .old_domain = iommu_get_domain_for_dev(dev),
> + .ssid = IOMMU_NO_PASID,
> + /* Currently invalidation of ATC is not supported */
> + .disable_ats = true,
> + };
> + struct arm_smmu_ste ste;
> + int ret;
> +
> + if (nested_domain->s2_parent->smmu != master->smmu)
> + return -EINVAL;
> + if (arm_smmu_ssids_in_use(&master->cd_table))
> + return -EBUSY;
> +
> + mutex_lock(&arm_smmu_asid_lock);
> + ret = arm_smmu_attach_prepare(&state, domain);
> + if (ret) {
> + mutex_unlock(&arm_smmu_asid_lock);
> + return ret;
> + }
> +
> + arm_smmu_make_nested_domain_ste(&ste, master, nested_domain,
> + state.ats_enabled);
> + arm_smmu_install_ste_for_dev(master, &ste);
> + arm_smmu_attach_commit(&state);
> + mutex_unlock(&arm_smmu_asid_lock);
> + return 0;
> +}
> +
> +static void arm_smmu_domain_nested_free(struct iommu_domain *domain)
> +{
> + kfree(to_smmu_nested_domain(domain));
> +}
> +
> +static const struct iommu_domain_ops arm_smmu_nested_ops = {
> + .attach_dev = arm_smmu_attach_dev_nested,
> + .free = arm_smmu_domain_nested_free,
> +};
> +
> +static int arm_smmu_validate_vste(struct iommu_hwpt_arm_smmuv3 *arg)
> +{
> + unsigned int cfg;
> +
> + if (!(arg->ste[0] & cpu_to_le64(STRTAB_STE_0_V))) {
> + memset(arg->ste, 0, sizeof(arg->ste));
> + return 0;
> + }
> +
> + /* EIO is reserved for invalid STE data. */
> + if ((arg->ste[0] & ~STRTAB_STE_0_NESTING_ALLOWED) ||
> + (arg->ste[1] & ~STRTAB_STE_1_NESTING_ALLOWED))
> + return -EIO;
> +
> + cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(arg->ste[0]));
> + if (cfg != STRTAB_STE_0_CFG_ABORT && cfg != STRTAB_STE_0_CFG_BYPASS &&
> + cfg != STRTAB_STE_0_CFG_S1_TRANS)
> + return -EIO;
> + return 0;
> +}
> +
> +struct iommu_domain *
> +arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
> + struct iommu_domain *parent,
> + const struct iommu_user_data *user_data)
> +{
> + struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> + struct arm_smmu_nested_domain *nested_domain;
> + struct arm_smmu_domain *smmu_parent;
> + struct iommu_hwpt_arm_smmuv3 arg;
> + int ret;
> +
> + if (flags || !(master->smmu->features & ARM_SMMU_FEAT_NESTING))
> + return ERR_PTR(-EOPNOTSUPP);
> +
> + /*
> + * Must support some way to prevent the VM from bypassing the cache
> + * because VFIO currently does not do any cache maintenance.
> + */
> + if (!arm_smmu_master_canwbs(master))
> + return ERR_PTR(-EOPNOTSUPP);
> +
> + /*
> + * The core code checks that parent was created with
> + * IOMMU_HWPT_ALLOC_NEST_PARENT
> + */
> + smmu_parent = to_smmu_domain(parent);
> + if (smmu_parent->smmu != master->smmu)
> + return ERR_PTR(-EINVAL);
> +
> + ret = iommu_copy_struct_from_user(&arg, user_data,
> + IOMMU_HWPT_DATA_ARM_SMMUV3, ste);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + ret = arm_smmu_validate_vste(&arg);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + nested_domain = kzalloc(sizeof(*nested_domain), GFP_KERNEL_ACCOUNT);
> + if (!nested_domain)
> + return ERR_PTR(-ENOMEM);
> +
> + nested_domain->domain.type = IOMMU_DOMAIN_NESTED;
> + nested_domain->domain.ops = &arm_smmu_nested_ops;
> + nested_domain->s2_parent = smmu_parent;
> + nested_domain->ste[0] = arg.ste[0];
> + nested_domain->ste[1] = arg.ste[1] & ~cpu_to_le64(STRTAB_STE_1_EATS);
> +
> + return &nested_domain->domain;
> +}
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index b4b03206afbf48..eb401a4adfedc8 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -295,6 +295,7 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
> case CMDQ_OP_TLBI_NH_ASID:
> cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
> fallthrough;
> + case CMDQ_OP_TLBI_NH_ALL:
> case CMDQ_OP_TLBI_S12_VMALL:
> cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
> break;
> @@ -2230,6 +2231,15 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
> }
> __arm_smmu_tlb_inv_range(&cmd, iova, size, granule, smmu_domain);
>
> + if (smmu_domain->nest_parent) {
Do we need a sync between the 2 invalidations to order them?
> + /*
> + * When the S2 domain changes all the nested S1 ASIDs have to be
> + * flushed too.
> + */
> + cmd.opcode = CMDQ_OP_TLBI_NH_ALL;
> + arm_smmu_cmdq_issue_cmd_with_sync(smmu_domain->smmu, &cmd);
> + }
> +
> /*
> * Unfortunately, this can't be leaf-only since we may have
> * zapped an entire table.
> @@ -2614,8 +2624,7 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
>
> static struct arm_smmu_master_domain *
> arm_smmu_find_master_domain(struct arm_smmu_domain *smmu_domain,
> - struct arm_smmu_master *master,
> - ioasid_t ssid)
> + struct arm_smmu_master *master, ioasid_t ssid)
> {
> struct arm_smmu_master_domain *master_domain;
>
> @@ -2644,6 +2653,8 @@ to_smmu_domain_devices(struct iommu_domain *domain)
> if ((domain->type & __IOMMU_DOMAIN_PAGING) ||
> domain->type == IOMMU_DOMAIN_SVA)
> return to_smmu_domain(domain);
> + if (domain->type == IOMMU_DOMAIN_NESTED)
> + return to_smmu_nested_domain(domain)->s2_parent;
> return NULL;
> }
>
> @@ -2716,7 +2727,8 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
> * enabled if we have arm_smmu_domain, those always have page
> * tables.
> */
> - state->ats_enabled = arm_smmu_ats_supported(master);
> + state->ats_enabled = !state->disable_ats &&
> + arm_smmu_ats_supported(master);
> }
>
> if (smmu_domain) {
> @@ -3107,9 +3119,13 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
> struct arm_smmu_domain *smmu_domain;
> int ret;
>
> + if (parent)
> + return arm_smmu_domain_alloc_nesting(dev, flags, parent,
> + user_data);
> +
> if (flags & ~PAGING_FLAGS)
> return ERR_PTR(-EOPNOTSUPP);
> - if (parent || user_data)
> + if (user_data)
> return ERR_PTR(-EOPNOTSUPP);
>
> smmu_domain = arm_smmu_domain_alloc();
> @@ -3122,6 +3138,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
> goto err_free;
> }
> smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
> + smmu_domain->nest_parent = true;
> }
>
> smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index c9e5290e995a64..b5dbf5acbfc4db 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -243,6 +243,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
> #define STRTAB_STE_0_CFG_BYPASS 4
> #define STRTAB_STE_0_CFG_S1_TRANS 5
> #define STRTAB_STE_0_CFG_S2_TRANS 6
> +#define STRTAB_STE_0_CFG_NESTED 7
>
> #define STRTAB_STE_0_S1FMT GENMASK_ULL(5, 4)
> #define STRTAB_STE_0_S1FMT_LINEAR 0
> @@ -294,6 +295,15 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
>
> #define STRTAB_STE_3_S2TTB_MASK GENMASK_ULL(51, 4)
>
> +/* These bits can be controlled by userspace for STRTAB_STE_0_CFG_NESTED */
> +#define STRTAB_STE_0_NESTING_ALLOWED \
> + cpu_to_le64(STRTAB_STE_0_V | STRTAB_STE_0_CFG | STRTAB_STE_0_S1FMT | \
> + STRTAB_STE_0_S1CTXPTR_MASK | STRTAB_STE_0_S1CDMAX)
> +#define STRTAB_STE_1_NESTING_ALLOWED \
> + cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR | \
> + STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH | \
> + STRTAB_STE_1_S1STALLD)
> +
> /*
> * Context descriptors.
> *
> @@ -513,6 +523,7 @@ struct arm_smmu_cmdq_ent {
> };
> } cfgi;
>
> + #define CMDQ_OP_TLBI_NH_ALL 0x10
> #define CMDQ_OP_TLBI_NH_ASID 0x11
> #define CMDQ_OP_TLBI_NH_VA 0x12
> #define CMDQ_OP_TLBI_EL2_ALL 0x20
> @@ -814,10 +825,18 @@ struct arm_smmu_domain {
> struct list_head devices;
> spinlock_t devices_lock;
> bool enforce_cache_coherency : 1;
> + bool nest_parent : 1;
>
> struct mmu_notifier mmu_notifier;
> };
>
> +struct arm_smmu_nested_domain {
> + struct iommu_domain domain;
> + struct arm_smmu_domain *s2_parent;
> +
> + __le64 ste[2];
> +};
> +
> /* The following are exposed for testing purposes. */
> struct arm_smmu_entry_writer_ops;
> struct arm_smmu_entry_writer {
> @@ -862,6 +881,12 @@ static inline struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
> return container_of(dom, struct arm_smmu_domain, domain);
> }
>
> +static inline struct arm_smmu_nested_domain *
> +to_smmu_nested_domain(struct iommu_domain *dom)
> +{
> + return container_of(dom, struct arm_smmu_nested_domain, domain);
> +}
> +
> extern struct xarray arm_smmu_asid_xa;
> extern struct mutex arm_smmu_asid_lock;
>
> @@ -908,6 +933,7 @@ struct arm_smmu_attach_state {
> struct iommu_domain *old_domain;
> struct arm_smmu_master *master;
> bool cd_needs_ats;
> + bool disable_ats;
> ioasid_t ssid;
> /* Resulting state */
> bool ats_enabled;
> @@ -978,8 +1004,19 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
>
> #if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
> void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
> +struct iommu_domain *
> +arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
> + struct iommu_domain *parent,
> + const struct iommu_user_data *user_data);
> #else
> #define arm_smmu_hw_info NULL
> +static inline struct iommu_domain *
> +arm_smmu_domain_alloc_nesting(struct device *dev, u32 flags,
> + struct iommu_domain *parent,
> + const struct iommu_user_data *user_data)
> +{
> + return ERR_PTR(-EOPNOTSUPP);
> +}
> #endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
>
> #endif /* _ARM_SMMU_V3_H */
> diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
> index b5c94fecb94ca5..cd4920886ad05e 100644
> --- a/include/uapi/linux/iommufd.h
> +++ b/include/uapi/linux/iommufd.h
> @@ -394,14 +394,34 @@ struct iommu_hwpt_vtd_s1 {
> __u32 __reserved;
> };
>
> +/**
> + * struct iommu_hwpt_arm_smmuv3 - ARM SMMUv3 Context Descriptor Table info
> + * (IOMMU_HWPT_DATA_ARM_SMMUV3)
> + *
That’s supposed to be stream table?
Thanks,
Mostafa
> + * @ste: The first two double words of the user space Stream Table Entry for
> + * a user stage-1 Context Descriptor Table. Must be little-endian.
> + * Allowed fields: (Refer to "5.2 Stream Table Entry" in SMMUv3 HW Spec)
> + * - word-0: V, Cfg, S1Fmt, S1ContextPtr, S1CDMax
> + * - word-1: S1DSS, S1CIR, S1COR, S1CSH, S1STALLD
> + *
> + * -EIO will be returned if @ste is not legal or contains any non-allowed field.
> + * Cfg can be used to select a S1, Bypass or Abort configuration. A Bypass
> + * nested domain will translate the same as the nesting parent.
> + */
> +struct iommu_hwpt_arm_smmuv3 {
> + __aligned_le64 ste[2];
> +};
> +
> /**
> * enum iommu_hwpt_data_type - IOMMU HWPT Data Type
> * @IOMMU_HWPT_DATA_NONE: no data
> * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table
> + * @IOMMU_HWPT_DATA_ARM_SMMUV3: ARM SMMUv3 Context Descriptor Table
> */
> enum iommu_hwpt_data_type {
> IOMMU_HWPT_DATA_NONE = 0,
> IOMMU_HWPT_DATA_VTD_S1 = 1,
> + IOMMU_HWPT_DATA_ARM_SMMUV3 = 2,
> };
>
> /**
> --
> 2.46.2
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info
2024-10-30 16:24 ` Mostafa Saleh
@ 2024-10-30 17:56 ` Jason Gunthorpe
2024-10-30 18:14 ` Nicolin Chen
0 siblings, 1 reply; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-30 17:56 UTC (permalink / raw)
To: Mostafa Saleh
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi
On Wed, Oct 30, 2024 at 04:24:44PM +0000, Mostafa Saleh wrote:
> > +void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
> > +{
> > + struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> > + struct iommu_hw_info_arm_smmuv3 *info;
> > + u32 __iomem *base_idr;
> > + unsigned int i;
> > +
> > + info = kzalloc(sizeof(*info), GFP_KERNEL);
> > + if (!info)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + base_idr = master->smmu->base + ARM_SMMU_IDR0;
> > + for (i = 0; i <= 5; i++)
> > + info->idr[i] = readl_relaxed(base_idr + i);
> > + info->iidr = readl_relaxed(master->smmu->base + ARM_SMMU_IIDR);
> > + info->aidr = readl_relaxed(master->smmu->base + ARM_SMMU_AIDR);
>
> I wonder if passing the IDRs is enough for the VMM, for example in some
> cases, firmware can override the coherency, also the IIDR can override
> some features (as MMU700 and BTM), although, the VMM can deal with.
I'm confident it is not enough
BTM support requires special kernel vBTM support which will need a
dedicated flag someday
ATS is linked to the kernel per-device enable_ats, that will have to
flow to ACPI/etc tables on a per-device basis
PRI is linked to the ability to attach a fault capable domain..
And so on.
Nicolin, what do your qemu patches even use IIDR for today?
It wouldn't surprise me if we end up only using a few bits of the raw
physical information.
> Maybe for those(coherency, ATS, PRI) we would need to keep the VMM view and
> the kernel in sync?
Definately
Jason
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info
2024-10-30 17:56 ` Jason Gunthorpe
@ 2024-10-30 18:14 ` Nicolin Chen
0 siblings, 0 replies; 34+ messages in thread
From: Nicolin Chen @ 2024-10-30 18:14 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Mostafa Saleh, acpica-devel, Hanjun Guo, iommu, Joerg Roedel,
Kevin Tian, kvm, Len Brown, linux-acpi, linux-arm-kernel,
Lorenzo Pieralisi, Rafael J. Wysocki, Robert Moore, Robin Murphy,
Sudeep Holla, Will Deacon, Alex Williamson, Eric Auger,
Jean-Philippe Brucker, Moritz Fischer, Michael Shavit, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi
On Wed, Oct 30, 2024 at 02:56:15PM -0300, Jason Gunthorpe wrote:
> On Wed, Oct 30, 2024 at 04:24:44PM +0000, Mostafa Saleh wrote:
> > > +void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type)
> > > +{
> > > + struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> > > + struct iommu_hw_info_arm_smmuv3 *info;
> > > + u32 __iomem *base_idr;
> > > + unsigned int i;
> > > +
> > > + info = kzalloc(sizeof(*info), GFP_KERNEL);
> > > + if (!info)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + base_idr = master->smmu->base + ARM_SMMU_IDR0;
> > > + for (i = 0; i <= 5; i++)
> > > + info->idr[i] = readl_relaxed(base_idr + i);
> > > + info->iidr = readl_relaxed(master->smmu->base + ARM_SMMU_IIDR);
> > > + info->aidr = readl_relaxed(master->smmu->base + ARM_SMMU_AIDR);
> >
> > I wonder if passing the IDRs is enough for the VMM, for example in some
> > cases, firmware can override the coherency, also the IIDR can override
> > some features (as MMU700 and BTM), although, the VMM can deal with.
>
> I'm confident it is not enough
>
> BTM support requires special kernel vBTM support which will need a
> dedicated flag someday
>
> ATS is linked to the kernel per-device enable_ats, that will have to
> flow to ACPI/etc tables on a per-device basis
>
> PRI is linked to the ability to attach a fault capable domain..
>
> And so on.
>
> Nicolin, what do your qemu patches even use IIDR for today?
Not yet.
I think this is a very good point. Checking IIDR in VMM as the
kernel driver does is doable with the iommu_hw_info_arm_smmuv3
while a firmware override like IORT might not..
Thanks
Nicolin
> It wouldn't surprise me if we end up only using a few bits of the raw
> physical information.
>
> > Maybe for those(coherency, ATS, PRI) we would need to keep the VMM view and
> > the kernel in sync?
>
> Definately
>
> Jason
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED
2024-10-30 16:29 ` Mostafa Saleh
@ 2024-10-30 23:59 ` Jason Gunthorpe
0 siblings, 0 replies; 34+ messages in thread
From: Jason Gunthorpe @ 2024-10-30 23:59 UTC (permalink / raw)
To: Mostafa Saleh
Cc: acpica-devel, Hanjun Guo, iommu, Joerg Roedel, Kevin Tian, kvm,
Len Brown, linux-acpi, linux-arm-kernel, Lorenzo Pieralisi,
Rafael J. Wysocki, Robert Moore, Robin Murphy, Sudeep Holla,
Will Deacon, Alex Williamson, Eric Auger, Jean-Philippe Brucker,
Moritz Fischer, Michael Shavit, Nicolin Chen, patches,
Rafael J. Wysocki, Shameerali Kolothum Thodi
On Wed, Oct 30, 2024 at 04:29:24PM +0000, Mostafa Saleh wrote:
> > diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > index b4b03206afbf48..eb401a4adfedc8 100644
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > @@ -295,6 +295,7 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
> > case CMDQ_OP_TLBI_NH_ASID:
> > cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
> > fallthrough;
> > + case CMDQ_OP_TLBI_NH_ALL:
> > case CMDQ_OP_TLBI_S12_VMALL:
> > cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
> > break;
> > @@ -2230,6 +2231,15 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
> > }
> > __arm_smmu_tlb_inv_range(&cmd, iova, size, granule, smmu_domain);
> >
> > + if (smmu_domain->nest_parent) {
>
> Do we need a sync between the 2 invalidations to order them?
Which two do you mean?
Yes, we must flush the S2 IOTLB before we go on to flush the S1
ASID's.
But __arm_smmu_tlb_inv_range() calls arm_smmu_cmdq_batch_submit() on
all paths which has a sync inside it.
> > + /*
> > + * When the S2 domain changes all the nested S1 ASIDs have to be
> > + * flushed too.
> > + */
> > + cmd.opcode = CMDQ_OP_TLBI_NH_ALL;
> > + arm_smmu_cmdq_issue_cmd_with_sync(smmu_domain->smmu, &cmd);
> > + }
> > +
> > /*
> > * Unfortunately, this can't be leaf-only since we may have
> > * zapped an entire table.
Which was already needed because the lines right below are:
arm_smmu_atc_inv_domain(smmu_domain, iova, size);
There must be a sync between IOTLB and ATC operations.
We also need a sync between the ATC operation and the all ASID
invalidation, which the _with_sync() should do.
> > +/**
> > + * struct iommu_hwpt_arm_smmuv3 - ARM SMMUv3 Context Descriptor Table info
> > + * (IOMMU_HWPT_DATA_ARM_SMMUV3)
> > + *
>
> That’s supposed to be stream table?
I think when the comment was written the only option was to program a
context descriptor. Now it can do more.. Let's try:
/**
* struct iommu_hwpt_arm_smmuv3 - ARM SMMUv3 nested STE
* (IOMMU_HWPT_DATA_ARM_SMMUV3)
*
* @ste: The first two double words of the user space Stream Table Entry for
* the translation. Must be little-endian.
* Allowed fields: (Refer to "5.2 Stream Table Entry" in SMMUv3 HW Spec)
* - word-0: V, Cfg, S1Fmt, S1ContextPtr, S1CDMax
* - word-1: EATS, S1DSS, S1CIR, S1COR, S1CSH, S1STALLD
*
* -EIO will be returned if @ste is not legal or contains any non-allowed field.
* Cfg can be used to select a S1, Bypass or Abort configuration. A Bypass
* nested domain will translate the same as the nesting parent. The S1 will
* install a Context Descriptor Table pointing at userspace memory translated
* by the nesting parent.
*/
Jason
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2024-10-31 0:01 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-09 16:23 [PATCH v3 0/9] Initial support for SMMUv3 nested translation Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 1/9] vfio: Remove VFIO_TYPE1_NESTING_IOMMU Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 2/9] ACPICA: IORT: Update for revision E.f Jason Gunthorpe
2024-10-10 1:48 ` Hanjun Guo
2024-10-09 16:23 ` [PATCH v3 3/9] ACPI/IORT: Support CANWBS memory access flag Jason Gunthorpe
2024-10-10 7:45 ` Hanjun Guo
2024-10-24 7:38 ` Tian, Kevin
2024-10-09 16:23 ` [PATCH v3 4/9] iommu/arm-smmu-v3: Report IOMMU_CAP_ENFORCE_CACHE_COHERENCY for CANWBS Jason Gunthorpe
2024-10-24 7:41 ` Tian, Kevin
2024-10-09 16:23 ` [PATCH v3 5/9] iommu/arm-smmu-v3: Support IOMMU_GET_HW_INFO via struct arm_smmu_hw_info Jason Gunthorpe
2024-10-30 16:24 ` Mostafa Saleh
2024-10-30 17:56 ` Jason Gunthorpe
2024-10-30 18:14 ` Nicolin Chen
2024-10-09 16:23 ` [PATCH v3 6/9] iommu/arm-smmu-v3: Implement IOMMU_HWPT_ALLOC_NEST_PARENT Jason Gunthorpe
2024-10-30 16:26 ` Mostafa Saleh
2024-10-09 16:23 ` [PATCH v3 7/9] iommu/arm-smmu-v3: Expose the arm_smmu_attach interface Jason Gunthorpe
2024-10-09 17:03 ` Nicolin Chen
2024-10-24 7:47 ` Tian, Kevin
2024-10-30 16:26 ` Mostafa Saleh
2024-10-09 16:23 ` [PATCH v3 8/9] iommu/arm-smmu-v3: Support IOMMU_DOMAIN_NESTED Jason Gunthorpe
2024-10-09 17:27 ` Nicolin Chen
2024-10-11 13:59 ` Jason Gunthorpe
2024-10-24 7:50 ` Tian, Kevin
2024-10-30 16:29 ` Mostafa Saleh
2024-10-30 23:59 ` Jason Gunthorpe
2024-10-09 16:23 ` [PATCH v3 9/9] iommu/arm-smmu-v3: Use S2FWB for NESTED domains Jason Gunthorpe
2024-10-09 17:42 ` Nicolin Chen
2024-10-11 14:00 ` Jason Gunthorpe
2024-10-24 7:54 ` Tian, Kevin
2024-10-25 14:00 ` Jason Gunthorpe
2024-10-28 2:25 ` Tian, Kevin
2024-10-09 17:46 ` [PATCH v3 0/9] Initial support for SMMUv3 nested translation Nicolin Chen
2024-10-26 20:26 ` Jerry Snitselaar
2024-10-30 4:06 ` Donald Dutile
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).