diff --git a/hypervisor/arch/x86/boot/cpu_primary.S b/hypervisor/arch/x86/boot/cpu_primary.S index dd9baa1cd..f7f58bf4b 100644 --- a/hypervisor/arch/x86/boot/cpu_primary.S +++ b/hypervisor/arch/x86/boot/cpu_primary.S @@ -163,31 +163,6 @@ after: mov %eax,%fs // Was 32bit POC Data mov %eax,%gs // Was 32bit POC CLS - /* - * Fix up the IDT desciptors - * The relocation delta in IDT tables has been fixed in relocate() - */ - movl %eax, %edx - leal HOST_IDT(%rip), %edx - movl $HOST_IDT_ENTRIES, %ecx - -.fixup_idt_entries: - xorl %eax, %eax - xchgl %eax, 12(%edx) /* Set rsvd bits to 0; eax now has - high 32 of entry point */ - xchgl %eax, 8(%edx) /* Set bits 63..32 of entry point; - eax now has low 32 of entry point */ - movw %ax, (%edx) /* Set bits 0-15 of procedure entry - point */ - shr $16, %eax - movw %ax, 6(%edx) /* Set bits 16-31 of entry point */ - addl $X64_IDT_DESC_SIZE,%edx - loop .fixup_idt_entries - - /* Load IDT */ - lea HOST_IDTR(%rip), %rbx - lidtq (%rbx) - /* continue with chipset level initialization */ call bsp_boot_init diff --git a/hypervisor/arch/x86/irq.c b/hypervisor/arch/x86/irq.c index e2315594d..53baed348 100644 --- a/hypervisor/arch/x86/irq.c +++ b/hypervisor/arch/x86/irq.c @@ -445,9 +445,24 @@ void init_default_irqs(uint16_t cpu_id) } } -static void set_idt(struct host_idt_descriptor *idtd) +static inline void fixup_idt(struct host_idt_descriptor *idtd) { + int i; + union idt_64_descriptor *idt_desc = (union idt_64_descriptor *)idtd->idt; + uint32_t entry_hi_32, entry_lo_32; + for (i = 0; i < HOST_IDT_ENTRIES; i++) { + entry_lo_32 = idt_desc[i].fields.offset_63_32; + entry_hi_32 = idt_desc[i].fields.rsvd; + idt_desc[i].fields.rsvd = 0U; + idt_desc[i].fields.offset_63_32 = entry_hi_32; + idt_desc[i].fields.high32.bits.offset_31_16 = entry_lo_32 >> 16U; + idt_desc[i].fields.low32.bits.offset_15_0 = entry_lo_32 & 0xffffUL; + } +} + +static inline void set_idt(struct host_idt_descriptor *idtd) +{ asm volatile (" lidtq %[idtd]\n" : /* no output parameters */ : /* input parameters */ [idtd] "m"(*idtd)); @@ -457,6 +472,9 @@ void interrupt_init(uint16_t pcpu_id) { struct host_idt_descriptor *idtd = &HOST_IDTR; + if (pcpu_id == BOOT_CPU_ID) { + fixup_idt(idtd); + } set_idt(idtd); init_lapic(pcpu_id); init_default_irqs(pcpu_id);