From: Binbin Wu <binbin.wu@linux.intel.com>
To: pbonzini@redhat.com, seanjc@google.com, kvm@vger.kernel.org
Cc: rick.p.edgecombe@intel.com, kai.huang@intel.com,
adrian.hunter@intel.com, reinette.chatre@intel.com,
xiaoyao.li@intel.com, tony.lindgren@intel.com,
isaku.yamahata@intel.com, yan.y.zhao@intel.com,
chao.gao@intel.com, linux-kernel@vger.kernel.org,
binbin.wu@linux.intel.com
Subject: [PATCH v3 11/16] KVM: TDX: Force APICv active for TDX guest
Date: Sat, 22 Feb 2025 09:47:52 +0800 [thread overview]
Message-ID: <20250222014757.897978-12-binbin.wu@linux.intel.com> (raw)
In-Reply-To: <20250222014757.897978-1-binbin.wu@linux.intel.com>
From: Isaku Yamahata <isaku.yamahata@intel.com>
Force APICv active for TDX guests in KVM because APICv is always enabled
by TDX module.
From the view of KVM, whether APICv state is active or not is decided by:
1. APIC is hw enabled
2. VM and vCPU have no inhibit reasons set.
After TDX vCPU init, APIC is set to x2APIC mode. KVM_SET_{SREGS,SREGS2} are
rejected due to has_protected_state for TDs and guest_state_protected
for TDX vCPUs are set. Reject KVM_{GET,SET}_LAPIC from userspace since
migration is not supported yet, so that userspace cannot disable APIC.
For various APICv inhibit reasons:
- APICV_INHIBIT_REASON_DISABLED is impossible after checking enable_apicv
in tdx_bringup(). If !enable_apicv, TDX support will be disabled.
- APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED is impossible since x2APIC is
mandatory, KVM emulates APIC_ID as read-only for x2APIC mode. (Note:
APICV_INHIBIT_REASON_PHYSICAL_ID_ALIASED could be set if the memory
allocation fails for KVM apic_map.)
- APICV_INHIBIT_REASON_HYPERV is impossible since TDX doesn't support
HyperV guest yet.
- APICV_INHIBIT_REASON_ABSENT is impossible since in-kernel LAPIC is
checked in tdx_vcpu_create().
- APICV_INHIBIT_REASON_BLOCKIRQ is impossible since TDX doesn't support
KVM_SET_GUEST_DEBUG.
- APICV_INHIBIT_REASON_APIC_ID_MODIFIED is impossible since x2APIC is
mandatory.
- APICV_INHIBIT_REASON_APIC_BASE_MODIFIED is impossible since KVM rejects
userspace to set APIC base.
- The rest inhibit reasons are relevant only to AMD's AVIC, including
APICV_INHIBIT_REASON_NESTED, APICV_INHIBIT_REASON_IRQWIN,
APICV_INHIBIT_REASON_PIT_REINJ, APICV_INHIBIT_REASON_SEV, and
APICV_INHIBIT_REASON_LOGICAL_ID_ALIASED.
(For APICV_INHIBIT_REASON_PIT_REINJ, similar to AVIC, KVM can't intercept
EOI for TDX guests neither, but KVM enforces KVM_IRQCHIP_SPLIT for TDX
guests, which eliminates the in-kernel PIT.)
Implement vt_refresh_apicv_exec_ctrl() to call KVM_BUG_ON() if APICv is
disabled for TDX guests.
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Co-developed-by: Binbin Wu <binbin.wu@linux.intel.com>
Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
---
TDX interrupts v3:
- No change.
TDX interrupts v2:
- Renamed from "KVM: TDX: Inhibit APICv for TDX guest"
- Check enable_apicv in tdx_bringup().
- Changed APICv active state from always false to true for TDX guests. (Sean)
- Reject KVM_{GET,SET}_LAPIC from userspace.
- Implement vt_refresh_apicv_exec_ctrl() to bug the VM if APICv is
disabled.
TDX interrupts v1:
- Removed WARN_ON_ONCE(kvm_apicv_activated(vcpu->kvm)) in
tdx_td_vcpu_init(). (Rick)
- Change APICV -> APICv in changelog for consistency.
- Split the changelog to 2 paragraphs.
---
arch/x86/kvm/vmx/main.c | 12 +++++++++++-
arch/x86/kvm/vmx/tdx.c | 5 +++++
arch/x86/kvm/x86.c | 6 ++++++
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c
index 6a066b7fb3dc..7d10b15cce27 100644
--- a/arch/x86/kvm/vmx/main.c
+++ b/arch/x86/kvm/vmx/main.c
@@ -437,6 +437,16 @@ static void vt_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
vmx_get_exit_info(vcpu, reason, info1, info2, intr_info, error_code);
}
+static void vt_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
+{
+ if (is_td_vcpu(vcpu)) {
+ KVM_BUG_ON(!kvm_vcpu_apicv_active(vcpu), vcpu->kvm);
+ return;
+ }
+
+ vmx_refresh_apicv_exec_ctrl(vcpu);
+}
+
static int vt_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
{
if (!is_td(kvm))
@@ -553,7 +563,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
.x2apic_icr_is_split = false,
.set_virtual_apic_mode = vmx_set_virtual_apic_mode,
.set_apic_access_page_addr = vmx_set_apic_access_page_addr,
- .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
+ .refresh_apicv_exec_ctrl = vt_refresh_apicv_exec_ctrl,
.load_eoi_exitmap = vmx_load_eoi_exitmap,
.apicv_pre_state_restore = vt_apicv_pre_state_restore,
.required_apicv_inhibits = VMX_REQUIRED_APICV_INHIBITS,
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index e2288ec5d1a5..532c2557ca0d 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -3071,6 +3071,11 @@ int __init tdx_bringup(void)
goto success_disable_tdx;
}
+ if (!enable_apicv) {
+ pr_err("APICv is required for TDX\n");
+ goto success_disable_tdx;
+ }
+
if (!cpu_feature_enabled(X86_FEATURE_MOVDIR64B)) {
pr_err("MOVDIR64B is reqiured for TDX\n");
goto success_disable_tdx;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7b5f5f603ceb..a144dbc81ac4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5105,6 +5105,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s)
{
+ if (vcpu->arch.apic->guest_apic_protected)
+ return -EINVAL;
+
kvm_x86_call(sync_pir_to_irr)(vcpu);
return kvm_apic_get_state(vcpu, s);
@@ -5115,6 +5118,9 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
{
int r;
+ if (vcpu->arch.apic->guest_apic_protected)
+ return -EINVAL;
+
r = kvm_apic_set_state(vcpu, s);
if (r)
return r;
--
2.46.0
next prev parent reply other threads:[~2025-02-22 1:46 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-22 1:47 [PATCH v3 00/16] KVM: TDX: TDX interrupts Binbin Wu
2025-02-22 1:47 ` [PATCH v3 01/16] KVM: TDX: Add support for find pending IRQ in a protected local APIC Binbin Wu
2025-02-22 1:47 ` [PATCH v3 02/16] KVM: TDX: Disable PI wakeup for IPIv Binbin Wu
2025-02-22 1:47 ` [PATCH v3 03/16] KVM: VMX: Move posted interrupt delivery code to common header Binbin Wu
2025-03-12 18:39 ` Paolo Bonzini
2025-02-22 1:47 ` [PATCH v3 04/16] KVM: TDX: Implement non-NMI interrupt injection Binbin Wu
2025-02-26 6:14 ` Chenyi Qiang
2025-02-22 1:47 ` [PATCH v3 05/16] KVM: x86: Assume timer IRQ was injected if APIC state is protected Binbin Wu
2025-02-22 1:47 ` [PATCH v3 06/16] KVM: TDX: Wait lapic expire when timer IRQ was injected Binbin Wu
2025-02-22 1:47 ` [PATCH v3 07/16] KVM: TDX: Implement methods to inject NMI Binbin Wu
2025-02-22 1:47 ` [PATCH v3 08/16] KVM: TDX: Handle SMI request as !CONFIG_KVM_SMM Binbin Wu
2025-02-22 1:47 ` [PATCH v3 09/16] KVM: TDX: Always block INIT/SIPI Binbin Wu
2025-02-22 1:47 ` [PATCH v3 10/16] KVM: TDX: Enforce KVM_IRQCHIP_SPLIT for TDX guests Binbin Wu
2025-02-22 1:47 ` Binbin Wu [this message]
2025-02-22 1:47 ` [PATCH v3 12/16] KVM: TDX: Add methods to ignore virtual apic related operation Binbin Wu
2025-02-22 1:47 ` [PATCH v3 13/16] KVM: VMX: Move emulation_required to struct vcpu_vt Binbin Wu
2025-02-22 1:47 ` [PATCH v3 14/16] KVM: VMX: Add a helper for NMI handling Binbin Wu
2025-02-22 1:47 ` [PATCH v3 15/16] KVM: TDX: Handle EXCEPTION_NMI and EXTERNAL_INTERRUPT Binbin Wu
2025-02-22 1:47 ` [PATCH v3 16/16] KVM: TDX: Handle EXIT_REASON_OTHER_SMI Binbin Wu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250222014757.897978-12-binbin.wu@linux.intel.com \
--to=binbin.wu@linux.intel.com \
--cc=adrian.hunter@intel.com \
--cc=chao.gao@intel.com \
--cc=isaku.yamahata@intel.com \
--cc=kai.huang@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=reinette.chatre@intel.com \
--cc=rick.p.edgecombe@intel.com \
--cc=seanjc@google.com \
--cc=tony.lindgren@intel.com \
--cc=xiaoyao.li@intel.com \
--cc=yan.y.zhao@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox