mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
KVM: arm64: Load VPIDR_EL2 with the VM's MIDR_EL1 value
Userspace will soon be able to change the value of MIDR_EL1. Prepare by loading VPIDR_EL2 with the guest value for non-nested VMs. Since VPIDR_EL2 is set for any VM, get rid of the NV-specific cleanup of reloading the hardware value on vcpu_put(). And for nVHE, load the hardware value before switching to the host. Link: https://lore.kernel.org/r/20250225005401.679536-4-oliver.upton@linux.dev Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
This commit is contained in:
parent
b4043e7cb7
commit
d0d81e03e6
3 changed files with 20 additions and 20 deletions
|
@ -43,6 +43,11 @@ static inline u64 *ctxt_mdscr_el1(struct kvm_cpu_context *ctxt)
|
|||
return &ctxt_sys_reg(ctxt, MDSCR_EL1);
|
||||
}
|
||||
|
||||
static inline u64 ctxt_midr_el1(struct kvm_cpu_context *ctxt)
|
||||
{
|
||||
return read_cpuid_id();
|
||||
}
|
||||
|
||||
static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
|
||||
{
|
||||
*ctxt_mdscr_el1(ctxt) = read_sysreg(mdscr_el1);
|
||||
|
@ -168,8 +173,9 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt)
|
|||
}
|
||||
|
||||
static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,
|
||||
u64 mpidr)
|
||||
u64 midr, u64 mpidr)
|
||||
{
|
||||
write_sysreg(midr, vpidr_el2);
|
||||
write_sysreg(mpidr, vmpidr_el2);
|
||||
|
||||
if (has_vhe() ||
|
||||
|
|
|
@ -28,7 +28,9 @@ void __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt)
|
|||
|
||||
void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt)
|
||||
{
|
||||
__sysreg_restore_el1_state(ctxt, ctxt_sys_reg(ctxt, MPIDR_EL1));
|
||||
u64 midr = ctxt_midr_el1(ctxt);
|
||||
|
||||
__sysreg_restore_el1_state(ctxt, midr, ctxt_sys_reg(ctxt, MPIDR_EL1));
|
||||
__sysreg_restore_common_state(ctxt);
|
||||
__sysreg_restore_user_state(ctxt);
|
||||
__sysreg_restore_el2_return_state(ctxt);
|
||||
|
|
|
@ -87,11 +87,12 @@ static void __sysreg_restore_vel2_state(struct kvm_vcpu *vcpu)
|
|||
write_sysreg(__vcpu_sys_reg(vcpu, PAR_EL1), par_el1);
|
||||
write_sysreg(__vcpu_sys_reg(vcpu, TPIDR_EL1), tpidr_el1);
|
||||
|
||||
write_sysreg(__vcpu_sys_reg(vcpu, MPIDR_EL1), vmpidr_el2);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, MAIR_EL2), SYS_MAIR);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, VBAR_EL2), SYS_VBAR);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, CONTEXTIDR_EL2), SYS_CONTEXTIDR);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, AMAIR_EL2), SYS_AMAIR);
|
||||
write_sysreg(ctxt_midr_el1(&vcpu->arch.ctxt), vpidr_el2);
|
||||
write_sysreg(__vcpu_sys_reg(vcpu, MPIDR_EL1), vmpidr_el2);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, MAIR_EL2), SYS_MAIR);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, VBAR_EL2), SYS_VBAR);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, CONTEXTIDR_EL2), SYS_CONTEXTIDR);
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, AMAIR_EL2), SYS_AMAIR);
|
||||
|
||||
if (vcpu_el2_e2h_is_set(vcpu)) {
|
||||
/*
|
||||
|
@ -191,7 +192,7 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
|
|||
{
|
||||
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
|
||||
struct kvm_cpu_context *host_ctxt;
|
||||
u64 mpidr;
|
||||
u64 midr, mpidr;
|
||||
|
||||
host_ctxt = host_data_ptr(host_ctxt);
|
||||
__sysreg_save_user_state(host_ctxt);
|
||||
|
@ -220,23 +221,18 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
|
|||
__sysreg_restore_vel2_state(vcpu);
|
||||
} else {
|
||||
if (vcpu_has_nv(vcpu)) {
|
||||
/*
|
||||
* Use the guest hypervisor's VPIDR_EL2 when in a
|
||||
* nested state. The hardware value of MIDR_EL1 gets
|
||||
* restored on put.
|
||||
*/
|
||||
write_sysreg(ctxt_sys_reg(guest_ctxt, VPIDR_EL2), vpidr_el2);
|
||||
|
||||
/*
|
||||
* As we're restoring a nested guest, set the value
|
||||
* provided by the guest hypervisor.
|
||||
*/
|
||||
midr = ctxt_sys_reg(guest_ctxt, VPIDR_EL2);
|
||||
mpidr = ctxt_sys_reg(guest_ctxt, VMPIDR_EL2);
|
||||
} else {
|
||||
midr = ctxt_midr_el1(guest_ctxt);
|
||||
mpidr = ctxt_sys_reg(guest_ctxt, MPIDR_EL1);
|
||||
}
|
||||
|
||||
__sysreg_restore_el1_state(guest_ctxt, mpidr);
|
||||
__sysreg_restore_el1_state(guest_ctxt, midr, mpidr);
|
||||
}
|
||||
|
||||
vcpu_set_flag(vcpu, SYSREGS_ON_CPU);
|
||||
|
@ -271,9 +267,5 @@ void __vcpu_put_switch_sysregs(struct kvm_vcpu *vcpu)
|
|||
/* Restore host user state */
|
||||
__sysreg_restore_user_state(host_ctxt);
|
||||
|
||||
/* If leaving a nesting guest, restore MIDR_EL1 default view */
|
||||
if (vcpu_has_nv(vcpu))
|
||||
write_sysreg(read_cpuid_id(), vpidr_el2);
|
||||
|
||||
vcpu_clear_flag(vcpu, SYSREGS_ON_CPU);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue