KVM: arm64: Trap guest MPAM accesses whenever MPAM is implemented
Fuad Tabba
reviewerPATCH v5 1/1 KVM: arm64: Trap guest MPAM accesses whenever MPAM is implemented
finalise_el2_state() clears the EL2 MPAM traps on every CPU whose ID registers advertise MPAM once the arm64.nompam override is applied. KVM sets them again on guest entry only when ARM64_MPAM is set, a capability that also requires MPAM1_EL1.MPAMEN. Without EL3, only MPAM2_EL2.MPAMEN is writable, and the kernel never sets it, so ARM64_MPAM stays clear and so do the traps. A guest can then access MPAM0_EL1, MPAM1_EL1, MPAMSM_EL1 and MPAMIDR_EL1 while its ID_AA64PFR0_EL1.MPAM reads 0.
Record two per-CPU flags at KVM's CPU init: whether MPAM is implemented as finalise_el2_state() tests it, and whether MPAMIDR_EL1.HAS_HCR is set (MPAMHCR_EL2 is UNDEFINED without it). Read ID_AA64PFR0_EL1, ID_AA64PFR1_EL1 and MPAMIDR_EL1 from cpu_data, which holds them with the overrides applied since commit 342e62ded77c6 ("arm64: cpufeature: Read MPAMIDR_EL1 in __cpuinfo_store_cpu()"). Set the traps from those flags. MPAMEN isn't part of any MPAM trap condition, so the traps take effect whether or not it is set.
---
Notes:
Changes since v4:
- Take ID_AA64PFR0_EL1, ID_AA64PFR1_EL1 and MPAMIDR_EL1 from cpu_data
(was __read_sysreg_by_encoding() and read_sysreg_s()).
- Commit message tightened, and the TIDR comment no longer
rewritten.
- Ben's Reviewed-by dropped, since the probe changed.
- Rebased on 7.4-rc1.
Based on Linux 7.4-rc1 (6628e7d4c6b25).
v4: https://lore.kernel.org/all/[email protected]/
v3: https://lore.kernel.org/all/[email protected]/
v2: https://lore.kernel.org/all/[email protected]/
v1: https://lore.kernel.org/all/[email protected]/arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/kvm/arm.c | 12 ++++++++++++ arch/arm64/kvm/hyp/include/hyp/switch.h | 8 ++++---- 3 files changed, 18 insertions(+), 4 deletions(-)
arch/arm64/include/asm/kvm_host.h +2 -0
@@ -839,6 +839,8 @@ struct kvm_host_data {#define KVM_HOST_DATA_FLAG_VCPU_IN_HYP_CONTEXT 4#define KVM_HOST_DATA_FLAG_L1_VNCR_MAPPED 5#define KVM_HOST_DATA_FLAG_HAS_BRBE 6 +#define KVM_HOST_DATA_FLAG_HAS_MPAM 7 +#define KVM_HOST_DATA_FLAG_HAS_MPAM_HCR 8unsigned long flags;struct kvm_cpu_context host_ctxt;
arch/arm64/kvm/arm.c +12 -0
@@ -32,6 +32,7 @@#include <asm/mman.h> #include <asm/tlbflush.h> #include <asm/cacheflush.h> +#include <asm/cpu.h> #include <asm/cpufeature.h> #include <asm/virt.h> #include <asm/kvm_arm.h>
@@ -2496,9 +2497,20 @@ static void cpu_set_hyp_vector(void)static void cpu_hyp_init_context (void ) { +struct cpuinfo_arm64 *info =this_cpu_ptr (&cpu_data); +u64 pfr0 = info->reg_id_aa64pfr0; +u64 pfr1 = info->reg_id_aa64pfr1; +kvm_init_host_cpu_context (host_data_ptr (host_ctxt));kvm_init_host_debug_data (); +/* cpu_data has the overrides applied, as finalise_el2_state() does. */ +if (id_aa64pfr0_mpam (pfr0) ||id_aa64pfr1_mpamfrac (pfr1)) { +host_data_set_flag (HAS_MPAM ); +if (info->reg_mpamidr &MPAMIDR_EL1_HAS_HCR ) +host_data_set_flag (HAS_MPAM_HCR ); + } +if (!is_kernel_in_hyp_mode ())cpu_init_hyp_mode (); }
arch/arm64/kvm/hyp/include/hyp/switch.h +4 -4
@@ -298,11 +298,11 @@ static inline void __activate_traps_mpam(struct kvm_vcpu *vcpu)u64 clr = MPAM2_EL2_EnMPAMSM;u64 set =MPAM2_EL2_TRAPMPAM0EL1 |MPAM2_EL2_TRAPMPAM1EL1 ; -if (!system_supports_mpam ()) +if (!host_data_test_flag (HAS_MPAM ))return ;/* trap guest access to MPAMIDR_EL1 */ -if (system_supports_mpam_hcr ()) { +if (host_data_test_flag (HAS_MPAM_HCR )) {write_sysreg_s (MPAMHCR_EL2_TRAP_MPAMIDR_EL1 ,SYS_MPAMHCR_EL2 ); }else {/* From v1.1 TIDR can trap MPAMIDR, set it unconditionally */
@@ -317,12 +317,12 @@ static inline void __deactivate_traps_mpam(void)u64 clr =MPAM2_EL2_TRAPMPAM0EL1 |MPAM2_EL2_TRAPMPAM1EL1 |MPAM2_EL2_TIDR ;u64 set = MPAM2_EL2_EnMPAMSM; -if (!system_supports_mpam ()) +if (!host_data_test_flag (HAS_MPAM ))return ;sysreg_clear_set_s (SYS_MPAM2_EL2 , clr, set); -if (system_supports_mpam_hcr ()) +if (host_data_test_flag (HAS_MPAM_HCR ))write_sysreg_s (MPAMHCR_HOST_FLAGS ,SYS_MPAMHCR_EL2 ); }
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
Signature · 1 line
2.47.3