[RFC PATCH v3 17/19] target/arm: Report 0 as supported for ID fields gated by vCPU init flags

Khushit Shah <[email protected]>
Newsgroups org.nongnu.qemu-arm,dev.linux.lists.kvmarm,org.nongnu.qemu-devel
Message-ID <[email protected]>
When QEMU queries supported CPU properties via KVM, it uses a scratch
vCPU initialized with all host-supported features (like SVE and PAuth).

KVM exposes the corresponding ID register fields (e.g.,
ID_AA64ISAR1_EL1.APA) as read-only, the supported values only shows the
enabled host value (e.g., 5) and omits 0. This will lead into falsely
flagging a model as blocked as the features can be masked by not
passing those flags. For these fields, even if KVM reports them as
non-writable, we explicitly append "0" to the list of supported values
if the host value is non-zero.

Signed-off-by: Khushit Shah <[email protected]>
---
 target/arm/kvm.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 042d5fe804..ce77758c87 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1292,6 +1292,24 @@ static void ranges_add(GArray *ranges, uint64_t min, uint64_t max)
     g_array_append_val(ranges, r);
 }
 
+/*
+ * Some fields are reported as non-writable by KVM but can still be
+ * disabled by not requesting the corresponding vCPU init feature flag
+ * (SVE, pauth). The supported values are derived from a scratch vCPU
+ * whose init flags may differ from the real vCPU, so for these fields
+ * "off" (0) is a supported value in addition to the host value.
+ */
+static bool arm_field_off_via_vcpu_flags(const ARM64SysRegField *field)
+{
+    return field_matches(field, ID_AA64PFR0_EL1_IDX, "SVE")   ||
+           field_matches(field, ID_AA64ISAR1_EL1_IDX, "APA")  ||
+           field_matches(field, ID_AA64ISAR1_EL1_IDX, "API")  ||
+           field_matches(field, ID_AA64ISAR1_EL1_IDX, "GPA")  ||
+           field_matches(field, ID_AA64ISAR1_EL1_IDX, "GPI")  ||
+           field_matches(field, ID_AA64ISAR2_EL1_IDX, "APA3") ||
+           field_matches(field, ID_AA64ISAR2_EL1_IDX, "GPA3");
+}
+
 void arm_field_get_supported_values(const ARM64SysRegField *field,
                                     const ARMISARegisters *host_isar,
                                     ArmFieldValueSet **value_set)
@@ -1304,6 +1322,13 @@ void arm_field_get_supported_values(const ARM64SysRegField *field,
     /* A non-writable field can only ever hold the host value. */
     if (!arm_field_is_writable(field)) {
         ranges_add(ranges, host, host);
+        /*
+         * ...unless it is one of the fields that can still be turned off
+         * via vCPU init flags, in which case "off" (0) is also supported.
+         */
+        if (host != 0 && arm_field_off_via_vcpu_flags(field)) {
+            ranges_add(ranges, 0, 0);
+        }
         goto done;
     }
 
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.