diff --git a/hypervisor/arch/x86/idt.S b/hypervisor/arch/x86/idt.S index 251d2eb3a..0cec1542e 100644 --- a/hypervisor/arch/x86/idt.S +++ b/hypervisor/arch/x86/idt.S @@ -389,7 +389,11 @@ external_interrupt_save_frame: /* Put current stack pointer into 1st param register (rdi) */ movq %rsp, %rdi +#ifdef CONFIG_PARTITION_MODE + call partition_mode_dispatch_interrupt +#else call dispatch_interrupt +#endif /* * We disable softirq path from interrupt IRET, since right now all IRQ diff --git a/hypervisor/arch/x86/irq.c b/hypervisor/arch/x86/irq.c index d48e15e79..1585097d5 100644 --- a/hypervisor/arch/x86/irq.c +++ b/hypervisor/arch/x86/irq.c @@ -431,6 +431,28 @@ ERR: return; } +#ifdef CONFIG_PARTITION_MODE +void partition_mode_dispatch_interrupt(struct intr_excp_ctx *ctx) +{ + uint8_t vr = ctx->vector; + struct vcpu *vcpu; + + /* + * There is no vector and APIC ID remapping for VMs in + * ACRN partition mode. Device interrupts are injected with the same + * vector into vLAPIC of vCPU running on the pCPU. Vectors used for + * HV services are handled by HV using dispatch_interrupt. + */ + vcpu = per_cpu(vcpu, get_cpu_id()); + if (vr < VECTOR_FOR_PRI_START) { + send_lapic_eoi(); + vlapic_intr_edge(vcpu, vr); + } else { + dispatch_interrupt(ctx); + } +} +#endif + int handle_level_interrupt_common(struct irq_desc *desc, __unused void *handler_data) { diff --git a/hypervisor/arch/x86/virq.c b/hypervisor/arch/x86/virq.c index e800b7838..e9c46f775 100644 --- a/hypervisor/arch/x86/virq.c +++ b/hypervisor/arch/x86/virq.c @@ -373,7 +373,11 @@ int external_interrupt_vmexit_handler(struct vcpu *vcpu) ctx.vector = intr_info & 0xFFU; +#ifdef CONFIG_PARTITION_MODE + partition_mode_dispatch_interrupt(&ctx); +#else dispatch_interrupt(&ctx); +#endif vcpu_retain_rip(vcpu); diff --git a/hypervisor/include/arch/x86/irq.h b/hypervisor/include/arch/x86/irq.h index ac5ee6184..a83df530e 100644 --- a/hypervisor/include/arch/x86/irq.h +++ b/hypervisor/include/arch/x86/irq.h @@ -55,6 +55,9 @@ void init_default_irqs(uint16_t cpu_id); void dispatch_exception(struct intr_excp_ctx *ctx); void dispatch_interrupt(struct intr_excp_ctx *ctx); +#ifdef CONFIG_PARTITION_MODE +void partition_mode_dispatch_interrupt(struct intr_excp_ctx *ctx); +#endif void setup_notification(void);