Commit 0ce6cda2 authored by Bart Kuivenhoven's avatar Bart Kuivenhoven Committed by Matt Fleming

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: default avatarBart Kuivenhoven <bemk@redhat.com>
Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
parent d2078d5a
...@@ -748,7 +748,7 @@ static efi_status_t exit_boot(struct boot_params *boot_params, ...@@ -748,7 +748,7 @@ static efi_status_t exit_boot(struct boot_params *boot_params,
struct boot_params *efi_main(void *handle, efi_system_table_t *_table, struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
struct boot_params *boot_params) struct boot_params *boot_params)
{ {
struct desc_ptr *gdt, *idt; struct desc_ptr *gdt;
efi_loaded_image_t *image; efi_loaded_image_t *image;
struct setup_header *hdr = &boot_params->hdr; struct setup_header *hdr = &boot_params->hdr;
efi_status_t status; efi_status_t status;
...@@ -780,17 +780,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, ...@@ -780,17 +780,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
goto fail; 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 * If the kernel isn't already loaded at the preferred load
* address, relocate it. * address, relocate it.
...@@ -865,10 +854,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, ...@@ -865,10 +854,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
desc->base2 = 0x00; desc->base2 = 0x00;
#endif /* CONFIG_X86_64 */ #endif /* CONFIG_X86_64 */
asm volatile ("lidt %0" : : "m" (*idt));
asm volatile ("lgdt %0" : : "m" (*gdt));
asm volatile("cli"); asm volatile("cli");
asm volatile ("lgdt %0" : : "m" (*gdt));
return boot_params; return boot_params;
fail: fail:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment