• Reiji Watanabe's avatar
    KVM: arm64: PMU: Don't overwrite PMUSERENR with vcpu loaded · 0c2f9acf
    Reiji Watanabe authored
    Currently, with VHE, KVM sets ER, CR, SW and EN bits of
    PMUSERENR_EL0 to 1 on vcpu_load(), and saves and restores
    the register value for the host on vcpu_load() and vcpu_put().
    If the value of those bits are cleared on a pCPU with a vCPU
    loaded (armv8pmu_start() would do that when PMU counters are
    programmed for the guest), PMU access from the guest EL0 might
    be trapped to the guest EL1 directly regardless of the current
    PMUSERENR_EL0 value of the vCPU.
    
    Fix this by not letting armv8pmu_start() overwrite PMUSERENR_EL0
    on the pCPU where PMUSERENR_EL0 for the guest is loaded, and
    instead updating the saved shadow register value for the host
    so that the value can be restored on vcpu_put() later.
    While vcpu_{put,load}() are manipulating PMUSERENR_EL0, disable
    IRQs to prevent a race condition between these processes and IPIs
    that attempt to update PMUSERENR_EL0 for the host EL0.
    Suggested-by: default avatarMark Rutland <mark.rutland@arm.com>
    Suggested-by: default avatarMarc Zyngier <maz@kernel.org>
    Fixes: 83a7a4d6 ("arm64: perf: Enable PMU counter userspace access for perf event")
    Signed-off-by: default avatarReiji Watanabe <reijiw@google.com>
    Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
    Link: https://lore.kernel.org/r/20230603025035.3781797-3-reijiw@google.com
    0c2f9acf
arm_pmuv3.c 43.3 KB