From nobody Fri Jun 19 15:47:43 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 DC248C433F5 for ; Sat, 2 Apr 2022 01:09:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353625AbiDBBLG (ORCPT ); Fri, 1 Apr 2022 21:11:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345558AbiDBBK7 (ORCPT ); Fri, 1 Apr 2022 21:10:59 -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 E15568A328 for ; Fri, 1 Apr 2022 18:09:07 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id 138-20020a621690000000b004fa807ac59aso2421061pfw.19 for ; Fri, 01 Apr 2022 18:09:07 -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=QQuySiCRGCJ6RvPIQ/BSFIhGVMRh766oWZ6w5lwsmv4=; b=HBsk46CaOocW/1oIhQTdaU2YWrEICiKdWGKu4ZKgs7qvpVBmvildZd/bEgCiEKbqiO RPYXO+Ret09cI0WIspij5+anNJWHBVMruj+veU56AX1l7pHRbJl1bt6hq3X3C0yk8ema pZAj0YysYkR4F/fSdoGF1rC94qijWnVQ1PiDiZWrmBZXbPY3EBGGf7NW1p2KdGsDZ/ez uyRWg0eY1nOvK7E2k2YRd5M8lCQUg8gzdcwrjmlJ4snsL21qUAOrq63TrmrrOyo0uc/2 uKIur0FCevxRs4x5oT4sgQLPIxFvx9EdHiA93RdQY1sdz7SWnnl66RBxDPWlvVGVPNbq aZUg== 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=QQuySiCRGCJ6RvPIQ/BSFIhGVMRh766oWZ6w5lwsmv4=; b=ZMCu73Ofj5h14RNkoMZxmnkvu2jcWui821lcwBwNPgUJTqtjMT8E9tHngJJ+f3mr9U Hpeyv6xXrRh0A8vqfABUN5TnqFK/3lP8MM4dHz7ORl2asryfy6HGSpdmj9bnqInMdoPJ /ahrH2s+/Q6hgVl/cUsMaNgyGHYWBCR9QWOcLsKfBd+Zkz8/T5jnZdBwy78iZd8hrM0Z POMg0qa2RvOvd4+uot3neHehX8LHj1KXOsgXJHo/AzTKIHbnNwRf0Kn/LDQQNqNbeqDk Qem90Vq/wud13g1+IeRajd0MVy+Eiqi1z7LOsv4b7+Qegc6Rwol1FJa4QullzSKVtHOT eqdw== X-Gm-Message-State: AOAM531gpzjuEbfdqehrPRtql3EtMtXq7SEd2rmKZMyp4Te/SYhxvHz0 YjofBYCyjpF+3iu81M99IJuYGYWSJRU= X-Google-Smtp-Source: ABdhPJxcxwbjgBmS5S7Od5qo4C/vjgUz/Mr0NzGn5XnSKA7RaYrosjsr0mT7mv79D4saIgkrMnnPAakU9Zc= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:24c6:b0:4fd:9038:74f0 with SMTP id d6-20020a056a0024c600b004fd903874f0mr13594229pfv.63.1648861747326; Fri, 01 Apr 2022 18:09:07 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:08:56 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-2-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 1/8] 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, "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). Signed-off-by: Maciej S. Szmigiero Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Maxim Levitsky --- 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 73b545278f5f..9a6dc2b38fcf 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -369,6 +369,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; @@ -606,7 +607,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; @@ -660,6 +662,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) @@ -743,7 +758,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, @@ -1422,6 +1437,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; @@ -1606,7 +1622,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 e246793cbeae..47e7427d0395 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.35.1.1094.g7c7d902a7c-goog From nobody Fri Jun 19 15:47:43 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 04E60C4332F for ; Sat, 2 Apr 2022 01:09:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353669AbiDBBLO (ORCPT ); Fri, 1 Apr 2022 21:11:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351069AbiDBBK7 (ORCPT ); Fri, 1 Apr 2022 21:10:59 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7CC148CCEE for ; Fri, 1 Apr 2022 18:09:09 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id h15-20020a17090aa88f00b001c9de032a8cso2414478pjq.2 for ; Fri, 01 Apr 2022 18:09:09 -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=8RHA9aUNJxFpM8yTJhP4ef1t/aKUFmzX6SMgtUXeSlU=; b=mu6m/a5O3VjsafgbIgGavNyaMXeK5i+9etdubuU+TMNUVKvHADJfk8RbYW9jX8JI6L fGcg3as7WwEUTD6BKHO8x+X8rl/KoQ0vXmuQKH+tbFQNlDrVvXZfTE7zAoIuYPNuYoyG 4rF6f4FEvRvKghKoT+T7LWlsqJkTfx+WAiA7dIFsjZBYLQK5i2aQ5Q3aDkknDP5IkLuK 8PZqwQKJXWZbP5fXXW8tZzVRpDTNYrHK2DY3GJtJN+1PdWtwqmiueLkl/nNduvbKONov n1k+OwCK0aN+DiRconoQP9ZKaQXkMGXCPrWjncL4jUH0SPVC14/yi5H2rq2jZXbaJ8IA nYUw== 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=8RHA9aUNJxFpM8yTJhP4ef1t/aKUFmzX6SMgtUXeSlU=; b=Zlb1Vs2W2hIPtvP07lITFFugPTb3Hh/ylsPx+xjQxxLay1+dlo2DO4Hd1zR4IqTbCj j2U1PqAgPXGKWgzrUalks4GTuzJR3p0ny+NnSxw8hPl/1sn2W4ws/U1Ie2xvYpQer3GZ k2z7vj3C4jzZm5iw7hfjlbfQZpwpdStmTZbgrLTbqnp+bhX9p7SDS1gH4UQeMaWU9EB1 Or48Y8CAyjh7Y7WGA+BDL4QjbHWMgXGHEXdOKn2Szn46Riq4bY4GODWkJP9npUTzNkts zxqtJf/SjQ63N20m7Weq0toFIuVDAM+7BEhLyGWDsvJ3xFxLSwNP/tVRsGjWLJ5QME3M wwtg== X-Gm-Message-State: AOAM530sjSE8AOhgjS+EFghB2Tj/bL4Mocj37ycNz4dZBaGW/muoNSMI 3PFTWIrCjf+iZcWva60uvUA9fHzyf+g= X-Google-Smtp-Source: ABdhPJz6eEt/o/RMT6jRF4o5mIUgYCP3Lxw3z5+HYs6xIhuayeX7wPusWKnd7JasHteXF2zCH0UcWHuQWv8= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:114e:b0:4c8:55f7:faad with SMTP id b14-20020a056a00114e00b004c855f7faadmr13709370pfm.86.1648861749019; Fri, 01 Apr 2022 18:09:09 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:08:57 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-3-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 2/8] KVM: SVM: Downgrade BUG_ON() to WARN_ON() in svm_inject_irq() 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, "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 There is no need to bring down the whole host just because there might be some issue with respect to guest GIF handling in KVM. Signed-off-by: Maciej S. Szmigiero 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 95b26dbfd561..2c86bd9176c6 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3383,7 +3383,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(!gif_set(svm)); =20 trace_kvm_inj_virq(vcpu->arch.interrupt.nr); ++vcpu->stat.irq_injections; --=20 2.35.1.1094.g7c7d902a7c-goog From nobody Fri Jun 19 15:47:43 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 CF172C433EF for ; Sat, 2 Apr 2022 01:09:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353656AbiDBBLQ (ORCPT ); Fri, 1 Apr 2022 21:11:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353506AbiDBBLB (ORCPT ); Fri, 1 Apr 2022 21:11:01 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14CBF8FE68 for ; Fri, 1 Apr 2022 18:09:11 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id fh22-20020a17090b035600b001c6a163499cso1894334pjb.2 for ; Fri, 01 Apr 2022 18:09:11 -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=Czzn9i/2i6B1OBdabyWFgGFqRWslyQJuAsyXE6/7mj0=; b=I/sR5Eyp0KnE20qAVSatSC9Qd8LA6B9L+YQcL1RO6LZoG+nQbxj7gR8VC+pSt159MB naW8IqzSxUtZ1tkcXuzCgT7fC4s7FNy2JBiqGuFCUJMOnwXaad4wfxO+RSJlGt2nKvta x8Lqh+z04e0vhr5s2mHUvv8LFCb7ORgxG0nTuZlyOWuMpkrGsYZOh+d9zG7eljfwEmpg lois9n6XSdpXL+FfqvQIWupDiB7tQCpF6alcGuoKdBg/DJVmUNxbOxLfSqj8ntciaMlV 8uVjEXlWKdmoAfv9fKjNkGOjM2f5M55lgONHC2aG3W0wwH5Z8xplGambc5G8kWZWdUA3 GhGg== 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=Czzn9i/2i6B1OBdabyWFgGFqRWslyQJuAsyXE6/7mj0=; b=X1yjQcIxpxtq1dtvTlHdA4WHX8Fv6pin6gSZljG/aMEtHarH9b1cJAlN44bUvudL7p xIWfp5weqRgYRoHRcw4QWGPZMiGNU7wNBZ2i6Ukxo8zQJ05gL6p5qYgFv+OIZ3tJWhfY 1V6yxZBHfpEGYSkB2pmKyky/534XMLMFSu4oiO8QGt/G273Yps67s6V+T/NxnOFzIqTi LzP76I+mQU3C2Hcwp10Du9lZrac4b/etG14INlBuFUv35FUQ/JE9TCgrlMeDjW7HBCdT +HfHYHOzFWke+VtFvBzmrtZoTEu1/JAMnDth2dkUlcyrR3QVbdls7PCLtn28UpaWxeJe Kd/Q== X-Gm-Message-State: AOAM531/133Ntr3fQ0ZaWn/nj6yXb2uBuBh5uqFPOO1gMC2R/UkJudgO 57uRniQzWadwUdLNdw1Y7JfQkGD87O8= X-Google-Smtp-Source: ABdhPJxUeBeLfnRYVU4NNoaIAkOp173uUFizIUjEgmhgVSqVzzTW/5EspfQz0Niq83TzQz2SLpLto22aL1Q= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:902:8c81:b0:156:7fee:643b with SMTP id t1-20020a1709028c8100b001567fee643bmr203850plo.59.1648861750610; Fri, 01 Apr 2022 18:09:10 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:08:58 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-4-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 3/8] 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, "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. Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3") Signed-off-by: Sean Christopherson Reviewed-by: Maxim Levitsky --- arch/x86/kvm/svm/svm.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 2c86bd9176c6..30cef3b10838 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3699,6 +3699,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; @@ -3715,13 +3727,9 @@ static void svm_complete_interrupts(struct kvm_vcpu = *vcpu) * but re-execute the instruction instead. Rewind RIP first * if we emulated INT3 before. */ - 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.35.1.1094.g7c7d902a7c-goog From nobody Fri Jun 19 15:47:43 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 ABCE8C433FE for ; Sat, 2 Apr 2022 01:09:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353678AbiDBBLU (ORCPT ); Fri, 1 Apr 2022 21:11:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353592AbiDBBLD (ORCPT ); Fri, 1 Apr 2022 21:11:03 -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 89B208FE68 for ; Fri, 1 Apr 2022 18:09:12 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id z8-20020a170903018800b001566875e0f5so1668387plg.21 for ; Fri, 01 Apr 2022 18:09:12 -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=7avyx91O5ONbDknYrTN91hag2V92Uiaf3yyc7ikJ6Oo=; b=lgN0JGg0wAU/S9xkkCMagwMhbjg+igv1CYSqU9NWY3LszidXgY9Q8mwSKtd0cN+kfP bbwg4h40YSIeXaYQyKZlaaD3Y1gdb9B4VINZmKU3T6ZvbTxe2t7Y8gDAD3ZnBDEZjCgj qG5lPOTOTYQ1rudMZVmQSZvIaffENRyCo7qIPIpLuPnyBlyk90j809EPFrK71YU/BFOk ALHT+cBCZJ5n9EQbfIka2+Pbe7xzXWWI3IycDUwkPM7/55Nw/Si1q3/WuWRZc1ERadnY 33HJeNGUtuLj+u2b9Ia8DrX1kuO/igrZ3L9FgTg8YxiQpeuN2rWqhtMvGg2tcENOx7F4 bVlA== 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=7avyx91O5ONbDknYrTN91hag2V92Uiaf3yyc7ikJ6Oo=; b=MrMZ8h4/IO35UjAa3wGLEMqLpKI1KvqN3Oeji6/kypds2EJUcEetFvL24Ca6PvYHAG 4Sc09X9F1QpEs8Y4yBsYVofUI+Oww/LFsQ3S68ITW2ys8Gn87VfiYhvbvaRcdTOmExns 4xPkxm/rkQ74ABjsYC/VTgbGfyoo4OQcPEMtKArOVGmibDE5KFEymjj03qjpq1X2idmv zrp00nM+Ko5R0YYdDKLqrTMhPbheJw2SX6vjRgiN87ICWmmCkhBuw+6TBqMwvGi3NhA6 oKVU96nqvIM19TQMrPSDN43zpUcUFYihzoGE0jujEKU9/iXGhRA0ImsB2jQK8op0XlXn sFZw== X-Gm-Message-State: AOAM533TIhbkUvAacicB18Q12HNwpPzvxuax7rewki2bhzzxhGzBlQUK M3wxYD4r66ONEwXt9pDSePMfja8Yj8A= X-Google-Smtp-Source: ABdhPJzvMNImKhhmy2dldTQRHr/5DfEDlkVSAfluMJDr/3Vdc7HuHvWtI4mJ23ei5/ubz4qjXLU7GsXO62Q= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:aa7:8256:0:b0:4e0:78ad:eb81 with SMTP id e22-20020aa78256000000b004e078adeb81mr13590929pfn.30.1648861752031; Fri, 01 Apr 2022 18:09:12 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:08:59 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-5-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 4/8] KVM: SVM: Stuff next_rip on emualted 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, "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. Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3") Signed-off-by: Sean Christopherson Reviewed-by: Maxim Levitsky --- arch/x86/kvm/svm/svm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 30cef3b10838..6ea8f16e39ac 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -391,6 +391,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; } --=20 2.35.1.1094.g7c7d902a7c-goog From nobody Fri Jun 19 15:47:43 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 9287BC433F5 for ; Sat, 2 Apr 2022 01:09:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353690AbiDBBL2 (ORCPT ); Fri, 1 Apr 2022 21:11:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43592 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353614AbiDBBLF (ORCPT ); Fri, 1 Apr 2022 21:11:05 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 348B78FE45 for ; Fri, 1 Apr 2022 18:09:14 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id o15-20020a17090aac0f00b001c6595a43dbso2405016pjq.4 for ; Fri, 01 Apr 2022 18:09:14 -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=Ol8exfApW6qp8ksY+lqUpF5z/oy5z9y8ZI2QOtFIzaY=; b=Mg+HcPSPAzhKgemV6VtSyQw1b+lZxkXiayU8hXXSVt6JO3BCHvxXvdSbAbQOTL7+Yp sxvAAyE2cJZIMrQwjYrdwNgEdaYb8oq0BOIfdnWcJ2r0R0lUZCQ0h1egoCn5Lqp8UHLj LdBk8g+GujiQY7A4CyhaTKH5gfXr2rXfIVZOpvRuooZYAX/tYWTMesQNuu4QIQIpakaj J77gqdAv3XNBVxnt9fwS8wkpo9hVd/eBSeaQmaNCzEHbMKC1zvGEKLyQOBbIJHOCyTvx Hs5SIDIKRbhwak/of+DWADUUjZTyKVz+w/bWKJN6FuLavdX//9ckRo5XlZoT8H/HEFKm 9z3g== 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=Ol8exfApW6qp8ksY+lqUpF5z/oy5z9y8ZI2QOtFIzaY=; b=cYldBAuAFglVfDIlkI/9/xgL2Xw6c0zSmry0RMgntJ5zVcryzXNAyDsdLwsK5Na1IW OzMBVGdVKqkZeAMvCjnGm3QryF1Q5zomlxlnWYnnlZ2OKt8ZATp4/aYJiSQWL4YukeAM pVrPziNgK9EIkz49L8oLO8LXf3mfRA9p0YqmSflPhAETmhC06fLd/ruuSYQYTwJ7Vt7a SwcB2FLYzQ6oRg8Zn2T6cohUJcGjqbV3GENZBeKMMIWTe2vUGJ0gZarMUlyZhBhqLxLl kf64CFynLMt7GehwEW31GvJrIFpYKBwtnY0VdOHN00GpfDZrtS8zPsvc6+zKQkDzdPDR Oz0w== X-Gm-Message-State: AOAM531kxyi3aZOsc4vLlklUhG9J1CQy+aPG5dupZ5mg9aj2vaTVYjdF Y3ydptyne+4shglBAj38PJqcFvNbz4Y= X-Google-Smtp-Source: ABdhPJwh/+tkHKjROpI8f4YVjL3HYSEb25RxtMSK2Di63Mhnl5I5MjZhGP/4LburLgNSPXEAy1Gz5q6Y8DM= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90b:2246:b0:1c6:5781:7193 with SMTP id hk6-20020a17090b224600b001c657817193mr14995812pjb.48.1648861753762; Fri, 01 Apr 2022 18:09:13 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:09:00 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-6-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 5/8] 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, "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_ript, and then unwind the RIP write and any side effects (RFLAGS updates). Reported-by: Maciej S. Szmigiero Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/svm.c | 111 ++++++++++++++++++++++++++++------------- arch/x86/kvm/svm/svm.h | 4 +- 2 files changed, 79 insertions(+), 36 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 6ea8f16e39ac..ecc828d6921e 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -341,9 +341,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 @@ -358,18 +360,71 @@ 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); + + /* + * If NextRIP is supported, rewind RIP and update NextRip. If NextRip + * isn't supported, keep the result of the skip as the CPU obviously + * won't advance RIP, but stash away the injection information so that + * RIP can be unwound if injection fails. + */ + if (nrips) { + kvm_rip_write(vcpu, old_rip); + svm->vmcb->control.next_rip =3D rip; + } else { + if (boot_cpu_has(X86_FEATURE_NRIPS)) + svm->vmcb->control.next_rip =3D rip; + + svm->soft_int_linear_rip =3D rip + svm->vmcb->save.cs.base; + svm->soft_int_injected =3D rip - old_rip; + } + return 0; +} + static void svm_queue_exception(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm =3D to_svm(vcpu); @@ -379,25 +434,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 @@ -3676,9 +3715,9 @@ static void svm_complete_interrupts(struct kvm_vcpu *= vcpu) u8 vector; int type; u32 exitintinfo =3D svm->vmcb->control.exit_int_info; - unsigned int3_injected =3D svm->int3_injected; + unsigned soft_int_injected =3D svm->soft_int_injected; =20 - svm->int3_injected =3D 0; + svm->soft_int_injected =3D 0; =20 /* * If we've made progress since setting HF_IRET_MASK, we've @@ -3698,6 +3737,18 @@ static void svm_complete_interrupts(struct kvm_vcpu = *vcpu) if (!(exitintinfo & SVM_EXITINTINFO_VALID)) return; =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 (soft_int_injected && + kvm_is_linear_rip(vcpu, to_svm(vcpu)->soft_int_linear_rip)) + kvm_rip_write(vcpu, kvm_rip_read(vcpu) - soft_int_injected); + kvm_make_request(KVM_REQ_EVENT, vcpu); =20 vector =3D exitintinfo & SVM_EXITINTINFO_VEC_MASK; @@ -3711,9 +3762,9 @@ static void svm_complete_interrupts(struct kvm_vcpu *= vcpu) * 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 && type =3D=3D SVM_EXITINTINFO_TYPE_EXEPT && + kvm_is_linear_rip(vcpu, svm->soft_int_linear_rip)) + kvm_rip_write(vcpu, kvm_rip_read(vcpu) - soft_int_injected); =20 switch (type) { case SVM_EXITINTINFO_TYPE_NMI: @@ -3726,14 +3777,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. Rewind RIP first - * if we emulated INT3 before. - */ - 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 47e7427d0395..a770a1c7ddd2 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -230,8 +230,8 @@ struct vcpu_svm { bool nmi_singlestep; u64 nmi_singlestep_guest_rflags; =20 - unsigned int3_injected; - unsigned long int3_rip; + unsigned soft_int_injected; + unsigned long soft_int_linear_rip; =20 /* optional nested SVM features that are enabled for this guest */ bool nrips_enabled : 1; --=20 2.35.1.1094.g7c7d902a7c-goog From nobody Fri Jun 19 15:47:43 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 90C4FC433F5 for ; Sat, 2 Apr 2022 01:09:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241384AbiDBBLp (ORCPT ); Fri, 1 Apr 2022 21:11:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43594 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353642AbiDBBLI (ORCPT ); Fri, 1 Apr 2022 21:11:08 -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 1403492D3B for ; Fri, 1 Apr 2022 18:09:16 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id p9-20020a63f449000000b0035ec8c16f0bso2356860pgk.11 for ; Fri, 01 Apr 2022 18:09: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=i0u4JArrhDsLDMn+I/rLz2mNP22Vvf7YGTWgik9+mpU=; b=qVDGL0IdD2Tdx7CvPjoGFys1TnI3wEvpBvsUv8P9V8q3FTljNfYJ2DPnWLfm/35OzJ PbT6IaDPucWH4KICB7hzdigaoj7xvylWvGxJeXIi+P9ovIJ148bq9LI//YlDaqEzycU2 H/Pec4/sMRC9KWL7rORgGHEqFqi2d2F97le923SgGv2YQbfootQxz9AvlO1zdiO1VdEF 3mWwX4hpVHo+UInfjOKAbUMF9PORaispXqGHyqdBTBY7jvasQQJ116Ey0kXxNHfncbBx UBr1yRcFTaFzGw3N7BwncRChA6aQNMe5g41GnN18St3Rs3Jk1uO1hEPfkW5BKVbj6Z8p cNCA== 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=i0u4JArrhDsLDMn+I/rLz2mNP22Vvf7YGTWgik9+mpU=; b=8MwIrlUFIioHvqdMg77yHc9xa9+tHoAuhfS/TMiibZ6OTdFIHxcLDSaPStZ8MWogLo C36QSkuLxDzkdEpgTLEZi1F1qfL7QRyr6nEH5K0MXJtIhVbs+X2dV8UHX3z4aGBGd5FG 2uUKUliJ5iIZYPcRRJz8M4y/suyR3dbqNxnEi0SVZcmwXug1JhtYjgAxF8Opuv97h+2D OoSS5y+SHS9va1rScCAdRLIokZe2SWoZ5pcGZ3269RMpW/K6x/1pOLiQYmhatOuKsimA eceJtElGbnFR9I4fqL49BwXAK6P8sKH4Js5ijRVM0SL1W/8kz7hx2Xpy04ifa2UMT6Pf rIKQ== X-Gm-Message-State: AOAM532jPJ4yoYPHNeTKXT4zjnv2Pxu19/9CktShavJBQM5cJm7ilbB9 Q/CxYG/i6oZGTmQUucti1r00vq8tTx0= X-Google-Smtp-Source: ABdhPJw+XcYjlX+TSsfNHGCX0p23GeF8EZ6cBnRjeUKPNISQbQvhYa3RrRsEt0XFpT2wLgjalMQPqT+9e+Y= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:10c2:b0:4fd:a140:d5a9 with SMTP id d2-20020a056a0010c200b004fda140d5a9mr13602205pfu.77.1648861755423; Fri, 01 Apr 2022 18:09:15 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:09:01 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-7-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 6/8] 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, "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/svm.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index ecc828d6921e..00b1399681d1 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3425,14 +3425,24 @@ 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(!gif_set(svm)); =20 + if (vcpu->arch.interrupt.soft) { + if (svm_update_soft_interrupt_rip(vcpu)) + return; + + type =3D SVM_EVTINJ_TYPE_SOFT; + } else { + type =3D SVM_EVTINJ_TYPE_INTR; + } + 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, @@ -3787,9 +3797,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.35.1.1094.g7c7d902a7c-goog From nobody Fri Jun 19 15:47:43 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 B2533C433EF for ; Sat, 2 Apr 2022 01:09:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353705AbiDBBLk (ORCPT ); Fri, 1 Apr 2022 21:11:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43880 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353648AbiDBBLI (ORCPT ); Fri, 1 Apr 2022 21:11:08 -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 A1BA99AE5D for ; Fri, 1 Apr 2022 18:09:17 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id 138-20020a621690000000b004fa807ac59aso2421205pfw.19 for ; Fri, 01 Apr 2022 18:09:17 -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=ypH5s9Nl45kyR4SuhKSlPLb77qSDCCBtuo3KelNxUkU=; b=BXvV6YKppMwrneibybdzCprZebgaEvZuaku3g2RP08ReeutXggwQUvUEMu2PdJkNW/ A0OeCGqKs5NsravDHk7WH5WR0/9K3xTlj8jSH5jMz19zxO6c5vICa+jOJdm5PfsonavW GzlcTn15RsgJexM1+R6HT8bULRuo8uhHwG/io90+NPf/VUA7DQY/rjEYkotOnuiffcK2 2mFahGJuY3hMiBB5eajBIsKa9CNmYVcV2NmeyNJkeCK4SyDKmR9+hi58C4dcY/ftu9Oz KYZ1yWUU+lOeGCrRX8XJdUgsmNpaGFeCwI1uNGOM1KALML8V9ri800OZVVfpYSo6aR9t X4gg== 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=ypH5s9Nl45kyR4SuhKSlPLb77qSDCCBtuo3KelNxUkU=; b=aqZqu9JhO1BV24sb/M/gUUTGLrPzbEEbcfwY7OHc3pXMtwpPky1RSJHUA3tJF/9x6r ucoviCEWJ086c7M+kU2NWJ4gzJPRZD7HiToDRZsQb6DyJZQMZYIKhhnO/1Lu5qupgPEs ejuTcrp2xcoKij1xsAe0gClx/wL9o+zFWc+Hiwf9JKNgCVa5LFhbTL9OOlFWUvx5Q/RL Ic+eqbq6TmJfWKSj8OB6kNV5QEaPhCv3bJLS/RicCiy+AgWGbCvP7iyetFJmkfKxHCmr BYwJhSC0NUBi6Gn4Fo5ZnIu9XA7NIKMwbAMA86xiY+KWUOqokMy9V1WGBMh27gfAzd1F JwPQ== X-Gm-Message-State: AOAM531YFF+DQc2rrS9yL0KaYfht179WG9+5F+UWAg+zbRwcjAHk/D94 5LlPFuoS4Wgb6lCijFs1SIkRYiCP4wU= X-Google-Smtp-Source: ABdhPJwVqOaLLTOsAFXe7H2DrUpM4AjNGa3ENYnyWHTSNot0jahAIZOQE0GVR+TBjQ6kE1cm0gpXEbB0OFA= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:902:bf06:b0:14d:8c72:96c6 with SMTP id bi6-20020a170902bf0600b0014d8c7296c6mr13129728plb.156.1648861757108; Fri, 01 Apr 2022 18:09:17 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:09:02 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-8-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 7/8] 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, "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. Signed-off-by: Sean Christopherson --- arch/x86/kvm/x86.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7a066cf92692..384091600bc2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9382,6 +9382,10 @@ 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); + if (vcpu->arch.exception.error_code && !is_protmode(vcpu)) vcpu->arch.exception.error_code =3D false; static_call(kvm_x86_queue_exception)(vcpu); @@ -9439,10 +9443,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; =20 --=20 2.35.1.1094.g7c7d902a7c-goog From nobody Fri Jun 19 15:47:43 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 7A6AAC433F5 for ; Sat, 2 Apr 2022 01:09:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353698AbiDBBLh (ORCPT ); Fri, 1 Apr 2022 21:11:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353675AbiDBBLO (ORCPT ); Fri, 1 Apr 2022 21:11:14 -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 5F3E0A145D for ; Fri, 1 Apr 2022 18:09:19 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id z8-20020a170903018800b001566875e0f5so1668480plg.21 for ; Fri, 01 Apr 2022 18:09: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=OExX1Igb+SEI7PdUVeKXKi/G1aHbfTSQe6uvI8ZE66s=; b=QoWYxsIze+C3Ee47cmi+k5goTPGx2Io4H2IyLGbi5BL+YuSOtk8JZB9VbBiKfn+5KE tyrkF6Zyy4naj8XbTkWvhkg/sFU+thgF+DR7zGxHaU0Zufu1ol74uxq4AXOtb0GAHX2+ RCwbWhRxvZMYnWlv5Pel0agogKAldZa+yRq1pBY6qslSIaYI1EsqNARyskD1VinUqj37 0o4B7ukkXknlytvlvFrKfIN3Log0v9sa7s+sDwVihw3X5My32CK4QQgkdwX9QMxI0OCg rolELI0I7ldjj+6WJTt4XTF7oYy1R+nt/GzVXksOb23zb7L7SLrRPoB+qBeferqjl3zT i/Qg== 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=OExX1Igb+SEI7PdUVeKXKi/G1aHbfTSQe6uvI8ZE66s=; b=pNtPBwdUOHqGAUkj/ukfOwn/c14196ZqQD26UxgS5MIbGZvWAz5D00qtYxakYDSMro gEiE4kW1fo2+hUPUkbe/w9BdbztSjOvWDh7YFUSZdktv0A2TTjhspV0vCA5Gwvg3EWsQ reNhrNFl1UJEVI2ckBrPDvc7+Eruak7bFJbkMK0hQ/1dum8xEp6TAa7V8l7zBO1nw1Ic C/AeLDriILP486aD5EWT2Hq9WfAJIGJCcRMc7z/xFdW/0a//Wz8WlT3M/BzN1W0Ze96G PR4rwdmekiw/kI1IM8DQ37rFHq9Bk+LcKGz54xJ9zoJcQ6KrrXnk4suThUHtQJ4E7KxN v2aQ== X-Gm-Message-State: AOAM533zN8NkGR4f7eEUz2xw/+A3/ceCiT/MHiT7Y4cXmDXgl4MDWH3D rb4rHUz7g99mB39FzIjjXsqYmNzkLpY= X-Google-Smtp-Source: ABdhPJySbHKlONilMxgSTz0tRz1iIrI+IQGst6MP1o+Dhm9cpdIUyvg75yFzuaUSapncQePMHGO9Y0zty3A= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a63:6d4c:0:b0:398:7c40:c160 with SMTP id i73-20020a636d4c000000b003987c40c160mr17309928pgc.109.1648861758524; Fri, 01 Apr 2022 18:09:18 -0700 (PDT) Reply-To: Sean Christopherson Date: Sat, 2 Apr 2022 01:09:03 +0000 In-Reply-To: <20220402010903.727604-1-seanjc@google.com> Message-Id: <20220402010903.727604-9-seanjc@google.com> Mime-Version: 1.0 References: <20220402010903.727604-1-seanjc@google.com> X-Mailer: git-send-email 2.35.1.1094.g7c7d902a7c-goog Subject: [PATCH 8/8] 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, "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. Signed-off-by: Maciej S. Szmigiero Signed-off-by: Sean Christopherson Reviewed-by: Maxim levitsky --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/include/x86_64/svm_util.h | 2 + .../kvm/x86_64/svm_nested_soft_inject_test.c | 147 ++++++++++++++++++ 4 files changed, 151 insertions(+) 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 1f1b6c978bf7..1354d3f4a362 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -33,6 +33,7 @@ /x86_64/state_test /x86_64/svm_vmcall_test /x86_64/svm_int_ctl_test +/x86_64/svm_nested_soft_inject_test /x86_64/sync_regs_test /x86_64/tsc_msrs_test /x86_64/userspace_io_test diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests= /kvm/Makefile index c9cdbd248727..cef6d583044b 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..d39be5d885c1 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c @@ -0,0 +1,147 @@ +// 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 guest_int_handler(struct ex_regs *regs) +{ + int_fired++; +} + +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.35.1.1094.g7c7d902a7c-goog