From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56FBBC433F5 for ; Sat, 23 Apr 2022 02:14:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231927AbiDWCRZ (ORCPT ); Fri, 22 Apr 2022 22:17:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231812AbiDWCRM (ORCPT ); Fri, 22 Apr 2022 22:17:12 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24426218ACB for ; Fri, 22 Apr 2022 19:14:15 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id y2-20020a62ce02000000b0050ac8d73c8dso6456546pfg.8 for ; Fri, 22 Apr 2022 19:14:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=WvYNbXCHSub5KkMALa85GDZKJJrB7zWtW+x8WTGBVkU=; b=IaXui+tsgGzP2B1ZAiifgEXK1LwLvFAo7dQbWGK1/kUsopw7JzrPTq/XaY/sraoP+9 Bvn7wl6jamlohzVvEulLZAh99z0PPVeZyAmPTK3Ivg/X2gXRg/qP2JdItQ4jtoukSOMn PduoYkBt8LCyWj05UZPWBhYr+jq5mijbSJ57KHgKDkUdWGCL9riUs3Pi+jiVVISUOLod R8PYEu4WrzKdjlEVZWPLKkuNbSlRxb71Jy7qVsuNf/OUUiYVn1RkHIl0QGsT/21l2A0M eNc+tB8rH2+1AsxUKyCq0GYaokxW9Dht6pkFLupuD6eRN92BEYBs2hM7/ZQz4CBFmIK3 sVYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=WvYNbXCHSub5KkMALa85GDZKJJrB7zWtW+x8WTGBVkU=; b=Rzya4KuhwrxmU6b4Yh3g5NEn6D1lojpRmlhO7FX3ji/eQwEjHZscE8wwT5BHUM8TZ9 1lbSQhWHBI5wS4BvKdPYDv08BTmbAr08YH1vyAStpwRfYQBpCcpw8MamUp0XxIE1B+qj 4vSQrKlOv1tGrwxuaI/5lJkZH/B83TfHeNo851z4ArrViehrfGipjjE4nOO8Vwhw/YEQ +iK5gyYZr2HSd06prWh1k97T4uKx6MI0J+PC7oRlRm0coC3V8/ISTnBpQ4wIBV56X3LY sidFzI1nTRTcmiEiLct/EEppJqigx2OeaU5ZhYxS2Cni6lbSBzt+xtyHwMUsO047McaX HB2w== X-Gm-Message-State: AOAM532nBufvOcQDudMKTfxHoVk807JK7TDcV9djQ9gVCn3/Gm1i54eM AveePllkghs8yBCvqPwiu9KuQqg7bkA= X-Google-Smtp-Source: ABdhPJzwtxGab+SWqq/nXEKXlT078e4hr6toJXE1iOhNPI6d699PB1AKdLAEBkjzPn0YhMl4kVkzs5NYF7Y= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:902:cf05:b0:156:2aa:6e13 with SMTP id i5-20020a170902cf0500b0015602aa6e13mr7472391plg.137.1650680054612; Fri, 22 Apr 2022 19:14:14 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:01 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-2-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 01/11] KVM: nSVM: Sync next_rip field from vmcb12 to vmcb02 From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej S. Szmigiero The next_rip field of a VMCB is *not* an output-only field for a VMRUN. This field value (instead of the saved guest RIP) in used by the CPU for the return address pushed on stack when injecting a software interrupt or INT3 or INTO exception. Make sure this field gets synced from vmcb12 to vmcb02 when entering L2 or loading a nested state and NRIPS is exposed to L1. If NRIPS is supported in hardware but not exposed to L1 (nrips=3D0 or hidden by userspace), stuff vmcb02's next_rip from the new L2 RIP to emulate a !NRIPS CPU (which saves RIP on the stack as-is). Reviewed-by: Maxim Levitsky Signed-off-by: Maciej S. Szmigiero Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/nested.c | 22 +++++++++++++++++++--- arch/x86/kvm/svm/svm.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index bed5e1692cef..461c5f247801 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -371,6 +371,7 @@ void __nested_copy_vmcb_control_to_cache(struct kvm_vcp= u *vcpu, to->nested_ctl =3D from->nested_ctl; to->event_inj =3D from->event_inj; to->event_inj_err =3D from->event_inj_err; + to->next_rip =3D from->next_rip; to->nested_cr3 =3D from->nested_cr3; to->virt_ext =3D from->virt_ext; to->pause_filter_count =3D from->pause_filter_count; @@ -608,7 +609,8 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm = *svm, struct vmcb *vmcb12 } } =20 -static void nested_vmcb02_prepare_control(struct vcpu_svm *svm) +static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, + unsigned long vmcb12_rip) { u32 int_ctl_vmcb01_bits =3D V_INTR_MASKING_MASK; u32 int_ctl_vmcb12_bits =3D V_TPR_MASK | V_IRQ_INJECTION_BITS_MASK; @@ -662,6 +664,19 @@ static void nested_vmcb02_prepare_control(struct vcpu_= svm *svm) vmcb02->control.event_inj =3D svm->nested.ctl.event_inj; vmcb02->control.event_inj_err =3D svm->nested.ctl.event_inj_err; =20 + /* + * 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=3D0 CPU would do (L1 is responsible for advancing RIP + * prior to injecting the event). + */ + if (svm->nrips_enabled) + vmcb02->control.next_rip =3D svm->nested.ctl.next_rip; + else if (boot_cpu_has(X86_FEATURE_NRIPS)) + vmcb02->control.next_rip =3D vmcb12_rip; + vmcb02->control.virt_ext =3D vmcb01->control.virt_ext & LBR_CTL_ENABLE_MASK; if (svm->lbrv_enabled) @@ -745,7 +760,7 @@ int enter_svm_guest_mode(struct kvm_vcpu *vcpu, u64 vmc= b12_gpa, nested_svm_copy_common_state(svm->vmcb01.ptr, svm->nested.vmcb02.ptr); =20 svm_switch_vmcb(svm, &svm->nested.vmcb02); - nested_vmcb02_prepare_control(svm); + nested_vmcb02_prepare_control(svm, vmcb12->save.rip); nested_vmcb02_prepare_save(svm, vmcb12); =20 ret =3D nested_svm_load_cr3(&svm->vcpu, svm->nested.save.cr3, @@ -1418,6 +1433,7 @@ static void nested_copy_vmcb_cache_to_control(struct = vmcb_control_area *dst, dst->nested_ctl =3D from->nested_ctl; dst->event_inj =3D from->event_inj; dst->event_inj_err =3D from->event_inj_err; + dst->next_rip =3D from->next_rip; dst->nested_cr3 =3D from->nested_cr3; dst->virt_ext =3D from->virt_ext; dst->pause_filter_count =3D from->pause_filter_count; @@ -1602,7 +1618,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, nested_copy_vmcb_control_to_cache(svm, ctl); =20 svm_switch_vmcb(svm, &svm->nested.vmcb02); - nested_vmcb02_prepare_control(svm); + nested_vmcb02_prepare_control(svm, save->rip); =20 /* * While the nested guest CR3 is already checked and set by diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 32220a1b0ea2..7d97e4d18c8b 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -139,6 +139,7 @@ struct vmcb_ctrl_area_cached { u64 nested_ctl; u32 event_inj; u32 event_inj_err; + u64 next_rip; u64 nested_cr3; u64 virt_ext; u32 clean; --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35FEAC433EF for ; Sat, 23 Apr 2022 02:14:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231892AbiDWCRS (ORCPT ); Fri, 22 Apr 2022 22:17:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49542 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231817AbiDWCRM (ORCPT ); Fri, 22 Apr 2022 22:17:12 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A5DBE21AF41 for ; Fri, 22 Apr 2022 19:14:16 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id x2-20020a63aa42000000b003aafe948eeeso81445pgo.0 for ; Fri, 22 Apr 2022 19:14:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=4V4fYOOx19aLgtO3bZkAZcLhXo54aE7TN/hmI1hVjK0=; b=fxN5sEadn4wpsVuyRDEN1xnjtYATl9Jnlz1X/u04pUWGdAY7yRwdXgWYouii6v/Ynh 0L0GDMLYsS7xNqWEudFlq/aNhrB4XVYfEICu7PnqkeRyXItjj/rELzxkxwvDiC4EuD10 SkQcdHOLprj8bmaFKELTi7uxOvKfbe+48AJ/ux7HSl2f7pvIIH4YxfhT98DB0t2+jRVU EH/CzjKSbZQwiCQzcSHbYUlGb8QpHPBr/JCLqTn8O4qLIVCKMYm/O3o462bqzh5H8gSJ boAtGxiSCbxfcGn0d9Zf2OWpNZR/qCbo2eWlUQNgZLYUH8yuOHOZCecEFgViDq6nI5Fh vPgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=4V4fYOOx19aLgtO3bZkAZcLhXo54aE7TN/hmI1hVjK0=; b=jdF5cZ7AnVc42lLli3OS+eH2aZ34Ga0C7WOOoypDqi6Nn/gWogBeuyg5iofFtWRqu5 j/iV7pyMuWiRI2r9DbbE/B2HLsnICGEiYQSfmPt2tAbE8W2EkXQvGPWOynJm4CuZ72u/ v0KsC0Cy+XHapb/fj4loyry+5JscolZ7bKTSZaW6Ey6ZcTMLxtxq7ePsAW1RFaVbnA2F roJfrQGecau6LpbolI2EiFc6p+jiqRptklqeOA1c7PDTI/2MODyH2y2FPLEtujSq1EAg G7M5n03PaO2yBEWZB9eRbBQv3obwPwjS0qj6JRibVbA2us7h/MLdVSjA94o4P5IRe6XV OuIw== X-Gm-Message-State: AOAM530WtbhaKSpucLS0nb2bkYCqiJfBJUBPIkKsPQsL3ppdeGN5vmho wSxt4oOle/nuznJtaSut1FWHLkxUYWg= X-Google-Smtp-Source: ABdhPJzQ/xbiIP/rNdWA1KVR1iUlC6bHzhLcVP7dnu4Hsyaxr1/n90CtPDb8g5YEeO16z5rt0uFKMql6qFg= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90a:8a92:b0:1d7:3cca:69d8 with SMTP id x18-20020a17090a8a9200b001d73cca69d8mr10179857pjn.61.1650680056056; Fri, 22 Apr 2022 19:14:16 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:02 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-3-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 02/11] KVM: SVM: Don't BUG if userspace injects a soft interrupt with GIF=0 From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej S. Szmigiero Don't BUG/WARN on interrupt injection due to GIF being cleared if the injected event is a soft interrupt, which are not actually IRQs and thus not subject to IRQ blocking conditions. KVM doesn't currently use event injection to handle incomplete soft interrupts, but it's trivial for userspace to force the situation via KVM_SET_VCPU_EVENTS. Opportunistically downgrade the BUG_ON() to WARN_ON(), there's no need to bring down the whole host just because there might be some issue with respect to guest GIF handling in KVM, or as evidenced here, an egregious oversight with respect to KVM's uAPI. kernel BUG at arch/x86/kvm/svm/svm.c:3386! invalid opcode: 0000 [#1] SMP CPU: 15 PID: 926 Comm: smm_test Not tainted 5.17.0-rc3+ #264 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:svm_inject_irq+0xab/0xb0 [kvm_amd] Code: <0f> 0b 0f 1f 00 0f 1f 44 00 00 80 3d ac b3 01 00 00 55 48 89 f5 53 RSP: 0018:ffffc90000b37d88 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff88810a234ac0 RCX: 0000000000000006 RDX: 0000000000000000 RSI: ffffc90000b37df7 RDI: ffff88810a234ac0 RBP: ffffc90000b37df7 R08: ffff88810a1fa410 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: ffff888109571000 R14: ffff88810a234ac0 R15: 0000000000000000 FS: 0000000001821380(0000) GS:ffff88846fdc0000(0000) knlGS:0000000000000= 000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f74fc550008 CR3: 000000010a6fe000 CR4: 0000000000350ea0 Call Trace: inject_pending_event+0x2f7/0x4c0 [kvm] kvm_arch_vcpu_ioctl_run+0x791/0x17a0 [kvm] kvm_vcpu_ioctl+0x26d/0x650 [kvm] __x64_sys_ioctl+0x82/0xb0 do_syscall_64+0x3b/0xc0 entry_SYSCALL_64_after_hwframe+0x44/0xae Fixes: 219b65dcf6c0 ("KVM: SVM: Improve nested interrupt injection") Cc: stable@vger.kernel.org Signed-off-by: Maciej S. Szmigiero Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 75b4f3ac8b1a..151fba0b405f 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3384,7 +3384,7 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm =3D to_svm(vcpu); =20 - BUG_ON(!(gif_set(svm))); + WARN_ON(!vcpu->arch.interrupt.soft && !gif_set(svm)); =20 trace_kvm_inj_virq(vcpu->arch.interrupt.nr); ++vcpu->stat.irq_injections; --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B179C433F5 for ; Sat, 23 Apr 2022 02:15:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232045AbiDWCR3 (ORCPT ); Fri, 22 Apr 2022 22:17:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231824AbiDWCRN (ORCPT ); Fri, 22 Apr 2022 22:17:13 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F82021AF56 for ; Fri, 22 Apr 2022 19:14:18 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id t3-20020a656083000000b0039cf337edd6so5949155pgu.18 for ; Fri, 22 Apr 2022 19:14:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=Fx01//NwlDcIPy9Gd6hi0TEGXUFkV39UbcfuM1U0Pac=; b=RaOWoAaVoZE+trOJkineMnnNNBOLtCqhTtXswHg7iJAUost1QTYPP/CRID7dK/kfea kfENExlBKBkOd92k+WRP/mLUzPCTxokKeFbFbUtPCPVoMy1RqUFSQrzQkGRLo3J2aG5E azQgnQ29v4QH/49ZyUK0pr6hLnHIWFZsllXr6+g8bzANSe63Fy2Ca5t2Qpx3ZMAYeNZF 7q9ue2c8E1jjCo59N+yf/7agfh0UCDbeMwSIDPG9oBRAFg13jfBFnIGUdVmVvDjXwTfN 1ynW96+WZnulm/GTSb5L/bQg2V65orFWW5oRqJYuj74/4jXOdOAy2GDl4+x1wqdI7kr9 RMaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=Fx01//NwlDcIPy9Gd6hi0TEGXUFkV39UbcfuM1U0Pac=; b=Qa3VHxKRvM0v7G3+T49AFQwVfVM/obHa2JQetRFqAnzD6bP3rMcbhUuxZFwvHMtmnt cA24D7A1y/u/1g6M7dcTwm580JocU/ME2ypF7k3iG3sm5opl6eSSkloFCHBn4J7aQwIe j0/qp6cfF3wCK/Zgoaz84gZ04j5ACrUpBwscz6n+a+9U45INkDp5W8sBmKY1TzGEQbey CkjF75LScOKUXeKbz+fJtqD3AzEOeRfr38oRRubLCH7KcAbQzEtau3yzZJNdqD/w0byt jIlZpcHUisEJ/2VnnvaKrtqHHnKNSJLqTGWeo/dIr6JkUwtS/E1uN+WVW9+1sypacoGN TFQw== X-Gm-Message-State: AOAM533eVRSgTLDoIcBqqyOJP9J2NiN7PGDgy5BYAcf7XMNMVDkyEZ2+ hV9H5tbB0LIE8hJ9eJ29089PN8YE81U= X-Google-Smtp-Source: ABdhPJxHrKcNAcpzYMl3xza9zupR0/MNb4GVV4iPrHFcAIG7ie4uua4bRBngh7F9T5WF9kjaB33yBo8dZwg= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90a:384d:b0:1d2:97de:eb8c with SMTP id l13-20020a17090a384d00b001d297deeb8cmr19587685pjf.208.1650680057791; Fri, 22 Apr 2022 19:14:17 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:03 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-4-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 03/11] KVM: SVM: Unwind "speculative" RIP advancement if INTn injection "fails" From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Unwind the RIP advancement done by svm_queue_exception() when injecting an INT3 ultimately "fails" due to the CPU encountering a VM-Exit while vectoring the injected event, even if the exception reported by the CPU isn't the same event that was injected. If vectoring INT3 encounters an exception, e.g. #NP, and vectoring the #NP encounters an intercepted exception, e.g. #PF when KVM is using shadow paging, then the #NP will be reported as the event that was in-progress. Note, this is still imperfect, as it will get a false positive if the INT3 is cleanly injected, no VM-Exit occurs before the IRET from the INT3 handler in the guest, the instruction following the INT3 generates an exception (directly or indirectly), _and_ vectoring that exception encounters an exception that is intercepted by KVM. The false positives could theoretically be solved by further analyzing the vectoring event, e.g. by comparing the error code against the expected error code were an exception to occur when vectoring the original injected exception, but SVM without NRIPS is a complete disaster, trying to make it 100% correct is a waste of time. Reviewed-by: Maxim Levitsky Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3") Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/svm.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 151fba0b405f..82175a13c668 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3700,6 +3700,18 @@ static void svm_complete_interrupts(struct kvm_vcpu = *vcpu) vector =3D exitintinfo & SVM_EXITINTINFO_VEC_MASK; type =3D exitintinfo & SVM_EXITINTINFO_TYPE_MASK; =20 + /* + * If NextRIP isn't enabled, KVM must manually advance RIP prior to + * injecting the soft exception/interrupt. That advancement needs to + * be unwound if vectoring didn't complete. Note, the _new_ event may + * not be the injected event, e.g. if KVM injected an INTn, the INTn + * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will + * be the reported vectored event, but RIP still needs to be unwound. + */ + if (int3_injected && type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT && + kvm_is_linear_rip(vcpu, svm->int3_rip)) + kvm_rip_write(vcpu, kvm_rip_read(vcpu) - int3_injected); + switch (type) { case SVM_EXITINTINFO_TYPE_NMI: vcpu->arch.nmi_injected =3D true; @@ -3713,16 +3725,11 @@ static void svm_complete_interrupts(struct kvm_vcpu= *vcpu) =20 /* * In case of software exceptions, do not reinject the vector, - * but re-execute the instruction instead. Rewind RIP first - * if we emulated INT3 before. + * but re-execute the instruction instead. */ - if (kvm_exception_is_soft(vector)) { - if (vector =3D=3D BP_VECTOR && int3_injected && - kvm_is_linear_rip(vcpu, svm->int3_rip)) - kvm_rip_write(vcpu, - kvm_rip_read(vcpu) - int3_injected); + if (kvm_exception_is_soft(vector)) break; - } + if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { u32 err =3D svm->vmcb->control.exit_int_info_err; kvm_requeue_exception_e(vcpu, vector, err); --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77B7AC433EF for ; Sat, 23 Apr 2022 02:14:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232065AbiDWCRc (ORCPT ); Fri, 22 Apr 2022 22:17:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231845AbiDWCRP (ORCPT ); Fri, 22 Apr 2022 22:17:15 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1AE9321B9A1 for ; Fri, 22 Apr 2022 19:14:20 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id n4-20020a170902f60400b00158d1f2d442so5713691plg.18 for ; Fri, 22 Apr 2022 19:14:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=PyT8c4uOpMREZ0ICFl/zs2j7McPJGYK9LkWRLQoEbds=; b=fSMxFj4x5SruHcAurF3Hkt5R2t78474Ci8gOTMRUVZEAZUv5QFEaSVW5YASiuKZmHL 458qRAV/dMQ1NTePpDszaMhgo3LMxvB9LsWHc2CbUusE/FTnw4mDV9crM7K5XeiIAo5K wjiF5ulN5I+Bf02AGazFTA4Ga/f0yuxapmWY9kVSagfsyn/Fg5rh5oJkg4uCwlp11bL7 sZ95T/wkiLftfMbUY8EgYvDUveVfIGYnAKRt9/HDuArfmwub/1xO2Z/WKxtqzAaW9fi9 YvckJBOmqnN38Yi/smWuAAzODcH80h/dt+XyNGN5/cuVrxGcltyBDotH/rC0ScFf878V Eibg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=PyT8c4uOpMREZ0ICFl/zs2j7McPJGYK9LkWRLQoEbds=; b=3weteGGrv5jzJtHFzD9L3HfelKcgn7LbGIcljJYU1RrLTzi49udmfb3Fv0SZU0UxvT XqhYGGBwfBmj+xc2NcR1D7jSj/MIEptwZFnpaktvXp91VO0QdSzmMUyiGWepfQr8E+Zr cD96+KfAL5vUfqeULImdQP8m5jNMX2zdPFcG/JIK+e4KkpKYvvVvqLNsRjkmwps8ROwX PH/WaERqLyAkofXZ2Kmo2eqvGStS786KjuWvnGp3hgW/bEeEPtkruLufpb+vWf2iy9a9 tNLdy1P1Iwk79OBDp2BL87vLqBHKaPlfUbx0arrTeKle43Z7XXrIFD3iM5Lt2t0BP2zT P6nQ== X-Gm-Message-State: AOAM5304luuuddx+ffzvzdrMFIOb0j/tnWSY1ZLFOL83KLwHEDWQp8F6 qReKK7XUI1RsRWKUf9nSR6FLyJjrrKY= X-Google-Smtp-Source: ABdhPJw5hXpv/3W1ZRCBDFE197HCr7uSU9IoBaxVUiWUd5dzGROUXkWDoEtWISqGRD7YhNCxphH44X2pfZQ= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a62:ed0e:0:b0:4fa:11ed:2ad1 with SMTP id u14-20020a62ed0e000000b004fa11ed2ad1mr8110804pfh.34.1650680059539; Fri, 22 Apr 2022 19:14:19 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:04 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-5-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 04/11] KVM: SVM: Stuff next_rip on emulated INT3 injection if NRIPS is supported From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If NRIPS is supported in hardware but disabled in KVM, set next_rip to the next RIP when advancing RIP as part of emulating INT3 injection. There is no flag to tell the CPU that KVM isn't using next_rip, and so leaving next_rip is left as is will result in the CPU pushing garbage onto the stack when vectoring the injected event. Reviewed-by: Maxim Levitsky Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3") Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/svm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 82175a13c668..14bc4e87437b 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -392,6 +392,10 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu) */ (void)svm_skip_emulated_instruction(vcpu); rip =3D kvm_rip_read(vcpu); + + if (boot_cpu_has(X86_FEATURE_NRIPS)) + svm->vmcb->control.next_rip =3D rip; + svm->int3_rip =3D rip + svm->vmcb->save.cs.base; svm->int3_injected =3D rip - old_rip; } @@ -3703,7 +3707,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *= vcpu) /* * If NextRIP isn't enabled, KVM must manually advance RIP prior to * injecting the soft exception/interrupt. That advancement needs to - * be unwound if vectoring didn't complete. Note, the _new_ event may + * be unwound if vectoring didn't complete. Note, the new event may * not be the injected event, e.g. if KVM injected an INTn, the INTn * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will * be the reported vectored event, but RIP still needs to be unwound. --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1742AC433FE for ; Sat, 23 Apr 2022 02:14:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231995AbiDWCRi (ORCPT ); Fri, 22 Apr 2022 22:17:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231867AbiDWCRR (ORCPT ); Fri, 22 Apr 2022 22:17:17 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2F5821BACC for ; Fri, 22 Apr 2022 19:14:21 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id i16-20020a170902cf1000b001540b6a09e3so5739313plg.0 for ; Fri, 22 Apr 2022 19:14:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=ba8LIU8FH+mXjQjFWa7QXl2T6SrpEezShnOHFtbNAJA=; b=YKen6L2/XEhVKCOOOx5vhV0fOWiOqk0CDUX52xswEpx649D60RMpaAhHVUYl0kw7z+ E9+jCiEaOKAaB4emBXyvmDwk+Hy0kk2RF1Rjflk+m8MtoXFz/Qov4muZlOiaG/rZZWK0 d9DByEAq4C0xJgBVT7bZWOEfNz/ToHrj2PsS6GmfUJmQod4vOJPIEnsRgEIASlING3kU i41G0I1tsZP1mIaCStwASMdYG4HPZBvIJCWxod85jhyXGv2r4fV1LhokowXx4VVoHNhd qKmCWIRRRvWv9WApLbZ3iM3EneCAktASjjNLKffOe7boeO7TCWOQ0WQ8xlO9+8K+eEa+ jgfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=ba8LIU8FH+mXjQjFWa7QXl2T6SrpEezShnOHFtbNAJA=; b=VqHavRwTSdFsN+RjQlgggL+P9seHO48FOcheQvkA8qgqr37M97Imka0jY2mcZq8nUH 1Rg9XU0ngSlbH6RYYqNQ4JUDfURJCb8mkz2wyhMlrUE1HdCPLe0Hgs0MUt2fcyMn7j69 L/lMUGdEGcXR767+0maB8adsf2m8bGqAhXtMwg/dRRm0S46skNSEqCF8sr9l/dShKDVz r6eFDFIxbR2vQXzL5aJbOFiMFK6YGVx43epelqPY2jFzB2/nFFmHzbjVUh0ApTVCDTe7 zdUw2ZBXGwKxkeEezF+XMDLuMv7SUKoriatRmtQm4Q2uz7j4uhJ2aS3Vz7e76v18JAYP KtIQ== X-Gm-Message-State: AOAM531ygrDh4a+WEPs9FERSUk6FG4YcvSjPnDYUFwOxz1ULX8f7pIvu xQL9cI1uCcVnwVTMzMD9ENTql3e/v5M= X-Google-Smtp-Source: ABdhPJzA/oVWsF1ZEyGrfuBSthWLekPBZle3O5WeFlKvV6N7TOCOTc7p6BaFAWIeVnhPUhf6yFVPX6cw3r4= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a62:170b:0:b0:50a:6901:b633 with SMTP id 11-20020a62170b000000b0050a6901b633mr8022175pfx.34.1650680061359; Fri, 22 Apr 2022 19:14:21 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:05 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-6-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 05/11] KVM: SVM: Re-inject INT3/INTO instead of retrying the instruction From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Re-inject INT3/INTO instead of retrying the instruction if the CPU encountered an intercepted exception while vectoring the software exception, e.g. if vectoring INT3 encounters a #PF and KVM is using shadow paging. Retrying the instruction is architecturally wrong, e.g. will result in a spurious #DB if there's a code breakpoint on the INT3/O, and lack of re-injection also breaks nested virtualization, e.g. if L1 injects a software exception and vectoring the injected exception encounters an exception that is intercepted by L0 but not L1. Due to, ahem, deficiencies in the SVM architecture, acquiring the next RIP may require flowing through the emulator even if NRIPS is supported, as the CPU clears next_rip if the VM-Exit is due to an exception other than "exceptions caused by the INT3, INTO, and BOUND instructions". To deal with this, "skip" the instruction to calculate next_rip (if it's not already known), and then unwind the RIP write and any side effects (RFLAGS updates). Save the computed next_rip and use it to re-stuff next_rip if injection doesn't complete. This allows KVM to do the right thing if next_rip was known prior to injection, e.g. if L1 injects a soft event into L2, and there is no backing INTn instruction, e.g. if L1 is injecting an arbitrary event. Note, it's impossible to guarantee architectural correctness given SVM's architectural flaws. E.g. if the guest executes INTn (no KVM injection), an exit occurs while vectoring the INTn, and the guest modifies the code stream while the exit is being handled, KVM will compute the incorrect next_rip due to "skipping" the wrong instruction. A future enhancement to make this less awful would be for KVM to detect that the decoded instruction is not the correct INTn and drop the to-be-injected soft event (retrying is a lesser evil compared to shoving the wrong RIP on the exception stack). Reported-by: Maciej S. Szmigiero Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/nested.c | 28 +++++++- arch/x86/kvm/svm/svm.c | 140 +++++++++++++++++++++++++++----------- arch/x86/kvm/svm/svm.h | 6 +- 3 files changed, 130 insertions(+), 44 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 461c5f247801..0163238aa198 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -609,6 +609,21 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm= *svm, struct vmcb *vmcb12 } } =20 +static inline bool is_evtinj_soft(u32 evtinj) +{ + u32 type =3D evtinj & SVM_EVTINJ_TYPE_MASK; + u8 vector =3D evtinj & SVM_EVTINJ_VEC_MASK; + + if (!(evtinj & SVM_EVTINJ_VALID)) + return false; + + /* + * Intentionally return false for SOFT events, SVM doesn't yet support + * re-injecting soft interrupts. + */ + return type =3D=3D SVM_EVTINJ_TYPE_EXEPT && kvm_exception_is_soft(vector); +} + static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, unsigned long vmcb12_rip) { @@ -677,6 +692,16 @@ static void nested_vmcb02_prepare_control(struct vcpu_= svm *svm, else if (boot_cpu_has(X86_FEATURE_NRIPS)) vmcb02->control.next_rip =3D vmcb12_rip; =20 + if (is_evtinj_soft(vmcb02->control.event_inj)) { + svm->soft_int_injected =3D true; + svm->soft_int_csbase =3D svm->vmcb->save.cs.base; + svm->soft_int_old_rip =3D vmcb12_rip; + if (svm->nrips_enabled) + svm->soft_int_next_rip =3D svm->nested.ctl.next_rip; + else + svm->soft_int_next_rip =3D vmcb12_rip; + } + vmcb02->control.virt_ext =3D vmcb01->control.virt_ext & LBR_CTL_ENABLE_MASK; if (svm->lbrv_enabled) @@ -849,6 +874,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) =20 out_exit_err: svm->nested.nested_run_pending =3D 0; + svm->soft_int_injected =3D false; =20 svm->vmcb->control.exit_code =3D SVM_EXIT_ERR; svm->vmcb->control.exit_code_hi =3D 0; @@ -1618,7 +1644,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, nested_copy_vmcb_control_to_cache(svm, ctl); =20 svm_switch_vmcb(svm, &svm->nested.vmcb02); - nested_vmcb02_prepare_control(svm, save->rip); + nested_vmcb02_prepare_control(svm, svm->vmcb->save.rip); =20 /* * While the nested guest CR3 is already checked and set by diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 14bc4e87437b..8321f9ce5e35 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -342,9 +342,11 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *= vcpu, int mask) =20 } =20 -static int svm_skip_emulated_instruction(struct kvm_vcpu *vcpu) +static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, + bool commit_side_effects) { struct vcpu_svm *svm =3D to_svm(vcpu); + unsigned long old_rflags; =20 /* * SEV-ES does not expose the next RIP. The RIP update is controlled by @@ -359,18 +361,75 @@ static int svm_skip_emulated_instruction(struct kvm_v= cpu *vcpu) } =20 if (!svm->next_rip) { + if (unlikely(!commit_side_effects)) + old_rflags =3D svm->vmcb->save.rflags; + if (!kvm_emulate_instruction(vcpu, EMULTYPE_SKIP)) return 0; + + if (unlikely(!commit_side_effects)) + svm->vmcb->save.rflags =3D old_rflags; } else { kvm_rip_write(vcpu, svm->next_rip); } =20 done: - svm_set_interrupt_shadow(vcpu, 0); + if (likely(commit_side_effects)) + svm_set_interrupt_shadow(vcpu, 0); =20 return 1; } =20 +static int svm_skip_emulated_instruction(struct kvm_vcpu *vcpu) +{ + return __svm_skip_emulated_instruction(vcpu, true); +} + +static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu) +{ + unsigned long rip, old_rip =3D kvm_rip_read(vcpu); + struct vcpu_svm *svm =3D to_svm(vcpu); + + /* + * Due to architectural shortcomings, the CPU doesn't always provide + * NextRIP, e.g. if KVM intercepted an exception that occurred while + * the CPU was vectoring an INTO/INT3 in the guest. Temporarily skip + * the instruction even if NextRIP is supported to acquire the next + * RIP so that it can be shoved into the NextRIP field, otherwise + * hardware will fail to advance guest RIP during event injection. + * Drop the exception/interrupt if emulation fails and effectively + * retry the instruction, it's the least awful option. If NRIPS is + * in use, the skip must not commit any side effects such as clearing + * the interrupt shadow or RFLAGS.RF. + */ + if (!__svm_skip_emulated_instruction(vcpu, !nrips)) + return -EIO; + + rip =3D kvm_rip_read(vcpu); + + /* + * Save the injection information, even when using next_rip, as the + * VMCB's next_rip will be lost (cleared on VM-Exit) if the injection + * doesn't complete due to a VM-Exit occurring while the CPU is + * vectoring the event. Decoding the instruction isn't guaranteed to + * work as there may be no backing instruction, e.g. if the event is + * being injected by L1 for L2, or if the guest is patching INT3 into + * a different instruction. + */ + svm->soft_int_injected =3D true; + svm->soft_int_csbase =3D svm->vmcb->save.cs.base; + svm->soft_int_old_rip =3D old_rip; + svm->soft_int_next_rip =3D rip; + + if (nrips) + kvm_rip_write(vcpu, old_rip); + + if (static_cpu_has(X86_FEATURE_NRIPS)) + svm->vmcb->control.next_rip =3D rip; + + return 0; +} + static void svm_queue_exception(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm =3D to_svm(vcpu); @@ -380,25 +439,9 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu) =20 kvm_deliver_exception_payload(vcpu); =20 - if (nr =3D=3D BP_VECTOR && !nrips) { - unsigned long rip, old_rip =3D kvm_rip_read(vcpu); - - /* - * For guest debugging where we have to reinject #BP if some - * INT3 is guest-owned: - * Emulate nRIP by moving RIP forward. Will fail if injection - * raises a fault that is not intercepted. Still better than - * failing in all cases. - */ - (void)svm_skip_emulated_instruction(vcpu); - rip =3D kvm_rip_read(vcpu); - - if (boot_cpu_has(X86_FEATURE_NRIPS)) - svm->vmcb->control.next_rip =3D rip; - - svm->int3_rip =3D rip + svm->vmcb->save.cs.base; - svm->int3_injected =3D rip - old_rip; - } + if (kvm_exception_is_soft(nr) && + svm_update_soft_interrupt_rip(vcpu)) + return; =20 svm->vmcb->control.event_inj =3D nr | SVM_EVTINJ_VALID @@ -3671,15 +3714,46 @@ static inline void sync_lapic_to_cr8(struct kvm_vcp= u *vcpu) svm->vmcb->control.int_ctl |=3D cr8 & V_TPR_MASK; } =20 +static void svm_complete_soft_interrupt(struct kvm_vcpu *vcpu, u8 vector, + int type) +{ + struct vcpu_svm *svm =3D to_svm(vcpu); + + /* + * If NRIPS is enabled, KVM must snapshot the pre-VMRUN next_rip that's + * associated with the original soft exception/interrupt. next_rip is + * cleared on all exits that can occur while vectoring an event, so KVM + * needs to manually set next_rip for re-injection. Unlike the !nrips + * case below, this needs to be done if and only if KVM is re-injecting + * the same event, i.e. if the event is a soft exception/interrupt, + * otherwise next_rip is unused on VMRUN. + */ + if (nrips && type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT && + kvm_exception_is_soft(vector) && + kvm_is_linear_rip(vcpu, svm->soft_int_old_rip + svm->soft_int_csbase)) + svm->vmcb->control.next_rip =3D svm->soft_int_next_rip; + /* + * If NRIPS isn't enabled, KVM must manually advance RIP prior to + * injecting the soft exception/interrupt. That advancement needs to + * be unwound if vectoring didn't complete. Note, the new event may + * not be the injected event, e.g. if KVM injected an INTn, the INTn + * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will + * be the reported vectored event, but RIP still needs to be unwound. + */ + else if (!nrips && type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT && + kvm_is_linear_rip(vcpu, svm->soft_int_next_rip + svm->soft_int_csbase)) + kvm_rip_write(vcpu, svm->soft_int_old_rip); +} + static void svm_complete_interrupts(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm =3D to_svm(vcpu); u8 vector; int type; u32 exitintinfo =3D svm->vmcb->control.exit_int_info; - unsigned int3_injected =3D svm->int3_injected; + bool soft_int_injected =3D svm->soft_int_injected; =20 - svm->int3_injected =3D 0; + svm->soft_int_injected =3D false; =20 /* * If we've made progress since setting HF_IRET_MASK, we've @@ -3704,17 +3778,8 @@ static void svm_complete_interrupts(struct kvm_vcpu = *vcpu) vector =3D exitintinfo & SVM_EXITINTINFO_VEC_MASK; type =3D exitintinfo & SVM_EXITINTINFO_TYPE_MASK; =20 - /* - * If NextRIP isn't enabled, KVM must manually advance RIP prior to - * injecting the soft exception/interrupt. That advancement needs to - * be unwound if vectoring didn't complete. Note, the new event may - * not be the injected event, e.g. if KVM injected an INTn, the INTn - * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will - * be the reported vectored event, but RIP still needs to be unwound. - */ - if (int3_injected && type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT && - kvm_is_linear_rip(vcpu, svm->int3_rip)) - kvm_rip_write(vcpu, kvm_rip_read(vcpu) - int3_injected); + if (soft_int_injected) + svm_complete_soft_interrupt(vcpu, vector, type); =20 switch (type) { case SVM_EXITINTINFO_TYPE_NMI: @@ -3727,13 +3792,6 @@ static void svm_complete_interrupts(struct kvm_vcpu = *vcpu) if (vector =3D=3D X86_TRAP_VC) break; =20 - /* - * In case of software exceptions, do not reinject the vector, - * but re-execute the instruction instead. - */ - if (kvm_exception_is_soft(vector)) - break; - if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { u32 err =3D svm->vmcb->control.exit_int_info_err; kvm_requeue_exception_e(vcpu, vector, err); diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 7d97e4d18c8b..6acb494e3598 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -230,8 +230,10 @@ struct vcpu_svm { bool nmi_singlestep; u64 nmi_singlestep_guest_rflags; =20 - unsigned int3_injected; - unsigned long int3_rip; + unsigned long soft_int_csbase; + unsigned long soft_int_old_rip; + unsigned long soft_int_next_rip; + bool soft_int_injected; =20 /* optional nested SVM features that are enabled for this guest */ bool nrips_enabled : 1; --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7CEEC433F5 for ; Sat, 23 Apr 2022 02:14:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232038AbiDWCRl (ORCPT ); Fri, 22 Apr 2022 22:17:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231888AbiDWCRS (ORCPT ); Fri, 22 Apr 2022 22:17:18 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A57C421BACC for ; Fri, 22 Apr 2022 19:14:23 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id j8-20020aa78d08000000b0050ade744b37so4407884pfe.16 for ; Fri, 22 Apr 2022 19:14:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=2vvWQ9/N6TBUtPpS273fWXc6JvToYd+8tR496nicoP4=; b=n3TDy7z9cxCWkbe0b3hZSx68GdKDEavEBHm2F/2UnaSWCFQX67C/O/sxgWC3RRbaFY 6++xptZLz9/3RWcuEGF9mur1xrOgcyh6i+HrlS/1MXF/E3mJIOmOzpPU1weA5QigFL4z 797WU5CVvsd35eTHEti0NijTeAZG31ROQv/Rz/xW3Ge5a8g9aFGrW5xzrFEZ3ZK5Za50 P1Vp+q3Cs6DPuwfsppq3GslpW6SszRWquVa1A/CSiv7ztDCU8bO4mlyn6hkCcFGPkyJF D8qMb/vxCLkULOfG4AJRNSzj1wsjFsGRZAK7plrVyD9jMKoBpjyQFS4PZX+s8wigC+wu JuEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=2vvWQ9/N6TBUtPpS273fWXc6JvToYd+8tR496nicoP4=; b=wuGqC2FFTr5SncG/MAE5trdhO4OPB8/kyY+rYgJByrg09+NIwZEpuX3sm8bdAbaiah CrOMGqThzepVVTpv3HPdoi0C1B2fw3DrjggMrmgOFhou0JeK0GAVA+zpPylVFx1JgBSu 6QT3+97+K7xP5Ue0PR8QwVv50L5PiYaNZnZBBkX/RAapMsdI9LUTI6ruT6tmd1NNVtdk McW4CJAUaMAOnOPMmqwrnsEo2RVOWWTFCkE6z9K2l1rEC1eY/223BZbbfVwSNCcymvk+ F7j4WgSKShRJuVe2MXSB+tSFn2ShK4k0mFMEcXI0aVJo8hFP+edyHfB/BX2Qy3a8rMXs cU4w== X-Gm-Message-State: AOAM530EwdnHtJiJgIkDMUv83SOcT4Qf+cS4VfoSU59igLOVGlthkCS6 hVEdOUqRKhfa/K99OFNED+7FyG4pNts= X-Google-Smtp-Source: ABdhPJwkgmq74doJUUfzWDwKUzbCOAwHJhdGFtSbxKNWqKLyDARCy1+spnoY/OA2++CPk27FgQGYWdk2+uU= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90a:9105:b0:1d2:9e98:7e1e with SMTP id k5-20020a17090a910500b001d29e987e1emr692797pjo.0.1650680062764; Fri, 22 Apr 2022 19:14:22 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:06 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-7-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 06/11] KVM: SVM: Re-inject INTn instead of retrying the insn on "failure" From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Re-inject INTn software interrupts instead of retrying the instruction if the CPU encountered an intercepted exception while vectoring the INTn, e.g. if KVM intercepted a #PF when utilizing shadow paging. Retrying the instruction is architecturally wrong e.g. will result in a spurious #DB if there's a code breakpoint on the INT3/O, and lack of re-injection also breaks nested virtualization, e.g. if L1 injects a software interrupt and vectoring the injected interrupt encounters an exception that is intercepted by L0 but not L1. Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/nested.c | 7 +++---- arch/x86/kvm/svm/svm.c | 24 +++++++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 0163238aa198..a83e367ade54 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -617,10 +617,9 @@ static inline bool is_evtinj_soft(u32 evtinj) if (!(evtinj & SVM_EVTINJ_VALID)) return false; =20 - /* - * Intentionally return false for SOFT events, SVM doesn't yet support - * re-injecting soft interrupts. - */ + if (type =3D=3D SVM_EVTINJ_TYPE_SOFT) + return true; + return type =3D=3D SVM_EVTINJ_TYPE_EXEPT && kvm_exception_is_soft(vector); } =20 diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 8321f9ce5e35..b8fb07eeeca5 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3430,14 +3430,23 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) static void svm_inject_irq(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm =3D to_svm(vcpu); + u32 type; =20 - WARN_ON(!vcpu->arch.interrupt.soft && !gif_set(svm)); + if (vcpu->arch.interrupt.soft) { + if (svm_update_soft_interrupt_rip(vcpu)) + return; + + type =3D SVM_EVTINJ_TYPE_SOFT; + } else { + WARN_ON(!gif_set(svm)); + type =3D SVM_EVTINJ_TYPE_INTR; + } =20 trace_kvm_inj_virq(vcpu->arch.interrupt.nr); ++vcpu->stat.irq_injections; =20 svm->vmcb->control.event_inj =3D vcpu->arch.interrupt.nr | - SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR; + SVM_EVTINJ_VALID | type; } =20 void svm_complete_interrupt_delivery(struct kvm_vcpu *vcpu, int delivery_m= ode, @@ -3717,6 +3726,8 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu = *vcpu) static void svm_complete_soft_interrupt(struct kvm_vcpu *vcpu, u8 vector, int type) { + bool is_exception =3D (type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT); + bool is_soft =3D (type =3D=3D SVM_EXITINTINFO_TYPE_SOFT); struct vcpu_svm *svm =3D to_svm(vcpu); =20 /* @@ -3728,8 +3739,7 @@ static void svm_complete_soft_interrupt(struct kvm_vc= pu *vcpu, u8 vector, * the same event, i.e. if the event is a soft exception/interrupt, * otherwise next_rip is unused on VMRUN. */ - if (nrips && type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT && - kvm_exception_is_soft(vector) && + if (nrips && (is_soft || (is_exception && kvm_exception_is_soft(vector)))= && kvm_is_linear_rip(vcpu, svm->soft_int_old_rip + svm->soft_int_csbase)) svm->vmcb->control.next_rip =3D svm->soft_int_next_rip; /* @@ -3740,7 +3750,7 @@ static void svm_complete_soft_interrupt(struct kvm_vc= pu *vcpu, u8 vector, * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will * be the reported vectored event, but RIP still needs to be unwound. */ - else if (!nrips && type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT && + else if (!nrips && (is_soft || is_exception) && kvm_is_linear_rip(vcpu, svm->soft_int_next_rip + svm->soft_int_csbase)) kvm_rip_write(vcpu, svm->soft_int_old_rip); } @@ -3802,9 +3812,13 @@ static void svm_complete_interrupts(struct kvm_vcpu = *vcpu) case SVM_EXITINTINFO_TYPE_INTR: kvm_queue_interrupt(vcpu, vector, false); break; + case SVM_EXITINTINFO_TYPE_SOFT: + kvm_queue_interrupt(vcpu, vector, true); + break; default: break; } + } =20 static void svm_cancel_injection(struct kvm_vcpu *vcpu) --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6082DC433F5 for ; Sat, 23 Apr 2022 02:15:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231991AbiDWCRz (ORCPT ); Fri, 22 Apr 2022 22:17:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231903AbiDWCRU (ORCPT ); Fri, 22 Apr 2022 22:17:20 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65A6B21BAC2 for ; Fri, 22 Apr 2022 19:14:25 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id l14-20020a63f30e000000b0039cc65bdc47so5966831pgh.17 for ; Fri, 22 Apr 2022 19:14:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=2fpXsZJhGbr4MoYNSTdShihZ64Vsg8Cw64xWWeEmfo8=; b=h1b6lSgWxe8TBdg42eLDaS/rCLqPvrgXgz9XuK1/dcZ+XRF2KuTO0fLelihQFovgIL oupmS6D6UcCvaYPnwp0D6Il6duyzcSQ7343q2f1nWaVesl9OlCtq9mkRkyiAiRSMbytF 7d+E4qjU04hxfbI0NmBx/31x628HGxgmf2C3qd2Hlj0/M9AkZqShmJ+YkXEa/mDirnlB wXhWU51c1t1c+ug4fiOdzmkPDVxnJx0Yn05SZfZwGucGVVdkBqxMqS+6d9B9mV5gw/01 sWDqDgcnlY7rMobVY8+3Oc2rC+cbJDFfrD3CVrU8Vot8zsc52p84b0WJHnl0o9CZUgcg EdfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=2fpXsZJhGbr4MoYNSTdShihZ64Vsg8Cw64xWWeEmfo8=; b=DilqJXrRINzzIPkyutaWd75XKBrch88osgZaurE95dsdLH9pIT05J7IuzWfx//Dir8 SO+2ooRmI8gF8PCTSlGHWRA7Eo2a/wc4dWxIFkhh4GgOp/U/LKvoq5tMEhZK5FgT4LAZ IgagPVcdV6uMEwgsJeJ38vlc2JghAiDAU21cWvXu1kiLaNuMlhWuNAlhyhZpitllQk3q nlCpUksCK9NyWxx0R5Qy8r8nwXdsq1zkvr/ak56SAEwEmhTcD/4ZjIoBLaFM8U7ZQgPm fGyy1siTsxfDkH8tBdwvn1+qVlttBaxjuWXpTpauSY5tiSDW0D+Tz0p5hsw6nkyTYFFb ByKw== X-Gm-Message-State: AOAM531O5lRsgXQOF+XSMwmwvKRwLPckmM1Q7E+t8/3s5bAyDy0cR+kk VkXkI4A0baM9d2SvILq7XpIDBpOx6aQ= X-Google-Smtp-Source: ABdhPJzkeFWXkid1f7CdUq2JgPMwKM+U8A2gs99SEHa1ULCf6QpWZgib2qh+1qu3CjwxCcXqx5APei0SkhI= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:22d4:b0:50a:8540:431f with SMTP id f20-20020a056a0022d400b0050a8540431fmr8059369pfj.54.1650680064933; Fri, 22 Apr 2022 19:14:24 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:07 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-8-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 07/11] KVM: x86: Trace re-injected exceptions From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Trace exceptions that are re-injected, not just those that KVM is injecting for the first time. Debugging re-injection bugs is painful enough as is, not having visibility into what KVM is doing only makes things worse. Delay propagating pending=3D>injected in the non-reinjection path so that the tracing can properly identify reinjected exceptions. Signed-off-by: Sean Christopherson Reviewed-by: Maxim Levitsky --- arch/x86/kvm/trace.h | 12 ++++++++---- arch/x86/kvm/x86.c | 16 +++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index de4762517569..d07428e660e3 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -358,25 +358,29 @@ TRACE_EVENT(kvm_inj_virq, * Tracepoint for kvm interrupt injection: */ TRACE_EVENT(kvm_inj_exception, - TP_PROTO(unsigned exception, bool has_error, unsigned error_code), - TP_ARGS(exception, has_error, error_code), + TP_PROTO(unsigned exception, bool has_error, unsigned error_code, + bool reinjected), + TP_ARGS(exception, has_error, error_code, reinjected), =20 TP_STRUCT__entry( __field( u8, exception ) __field( u8, has_error ) __field( u32, error_code ) + __field( bool, reinjected ) ), =20 TP_fast_assign( __entry->exception =3D exception; __entry->has_error =3D has_error; __entry->error_code =3D error_code; + __entry->reinjected =3D reinjected; ), =20 - TP_printk("%s (0x%x)", + TP_printk("%s (0x%x)%s", __print_symbolic(__entry->exception, kvm_trace_sym_exc), /* FIXME: don't print error_code if not present */ - __entry->has_error ? __entry->error_code : 0) + __entry->has_error ? __entry->error_code : 0, + __entry->reinjected ? " [reinjected]" : "") ); =20 /* diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 951d0a78ccda..c3ee8dc00d3a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9393,6 +9393,11 @@ int kvm_check_nested_events(struct kvm_vcpu *vcpu) =20 static void kvm_inject_exception(struct kvm_vcpu *vcpu) { + trace_kvm_inj_exception(vcpu->arch.exception.nr, + vcpu->arch.exception.has_error_code, + vcpu->arch.exception.error_code, + vcpu->arch.exception.injected); + if (vcpu->arch.exception.error_code && !is_protmode(vcpu)) vcpu->arch.exception.error_code =3D false; static_call(kvm_x86_queue_exception)(vcpu); @@ -9450,13 +9455,6 @@ static int inject_pending_event(struct kvm_vcpu *vcp= u, bool *req_immediate_exit) =20 /* try to inject new event if pending */ if (vcpu->arch.exception.pending) { - trace_kvm_inj_exception(vcpu->arch.exception.nr, - vcpu->arch.exception.has_error_code, - vcpu->arch.exception.error_code); - - vcpu->arch.exception.pending =3D false; - vcpu->arch.exception.injected =3D true; - if (exception_type(vcpu->arch.exception.nr) =3D=3D EXCPT_FAULT) __kvm_set_rflags(vcpu, kvm_get_rflags(vcpu) | X86_EFLAGS_RF); @@ -9470,6 +9468,10 @@ static int inject_pending_event(struct kvm_vcpu *vcp= u, bool *req_immediate_exit) } =20 kvm_inject_exception(vcpu); + + vcpu->arch.exception.pending =3D false; + vcpu->arch.exception.injected =3D true; + can_inject =3D false; } =20 --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58FBEC433EF for ; Sat, 23 Apr 2022 02:14:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230435AbiDWCRr (ORCPT ); Fri, 22 Apr 2022 22:17:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231938AbiDWCR1 (ORCPT ); Fri, 22 Apr 2022 22:17:27 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63B11223C40 for ; Fri, 22 Apr 2022 19:14:27 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id c194-20020a6335cb000000b0039d9a489d44so5968655pga.6 for ; Fri, 22 Apr 2022 19:14:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=RGenDiR0ZcLVqMaJHYtAxEAhb2eb3EmoI6gfQimOxU8=; b=jzTs+CKyCF2je0Je2OZVpPMBUjSzfqPrEV17e+v9Tvq4OBlFPnJaOrsax97rn4QtWQ 0HPB2ziE3zuBhQYXHtmNGy/weNzkHojxTOyhfdEP1qlBfi8GMXy7MSffHg1t8hFIzDsX Yj+8urZRvJekIERa/htKYM84/ZQFFpAR71VzOGjDOCwV3L7PpylzyjL5ldzGnn1d7KwE Va6/LdC8V6C6a+YN1mszCNKvCpg8SoxMMtnMIHbol1WBM07Of51j4l5kpR3XbtdnxBX4 cf2iQzTRDtzfaucfF/shswKdoX6wCxlGm2WiPS+oQ/9n6f8zYh7MwWrKUMCjA+QxVz6r nJ7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=RGenDiR0ZcLVqMaJHYtAxEAhb2eb3EmoI6gfQimOxU8=; b=xdRrgMdiskfW8Ou560GwPeYxFtyVzzPX/TkwX3pVInoqWUFITqh2pWdPPm5GcvQraW Oj4+ajpHry/obGaJE1TWk2uF3H1tbVpCFIkCNVTrTcem/LEtuS+EaJi9LDFxLmeUeNZP zzIDoDc+0pkuPINbtRktAILPi68PmaizE2AyUf949j6duTVJlT7kuP44LMro2k7ZnD71 1PqhHI9Pl76e4MfRcIDnuVBRtsHO789sAdp8lY1o0buS5hp432P2kIRm+GYyxfd52/s2 vCR/tpGAObh6C3kpxCWSLnDTaJAdR6WnEHXSO/aR3cUDd47j6kBklRFMD7zvvp7Iy+us yeLA== X-Gm-Message-State: AOAM531NYmh+nUoup52bnzKx5Ze8AMSathfwzCaDrqGUrEZkPGR4lhWP xAIbxsISXGlXh9XVb4aRBF80E9tDp2A= X-Google-Smtp-Source: ABdhPJx7DfzNQ+mxhJvDS3YfMqoaVGp3gPjGg1aTFtRTllkuiwAoMZ8TpHnjL+0JLlrM14S5gtxLts6ixB0= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:16c7:b0:4f7:e497:69b8 with SMTP id l7-20020a056a0016c700b004f7e49769b8mr7948529pfc.6.1650680066547; Fri, 22 Apr 2022 19:14:26 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:08 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-9-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 08/11] KVM: x86: Print error code in exception injection tracepoint iff valid From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Print the error code in the exception injection tracepoint if and only if the exception has an error code. Define the entire error code sequence as a set of formatted strings, print empty strings if there's no error code, and abuse __print_symbolic() by passing it an empty array to coerce it into printing the error code as a hex string. Signed-off-by: Sean Christopherson Reviewed-by: Maxim Levitsky --- arch/x86/kvm/trace.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index d07428e660e3..385436d12024 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -376,10 +376,11 @@ TRACE_EVENT(kvm_inj_exception, __entry->reinjected =3D reinjected; ), =20 - TP_printk("%s (0x%x)%s", + TP_printk("%s%s%s%s%s", __print_symbolic(__entry->exception, kvm_trace_sym_exc), - /* FIXME: don't print error_code if not present */ - __entry->has_error ? __entry->error_code : 0, + !__entry->has_error ? "" : " (", + !__entry->has_error ? "" : __print_symbolic(__entry->error_code, { }), + !__entry->has_error ? "" : ")", __entry->reinjected ? " [reinjected]" : "") ); =20 --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84CBAC433F5 for ; Sat, 23 Apr 2022 02:14:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232047AbiDWCRu (ORCPT ); Fri, 22 Apr 2022 22:17:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231965AbiDWCR2 (ORCPT ); Fri, 22 Apr 2022 22:17:28 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD419223C60 for ; Fri, 22 Apr 2022 19:14:28 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id z132-20020a63338a000000b003844e317066so5957865pgz.19 for ; Fri, 22 Apr 2022 19:14:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=YP3aW6zH/fPatigZ4/X2xyENnpxrIf5NXRWAQXh1KLg=; b=rpke6V8tq81cNiJq2YbH/e/SKEreh+ccqI6cvAcxsFxbZzVRTwQBkT2K5IOGGNpyTN MMuqFixY9wazTtMwAPYIiiGJw+nln9T28cLoEEUeVw9SqanV79u1LJyrDFDKgDqM6uTZ vTje6rQXKM/H9sY9rS0xXC/TTEZ/rgYIBX++3JfGU/cHxcBePPr86shcjIhBkGd9GtDq aRMPPAMPdaE1k+5PrQJWUWiMkg/4ccEbBCTQPNtAGPI+DF/BfSBtwJFs1fgNP/UY+21x 6pz9pIYewZSt1A2Px7+30nUzMeF0gm6zzika0ZhX1EhsfoUyEJMpkQ3kfy34jfmuD5qk zBuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=YP3aW6zH/fPatigZ4/X2xyENnpxrIf5NXRWAQXh1KLg=; b=liSlGoHNuCaZteS0h5VppLU42ZZZUzOwQLeeFtnToiKSEPSj9y+Tv5IRlT2wIDKNaE KMZ0BhzKuc8cVqxWDt3skUward0lkSjrd5mlMsPBLjqrklfeF/+IYS+8yWpV2ommQJXT w0I95Kpa/quBd7VRrInuEyWZ0q+29XiJQ/Y0Qw9lFcYRZlJ3zJdSEbUVZvYyP9Ik6JyF MC+lHylsfCjkQm13GgNcYx8byESc6ZUONb2TAIU8hLLo2WrIThfKU3zwtA/ZGHD72oP3 OiHaIKNX3rYpGM23SbBsm+KkUfEVkQ3lHbJC6E9HASAsWoiDe8lp6CvFE6Ys200Yggho K9Qg== X-Gm-Message-State: AOAM530tnp9mkrOmP53LAYgVfc0wQ2LDA/8Hxrs8KTBKVNacTQD44skZ aUHWpDCyJVWieHAvSVhGMrr1nkeue7U= X-Google-Smtp-Source: ABdhPJzBvVLBVOJkFuVNdSGeoj3Ci9BrrzKHIL3X4LWZX/7nIkrKwJyzT9JIpsHPvrHoD2c6LWWya7UkcAQ= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:902:ccc9:b0:15b:c265:b7a0 with SMTP id z9-20020a170902ccc900b0015bc265b7a0mr6812946ple.107.1650680068213; Fri, 22 Apr 2022 19:14:28 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:09 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-10-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 09/11] KVM: x86: Differentiate Soft vs. Hard IRQs vs. reinjected in tracepoint From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the IRQ injection tracepoint, differentiate between Hard IRQs and Soft "IRQs", i.e. interrupts that are reinjected after incomplete delivery of a software interrupt from an INTn instruction. Tag reinjected interrupts as such, even though the information is usually redundant since soft interrupts are only ever reinjected by KVM. Though rare in practice, a hard IRQ can be reinjected. Signed-off-by: Sean Christopherson --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/svm/svm.c | 5 +++-- arch/x86/kvm/trace.h | 16 +++++++++++----- arch/x86/kvm/vmx/vmx.c | 4 ++-- arch/x86/kvm/x86.c | 4 ++-- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index f164c6c1514a..ae088c6fb287 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1400,7 +1400,7 @@ struct kvm_x86_ops { u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu); void (*patch_hypercall)(struct kvm_vcpu *vcpu, unsigned char *hypercall_addr); - void (*inject_irq)(struct kvm_vcpu *vcpu); + void (*inject_irq)(struct kvm_vcpu *vcpu, bool reinjected); void (*inject_nmi)(struct kvm_vcpu *vcpu); void (*queue_exception)(struct kvm_vcpu *vcpu); void (*cancel_injection)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index b8fb07eeeca5..4a912623b961 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3427,7 +3427,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) ++vcpu->stat.nmi_injections; } =20 -static void svm_inject_irq(struct kvm_vcpu *vcpu) +static void svm_inject_irq(struct kvm_vcpu *vcpu, bool reinjected) { struct vcpu_svm *svm =3D to_svm(vcpu); u32 type; @@ -3442,7 +3442,8 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu) type =3D SVM_EVTINJ_TYPE_INTR; } =20 - trace_kvm_inj_virq(vcpu->arch.interrupt.nr); + trace_kvm_inj_virq(vcpu->arch.interrupt.nr, + vcpu->arch.interrupt.soft, reinjected); ++vcpu->stat.irq_injections; =20 svm->vmcb->control.event_inj =3D vcpu->arch.interrupt.nr | diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 385436d12024..e1b089285c55 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -333,18 +333,24 @@ TRACE_EVENT_KVM_EXIT(kvm_exit); * Tracepoint for kvm interrupt injection: */ TRACE_EVENT(kvm_inj_virq, - TP_PROTO(unsigned int irq), - TP_ARGS(irq), + TP_PROTO(unsigned int vector, bool soft, bool reinjected), + TP_ARGS(vector, soft, reinjected), =20 TP_STRUCT__entry( - __field( unsigned int, irq ) + __field( unsigned int, vector ) + __field( bool, soft ) + __field( unsigned int, reinjected ) ), =20 TP_fast_assign( - __entry->irq =3D irq; + __entry->vector =3D vector; + __entry->soft =3D soft; + __entry->reinjected =3D reinjected; ), =20 - TP_printk("irq %u", __entry->irq) + TP_printk("%s 0x%x%s", + __entry->soft ? "Soft/INTn" : "IRQ", __entry->vector, + __entry->reinjected ? " [reinjected]" : "") ); =20 #define EXS(x) { x##_VECTOR, "#" #x } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index cf8581978bce..a0083464682d 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4566,13 +4566,13 @@ static void vmx_enable_nmi_window(struct kvm_vcpu *= vcpu) exec_controls_setbit(to_vmx(vcpu), CPU_BASED_NMI_WINDOW_EXITING); } =20 -static void vmx_inject_irq(struct kvm_vcpu *vcpu) +static void vmx_inject_irq(struct kvm_vcpu *vcpu, bool reinjected) { struct vcpu_vmx *vmx =3D to_vmx(vcpu); uint32_t intr; int irq =3D vcpu->arch.interrupt.nr; =20 - trace_kvm_inj_virq(irq); + trace_kvm_inj_virq(irq, vcpu->arch.interrupt.soft, reinjected); =20 ++vcpu->stat.irq_injections; if (vmx->rmode.vm86_active) { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c3ee8dc00d3a..0a154b54b8aa 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9433,7 +9433,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu= , bool *req_immediate_exit) static_call(kvm_x86_inject_nmi)(vcpu); can_inject =3D false; } else if (vcpu->arch.interrupt.injected) { - static_call(kvm_x86_inject_irq)(vcpu); + static_call(kvm_x86_inject_irq)(vcpu, true); can_inject =3D false; } } @@ -9524,7 +9524,7 @@ static int inject_pending_event(struct kvm_vcpu *vcpu= , bool *req_immediate_exit) goto out; if (r) { kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false); - static_call(kvm_x86_inject_irq)(vcpu); + static_call(kvm_x86_inject_irq)(vcpu, false); WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0); } if (kvm_cpu_has_injectable_intr(vcpu)) --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72444C433EF for ; Sat, 23 Apr 2022 02:15:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229826AbiDWCSk (ORCPT ); Fri, 22 Apr 2022 22:18:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231982AbiDWCR2 (ORCPT ); Fri, 22 Apr 2022 22:17:28 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80978223C7C for ; Fri, 22 Apr 2022 19:14:30 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id n4-20020a170902f60400b00158d1f2d442so5713842plg.18 for ; Fri, 22 Apr 2022 19:14:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=d/SdPO1Vv4rU9lCOmy+jzP8vSw2/8svTwDt3X3jyL+E=; b=fpGCuDIKiUEBtWUFXzxOcTLpNElXWXUvDFxT13ygkTKRN27WK59npvqxfFYCFgvqWu LxHFLqVIEB26w9ybeZclWGN1uxaZqdn9Phyoydn9U//1K3ad+3IRjcSLkt3nMIgsDE/U SiLhcKZMFRRjIHKhxBKCVUGvx1ZnA+UVLp9WbpxDA7DYC2gegBsHtNTUGBXwa9+h7vfp HWS9nR7VKmhQGa8XKYXeSfpoWkJxrcryIAvhJj+vauGHdHHhdyV92IZOq5jFgUiDb0LZ YdOX7Ir4FXMMQg0XRUhXKUJu8lbCbtWpWlGKJy3Pu94T/D+fo+7nmoyMxEEdLBmHWYa3 AA4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=d/SdPO1Vv4rU9lCOmy+jzP8vSw2/8svTwDt3X3jyL+E=; b=t6FMeZjksug9bjIQwwYfGkjTJdq/8UNchS7TiDHJLA+xpRqcGNEdRdlsL0DlNANFEe 114NYC+iUcScfrQEPmmabmfeV5QO1Wnk7vgVGkPNMddvj0NnZeSRTtfl5L4e8MhlVmBt 2SKLxMAt2iM3o4aBSYFGkwmiZw6pDyjsyYV66uewaee6quWhXnN+zRPHuvqiLqwrOIEA 7Cw0u6a+ZiRS7xomsuWYNiW0viaBlXe/onjhqngAjw7aKs340m3dxPjc2HnATWKN+xvs iCbUsKCHNJQAMGoKXq3hizWGL8zr0FJsQ+GDAelVPuVuasv37QPLZ57kmPq/LJWk8h6l dRcw== X-Gm-Message-State: AOAM532u4ErwtdK5POe2fBrGztkPufAjWZ5OdcjfJpnIZeYeDn4XyVg1 F6e7XbqtcHjsdwpkwI5KmrIx/TGKH2U= X-Google-Smtp-Source: ABdhPJzRAKMMl9jvcUVVo/JbXi+/3XEovu4fh5ysH5cQ2bkaxizwsb/lxlFrbWarppfjF05Oc3i1x9G/PNw= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:14d2:b0:50a:48f0:881a with SMTP id w18-20020a056a0014d200b0050a48f0881amr7930016pfu.36.1650680069966; Fri, 22 Apr 2022 19:14:29 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:10 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-11-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 10/11] KVM: selftests: nSVM: Add svm_nested_soft_inject_test From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maciej S. Szmigiero Add a KVM self-test that checks whether a nSVM L1 is able to successfully inject a software interrupt and a soft exception into its L2 guest. In practice, this tests both the next_rip field consistency and L1-injected event with intervening L0 VMEXIT during its delivery: the first nested VMRUN (that's also trying to inject a software interrupt) will immediately trigger a L0 NPF. This L0 NPF will have zero in its CPU-returned next_rip field, which if incorrectly reused by KVM will trigger a #PF when trying to return to such address 0 from the interrupt handler. Reviewed-by: Maxim Levitsky Signed-off-by: Maciej S. Szmigiero [sean: check exact L2 RIP on first soft interrupt] Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/.gitignore | 3 +- tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/include/x86_64/svm_util.h | 2 + .../kvm/x86_64/svm_nested_soft_inject_test.c | 151 ++++++++++++++++++ 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/x86_64/svm_nested_soft_inje= ct_test.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftes= ts/kvm/.gitignore index 56140068b763..74f3099f0ad3 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -35,9 +35,10 @@ /x86_64/state_test /x86_64/svm_vmcall_test /x86_64/svm_int_ctl_test -/x86_64/tsc_scaling_sync +/x86_64/svm_nested_soft_inject_test /x86_64/sync_regs_test /x86_64/tsc_msrs_test +/x86_64/tsc_scaling_sync /x86_64/userspace_io_test /x86_64/userspace_msr_exit_test /x86_64/vmx_apic_access_test diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests= /kvm/Makefile index af582d168621..eedf6bf713d3 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -66,6 +66,7 @@ TEST_GEN_PROGS_x86_64 +=3D x86_64/state_test TEST_GEN_PROGS_x86_64 +=3D x86_64/vmx_preemption_timer_test TEST_GEN_PROGS_x86_64 +=3D x86_64/svm_vmcall_test TEST_GEN_PROGS_x86_64 +=3D x86_64/svm_int_ctl_test +TEST_GEN_PROGS_x86_64 +=3D x86_64/svm_nested_soft_inject_test TEST_GEN_PROGS_x86_64 +=3D x86_64/tsc_scaling_sync TEST_GEN_PROGS_x86_64 +=3D x86_64/sync_regs_test TEST_GEN_PROGS_x86_64 +=3D x86_64/userspace_io_test diff --git a/tools/testing/selftests/kvm/include/x86_64/svm_util.h b/tools/= testing/selftests/kvm/include/x86_64/svm_util.h index a25aabd8f5e7..d49f7c9b4564 100644 --- a/tools/testing/selftests/kvm/include/x86_64/svm_util.h +++ b/tools/testing/selftests/kvm/include/x86_64/svm_util.h @@ -16,6 +16,8 @@ #define CPUID_SVM_BIT 2 #define CPUID_SVM BIT_ULL(CPUID_SVM_BIT) =20 +#define SVM_EXIT_EXCP_BASE 0x040 +#define SVM_EXIT_HLT 0x078 #define SVM_EXIT_MSR 0x07c #define SVM_EXIT_VMMCALL 0x081 =20 diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test= .c b/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c new file mode 100644 index 000000000000..257aa2280b5c --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022 Oracle and/or its affiliates. + * + * Based on: + * svm_int_ctl_test + * + * Copyright (C) 2021, Red Hat, Inc. + * + */ + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" +#include "svm_util.h" + +#define VCPU_ID 0 +#define INT_NR 0x20 +#define X86_FEATURE_NRIPS BIT(3) + +#define vmcall() \ + __asm__ __volatile__( \ + "vmmcall\n" \ + ) + +#define ud2() \ + __asm__ __volatile__( \ + "ud2\n" \ + ) + +#define hlt() \ + __asm__ __volatile__( \ + "hlt\n" \ + ) + +static unsigned int bp_fired; +static void guest_bp_handler(struct ex_regs *regs) +{ + bp_fired++; +} + +static unsigned int int_fired; +static void l2_guest_code(void); + +static void guest_int_handler(struct ex_regs *regs) +{ + int_fired++; + GUEST_ASSERT_2(regs->rip =3D=3D (unsigned long)l2_guest_code, + regs->rip, (unsigned long)l2_guest_code); +} + +static void l2_guest_code(void) +{ + GUEST_ASSERT(int_fired =3D=3D 1); + vmcall(); + ud2(); + + GUEST_ASSERT(bp_fired =3D=3D 1); + hlt(); +} + +static void l1_guest_code(struct svm_test_data *svm) +{ + #define L2_GUEST_STACK_SIZE 64 + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + struct vmcb *vmcb =3D svm->vmcb; + + /* Prepare for L2 execution. */ + generic_svm_setup(svm, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + vmcb->control.intercept_exceptions |=3D BIT(PF_VECTOR) | BIT(UD_VECTOR); + vmcb->control.intercept |=3D BIT(INTERCEPT_HLT); + + vmcb->control.event_inj =3D INT_NR | SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_S= OFT; + /* The return address pushed on stack */ + vmcb->control.next_rip =3D vmcb->save.rip; + + run_guest(vmcb, svm->vmcb_gpa); + GUEST_ASSERT_3(vmcb->control.exit_code =3D=3D SVM_EXIT_VMMCALL, + vmcb->control.exit_code, + vmcb->control.exit_info_1, vmcb->control.exit_info_2); + + /* Skip over VMCALL */ + vmcb->save.rip +=3D 3; + + vmcb->control.event_inj =3D BP_VECTOR | SVM_EVTINJ_VALID | SVM_EVTINJ_TYP= E_EXEPT; + /* The return address pushed on stack, skip over UD2 */ + vmcb->control.next_rip =3D vmcb->save.rip + 2; + + run_guest(vmcb, svm->vmcb_gpa); + GUEST_ASSERT_3(vmcb->control.exit_code =3D=3D SVM_EXIT_HLT, + vmcb->control.exit_code, + vmcb->control.exit_info_1, vmcb->control.exit_info_2); + + GUEST_DONE(); +} + +int main(int argc, char *argv[]) +{ + struct kvm_cpuid_entry2 *cpuid; + struct kvm_vm *vm; + vm_vaddr_t svm_gva; + struct kvm_guest_debug debug; + + nested_svm_check_supported(); + + cpuid =3D kvm_get_supported_cpuid_entry(0x8000000a); + if (!(cpuid->edx & X86_FEATURE_NRIPS)) { + print_skip("nRIP Save unavailable"); + exit(KSFT_SKIP); + } + + vm =3D vm_create_default(VCPU_ID, 0, (void *) l1_guest_code); + + vm_init_descriptor_tables(vm); + vcpu_init_descriptor_tables(vm, VCPU_ID); + + vm_install_exception_handler(vm, BP_VECTOR, guest_bp_handler); + vm_install_exception_handler(vm, INT_NR, guest_int_handler); + + vcpu_alloc_svm(vm, &svm_gva); + vcpu_args_set(vm, VCPU_ID, 1, svm_gva); + + memset(&debug, 0, sizeof(debug)); + vcpu_set_guest_debug(vm, VCPU_ID, &debug); + + struct kvm_run *run =3D vcpu_state(vm, VCPU_ID); + struct ucall uc; + + vcpu_run(vm, VCPU_ID); + TEST_ASSERT(run->exit_reason =3D=3D KVM_EXIT_IO, + "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n", + run->exit_reason, + exit_reason_str(run->exit_reason)); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_ABORT: + TEST_FAIL("%s at %s:%ld, vals =3D 0x%lx 0x%lx 0x%lx", (const char *)uc.a= rgs[0], + __FILE__, uc.args[1], uc.args[2], uc.args[3], uc.args[4]); + break; + /* NOT REACHED */ + case UCALL_DONE: + goto done; + default: + TEST_FAIL("Unknown ucall 0x%lx.", uc.cmd); + } +done: + kvm_vm_free(vm); + return 0; +} --=20 2.36.0.rc2.479.g8af0fa9b8e-goog From nobody Sun May 10 21:17:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14497C433EF for ; Sat, 23 Apr 2022 02:15:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231962AbiDWCSd (ORCPT ); Fri, 22 Apr 2022 22:18:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232021AbiDWCR3 (ORCPT ); Fri, 22 Apr 2022 22:17:29 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5885D224054 for ; Fri, 22 Apr 2022 19:14:32 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id u5-20020a63f645000000b003aa5613d99cso5979002pgj.5 for ; Fri, 22 Apr 2022 19:14:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=wdag41y9OAVtS7teqp0JXkEIzXyC8dZApV/tVU+ozDA=; b=GB79v8TM62ZWtiJrKgnl7W1jl715WI0N878ZZ/dJDU6dmO3fB2jM6kqb74x5jYLV8a sy0B9lRDRzI2TVjy/irDRLApw/aX2i+RYq4uPlUxfuyPUp3xmN0fweaIRHGlHKEOkJOu 04LpgZ8tQ4auviJH26kQLv5/l4Z0mMiHPFIipsDxamZ2KZtenzTcnF3WtXgypUqTyDzO lYl1HDUEOxGMgrwEUZR+KtEaQ/Qem30E6LIxvCO0MSPdwV5poDPDe4QwHbfOF18m7LGF poMzDybCLr5R/W2TzdjAhmQdeJX8ycowK2dROYn6M8eEHoHgRwbo7/rpSPx2nwziO7OV MPlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=wdag41y9OAVtS7teqp0JXkEIzXyC8dZApV/tVU+ozDA=; b=bsHrC1Ew+Q49pr3xrK35ibLzGcRo5jzwA4vvDSf2zno79+ojVyKBc3EKcCxUecIsSA 5eRyMaBuTkJqDNOBTXp5gQKf1FAnwqiFOrf2d/rI0Rk8czS0nnDWzTKhfnlWJK7DIPem 9Fi4U9iOsRo7Ds4Td5S52vVve7FtMdrPck4NOroEZ+/ALSrXDFdIUXCHwZJpxaN0+bA3 v6EtF6cNqYpNPbGct6EeV9RE2ZGfN13oLQtSp9JPbFXtuRK9hRt8iCQIjBJASleCz/PG vULzX2hFPkYrjbHghDXeMEwg/9CY4Dk1qVn0sifevlidx2+7LRCQnGrHptg0lvomsCaa 7wsg== X-Gm-Message-State: AOAM531nuiE6RVGlboVJA5Z1jxePAEqsxgMji7srIXhXdAtT0dzbnUGh cL2mlGH/fbU9rmpwu+RH0nHpbaMV4Qw= X-Google-Smtp-Source: ABdhPJwoAt5wYJQnjpSWq2Cdj4a85+ur/HPU9Dgo9kkad+up8vSwBKg2bsvtPB+V7n+62n885+y4lUtvyYY= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90b:2384:b0:1cb:5223:9dc4 with SMTP id mr4-20020a17090b238400b001cb52239dc4mr693294pjb.1.1650680071424; Fri, 22 Apr 2022 19:14:31 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 23 Apr 2022 02:14:11 +0000 In-Reply-To: <20220423021411.784383-1-seanjc@google.com> Message-Id: <20220423021411.784383-12-seanjc@google.com> Mime-Version: 1.0 References: <20220423021411.784383-1-seanjc@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v2 11/11] KVM: SVM: Drop support for CPUs without NRIPS (NextRIP Save) support From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Maxim Levitsky , "Maciej S . Szmigiero" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Drop support for CPUs without NRIPS along with the associated module param. Requiring NRIPS simplifies a handful of paths in KVM, especially paths where KVM has to do silly things when nrips=3Dfalse but supported in hardware as there is no way to tell the CPU _not_ to use NRIPS. NRIPS was introduced in 2009, i.e. every AMD-based CPU released in the last decade should support NRIPS. Suggested-by: Paolo Bonzini Not-signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/nested.c | 9 +-- arch/x86/kvm/svm/svm.c | 77 +++++++------------ .../kvm/x86_64/svm_nested_soft_inject_test.c | 6 +- 3 files changed, 32 insertions(+), 60 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index a83e367ade54..f39c958c77f5 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -681,14 +681,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=3D0 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=3D0 CPU would do (L1 + * is responsible for advancing RIP prior to injecting the event). */ if (svm->nrips_enabled) vmcb02->control.next_rip =3D svm->nested.ctl.next_rip; - else if (boot_cpu_has(X86_FEATURE_NRIPS)) + else vmcb02->control.next_rip =3D vmcb12_rip; =20 if (is_evtinj_soft(vmcb02->control.event_inj)) { diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 4a912623b961..6e6530c01e34 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -162,10 +162,6 @@ module_param_named(npt, npt_enabled, bool, 0444); static int nested =3D true; module_param(nested, int, S_IRUGO); =20 -/* enable/disable Next RIP Save */ -static int nrips =3D true; -module_param(nrips, int, 0444); - /* enable/disable Virtual VMLOAD VMSAVE */ static int vls =3D true; module_param(vls, int, 0444); @@ -355,10 +351,8 @@ static int __svm_skip_emulated_instruction(struct kvm_= vcpu *vcpu, if (sev_es_guest(vcpu->kvm)) goto done; =20 - if (nrips && svm->vmcb->control.next_rip !=3D 0) { - WARN_ON_ONCE(!static_cpu_has(X86_FEATURE_NRIPS)); + if (svm->vmcb->control.next_rip !=3D 0) svm->next_rip =3D svm->vmcb->control.next_rip; - } =20 if (!svm->next_rip) { if (unlikely(!commit_side_effects)) @@ -394,15 +388,14 @@ static int svm_update_soft_interrupt_rip(struct kvm_v= cpu *vcpu) * Due to architectural shortcomings, the CPU doesn't always provide * NextRIP, e.g. if KVM intercepted an exception that occurred while * the CPU was vectoring an INTO/INT3 in the guest. Temporarily skip - * the instruction even if NextRIP is supported to acquire the next - * RIP so that it can be shoved into the NextRIP field, otherwise - * hardware will fail to advance guest RIP during event injection. - * Drop the exception/interrupt if emulation fails and effectively - * retry the instruction, it's the least awful option. If NRIPS is - * in use, the skip must not commit any side effects such as clearing - * the interrupt shadow or RFLAGS.RF. + * the instruction to acquire the next RIP so that it can be shoved + * into the NextRIP field, otherwise hardware will fail to advance + * guest RIP during event injection. Drop the exception/interrupt if + * emulation fails and effectively retry the instruction, it's the + * least awful option. The skip must not commit any side effects such + * as clearing the interrupt shadow or RFLAGS.RF. */ - if (!__svm_skip_emulated_instruction(vcpu, !nrips)) + if (!__svm_skip_emulated_instruction(vcpu, false)) return -EIO; =20 rip =3D kvm_rip_read(vcpu); @@ -421,11 +414,9 @@ static int svm_update_soft_interrupt_rip(struct kvm_vc= pu *vcpu) svm->soft_int_old_rip =3D old_rip; svm->soft_int_next_rip =3D rip; =20 - if (nrips) - kvm_rip_write(vcpu, old_rip); + kvm_rip_write(vcpu, old_rip); =20 - if (static_cpu_has(X86_FEATURE_NRIPS)) - svm->vmcb->control.next_rip =3D rip; + svm->vmcb->control.next_rip =3D rip; =20 return 0; } @@ -3732,28 +3723,16 @@ static void svm_complete_soft_interrupt(struct kvm_= vcpu *vcpu, u8 vector, struct vcpu_svm *svm =3D to_svm(vcpu); =20 /* - * If NRIPS is enabled, KVM must snapshot the pre-VMRUN next_rip that's - * associated with the original soft exception/interrupt. next_rip is - * cleared on all exits that can occur while vectoring an event, so KVM - * needs to manually set next_rip for re-injection. Unlike the !nrips - * case below, this needs to be done if and only if KVM is re-injecting - * the same event, i.e. if the event is a soft exception/interrupt, - * otherwise next_rip is unused on VMRUN. + * KVM must snapshot the pre-VMRUN next_rip that's associated with the + * original soft exception/interrupt. next_rip is cleared on all exits + * that can occur while vectoring an event, so KVM needs to manually + * set next_rip for re-injection. This needs to be done if and only if + * KVM is re-injecting the same event, i.e. if the event is a soft + * exception/interrupt, otherwise next_rip is unused on VMRUN. */ - if (nrips && (is_soft || (is_exception && kvm_exception_is_soft(vector)))= && + if ((is_soft || (is_exception && kvm_exception_is_soft(vector))) && kvm_is_linear_rip(vcpu, svm->soft_int_old_rip + svm->soft_int_csbase)) svm->vmcb->control.next_rip =3D svm->soft_int_next_rip; - /* - * If NRIPS isn't enabled, KVM must manually advance RIP prior to - * injecting the soft exception/interrupt. That advancement needs to - * be unwound if vectoring didn't complete. Note, the new event may - * not be the injected event, e.g. if KVM injected an INTn, the INTn - * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will - * be the reported vectored event, but RIP still needs to be unwound. - */ - else if (!nrips && (is_soft || is_exception) && - kvm_is_linear_rip(vcpu, svm->soft_int_next_rip + svm->soft_int_csbase)) - kvm_rip_write(vcpu, svm->soft_int_old_rip); } =20 static void svm_complete_interrupts(struct kvm_vcpu *vcpu) @@ -4112,8 +4091,7 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu = *vcpu) boot_cpu_has(X86_FEATURE_XSAVES); =20 /* Update nrips enabled cache */ - svm->nrips_enabled =3D kvm_cpu_cap_has(X86_FEATURE_NRIPS) && - guest_cpuid_has(vcpu, X86_FEATURE_NRIPS); + svm->nrips_enabled =3D guest_cpuid_has(vcpu, X86_FEATURE_NRIPS); =20 svm->tsc_scaling_enabled =3D tsc_scaling && guest_cpuid_has(vcpu, X86_FEA= TURE_TSCRATEMSR); svm->lbrv_enabled =3D lbrv && guest_cpuid_has(vcpu, X86_FEATURE_LBRV); @@ -4324,9 +4302,7 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, break; } =20 - /* TODO: Advertise NRIPS to guest hypervisor unconditionally */ - if (static_cpu_has(X86_FEATURE_NRIPS)) - vmcb->control.next_rip =3D info->next_rip; + vmcb->control.next_rip =3D info->next_rip; vmcb->control.exit_code =3D icpt_info.exit_code; vmexit =3D nested_svm_exit_handled(svm); =20 @@ -4859,9 +4835,7 @@ static __init void svm_set_cpu_caps(void) if (nested) { kvm_cpu_cap_set(X86_FEATURE_SVM); kvm_cpu_cap_set(X86_FEATURE_VMCBCLEAN); - - if (nrips) - kvm_cpu_cap_set(X86_FEATURE_NRIPS); + kvm_cpu_cap_set(X86_FEATURE_NRIPS); =20 if (npt_enabled) kvm_cpu_cap_set(X86_FEATURE_NPT); @@ -4908,6 +4882,12 @@ static __init int svm_hardware_setup(void) int r; unsigned int order =3D get_order(IOPM_SIZE); =20 + /* KVM no longer supports CPUs without NextRIP Save support. */ + if (!boot_cpu_has(X86_FEATURE_NRIPS)) { + pr_err_ratelimited("NRIPS (NextRIP Save) not supported\n"); + return -EOPNOTSUPP; + } + /* * NX is required for shadow paging and for NPT if the NX huge pages * mitigation is enabled. @@ -4989,11 +4969,6 @@ static __init int svm_hardware_setup(void) goto err; } =20 - if (nrips) { - if (!boot_cpu_has(X86_FEATURE_NRIPS)) - nrips =3D false; - } - enable_apicv =3D avic =3D avic && npt_enabled && (boot_cpu_has(X86_FEATUR= E_AVIC) || force_avic); =20 if (enable_apicv) { diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test= .c b/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c index 257aa2280b5c..39a6569715fd 100644 --- a/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c +++ b/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c @@ -106,10 +106,8 @@ int main(int argc, char *argv[]) nested_svm_check_supported(); =20 cpuid =3D kvm_get_supported_cpuid_entry(0x8000000a); - if (!(cpuid->edx & X86_FEATURE_NRIPS)) { - print_skip("nRIP Save unavailable"); - exit(KSFT_SKIP); - } + TEST_ASSERT(cpuid->edx & X86_FEATURE_NRIPS, + "KVM is supposed to unconditionally advertise nRIP Save\n"); =20 vm =3D vm_create_default(VCPU_ID, 0, (void *) l1_guest_code); =20 --=20 2.36.0.rc2.479.g8af0fa9b8e-goog