The ICC_PPI_HMR<n>_EL1 and ICV_PPI_HMR<n>_EL1 registers are both read-only and report whether PPIs have the edge or level handling mode. This doesn't change under virtualization and there is no mechanism for the hypervisor to report a different value to the guest. However, we do need to honour the ICH_PPI_HVI bits that make the PPI behave as if it was unimplemented (bit is RAZ/WI).
Add a readfn for these registers so we can mask them when they are read by the hypervisor guest. Signed-off-by: Peter Maydell <[email protected]> --- target/arm/tcg/gicv5-cpuif.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c index e1d3ffb7b1e..b55fe4991ba 100644 --- a/target/arm/tcg/gicv5-cpuif.c +++ b/target/arm/tcg/gicv5-cpuif.c @@ -425,6 +425,23 @@ static void gic_cdhm_write(CPUARMState *env, const ARMCPRegInfo *ri, gicv5_set_handling(gic, id, hm, domain, type, virtual); } +static uint64_t gic_ppi_hmr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + uint64_t value = raw_read(env, ri); + + if (gicv5_icv_access(env)) { + /* + * The spec defines ICV_PPI_HMR<n>_EL1 virtual versions of these + * registers, but they are read-only and can only ever report the + * same value as the physical ICC_ versions. However we do need + * to make sure the bits RAZ/WI if the hypervisor has made the + * PPI appear disabled to the guest via ICH_PPI_HVIR<n>_EL2. + */ + value &= ~env->gicv5_cpuif.ich_ppi_hvi[ri->opc2 & 1]; + } + return value; +} + static void gic_ppi_cactive_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1054,6 +1071,7 @@ static const ARMCPRegInfo gicv5_cpuif_reginfo[] = { .access = PL1_R, .type = ARM_CP_IO | ARM_CP_NO_RAW, .fgt = FGT_ICC_PPI_HMRN_EL1, .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_hm[0]), + .readfn = gic_ppi_hmr_read, .resetvalue = PPI_HMR0_RESET, }, { .name = "ICC_PPI_HMR1_EL1", .state = ARM_CP_STATE_AA64, @@ -1061,6 +1079,7 @@ static const ARMCPRegInfo gicv5_cpuif_reginfo[] = { .access = PL1_R, .type = ARM_CP_IO | ARM_CP_NO_RAW, .fgt = FGT_ICC_PPI_HMRN_EL1, .fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_hm[1]), + .readfn = gic_ppi_hmr_read, .resetvalue = PPI_HMR1_RESET, }, { .name = "ICC_HPPIR_EL1", .state = ARM_CP_STATE_AA64, -- 2.43.0
