[PATCH v2 3/7] KVM: SVM: Save restore FRED_RSP0 for FRED supported guests

Shivansh Dhiman posted 7 patches 3 hours ago
[PATCH v2 3/7] KVM: SVM: Save restore FRED_RSP0 for FRED supported guests
Posted by Shivansh Dhiman 3 hours ago
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