RE: [PATCH v1 8/8] iommu/arm-smmu-v3: Probe a guest-level Realm VSMMU via RSI commands

From: Shameer Kolothum Thodi

Date: Wed Oct 28 2026 - 11:47:38 EST




> -----Original Message-----
> From: Nicolin Chen <nicolinc@xxxxxxxxxx>
> Sent: 10 September 2026 04:33
> To: Jason Gunthorpe <jgg@xxxxxxxxxx>; Catalin Marinas
> <catalin.marinas@xxxxxxx>; Will Deacon <will@xxxxxxxxxx>;
> joro@xxxxxxxxxx; Robin Murphy <robin.murphy@xxxxxxx>;
> rafael@xxxxxxxxxx; Danilo Krummrich <dakr@xxxxxxxxxx>; Marek Szyprowski
> <m.szyprowski@xxxxxxxxxxx>; aneesh.kumar@xxxxxxxxxx
> Cc: Mark Rutland <mark.rutland@xxxxxxx>; Greg Kroah-Hartman
> <gregkh@xxxxxxxxxxxxxxxxxxx>; Suzuki K Poulose
> <suzuki.poulose@xxxxxxx>; Gavin Shan <gshan@xxxxxxxxxx>; Vikram Sethi
> <vsethi@xxxxxxxxxx>; Anshuman Khandual
> <anshuman.khandual@xxxxxxx>; Shanker Donthineni
> <sdonthineni@xxxxxxxxxx>; Mostafa Saleh <smostafa@xxxxxxxxxx>;
> rppt@xxxxxxxxxx; Thomas Huth <thuth@xxxxxxxxxx>; Marc Zyngier
> <maz@xxxxxxxxxx>; Ryan Roberts <ryan.roberts@xxxxxxx>; kas@xxxxxxxxxx;
> Kohei Enju <enju.kohei@xxxxxxxxxxx>; Shaopeng Tan
> <tan.shaopeng@xxxxxxxxxxxxxx>; Ard Biesheuvel <ardb@xxxxxxxxxx>; James
> Morse <james.morse@xxxxxxx>; Steven Price <steven.price@xxxxxxx>;
> Sang-Heon Jeon <ekffu200098@xxxxxxxxx>; Omar Sandoval
> <osandov@xxxxxx>; Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>; Jinjie
> Ruan <ruanjinjie@xxxxxxxxxx>; Sam Edwards <cfsworks@xxxxxxxxx>;
> Douglas Anderson <dianders@xxxxxxxxxxxx>; Florian Fainelli
> <florian.fainelli@xxxxxxxxxxxx>; Chen-Yu Tsai <wenst@xxxxxxxxxxxx>;
> Huacai Chen <chenhuacai@xxxxxxxxxx>; Thomas Zimmermann
> <tzimmermann@xxxxxxx>; Pranjal Shrivastava <praan@xxxxxxxxxx>; Ashish
> Mhetre <amhetre@xxxxxxxxxx>; Shameer Kolothum Thodi
> <skolothumtho@xxxxxxxxxx>; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux-
> kernel@xxxxxxxxxxxxxxx; iommu@xxxxxxxxxxxxxxx; driver-core@xxxxxxxxxxxxxxx;
> Sonang Patel <sonangp@xxxxxxxxxx>; Ankit Agrawal <ankita@xxxxxxxxxx>
> Subject: [PATCH v1 8/8] iommu/arm-smmu-v3: Probe a guest-level Realm
> VSMMU via RSI commands
>
> In CCA, the ACPI/etc doesn't tell the OS whether the SMMU is a confidential
> T=1 instance or a normal T=0 one. Instead, it has to be learned by issuing
> a trusted RSI. Before the kernel can operate the trusted T=1 IOMMU, it also
> has to validate all the information that it gets from ACPI against the true
> information that it gets from the RSI call, to ensure the ACPI is correct
> and prevent substitution attacks.
>
> Use RSI_VSMMU_GET_INFO during probe and require the returned register
> range
> to match firmware. Then use RSI_ARCH_DEV_ACTIVATE before mapping
> registers.
>
> Currently the driver doesn't support a T=0 SMMU inside a realm. For example
> it doesn't make the page table allocations into shared memory. If we are in
> a realm reject any SMMU that is not T=1.
>
> Once the SMMU is activated, its DMA will follow the
> DEV_FLAG_DMA_CC_PRIVATE
> rules. It must set that flag to ensure its coherent allocations for its own
> structures are allocated from private memory, not the SWIOTLB shared pool.
>
> Assisted-by: Codex:gpt-5.6-sol
> Signed-off-by: Nicolin Chen <nicolinc@xxxxxxxxxx>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 55
> +++++++++++++++++++++
> 1 file changed, 55 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 5732f3ba0122d..972815c54b11f 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -11,9 +11,11 @@
>
> #include <linux/acpi.h>
> #include <linux/acpi_iort.h>
> +#include <linux/arm-rsi-cmds.h>
> #include <linux/bitops.h>
> #include <linux/crash_dump.h>
> #include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> #include <linux/err.h>
> #include <linux/interrupt.h>
> #include <linux/io-pgtable.h>
> @@ -5507,6 +5509,53 @@ static struct arm_smmu_device
> *arm_smmu_impl_probe(struct arm_smmu_device *smmu)
> return ERR_PTR(ret);
> }
>
> +static void arm_smmu_clear_realm_private(void *dev)
> +{
> + dma_set_cc_private(dev, false);
> +}
> +
> +static int arm_smmu_probe_realm_vsmmu(struct arm_smmu_device
> *smmu,
> + const struct resource *res)
> +{
> + struct device *dev = smmu->dev;
> + unsigned long rsi_ret;
> + phys_addr_t top;
> +
> + /*
> + * Currently the driver does not support a T=0 SMMU inside a realm.
> For
> + * instance it does not make the page table allocations into shared
> + * memory. If we are in a realm reject any SMMU that is not T=1.
> + */
> + rsi_ret = rsi_vsmmu_get_info(res->start, &top);
> + if (rsi_ret != RSI_SUCCESS) {
> + dev_err(dev, "RSI_VSMMU_GET_INFO failed for %pr: %lu\n",
> res,
> + rsi_ret);
> + return -ENODEV;
> + }
> +
> + if (top != res->end + 1) {
> + dev_err(dev, "VSMMU range %pr ends at %pa\n", res, &top);
> + return -EINVAL;
> + }
> +
> + rsi_ret = rsi_arch_dev_activate(res->start, RSI_ARCH_DEV_SMMUV3);
> + if (rsi_ret != RSI_SUCCESS) {
> + dev_err(dev, "RSI_ARCH_DEV_ACTIVATE failed for %pr:
> %lu\n", res,
> + rsi_ret);
> + return -EIO;
> + }
> +
> + /*
> + * Once activated, the SMMU DMA follows
> DEV_FLAG_DMA_CC_PRIVATE so its
> + * queues and tables are allocated from private memory, not the
> SWIOTLB
> + * shared pool. It only translates for a device we've requested the
> RMM
> + * to put into T=1.
> + */
> + iommu_device_set_confidential(&smmu->iommu, dev);
> +
> + return devm_add_action_or_reset(dev,
> arm_smmu_clear_realm_private, dev);
> +}
> +
> static int arm_smmu_device_probe(struct platform_device *pdev)
> {
> int irq, ret;
> @@ -5542,6 +5591,12 @@ static int arm_smmu_device_probe(struct
> platform_device *pdev)
> }
> ioaddr = res->start;
>
> + if (is_realm_world()) {
> + ret = arm_smmu_probe_realm_vsmmu(smmu, res);
> + if (ret)
> + return ret;
> + }

If probe fails after activation succeeds above, wouldn't a module
reload hit RSI_ERROR_DEVICE since the VSMMU is still ACTIVE?

B5.4.1.2:

pre: vsmmu.state == VSMMU_ACTIVE
post: result == RSI_ERROR_DEVICE

How is recovery handled?

Thanks,
Shameer