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~