summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Kuivenhoven <bemk@redhat.com>2013-09-23 11:45:28 +0200
committerMatt Fleming <matt.fleming@intel.com>2013-09-30 10:23:11 +0100
commit0ce6cda2c75d64175394341ef60e6e1d27dd9c10 (patch)
treeed589e47d86362a651ef1cf7427edc0dbb988480
parentd2078d5adbe227d64d7963d93f13479c890a9a16 (diff)
downloadop-kernel-dev-0ce6cda2c75d64175394341ef60e6e1d27dd9c10.zip
op-kernel-dev-0ce6cda2c75d64175394341ef60e6e1d27dd9c10.tar.gz
x86 efi: bugfix interrupt disabling sequence
The problem in efi_main was that the idt was cleared before the interrupts were disabled. The UEFI spec states that interrupts aren't used so this shouldn't be too much of a problem. Peripherals however don't necessarily know about this and thus might cause interrupts to happen anyway. Even if ExitBootServices() has been called. This means there is a risk of an interrupt being triggered while the IDT register is nullified and the interrupt bit hasn't been cleared, allowing for a triple fault. This patch disables the interrupt flag, while leaving the existing IDT in place. The CPU won't care about the IDT at all as long as the interrupt bit is off, so it's safe to leave it in place as nothing will ever happen to it. [ Removed the now unused 'idt' variable - Matt ] Signed-off-by: Bart Kuivenhoven <bemk@redhat.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--arch/x86/boot/compressed/eboot.c17
1 files changed, 2 insertions, 15 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 5c0dc55..a7677ba 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -748,7 +748,7 @@ free_mem_map:
struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
struct boot_params *boot_params)
{
- struct desc_ptr *gdt, *idt;
+ struct desc_ptr *gdt;
efi_loaded_image_t *image;
struct setup_header *hdr = &boot_params->hdr;
efi_status_t status;
@@ -780,17 +780,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
goto fail;
}
- status = efi_call_phys3(sys_table->boottime->allocate_pool,
- EFI_LOADER_DATA, sizeof(*idt),
- (void **)&idt);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table, "Failed to alloc mem for idt structure\n");
- goto fail;
- }
-
- idt->size = 0;
- idt->address = 0;
-
/*
* If the kernel isn't already loaded at the preferred load
* address, relocate it.
@@ -865,10 +854,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
desc->base2 = 0x00;
#endif /* CONFIG_X86_64 */
- asm volatile ("lidt %0" : : "m" (*idt));
- asm volatile ("lgdt %0" : : "m" (*gdt));
-
asm volatile("cli");
+ asm volatile ("lgdt %0" : : "m" (*gdt));
return boot_params;
fail:
OpenPOWER on IntegriCloud