Skip to content

Commit f65916a

Browse files
yamahatabonzini
authored andcommitted
KVM: TDX: Force APICv active for TDX guest
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> Message-ID: <20250222014757.897978-12-binbin.wu@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 209afc0 commit f65916a

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

arch/x86/kvm/vmx/main.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,16 @@ static void vt_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason,
437437
vmx_get_exit_info(vcpu, reason, info1, info2, intr_info, error_code);
438438
}
439439

440+
static void vt_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
441+
{
442+
if (is_td_vcpu(vcpu)) {
443+
KVM_BUG_ON(!kvm_vcpu_apicv_active(vcpu), vcpu->kvm);
444+
return;
445+
}
446+
447+
vmx_refresh_apicv_exec_ctrl(vcpu);
448+
}
449+
440450
static int vt_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
441451
{
442452
if (!is_td(kvm))
@@ -553,7 +563,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
553563
.x2apic_icr_is_split = false,
554564
.set_virtual_apic_mode = vmx_set_virtual_apic_mode,
555565
.set_apic_access_page_addr = vmx_set_apic_access_page_addr,
556-
.refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
566+
.refresh_apicv_exec_ctrl = vt_refresh_apicv_exec_ctrl,
557567
.load_eoi_exitmap = vmx_load_eoi_exitmap,
558568
.apicv_pre_state_restore = vt_apicv_pre_state_restore,
559569
.required_apicv_inhibits = VMX_REQUIRED_APICV_INHIBITS,

arch/x86/kvm/vmx/tdx.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,6 +3058,11 @@ int __init tdx_bringup(void)
30583058
goto success_disable_tdx;
30593059
}
30603060

3061+
if (!enable_apicv) {
3062+
pr_err("APICv is required for TDX\n");
3063+
goto success_disable_tdx;
3064+
}
3065+
30613066
if (!cpu_feature_enabled(X86_FEATURE_OSXSAVE)) {
30623067
pr_err("tdx: OSXSAVE is required for TDX\n");
30633068
goto success_disable_tdx;

arch/x86/kvm/x86.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5114,6 +5114,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
51145114
static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
51155115
struct kvm_lapic_state *s)
51165116
{
5117+
if (vcpu->arch.apic->guest_apic_protected)
5118+
return -EINVAL;
5119+
51175120
kvm_x86_call(sync_pir_to_irr)(vcpu);
51185121

51195122
return kvm_apic_get_state(vcpu, s);
@@ -5124,6 +5127,9 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
51245127
{
51255128
int r;
51265129

5130+
if (vcpu->arch.apic->guest_apic_protected)
5131+
return -EINVAL;
5132+
51275133
r = kvm_apic_set_state(vcpu, s);
51285134
if (r)
51295135
return r;

0 commit comments

Comments
 (0)