--- /dev/null
+/*
+ * Generator for IDT entries.
+ *
+ * Caller to provide GEN(vector, symbol, dpl, auto) macro
+ *
+ * Symbols of the form 'entry_0xYY' set auto=1 and want a stub generating
+ * automatically. Other symbols are ones with a more specific name, and most
+ * are provided elsewhere rather than autogenerated.
+ */
+
+#define GEN16(i) \
+ GEN(0x ## i ## 0, entry_0x ## i ## 0, 0, 1) \
+ GEN(0x ## i ## 1, entry_0x ## i ## 1, 0, 1) \
+ GEN(0x ## i ## 2, entry_0x ## i ## 2, 0, 1) \
+ GEN(0x ## i ## 3, entry_0x ## i ## 3, 0, 1) \
+ GEN(0x ## i ## 4, entry_0x ## i ## 4, 0, 1) \
+ GEN(0x ## i ## 5, entry_0x ## i ## 5, 0, 1) \
+ GEN(0x ## i ## 6, entry_0x ## i ## 6, 0, 1) \
+ GEN(0x ## i ## 7, entry_0x ## i ## 7, 0, 1) \
+ GEN(0x ## i ## 8, entry_0x ## i ## 8, 0, 1) \
+ GEN(0x ## i ## 9, entry_0x ## i ## 9, 0, 1) \
+ GEN(0x ## i ## a, entry_0x ## i ## a, 0, 1) \
+ GEN(0x ## i ## b, entry_0x ## i ## b, 0, 1) \
+ GEN(0x ## i ## c, entry_0x ## i ## c, 0, 1) \
+ GEN(0x ## i ## d, entry_0x ## i ## d, 0, 1) \
+ GEN(0x ## i ## e, entry_0x ## i ## e, 0, 1) \
+ GEN(0x ## i ## f, entry_0x ## i ## f, 0, 1)
+
+
+GEN(0x00, entry_DE, 0, 0)
+GEN(0x01, entry_DB, 0, 0)
+GEN(0x02, entry_NMI, 0, 0)
+GEN(0x03, entry_BP, 3, 0)
+GEN(0x04, entry_OF, 3, 0)
+GEN(0x05, entry_BR, 0, 0)
+GEN(0x06, entry_UD, 0, 0)
+GEN(0x07, entry_NM, 0, 0)
+GEN(0x08, entry_DF, 0, 0)
+GEN(0x09, entry_0x09, 0, 1) /* Coprocessor Segment Overrun */
+GEN(0x0a, entry_TS, 0, 0)
+GEN(0x0b, entry_NP, 0, 0)
+GEN(0x0c, entry_SS, 0, 0)
+GEN(0x0d, entry_GP, 0, 0)
+GEN(0x0e, early_page_fault, 0, 0)
+GEN(0x0f, entry_0x0f, 0, 1) /* PIC Spurious Interrupt Vector */
+
+GEN(0x10, entry_MF, 0, 0)
+GEN(0x11, entry_AC, 0, 0)
+GEN(0x12, entry_MC, 0, 0)
+GEN(0x13, entry_XM, 0, 0)
+GEN(0x14, entry_VE, 0, 1)
+GEN(0x15, entry_CP, 0, 0)
+GEN(0x16, entry_0x16, 0, 1)
+GEN(0x17, entry_0x17, 0, 1)
+GEN(0x18, entry_0x18, 0, 1)
+GEN(0x19, entry_0x19, 0, 1)
+GEN(0x1a, entry_0x1a, 0, 1)
+GEN(0x1b, entry_0x1b, 0, 1)
+GEN(0x1c, entry_HV, 0, 1)
+GEN(0x1d, entry_VC, 0, 1)
+GEN(0x1e, entry_SX, 0, 1)
+GEN(0x1f, entry_0x1f, 0, 1)
+
+GEN16(2)
+GEN16(3)
+GEN16(4)
+GEN16(5)
+GEN16(6)
+GEN16(7)
+
+#ifdef CONFIG_PV
+GEN(0x80, entry_int80, 0, 0)
+#else
+GEN(0x80, entry_0x80, 0, 1)
+#endif
+
+GEN(0x81, entry_0x81, 0, 1)
+
+#ifdef CONFIG_PV32
+GEN(0x82, entry_int82, 1, 0)
+#else
+GEN(0x82, entry_0x82, 0, 1)
+#endif
+
+GEN(0x83, entry_0x83, 0, 1)
+GEN(0x84, entry_0x84, 0, 1)
+GEN(0x85, entry_0x85, 0, 1)
+GEN(0x86, entry_0x86, 0, 1)
+GEN(0x87, entry_0x87, 0, 1)
+GEN(0x88, entry_0x88, 0, 1)
+GEN(0x89, entry_0x89, 0, 1)
+GEN(0x8a, entry_0x8a, 0, 1)
+GEN(0x8b, entry_0x8b, 0, 1)
+GEN(0x8c, entry_0x8c, 0, 1)
+GEN(0x8d, entry_0x8d, 0, 1)
+GEN(0x8e, entry_0x8e, 0, 1)
+GEN(0x8f, entry_0x8f, 0, 1)
+
+GEN16(9)
+GEN16(a)
+GEN16(b)
+GEN16(c)
+GEN16(d)
+GEN16(e)
+GEN16(f)
iretq
END(trap_nop)
+/*
+ * Automatically generated entrypoints, and IDT
+ */
+
+ .pushsection .data.page_aligned, "aw", @progbits
+DATA(bsp_idt, PAGE_SIZE)
+ .popsection
+
+/*
+ * Write an IDT Entry. The linker provides us new _ADDR1/2 symbols calculated
+ * from \sym.
+ */
+.macro write_idte sym, dpl
+ .pushsection .data.page_aligned, "aw", @progbits
+ .word IDT_\sym\()_ADDR1
+ .word __HYPERVISOR_CS
+ .word 0x8e00 | (\dpl << 13) /* Present, DPL, Interrupt Gate */
+ .word IDT_\sym\()_ADDR2
+ .long __XEN_VIRT_START >> 32
+ .long 0
+ .popsection
+.endm
+
+/*
+ * Write an automatically generated stub. Vectors in the exception range keep
+ * the stack properly aligned by judging whether the CPU pushed an error code
+ * or not.
+ *
+ * Alignment is forced to 16 because that's the size of the interrupt stub
+ * with CET active.
+ */
+.macro gen_entry vec, sym
+
+FUNC(\sym, 16)
+ ENDBR64
+
+ .if \vec < 0x20 /* Exception. */
+
+ test $8, %spl /* 64bit exception frames are 16 byte aligned, but the word */
+ jz 1f /* size is 8 bytes. Check whether the processor gave us an */
+ pushq $0 /* error code, and insert an empty one if not. */
+1: movb $\vec, EFRAME_entry_vector(%rsp)
+ jmp handle_exception
+
+ .else /* Interrupt. */
+
+ pushq $0
+ movb $\vec, EFRAME_entry_vector(%rsp)
+ jmp common_interrupt
+
+ .endif
+END(\sym)
+.endm
+
+/*
+ * Generator. Write an entrypoint if necessary, and record an IDT entry.
+ */
+.macro gen vec, sym, dpl, auto
+
+ .if \auto
+ gen_entry \vec, \sym
+ .endif
+
+ write_idte \sym, \dpl
+.endm
+#define GEN(v, s, d, a) gen vec=v, sym=s, dpl=d auto=a;
+#include <asm/gen-idt.h>
+#undef GEN
+
+ .pushsection .data.page_aligned, "aw", @progbits
+END(bsp_idt)
+ .if . - bsp_idt != PAGE_SIZE
+ .error "Bad bsp_idt size, should be PAGE_SIZE"
+ .endif
+ .popsection
+
/* Table of automatically generated entry points. One per vector. */
.pushsection .init.rodata, "a", @progbits
DATA(autogen_entrypoints, 8)