Nathan Chen <[email protected]> writes:
> From: Nathan Chen <[email protected]>
>
> Allow accelerated SMMUv3 Range Invalidation support property to be
> derived from host IOMMU capabilities. Derive host values using
> IOMMU_GET_HW_INFO, retrieving RIL capability from IDR3.
>
> Set the default value of RIL to auto. The default for RIL support used
> to be set to on, but we change it to match what the host IOMMU
> properties report so that users do not have to introspect host IDR3 for
> Range Invalidation support. The RIL support needs to be compatible with
> host SMMUv3 if accelerated mode is enabled.
>
> Signed-off-by: Nathan Chen <[email protected]>
> ---
> hw/arm/smmuv3-accel.c | 20 +++++++++++++++++---
> hw/arm/smmuv3.c | 4 ++--
> include/hw/arm/smmuv3.h | 2 +-
> 3 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 8fec335557..02e3f7a9f3 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -58,6 +58,12 @@ static void smmuv3_accel_auto_finalise(SMMUv3State *s,
> PCIDevice *pdev,
> FIELD_EX32(info->idr[0], IDR0, ATS));
> }
>
> + /* Update RIL if auto from info */
> + if (s->ril == ON_OFF_AUTO_AUTO) {
> + s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL,
> + FIELD_EX32(info->idr[3], IDR3, RIL));
> + }
> +
> accel->auto_finalised = true;
> }
>
> @@ -854,8 +860,15 @@ void smmuv3_accel_idr_override(SMMUv3State *s)
> return;
> }
>
> - /* By default QEMU SMMUv3 has RIL. Update IDR3 if user has disabled it */
> - s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, s->ril);
> + /*
> + * Only override RIL if user explicitly set ON or OFF.
> + * AUTO will be resolved later when host info is available.
> + */
> + if (s->ril == ON_OFF_AUTO_ON) {
> + s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
> + } else if (s->ril == ON_OFF_AUTO_OFF) {
> + s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 0);
> + }
>
> /* Only override ATS if user explicitly set ON or OFF */
> if (s->ats == ON_OFF_AUTO_ON) {
> @@ -941,7 +954,8 @@ void smmuv3_accel_init(SMMUv3State *s)
> bs->iommu_ops = &smmuv3_accel_ops;
> smmuv3_accel_as_init(s);
>
> - if (s->ats == ON_OFF_AUTO_AUTO) {
> + if (s->ats == ON_OFF_AUTO_AUTO ||
> + s->ril == ON_OFF_AUTO_AUTO) {
> s->s_accel->auto_mode = true;
> }
> }
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index 197ba7c77b..7791e5294d 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -1973,7 +1973,7 @@ static bool smmu_validate_property(SMMUv3State *s,
> Error **errp)
> #endif
>
> if (!s->accel) {
> - if (!s->ril) {
> + if (s->ril == ON_OFF_AUTO_OFF) {
> error_setg(errp, "ril can only be disabled if accel=on");
> return false;
> }
> @@ -2133,7 +2133,7 @@ static const Property smmuv3_properties[] = {
> /* GPA of MSI doorbell, for SMMUv3 accel use. */
> DEFINE_PROP_UINT64("msi-gpa", SMMUv3State, msi_gpa, 0),
> /* RIL can be turned off for accel cases */
> - DEFINE_PROP_BOOL("ril", SMMUv3State, ril, true),
> + DEFINE_PROP_ON_OFF_AUTO("ril", SMMUv3State, ril, ON_OFF_AUTO_AUTO),
Is property "ril" accessible via QMP or JSON command line? If yes, this
is an incompatible change: JSON values false and true no longer work.
> DEFINE_PROP_ON_OFF_AUTO("ats", SMMUv3State, ats, ON_OFF_AUTO_AUTO),
> DEFINE_PROP_UINT8("oas", SMMUv3State, oas, 44),
> DEFINE_PROP_UINT8("ssidsize", SMMUv3State, ssidsize, 0),
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index 2ca49ded36..9124bfe751 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -69,7 +69,7 @@ struct SMMUv3State {
> struct SMMUv3AccelState *s_accel;
> uint64_t msi_gpa;
> Error *migration_blocker;
> - bool ril;
> + OnOffAuto ril;
> OnOffAuto ats;
> uint8_t oas;
> uint8_t ssidsize;