Apple headers say: > When EL2 is disabled, PMU register accesses trigger "Trapped MSR, MRS, or > System Instruction" exceptions. When this happens, hv_vcpu_run() returns, and > the > hv_vcpu_exit_t object contains the information about this exception.
> When EL2 is enabled, the handling of PMU register accesses is determined by > the PMUVer > field of ID_AA64DFR0_EL1 register. > If the PMUVer field value is zero or is invalid, PMU register accesses > generate "Undefined" > exceptions, which are sent to the guest. > If the PMUVer field value is non-zero and valid, PMU register accesses are > emulated by the framework. > The ID_AA64DFR0_EL1 register can be modified via hv_vcpu_set_sys_reg API. That documentation turns out to not be so accurate, with the determining factor being whether the vGIC is enabled instead of nested virtualisation. If ID_AA64DFR0_EL1.PMUVer = 0, Hypervisor.framework doesn't give us the luxury of having PMU sysreg accesses trapped to the VMM when the vGIC is enabled. As Windows really wants at least a single counter PMU, give it even when using the kernel-irqchip with nested virt off. Signed-off-by: Mohamed Mediouni <[email protected]> --- target/arm/hvf/hvf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c index 8aa59a1f77..136761b429 100644 --- a/target/arm/hvf/hvf.c +++ b/target/arm/hvf/hvf.c @@ -1187,8 +1187,12 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) clamp_id_aa64mmfr0_parange_to_ipa_size(&host_isar); - if (hvf_nested_virt_enabled()) { + /* Windows really wants at least a single counter PMU... */ + if (hvf_irqchip_in_kernel()) { FIELD_DP64_IDREG(&host_isar, ID_AA64DFR0, PMUVER, 0x1); + } + + if (hvf_nested_virt_enabled()) { /* SME is not implemented with nested virt on the Apple side */ FIELD_DP64_IDREG(&host_isar, ID_AA64PFR1, SME, 0); } @@ -1660,7 +1664,7 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint64_t *val) ARMCPU *arm_cpu = ARM_CPU(cpu); CPUARMState *env = &arm_cpu->env; - if (!hvf_nested_virt_enabled() && arm_feature(env, ARM_FEATURE_PMU)) { + if (!hvf_irqchip_in_kernel() && arm_feature(env, ARM_FEATURE_PMU)) { switch (reg) { case SYSREG_PMCR_EL0: *val = env->cp15.c9_pmcr; @@ -1930,7 +1934,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val) SYSREG_OP2(reg), val); - if (!hvf_nested_virt_enabled() && arm_feature(env, ARM_FEATURE_PMU)) { + if (!hvf_irqchip_in_kernel() && arm_feature(env, ARM_FEATURE_PMU)) { switch (reg) { case SYSREG_PMCCNTR_EL0: pmu_op_start(env); -- 2.50.1 (Apple Git-155)
