Currently QEMU SMMUv3 has RIL support by default. But if accelerated mode is enabled, RIL has to be compatible with host SMMUv3 support.
Add a property so that the user can specify this. Signed-off-by: Shameer Kolothum <[email protected]> --- hw/arm/smmuv3-accel.c | 16 ++++++++++++++-- hw/arm/smmuv3-accel.h | 4 ++++ hw/arm/smmuv3.c | 13 +++++++++++++ include/hw/arm/smmuv3.h | 1 + 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c index 8396053a6c..e8607b253e 100644 --- a/hw/arm/smmuv3-accel.c +++ b/hw/arm/smmuv3-accel.c @@ -79,10 +79,10 @@ smmuv3_accel_check_hw_compatible(SMMUv3State *s, return false; } - /* QEMU SMMUv3 supports Range Invalidation by default */ + /* User can override QEMU SMMUv3 Range Invalidation support */ val = FIELD_EX32(info->idr[3], IDR3, RIL); if (val != FIELD_EX32(s->idr[3], IDR3, RIL)) { - error_setg(errp, "Host SUMMUv3 deosn't support Range Invalidation"); + error_setg(errp, "Host SUMMUv3 differs in Range Invalidation support"); return false; } @@ -634,6 +634,18 @@ static const PCIIOMMUOps smmuv3_accel_ops = { .get_msi_address_space = smmuv3_accel_find_msi_as, }; +void smmuv3_accel_idr_override(SMMUv3State *s) +{ + if (!s->accel) { + return; + } + + /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */ + if (!s->ril) { + s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 0); + } +} + /* * If the guest reboots and devices are configured for S1+S2, Stage1 must * be switched to bypass. Otherwise, QEMU/UEFI may fail when accessing a diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h index 75f858e34a..357d8352c5 100644 --- a/hw/arm/smmuv3-accel.h +++ b/hw/arm/smmuv3-accel.h @@ -49,6 +49,7 @@ bool smmuv3_accel_install_nested_ste_range(SMMUv3State *s, SMMUSIDRange *range, bool smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev, Error **errp); void smmuv3_accel_attach_bypass_hwpt(SMMUv3State *s); +void smmuv3_accel_idr_override(SMMUv3State *s); #else static inline void smmuv3_accel_init(SMMUv3State *s) { @@ -74,6 +75,9 @@ smmuv3_accel_issue_inv_cmd(SMMUv3State *s, void *cmd, SMMUDevice *sdev, static inline void smmuv3_accel_attach_bypass_hwpt(SMMUv3State *s) { } +static inline void smmuv3_accel_idr_override(SMMUv3State *s) +{ +} #endif #endif /* HW_ARM_SMMUV3_ACCEL_H */ diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index a0f704fc35..0f3a61646a 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -300,6 +300,8 @@ static void smmuv3_init_regs(SMMUv3State *s) s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1); s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1); + smmuv3_accel_idr_override(s); + s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS); s->cmdq.prod = 0; s->cmdq.cons = 0; @@ -1925,6 +1927,13 @@ static bool smmu_validate_property(SMMUv3State *s, Error **errp) return false; } #endif + if (s->accel) { + return true; + } + if (!s->ril) { + error_setg(errp, "ril can only be disabled if accel=on"); + return false; + } return true; } @@ -2047,6 +2056,8 @@ static const Property smmuv3_properties[] = { */ DEFINE_PROP_STRING("stage", SMMUv3State, stage), DEFINE_PROP_BOOL("accel", SMMUv3State, accel, false), + /* RIL can be turned off for accel cases */ + DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true), }; static void smmuv3_instance_init(Object *obj) @@ -2074,6 +2085,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data) "Enable SMMUv3 accelerator support." "Allows host SMMUv3 to be configured " "in nested mode for vfio-pci dev assignment"); + object_class_property_set_description(klass, "ril", + "Enable/disable range invalidation support"); } static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu, diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h index 874cbaaf32..c555ea684e 100644 --- a/include/hw/arm/smmuv3.h +++ b/include/hw/arm/smmuv3.h @@ -68,6 +68,7 @@ struct SMMUv3State { bool accel; struct SMMUv3AccelState *s_accel; Error *migration_blocker; + bool ril; }; typedef enum { -- 2.43.0
