Skip to content

Commit 189329e

Browse files
fyin1jren1
authored andcommitted
apicv: cancel event injection if vcpu is scheduled out
And re-inject the event after vcpu is scheduled in. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com>
1 parent c8d2cdc commit 189329e

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

hypervisor/arch/x86/interrupt.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,18 @@ int acrn_do_intr_process(struct vcpu *vcpu)
293293
if (bitmap_test_and_clear(ACRN_REQUEST_TMR_UPDATE, pending_intr_bits))
294294
vioapic_update_tmr(vcpu);
295295

296+
/* handling cancelled event injection when vcpu is switched out */
297+
if (vcpu->arch_vcpu.inject_event_pending) {
298+
exec_vmwrite(VMX_ENTRY_EXCEPTION_EC,
299+
vcpu->arch_vcpu.inject_info.error_code);
300+
301+
exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD,
302+
vcpu->arch_vcpu.inject_info.intr_info);
303+
304+
vcpu->arch_vcpu.inject_event_pending = false;
305+
goto INTR_WIN;
306+
}
307+
296308
/* handling pending vector injection:
297309
* there are many reason inject failed, we need re-inject again
298310
*/
@@ -380,6 +392,30 @@ int acrn_do_intr_process(struct vcpu *vcpu)
380392
return ret;
381393
}
382394

395+
void cancel_event_injection(struct vcpu *vcpu)
396+
{
397+
uint32_t intinfo;
398+
399+
intinfo = exec_vmread(VMX_ENTRY_INT_INFO_FIELD);
400+
401+
/*
402+
* If event is injected, we clear VMX_ENTRY_INT_INFO_FIELD,
403+
* save injection info, and mark inject event pending.
404+
* The event will be re-injected in next acrn_do_intr_process
405+
* call.
406+
*/
407+
if (intinfo & VMX_INT_INFO_VALID) {
408+
vcpu->arch_vcpu.inject_event_pending = true;
409+
410+
if (intinfo & (EXCEPTION_ERROR_CODE_VALID << 8))
411+
vcpu->arch_vcpu.inject_info.error_code =
412+
exec_vmread(VMX_ENTRY_EXCEPTION_EC);
413+
414+
vcpu->arch_vcpu.inject_info.intr_info = intinfo;
415+
exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD, 0);
416+
}
417+
}
418+
383419
int exception_handler(struct vcpu *vcpu)
384420
{
385421
uint32_t intinfo, int_err_code;

hypervisor/common/schedule.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ static void context_switch_out(struct vcpu *vcpu)
147147
if (vcpu == NULL)
148148
return;
149149

150+
/* cancel event(int, gp, nmi and exception) injection */
151+
cancel_event_injection(vcpu);
152+
150153
atomic_store_rel_32(&vcpu->running, 0);
151154
/* do prev vcpu context switch out */
152155
/* For now, we don't need to invalid ept.

hypervisor/include/arch/x86/guest/vcpu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ struct run_context {
185185
#define NORMAL_WORLD 0
186186
#define SECURE_WORLD 1
187187

188+
struct event_injection_info {
189+
uint32_t intr_info;
190+
uint32_t error_code;
191+
};
192+
188193
struct vcpu_arch {
189194
int cur_context;
190195
struct run_context contexts[NR_WORLD];
@@ -221,6 +226,8 @@ struct vcpu_arch {
221226

222227
/* interrupt injection information */
223228
uint64_t pending_intr;
229+
bool inject_event_pending;
230+
struct event_injection_info inject_info;
224231

225232
/* per vcpu lapic */
226233
void *vlapic;

hypervisor/include/arch/x86/irq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,6 @@ int interrupt_win_exiting_handler(struct vcpu *vcpu);
161161
int external_interrupt_handler(struct vcpu *vcpu);
162162
int acrn_do_intr_process(struct vcpu *vcpu);
163163
int interrupt_init(uint32_t logical_id);
164+
165+
void cancel_event_injection(struct vcpu *vcpu);
164166
#endif /* IRQ_H */

0 commit comments

Comments
 (0)