On 8/2/25 18:17, Mohamed Mediouni wrote:
@@ -522,7 +524,7 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
      isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0);
      isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0);
- if (kvm_enabled() || hvf_enabled()) {
+    if (kvm_enabled() || hvf_enabled() || whpx_enabled()) {

Just a heads up, Phil has a patch which adds hwaccel_enabled().

https://lore.kernel.org/qemu-devel/20250703105540.67664-47-phi...@linaro.org/

and I believe cleans up both here...

          /*
           * Exit early if PAuth is enabled and fall through to disable it.
           * The algorithm selection properties are not present.
@@ -599,7 +601,7 @@ void aarch64_add_pauth_properties(Object *obj)
/* Default to PAUTH on, with the architected algorithm on TCG. */
      qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property);
-    if (kvm_enabled() || hvf_enabled()) {
+    if (kvm_enabled() || hvf_enabled() || whpx_enabled()) {

here...

@@ -780,7 +786,7 @@ static void aarch64_host_initfn(Object *obj)
static void aarch64_max_initfn(Object *obj)
  {
-    if (kvm_enabled() || hvf_enabled()) {
+    if (kvm_enabled() || hvf_enabled() || whpx_enabled()) {
          /* With KVM or HVF, '-cpu max' is identical to '-cpu host' */

and here.

+static HKEY OpenProcessorKey(void)
+{
+  HKEY Out;
+  const char *path = "Hardware\\Description\\System\\CentralProcessor\\0\\";
+  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &Out)) {
+    return NULL;
+  }
+  return Out;
+}
+
+static uint64_t ReadRegU64(HKEY Key, const char *name)
+{
+  uint64_t Value = 0;
+  DWORD Size = sizeof(Value);
+  LONG res = RegGetValueA(Key, NULL, name, RRF_RT_REG_QWORD, NULL, &Value, 
&Size);
+  if (res != ERROR_SUCCESS) {
+    printf("Failed to get register value: error: 0x%x\n", res);
+  }
+  return Value;
+}

4 space indentation.
assert, not printf.  :-)

+
+static bool whpx_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+{
+    ARMISARegisters host_isar = {};
+    const struct isar_regs {
+        WHV_REGISTER_NAME reg;
+        uint64_t *val;
+    } regs[] = {
+        { WHvArm64RegisterIdAa64Pfr0El1, 
&host_isar.idregs[ID_AA64PFR0_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Pfr1El1, 
&host_isar.idregs[ID_AA64PFR1_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Dfr0El1, 
&host_isar.idregs[ID_AA64DFR0_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Dfr1El1 , 
&host_isar.idregs[ID_AA64DFR1_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Isar0El1, 
&host_isar.idregs[ID_AA64ISAR0_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Isar1El1, 
&host_isar.idregs[ID_AA64ISAR1_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Isar2El1, 
&host_isar.idregs[ID_AA64ISAR2_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Mmfr0El1, 
&host_isar.idregs[ID_AA64MMFR0_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Mmfr1El1, 
&host_isar.idregs[ID_AA64MMFR1_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Mmfr2El1, 
&host_isar.idregs[ID_AA64MMFR2_EL1_IDX] },
+        { WHvArm64RegisterIdAa64Mmfr3El1, 
&host_isar.idregs[ID_AA64MMFR2_EL1_IDX] }
+    };

I'm sure this arrangement was easiest before the id regs reorg, but now we can store the ID_* not the pointer in the table, and the table can be static const.

Why do we need the host_isar local variable?
We could be writing to ahcf->isar to begin.

+    /*
+     * Disable SME, which is not properly handled by QEMU hvf yet.

hvf.  :-)

+    /*
+     * A scratch vCPU returns SCTLR 0, so let's fill our default with the M1
+     * boot SCTLR from https://github.com/AsahiLinux/m1n1/issues/97
+     */
+    ahcf->reset_sctlr = 0x30100180;
+    /*
+     * SPAN is disabled by default when SCTLR.SPAN=1. To improve compatibility,
+     * let's disable it on boot and then allow guest software to turn it on by
+     * setting it to 0.
+     */
+    ahcf->reset_sctlr |= 0x00800000;

Is this really required, or just copied from hvf?


r~

Reply via email to