#include <machine/asm.h>
__KERNEL_RCSID(0, "$NetBSD: vector.S,v 1.90 2024/08/28 23:20:50 christos Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
#include "opt_xen.h"
#include "opt_dtrace.h"
#include <machine/i8259.h>
#include <machine/i82093reg.h>
#include <machine/i82489reg.h>
#include <machine/frameasm.h>
#include <machine/segments.h>
#include <machine/specialreg.h>
#include <machine/trap.h>
#ifdef XEN
#include <xen/xen.h>
#endif
#include "ioapic.h"
#include "lapic.h"
#ifndef XENPV
#include "hyperv.h"
#endif
#include "assym.h"
#define GET_TSS \
andl $0xfff8,%eax ;\
addl CPUVAR(GDT),%eax ;\
movl 2(%eax),%edx ;\
andl $0xffffff,%edx ;\
movzbl 7(%eax),%eax ;\
shl $24,%eax ;\
orl %edx,%eax
#ifdef KDTRACE_HOOKS
.bss
.globl dtrace_invop_jump_addr
.align 4
.type dtrace_invop_jump_addr, @object
.size dtrace_invop_jump_addr, 4
dtrace_invop_jump_addr:
.zero 4
.globl dtrace_invop_calltrap_addr
.align 4
.type dtrace_invop_calltrap_addr, @object
.size dtrace_invop_calltrap_addr, 4
dtrace_invop_calltrap_addr:
.zero 8
.text
#endif
#ifndef XENPV
#if NLAPIC > 0
#ifdef MULTIPROCESSOR
IDTVEC(recurse_lapic_ipi)
INTR_RECURSE_HWFRAME
pushl $0
pushl $T_ASTFLT
INTRENTRY
jmp 1f
IDTVEC_END(recurse_lapic_ipi)
IDTVEC(intr_x2apic_ipi)
pushl $0
pushl $T_ASTFLT
INTRENTRY
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_HIGH,%ebx
jae 2f
jmp 1f
IDTVEC_END(intr_x2apic_ipi)
IDTVEC(intr_lapic_ipi)
pushl $0
pushl $T_ASTFLT
INTRENTRY
movl _C_LABEL(local_apic_va),%ebx
movl $0,LAPIC_EOI(%ebx)
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_HIGH,%ebx
jae 2f
IDTVEC_END(intr_lapic_ipi)
IDTVEC(resume_lapic_ipi)
1:
pushl %ebx
IDEPTH_INCR
movb $IPL_HIGH,CPUVAR(ILEVEL)
sti
call _C_LABEL(x86_ipi_handler)
cli
jmp _C_LABEL(Xdoreti)
2:
btsl $(LIR_IPI - 32),CPUVAR(IPENDING)+4
INTRFASTEXIT
IDTVEC_END(resume_lapic_ipi)
IDTVEC(intr_lapic_tlb)
pushl $0
pushl $T_ASTFLT
INTRENTRY
call _C_LABEL(pmap_tlb_intr)
movl _C_LABEL(local_apic_va),%eax
movl $0,LAPIC_EOI(%eax)
INTRFASTEXIT
IDTVEC_END(intr_lapic_tlb)
IDTVEC(intr_x2apic_tlb)
pushl $0
pushl $T_ASTFLT
INTRENTRY
call _C_LABEL(pmap_tlb_intr)
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
INTRFASTEXIT
IDTVEC_END(intr_x2apic_tlb)
#if defined(DDB)
IDTVEC(intr_ddbipi)
1:
str %ax
GET_TSS
movzwl (%eax),%eax
GET_TSS
pushl %eax
movl _C_LABEL(local_apic_va),%ebx
movl $0xff,LAPIC_TPRI(%ebx)
movl _C_LABEL(local_apic_va),%ebx
movl $0,LAPIC_EOI(%ebx)
sti
call _C_LABEL(ddb_ipi_tss)
addl $4,%esp
movl _C_LABEL(local_apic_va),%ebx
movl $0,LAPIC_TPRI(%ebx)
iret
jmp 1b
IDTVEC_END(intr_ddbipi)
IDTVEC(intr_x2apic_ddbipi)
1:
str %ax
GET_TSS
movzwl (%eax),%eax
GET_TSS
pushl %eax
movl $(MSR_X2APIC_BASE + MSR_X2APIC_TPRI),%ecx
movl 0xff,%eax
xorl %edx,%edx
wrmsr
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
sti
call _C_LABEL(ddb_ipi_tss)
addl $4,%esp
movl $(MSR_X2APIC_BASE + MSR_X2APIC_TPRI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
iret
jmp 1b
IDTVEC_END(intr_x2apic_ddbipi)
#endif
#endif
IDTVEC(recurse_lapic_ltimer)
INTR_RECURSE_HWFRAME
pushl $0
pushl $T_ASTFLT
INTRENTRY
jmp 1f
IDTVEC_END(recurse_lapic_ltimer)
IDTVEC(intr_x2apic_ltimer)
pushl $0
pushl $T_ASTFLT
INTRENTRY
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_CLOCK,%ebx
jae 2f
jmp 1f
IDTVEC_END(intr_x2apic_ltimer)
IDTVEC(intr_lapic_ltimer)
pushl $0
pushl $T_ASTFLT
INTRENTRY
movl _C_LABEL(local_apic_va),%ebx
movl $0,LAPIC_EOI(%ebx)
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_CLOCK,%ebx
jae 2f
IDTVEC_END(intr_lapic_ltimer)
IDTVEC(resume_lapic_ltimer)
1:
pushl %ebx
IDEPTH_INCR
movb $IPL_CLOCK,CPUVAR(ILEVEL)
sti
pushl $0
call _C_LABEL(lapic_clockintr)
addl $4,%esp
cli
jmp _C_LABEL(Xdoreti)
2:
btsl $(LIR_TIMER - 32),CPUVAR(IPENDING)+4
INTRFASTEXIT
IDTVEC_END(resume_lapic_ltimer)
#if NHYPERV > 0
IDTVEC(recurse_hyperv_hypercall)
INTR_RECURSE_HWFRAME
pushl $0
pushl $T_ASTFLT
INTRENTRY
jmp 1f
IDTVEC_END(recurse_hyperv_hypercall)
IDTVEC(intr_hyperv_hypercall)
pushl $0
pushl $T_ASTFLT
INTRENTRY
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_NET,%ebx
jae 2f
jmp 1f
IDTVEC_END(intr_hyperv_hypercall)
IDTVEC(resume_hyperv_hypercall)
1:
pushl %ebx
IDEPTH_INCR
movb $IPL_NET,CPUVAR(ILEVEL)
sti
pushl %esp
call _C_LABEL(hyperv_hypercall_intr)
addl $4,%esp
cli
jmp _C_LABEL(Xdoreti)
2:
orl $(1 << LIR_HV),CPUVAR(IPENDING)
INTRFASTEXIT
IDTVEC_END(resume_hyperv_hypercall)
#endif
#endif
#define voidop(num)
#define INTRSTUB1(name, num, sub, off, early_ack, late_ack, mask, unmask, level_mask) \
IDTVEC(recurse_ ## name ## num) ;\
INTR_RECURSE_HWFRAME ;\
subl $4,%esp ;\
pushl $T_ASTFLT ;\
INTRENTRY ;\
IDTVEC_END(recurse_ ## name ## num) ;\
IDTVEC(resume_ ## name ## num) \
movl $IREENT_MAGIC,TF_ERR(%esp) ;\
movl %ebx,%esi ;\
movl CPUVAR(ISOURCES) + (num) * 4,%ebp ;\
movl IS_MAXLEVEL(%ebp),%ebx ;\
jmp 1f ;\
IDTVEC_END(resume_ ## name ## num) ;\
IDTVEC(intr_ ## name ## num) ;\
pushl $0 ;\
pushl $T_ASTFLT ;\
INTRENTRY ;\
movl CPUVAR(ISOURCES) + (num) * 4,%ebp ;\
mask(num) ;\
early_ack(num) ;\
testl %ebp,%ebp ;\
jz 9f ;\
movl IS_MAXLEVEL(%ebp),%ebx ;\
movzbl CPUVAR(ILEVEL),%esi ;\
cmpl %ebx,%esi ;\
jae 10f ;\
addl $1,CPUVAR(NINTR) ;\
adcl $0,CPUVAR(NINTR)+4 ;\
addl $1,IS_EVCNTLO(%ebp) ;\
adcl $0,IS_EVCNTHI(%ebp) ;\
1: \
pushl %esi ;\
movb %bl,CPUVAR(ILEVEL) ;\
\
IDEPTH_INCR ;\
sti ;\
movl IS_HANDLERS(%ebp),%ebx ;\
cmpl $0,IS_MASK_COUNT(%ebp) ;\
jne 12f ;\
6: \
movl IH_LEVEL(%ebx),%eax ;\
cmpl %esi,%eax ;\
jle 7f ;\
pushl IH_ARG(%ebx) ;\
movl IH_FUN(%ebx),%edi ;\
movb %al,CPUVAR(ILEVEL) ;\
movl IH_NEXT(%ebx),%ebx ;\
call *%edi ;\
addl $4,%esp ;\
testl %ebx,%ebx ;\
jnz 6b ;\
cmpl $0,IS_MASK_COUNT(%ebp) ;\
jne 12f ;\
cli ;\
unmask(num) ;\
late_ack(num) ;\
jmp _C_LABEL(Xdoreti) ;\
7: \
cli ;\
btsl $(num - sub),CPUVAR(IPENDING) + off ;\
8: level_mask(num) ;\
late_ack(num) ;\
jmp _C_LABEL(Xdoreti) ;\
12: \
cli ;\
btsl $(num - sub),CPUVAR(IMASKED) + off ;\
btrl $(num - sub),CPUVAR(IPENDING) + off ;\
jmp 8b ;\
10: \
btsl $(num - sub),CPUVAR(IPENDING) + off ;\
level_mask(num) ;\
late_ack(num) ;\
INTRFASTEXIT ;\
9: \
pushl %esp ;\
unmask(num) ;\
late_ack(num) ;\
addl $4,%esp ;\
INTRFASTEXIT ;\
IDTVEC_END(intr_ ## name ## num)
#define INTRSTUB(name, num, early_ack, late_ack, mask, unmask, level_mask) \
INTRSTUB1(name, num, 0, 0, early_ack, late_ack, mask, unmask, level_mask)
#define INTRSTUB32(name, num, early_ack, late_ack, mask, unmask, level_mask) \
INTRSTUB1(name, num, 32, 4, early_ack, late_ack, mask, unmask, level_mask)
#define ICUADDR IO_ICU1
INTRSTUB(legacy,0,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,1,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,2,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,3,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,4,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,5,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,6,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,7,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
#undef ICUADDR
#define ICUADDR IO_ICU2
INTRSTUB(legacy,8,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,9,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,10,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,11,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,12,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,13,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,14,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,15,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
#if NIOAPIC > 0
#define INTRSTUB_56(name,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,0,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,1,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,2,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,3,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,4,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,5,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,6,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,7,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,8,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,9,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,10,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,11,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,12,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,13,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,14,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,15,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,16,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,17,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,18,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,19,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,20,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,21,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,22,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,23,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,24,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,25,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,26,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,27,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,28,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,29,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,30,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,31,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,32,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,33,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,34,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,35,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,36,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,37,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,38,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,39,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,40,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,41,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,42,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,43,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,44,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,45,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,46,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,47,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,48,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,49,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,50,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,51,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,52,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,53,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,54,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB32(name,55,early_ack,late_ack,mask,unmask,level_mask)
INTRSTUB_56(ioapic_edge,voidop,ioapic_asm_ack,voidop,voidop,voidop)
INTRSTUB_56(ioapic_level,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
INTRSTUB_56(x2apic_edge,voidop,x2apic_asm_ack,voidop,voidop,voidop)
INTRSTUB_56(x2apic_level,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
#endif
#define INTRSTUB_ENTRY(name) \
.long _C_LABEL(Xintr_ ## name ), _C_LABEL(Xrecurse_ ## name ) ; \
.long _C_LABEL(Xresume_ ## name ) ;
#define INTRSTUB_ARRAY_16(name) ; \
.type _C_LABEL(name ## _stubs), @object ; \
LABEL(name ## _stubs) ; \
INTRSTUB_ENTRY(name ## 0) ; \
INTRSTUB_ENTRY(name ## 1) ; \
INTRSTUB_ENTRY(name ## 2) ; \
INTRSTUB_ENTRY(name ## 3) ; \
INTRSTUB_ENTRY(name ## 4) ; \
INTRSTUB_ENTRY(name ## 5) ; \
INTRSTUB_ENTRY(name ## 6) ; \
INTRSTUB_ENTRY(name ## 7) ; \
INTRSTUB_ENTRY(name ## 8) ; \
INTRSTUB_ENTRY(name ## 9) ; \
INTRSTUB_ENTRY(name ## 10) ; \
INTRSTUB_ENTRY(name ## 11) ; \
INTRSTUB_ENTRY(name ## 12) ; \
INTRSTUB_ENTRY(name ## 13) ; \
INTRSTUB_ENTRY(name ## 14) ; \
INTRSTUB_ENTRY(name ## 15) ; \
END(name ## _stubs)
#define INTRSTUB_ARRAY_56(name) ; \
.type _C_LABEL(name ## _stubs), @object ; \
LABEL(name ## _stubs) ; \
INTRSTUB_ENTRY(name ## 0) ; \
INTRSTUB_ENTRY(name ## 1) ; \
INTRSTUB_ENTRY(name ## 2) ; \
INTRSTUB_ENTRY(name ## 3) ; \
INTRSTUB_ENTRY(name ## 4) ; \
INTRSTUB_ENTRY(name ## 5) ; \
INTRSTUB_ENTRY(name ## 6) ; \
INTRSTUB_ENTRY(name ## 7) ; \
INTRSTUB_ENTRY(name ## 8) ; \
INTRSTUB_ENTRY(name ## 9) ; \
INTRSTUB_ENTRY(name ## 10) ; \
INTRSTUB_ENTRY(name ## 11) ; \
INTRSTUB_ENTRY(name ## 12) ; \
INTRSTUB_ENTRY(name ## 13) ; \
INTRSTUB_ENTRY(name ## 14) ; \
INTRSTUB_ENTRY(name ## 15) ; \
INTRSTUB_ENTRY(name ## 16) ; \
INTRSTUB_ENTRY(name ## 17) ; \
INTRSTUB_ENTRY(name ## 18) ; \
INTRSTUB_ENTRY(name ## 19) ; \
INTRSTUB_ENTRY(name ## 20) ; \
INTRSTUB_ENTRY(name ## 21) ; \
INTRSTUB_ENTRY(name ## 22) ; \
INTRSTUB_ENTRY(name ## 23) ; \
INTRSTUB_ENTRY(name ## 24) ; \
INTRSTUB_ENTRY(name ## 25) ; \
INTRSTUB_ENTRY(name ## 26) ; \
INTRSTUB_ENTRY(name ## 27) ; \
INTRSTUB_ENTRY(name ## 28) ; \
INTRSTUB_ENTRY(name ## 29) ; \
INTRSTUB_ENTRY(name ## 30) ; \
INTRSTUB_ENTRY(name ## 31) ; \
INTRSTUB_ENTRY(name ## 32) ; \
INTRSTUB_ENTRY(name ## 33) ; \
INTRSTUB_ENTRY(name ## 34) ; \
INTRSTUB_ENTRY(name ## 35) ; \
INTRSTUB_ENTRY(name ## 36) ; \
INTRSTUB_ENTRY(name ## 37) ; \
INTRSTUB_ENTRY(name ## 38) ; \
INTRSTUB_ENTRY(name ## 39) ; \
INTRSTUB_ENTRY(name ## 40) ; \
INTRSTUB_ENTRY(name ## 41) ; \
INTRSTUB_ENTRY(name ## 42) ; \
INTRSTUB_ENTRY(name ## 43) ; \
INTRSTUB_ENTRY(name ## 44) ; \
INTRSTUB_ENTRY(name ## 45) ; \
INTRSTUB_ENTRY(name ## 46) ; \
INTRSTUB_ENTRY(name ## 47) ; \
INTRSTUB_ENTRY(name ## 48) ; \
INTRSTUB_ENTRY(name ## 49) ; \
INTRSTUB_ENTRY(name ## 50) ; \
INTRSTUB_ENTRY(name ## 51) ; \
INTRSTUB_ENTRY(name ## 52) ; \
INTRSTUB_ENTRY(name ## 53) ; \
INTRSTUB_ENTRY(name ## 54) ; \
INTRSTUB_ENTRY(name ## 55) ; \
END(name ## _stubs)
#endif
#if defined(XEN)
#define voidop(num)
#define XENINTRSTUB(name, sir, level, unmask) \
IDTVEC(recurse_ ## name ## sir) ;\
INTR_RECURSE_HWFRAME ;\
subl $4,%esp ;\
pushl $T_ASTFLT ;\
INTRENTRY ;\
IDTVEC(resume_ ## name ## sir) \
movl $IREENT_MAGIC,TF_ERR(%esp) ;\
pushl %ebx ;\
movl CPUVAR(ISOURCES) + (sir) * 4,%ebp ;\
movb $level,CPUVAR(ILEVEL) ;\
IDEPTH_INCR ;\
STI(%eax) ;\
movl IS_HANDLERS(%ebp),%ebx ;\
6: \
cmpl $0, IH_PENDING(%ebx) ;\
je 7f ;\
movl $0, IH_PENDING(%ebx) ;\
pushl IH_ARG(%ebx) ;\
call *IH_FUN(%ebx) ;\
addl $4,%esp ;\
7: \
movl IH_NEXT(%ebx),%ebx ;\
testl %ebx,%ebx ;\
jnz 6b ;\
\
CLI(%eax) ;\
unmask(sir) ;\
jmp _C_LABEL(Xdoreti) ;\
#define hypervisor_asm_unmask(sir) \
pushl $sir ;\
call _C_LABEL(hypervisor_enable_sir) ;\
addl $4,%esp
XENINTRSTUB(xenev,SIR_XENIPL_VM,IPL_VM,hypervisor_asm_unmask)
XENINTRSTUB(xenev,SIR_XENIPL_SCHED,IPL_SCHED,hypervisor_asm_unmask)
XENINTRSTUB(xenev,SIR_XENIPL_HIGH,IPL_HIGH,hypervisor_asm_unmask)
panicmsg: .ascii "vector Xen event entry path entered."
LABEL(entry_xenev)
pushl $panicmsg
call _C_LABEL(panic)
END(entry_xenev)
#define XENINTRSTUB_ENTRY(name, sir) \
.long entry_xenev , _C_LABEL(Xrecurse_ ## name ## sir); \
.long _C_LABEL(Xresume_ ## name ## sir);
.type _C_LABEL(xenev_stubs), @object
LABEL(xenev_stubs)
XENINTRSTUB_ENTRY(xenev, SIR_XENIPL_VM) ;
XENINTRSTUB_ENTRY(xenev, SIR_XENIPL_SCHED) ;
XENINTRSTUB_ENTRY(xenev, SIR_XENIPL_HIGH) ;
END(xenev_stubs)
#endif
#include "i386_trap.S"
#ifdef XEN
ENTRY(hypervisor_callback)
IDTVEC(hypervisor_pvhvm_callback)
pushl $0
pushl $T_ASTFLT
INTRENTRY
movzbl CPUVAR(ILEVEL),%eax
pushl %eax
IDEPTH_INCR
call do_hypervisor_callback
#ifndef XENPV
movzbl _C_LABEL(xenhvm_use_percpu_callback),%eax
testl %eax, %eax
jz 1f
movl _C_LABEL(local_apic_va),%eax
movl $0, LAPIC_EOI(%eax)
1:
#endif
jmp _C_LABEL(Xdoreti)
IDTVEC_END(hypervisor_pvhvm_callback)
END(hypervisor_callback)
#endif
#ifdef XENPV
ENTRY(failsafe_callback)
pop %ds
pop %es
pop %fs
pop %gs
call _C_LABEL(xen_failsafe_handler)
iret
END(failsafe_callback)
#else
.section .rodata
INTRSTUB_ARRAY_16(legacy)
#if NIOAPIC > 0
INTRSTUB_ARRAY_56(ioapic_edge)
INTRSTUB_ARRAY_56(ioapic_level)
INTRSTUB_ARRAY_56(x2apic_edge)
INTRSTUB_ARRAY_56(x2apic_level)
#endif
#endif