For accelerated SMMUv3, we need nested parent domain creation. Add the callback support so that VFIO can create a nested parent.
In the accelerated SMMUv3 case, the host SMMUv3 is configured in nested mode (S1 + S2), and the guest owns the Stage-1 page table. Therefore, we expose only Stage-1 to the guest to ensure it uses the correct page-table format. Reviewed-by: Nicolin Chen <[email protected]> Signed-off-by: Shameer Kolothum <[email protected]> Signed-off-by: Shameer Kolothum <[email protected]> --- hw/arm/smmuv3-accel.c | 13 +++++++++++++ hw/arm/virt.c | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 44410cfb2a..6b0e512d86 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -10,6 +10,7 @@ #include "qemu/error-report.h" #include "hw/arm/smmuv3.h" +#include "hw/iommu.h" #include "hw/pci/pci_bridge.h" #include "hw/pci-host/gpex.h" #include "hw/vfio/pci.h" @@ -106,8 +107,20 @@ static AddressSpace *smmuv3_accel_find_add_as(PCIBus *bus, void *opaque, } } +static uint64_t smmuv3_accel_get_viommu_flags(void *opaque) +{ + /* + * We return VIOMMU_FLAG_WANT_NESTING_PARENT to inform VFIO core to create a + * nesting parent which is required for accelerated SMMUv3 support. + * The real HW nested support should be reported from host SMMUv3 and if + * it doesn't, the nesting parent allocation will fail anyway in VFIO core. + */ + return VIOMMU_FLAG_WANT_NESTING_PARENT; +} + static const PCIIOMMUOps smmuv3_accel_ops = { .get_address_space = smmuv3_accel_find_add_as, + .get_viommu_flags = smmuv3_accel_get_viommu_flags, }; void smmuv3_accel_init(SMMUv3State *s) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 02209fadcf..b533b0556e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -3073,6 +3073,19 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, return; } + if (object_property_get_bool(OBJECT(dev), "accel", &error_abort)) { + char *stage; + + stage = object_property_get_str(OBJECT(dev), "stage", + &error_fatal); + /* If no stage specified, SMMUv3 will default to stage 1 */ + if (*stage && strcmp("1", stage)) { + error_setg(errp, "Only stage1 is supported for SMMUV3 with " + "accel=on"); + return; + } + } + create_smmuv3_dev_dtb(vms, dev, bus); } } -- 2.43.0
