From: Sean Christopherson <seanjc@xxxxxxxxxx> Drop nested support for CPUs without NRIPS, as requiring NRIPS simplifies a handful of paths in KVM. NRIPS was introduced in 2009, i.e. every AMD-based CPU released in the last decade should support NRIPS. Suggested-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> Not-signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> [MSS: Just drop nested support for these CPUs instead of SVM support in general] Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@xxxxxxxxxx> --- arch/x86/kvm/svm/nested.c | 14 +++++--------- arch/x86/kvm/svm/svm.c | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 2cf92c12706a..e5c05e3427ae 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -691,14 +691,13 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, /* * next_rip is consumed on VMRUN as the return address pushed on the * stack for injected soft exceptions/interrupts. If nrips is exposed - * to L1, take it verbatim from vmcb12. If nrips is supported in - * hardware but not exposed to L1, stuff the actual L2 RIP to emulate - * what a nrips=0 CPU would do (L1 is responsible for advancing RIP - * prior to injecting the event). + * to L1, take it verbatim from vmcb12. If nrips is not exposed to L1, + * stuff the actual L2 RIP to emulate what an nrips=0 CPU would do (L1 + * is responsible for advancing RIP prior to injecting the event). */ if (svm->nrips_enabled) vmcb02->control.next_rip = svm->nested.ctl.next_rip; - else if (boot_cpu_has(X86_FEATURE_NRIPS)) + else vmcb02->control.next_rip = vmcb12_rip; svm->nmi_l1_to_l2 = is_evtinj_nmi(vmcb02->control.event_inj); @@ -706,10 +705,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, svm->soft_int_injected = true; svm->soft_int_csbase = svm->vmcb->save.cs.base; svm->soft_int_old_rip = vmcb12_rip; - if (svm->nrips_enabled) - svm->soft_int_next_rip = svm->nested.ctl.next_rip; - else - svm->soft_int_next_rip = vmcb12_rip; + svm->soft_int_next_rip = vmcb02->control.next_rip; } vmcb02->control.virt_ext = vmcb01->control.virt_ext & diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 88eacbbe9348..dc980fa0daa8 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4330,9 +4330,7 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, break; } - /* TODO: Advertise NRIPS to guest hypervisor unconditionally */ - if (static_cpu_has(X86_FEATURE_NRIPS)) - vmcb->control.next_rip = info->next_rip; + vmcb->control.next_rip = info->next_rip; vmcb->control.exit_code = icpt_info.exit_code; vmexit = nested_svm_exit_handled(svm); @@ -4961,6 +4959,16 @@ static __init int svm_hardware_setup(void) pause_filter_thresh = 0; } + if (nrips) { + if (!boot_cpu_has(X86_FEATURE_NRIPS)) + nrips = false; + } + + if (!nrips && nested) { + pr_notice("kvm: Nested Virtualization requires NRIPS (NextRIP Save)\n"); + nested = false; + } + if (nested) { printk(KERN_INFO "kvm: Nested Virtualization enabled\n"); kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE); @@ -4995,11 +5003,6 @@ static __init int svm_hardware_setup(void) goto err; } - if (nrips) { - if (!boot_cpu_has(X86_FEATURE_NRIPS)) - nrips = false; - } - enable_apicv = avic = avic && npt_enabled && (boot_cpu_has(X86_FEATURE_AVIC) || force_avic); if (enable_apicv) {