From nobody Sun Apr 5 18:17:37 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 72FAD2E03F1 for ; Sat, 28 Feb 2026 03:33:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772249620; cv=none; b=cqABvg27FYqAmdfxNN4O1HBsKWNkgAerRUuTGjyWqFcI2zVKdcGUzflGSbL3VAq/EbfJeWVca/2JwLMB7HNKLMBggCtx5EZEhz2kNFnBDZ6UTasYVyoLaO2Tz990uiTqzz0vqLHnsRFHehB46MR6KeGDoOSlnZFiO9pou0z9704= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772249620; c=relaxed/simple; bh=/lCxiHbvKeja+uJyJNRaWhTwWnRWmN3ecTB1MEqsjPs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=f5QdRyCGYVPiTCnaAChy/5L4dulDIR3f317Sswzs5iyjLzba488Hqdsp4Pe9O7MXGRvKIVgTOpb4LjM/8CXyl4YUCet0IDp+QF3R1nf2d8TlrOLH+/xdkWaTMUC1oDbPxjnNAaDuSZwqYLhfBjxth01q2lnOOUHscq+7cPN+Ckc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--chengkev.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=aVcInqJu; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--chengkev.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="aVcInqJu" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2aaeafeadbcso29090725ad.1 for ; Fri, 27 Feb 2026 19:33:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772249619; x=1772854419; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=zzK+ahrN0WrI65Z8BtzgCkPZKdVkUFBx57SYFZxh0S8=; b=aVcInqJullGrn8lOqBWKmJSXiZiCYX8JJuMsK2j3Xs7MdYwl59Tl/RP2sWt402/9Sp eXpFqAQxWi7lADL0JFOTU3+tblhmrp72YwsjsQAftjtvD18s2er3jNH4+PuQfuaIScXA spQOstvGflDaiwFdrlPhRzQdMv65kosbtbjzN+ro7esGKC4WaZ0P3H5ww25FOmhqJ9KN zOouHD3n0RXubNxBsA7/llhenCbn5sMNRbqJYkSlbqoVTPazFuj0FkttFB7At2Yqy58g ppB12taDb8e5EtmHoNQTXMeVeK6i3w/9W6kzEM62TLz6j9yXxP9trajNlilPy4QLBWnV OK0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772249619; x=1772854419; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=zzK+ahrN0WrI65Z8BtzgCkPZKdVkUFBx57SYFZxh0S8=; b=v7DVeW5jGHZt3Bd/yX97BB5O1kDLQCIKcINQilbHrthWOmBwf4SadNKjjROREhVJwf 9x8Biiep2Pg7wuOnFpGXN1/fONTTOiXwmpBlbpSDp+breQtNtPdbvQbJInZYk8Pn8r4i vXzBaXVVuwuniHO4w8eW/VwdjyZ7kXm90hW0D6oMPe/rbqE5xFq4NuQNOxbd+6EJ3Xtz iXE8ipjRMes5HKBEH8gco/1SLP0LJuMV5S/6/QdWeLeGBT0/FlyuUt0xtQPkCQ0x6RSr hDz9lwMdF/+xQu0qed204kp5r8vp5+iVFEdP/+0io4aiTjJ10amOgly6g50no8eUhEl+ wC/Q== X-Forwarded-Encrypted: i=1; AJvYcCUR3JpJH5WWaZQufiDKzL334bJ49lE6hShg1cwNdfSfrdorOaJ+o7hX5Bcn67oBaBccK9TJFS/dvtZ6QjE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx0m5RuLfGt2gh+mpFSZ3DIZo1xFMLRFa1GuUhP0MAW/cItxVPB BwTc/V/dNDI8yIW2u2e/K8YoH+3dO1Scdbv7kIhrWkO5HTCq2z0S9lesmmBJ+nYdaaLSMd5w6kv 5gSZOYn+iirnPVw== X-Received: from plkg16.prod.google.com ([2002:a17:903:19d0:b0:298:1151:5f6d]) (user=chengkev job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:18b:b0:2ad:da26:c2c4 with SMTP id d9443c01a7336-2ae2e3ce810mr48921795ad.9.1772249618503; Fri, 27 Feb 2026 19:33:38 -0800 (PST) Date: Sat, 28 Feb 2026 03:33:28 +0000 In-Reply-To: <20260228033328.2285047-1-chengkev@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260228033328.2285047-1-chengkev@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260228033328.2285047-5-chengkev@google.com> Subject: [PATCH V4 4/4] KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted From: Kevin Cheng To: seanjc@google.com, pbonzini@redhat.com Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, yosry@kernel.org, Kevin Cheng Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The AMD APM states that if VMMCALL instruction is not intercepted, the instruction raises a #UD exception. Create a vmmcall exit handler that generates a #UD if a VMMCALL exit from L2 is being handled by L0, which means that L1 did not intercept the VMMCALL instruction. The exception to this is if the exiting instruction was for Hyper-V L2 TLB flush hypercalls as they are handled by L0. Suggested-by: Sean Christopherson Signed-off-by: Kevin Cheng --- arch/x86/kvm/svm/hyperv.h | 11 +++++++++++ arch/x86/kvm/svm/nested.c | 4 +--- arch/x86/kvm/svm/svm.c | 19 ++++++++++++++++++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/svm/hyperv.h b/arch/x86/kvm/svm/hyperv.h index d3f8bfc05832e..9af03970d40c2 100644 --- a/arch/x86/kvm/svm/hyperv.h +++ b/arch/x86/kvm/svm/hyperv.h @@ -41,6 +41,13 @@ static inline bool nested_svm_l2_tlb_flush_enabled(struc= t kvm_vcpu *vcpu) return hv_vcpu->vp_assist_page.nested_control.features.directhypercall; } +static inline bool nested_svm_is_l2_tlb_flush_hcall(struct kvm_vcpu *vcpu) +{ + return guest_hv_cpuid_has_l2_tlb_flush(vcpu) && + nested_svm_l2_tlb_flush_enabled(vcpu) && + kvm_hv_is_tlb_flush_hcall(vcpu); +} + void svm_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu); #else /* CONFIG_KVM_HYPERV */ static inline void nested_svm_hv_update_vm_vp_ids(struct kvm_vcpu *vcpu) {} @@ -48,6 +55,10 @@ static inline bool nested_svm_l2_tlb_flush_enabled(struc= t kvm_vcpu *vcpu) { return false; } +static inline bool nested_svm_is_l2_tlb_flush_hcall(struct kvm_vcpu *vcpu) +{ + return false; +} static inline void svm_hv_inject_synthetic_vmexit_post_tlb_flush(struct kv= m_vcpu *vcpu) {} #endif /* CONFIG_KVM_HYPERV */ diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index de90b104a0dd5..45d1496031a74 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1674,9 +1674,7 @@ int nested_svm_exit_special(struct vcpu_svm *svm) } case SVM_EXIT_VMMCALL: /* Hyper-V L2 TLB flush hypercall is handled by L0 */ - if (guest_hv_cpuid_has_l2_tlb_flush(vcpu) && - nested_svm_l2_tlb_flush_enabled(vcpu) && - kvm_hv_is_tlb_flush_hcall(vcpu)) + if (nested_svm_is_l2_tlb_flush_hcall(vcpu)) return NESTED_EXIT_HOST; break; default: diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index f8f9b7a124c36..d662d5ce986ac 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -52,6 +52,7 @@ #include "svm.h" #include "svm_ops.h" +#include "hyperv.h" #include "kvm_onhyperv.h" #include "svm_onhyperv.h" @@ -3258,6 +3259,22 @@ static int bus_lock_exit(struct kvm_vcpu *vcpu) return 0; } +static int vmmcall_interception(struct kvm_vcpu *vcpu) +{ + /* + * Per the AMD APM, VMMCALL raises #UD if the VMMCALL intercept + * is not set. For an L2 guest, inject #UD as L1 did not intercept + * VMMCALL, except for Hyper-V L2 TLB flush hypercalls as they + * are handled by L0. + */ + if (is_guest_mode(vcpu) && !nested_svm_is_l2_tlb_flush_hcall(vcpu)) { + kvm_queue_exception(vcpu, UD_VECTOR); + return 1; + } + + return kvm_emulate_hypercall(vcpu); +} + static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) =3D { [SVM_EXIT_READ_CR0] =3D cr_interception, [SVM_EXIT_READ_CR3] =3D cr_interception, @@ -3308,7 +3325,7 @@ static int (*const svm_exit_handlers[])(struct kvm_vc= pu *vcpu) =3D { [SVM_EXIT_TASK_SWITCH] =3D task_switch_interception, [SVM_EXIT_SHUTDOWN] =3D shutdown_interception, [SVM_EXIT_VMRUN] =3D vmrun_interception, - [SVM_EXIT_VMMCALL] =3D kvm_emulate_hypercall, + [SVM_EXIT_VMMCALL] =3D vmmcall_interception, [SVM_EXIT_VMLOAD] =3D vmload_interception, [SVM_EXIT_VMSAVE] =3D vmsave_interception, [SVM_EXIT_STGI] =3D stgi_interception, -- 2.53.0.473.g4a7958ca14-goog