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)


Reply via email to