Hardware does not save/restore FRED_RSP0 for Non-SEV-ES guests. Save it
in svm_prepare_host_switch() and restore it in svm_prepare_switch_to_guest()
so that the correct physical CPU state is updated.
Also, synchronize the current value of MSR_IA32_FRED_RSP0 in hardware to the
kernel's local cache. Note that the desired host's RSP0 will be set when the
CPU exits to userspace for servicing vCPU tasks.
Co-developed-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Signed-off-by: Shivansh Dhiman <shivansh.dhiman@amd.com>
---
Changes in v2:
- Moved FRED MSRs save/restore logic from svm_vcpu_enter_exit() to
svm_prepare_[host_switch/switch_to_guest]() to reduce some MSR accesses.
- While switching to host, added a safety check on guest_state_loaded.
---
arch/x86/kvm/svm/svm.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 5e85b2853ad6..3f7f8fb0dfac 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1383,12 +1383,34 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
sd->bp_spec_reduce_set = true;
msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT);
}
+
+ /*
+ * Hardware does not save/restore FRED_RSP0 for Non-SEV-ES guests.
+ */
+ if (!sev_es_guest(vcpu->kvm) && guest_cpu_cap_has(vcpu, X86_FEATURE_FRED))
+ wrmsrq(MSR_IA32_FRED_RSP0, svm->vmcb->save.fred_rsp0);
+
svm->guest_state_loaded = true;
}
static void svm_prepare_host_switch(struct kvm_vcpu *vcpu)
{
- to_svm(vcpu)->guest_state_loaded = false;
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ if (!svm->guest_state_loaded)
+ return;
+
+ /*
+ * Hardware does not save/restore FRED_RSP0 for Non-SEV-ES guests.
+ * Also, sync hardware MSR value to per-CPU cache. This helps in
+ * restoring Host RSP0 when exiting to userspace in fred_update_rsp0().
+ */
+ if (!sev_es_guest(vcpu->kvm) && guest_cpu_cap_has(vcpu, X86_FEATURE_FRED)) {
+ rdmsrq(MSR_IA32_FRED_RSP0, svm->vmcb->save.fred_rsp0);
+ fred_sync_rsp0(svm->vmcb->save.fred_rsp0);
+ }
+
+ svm->guest_state_loaded = false;
}
static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
--
2.43.0