Skip to content

Commit 4cdf243

Browse files
yamahatabonzini
authored andcommitted
KVM: TDX: Always block INIT/SIPI
Always block INIT and SIPI events for the TDX guest because the TDX module doesn't provide API for VMM to inject INIT IPI or SIPI. TDX defines its own vCPU creation and initialization sequence including multiple seamcalls. Also, it's only allowed during TD build time. Given that TDX guest is para-virtualized to boot BSP/APs, normally there shouldn't be any INIT/SIPI event for TDX guest. If any, three options to handle them: 1. Always block INIT/SIPI request. 2. (Silently) ignore INIT/SIPI request during delivery. 3. Return error to guest TDs somehow. Choose option 1 for simplicity. Since INIT and SIPI are always blocked, INIT handling and the OP vcpu_deliver_sipi_vector() won't be called, no need to add new interface or helper function for INIT/SIPI delivery. 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-10-binbin.wu@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 2b06beb commit 4cdf243

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

arch/x86/kvm/vmx/main.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ static void vt_vcpu_free(struct kvm_vcpu *vcpu)
118118

119119
static void vt_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
120120
{
121-
if (is_td_vcpu(vcpu))
121+
if (is_td_vcpu(vcpu)) {
122+
tdx_vcpu_reset(vcpu, init_event);
122123
return;
124+
}
123125

124126
vmx_vcpu_reset(vcpu, init_event);
125127
}
@@ -226,6 +228,18 @@ static void vt_enable_smi_window(struct kvm_vcpu *vcpu)
226228
}
227229
#endif
228230

231+
static bool vt_apic_init_signal_blocked(struct kvm_vcpu *vcpu)
232+
{
233+
/*
234+
* INIT and SIPI are always blocked for TDX, i.e., INIT handling and
235+
* the OP vcpu_deliver_sipi_vector() won't be called.
236+
*/
237+
if (is_td_vcpu(vcpu))
238+
return true;
239+
240+
return vmx_apic_init_signal_blocked(vcpu);
241+
}
242+
229243
static void vt_apicv_pre_state_restore(struct kvm_vcpu *vcpu)
230244
{
231245
struct pi_desc *pi = vcpu_to_pi_desc(vcpu);
@@ -591,7 +605,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
591605
#endif
592606

593607
.check_emulate_instruction = vmx_check_emulate_instruction,
594-
.apic_init_signal_blocked = vmx_apic_init_signal_blocked,
608+
.apic_init_signal_blocked = vt_apic_init_signal_blocked,
595609
.migrate_timers = vmx_migrate_timers,
596610

597611
.msr_filter_changed = vmx_msr_filter_changed,

arch/x86/kvm/vmx/tdx.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,19 @@ static int tdx_vcpu_init(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *cmd)
26262626
return 0;
26272627
}
26282628

2629+
void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
2630+
{
2631+
/*
2632+
* Yell on INIT, as TDX doesn't support INIT, i.e. KVM should drop all
2633+
* INIT events.
2634+
*
2635+
* Defer initializing vCPU for RESET state until KVM_TDX_INIT_VCPU, as
2636+
* userspace needs to define the vCPU model before KVM can initialize
2637+
* vCPU state, e.g. to enable x2APIC.
2638+
*/
2639+
WARN_ON_ONCE(init_event);
2640+
}
2641+
26292642
struct tdx_gmem_post_populate_arg {
26302643
struct kvm_vcpu *vcpu;
26312644
__u32 flags;

arch/x86/kvm/vmx/x86_ops.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void tdx_vm_destroy(struct kvm *kvm);
128128
int tdx_vm_ioctl(struct kvm *kvm, void __user *argp);
129129

130130
int tdx_vcpu_create(struct kvm_vcpu *vcpu);
131+
void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
131132
void tdx_vcpu_free(struct kvm_vcpu *vcpu);
132133
void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
133134
int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu);
@@ -167,6 +168,7 @@ static inline void tdx_vm_destroy(struct kvm *kvm) {}
167168
static inline int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) { return -EOPNOTSUPP; }
168169

169170
static inline int tdx_vcpu_create(struct kvm_vcpu *vcpu) { return -EOPNOTSUPP; }
171+
static inline void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) {}
170172
static inline void tdx_vcpu_free(struct kvm_vcpu *vcpu) {}
171173
static inline void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) {}
172174
static inline int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu) { return -EOPNOTSUPP; }

0 commit comments

Comments
 (0)