Commit 67faed4c authored by James Morse's avatar James Morse
Browse files

KVM: arm64: Force guest EL1 to use user-space's partid configuration



While we trap the guest's attempts to read/write the MPAM control
registers, the hardware continues to use them. Guest-EL0 uses KVM's
user-space's configuration, as the value is left in the register, and
guest-EL1 uses either the host kernel's configuration, or in the case of
VHE, the UNKNOWN reset value of MPAM1_EL1.

We want to force the guest-EL1 to use KVM's user-space's MPAM
configuration. On nVHE rely on MPAM0_EL1 and MPAM1_EL1 always being
programmed the same and on VHE copy MPAM0_EL1 into the guest's
MPAM1_EL1. There is no need to restore as this is out of context once TGE
is set.

Tested-by: default avatarGavin Shan <gshan@redhat.com>
Tested-by: default avatarShaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: default avatarPeter Newman <peternewman@google.com>
Tested-by: default avatarZeng Heng <zengheng4@huawei.com>
Tested-by: default avatarPunit Agrawal <punit.agrawal@oss.qualcomm.com>
Tested-by: default avatarJesse Chick <jessechick@os.amperecomputing.com>
Reviewed-by: default avatarZeng Heng <zengheng4@huawei.com>
Reviewed-by: default avatarShaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: default avatarGavin Shan <gshan@redhat.com>
Acked-by: default avatarMarc Zyngier <maz@kernel.org>
Co-developed-by: default avatarBen Horgan <ben.horgan@arm.com>
Signed-off-by: default avatarBen Horgan <ben.horgan@arm.com>
Signed-off-by: default avatarJames Morse <james.morse@arm.com>
parent 2cf9ca3f
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -183,6 +183,21 @@ void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt)
}
NOKPROBE_SYMBOL(sysreg_restore_guest_state_vhe);

/*
 * The _EL0 value was written by the host's context switch and belongs to the
 * VMM. Copy this into the guest's _EL1 register.
 */
static inline void __mpam_guest_load(void)
{
	u64 mask = MPAM0_EL1_PARTID_D | MPAM0_EL1_PARTID_I | MPAM0_EL1_PMG_D | MPAM0_EL1_PMG_I;

	if (system_supports_mpam()) {
		u64 val = (read_sysreg_s(SYS_MPAM0_EL1) & mask) | MPAM1_EL1_MPAMEN;

		write_sysreg_el1(val, SYS_MPAM1);
	}
}

/**
 * __vcpu_load_switch_sysregs - Load guest system registers to the physical CPU
 *
@@ -222,6 +237,7 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
	 */
	__sysreg32_restore_state(vcpu);
	__sysreg_restore_user_state(guest_ctxt);
	__mpam_guest_load();

	if (unlikely(is_hyp_ctxt(vcpu))) {
		__sysreg_restore_vel2_state(vcpu);