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 Signed-off-by: Neeraj Upadhyay Signed-off-by: Shivansh Dhiman --- 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