linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86 efi: bugfix interrupt disabling sequence
@ 2013-09-18 17:28 Bart Kuivenhoven
       [not found] ` <1379525333-4373-1-git-send-email-bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Bart Kuivenhoven @ 2013-09-18 17:28 UTC (permalink / raw)
  To: matt.fleming-ral2JQCrhuEAvxtiuMwx3w
  Cc: hpa-YMNOUZJC4hwAvxtiuMwx3w, tglx-hfZtesqFncYOwBW4kG4KsQ,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, Bart Kuivenhoven

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 fixes this by clearing the interrupt bit before the lidt
instruction.

Signed-off-by: Bart Kuivenhoven <bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/x86/boot/compressed/eboot.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..100b812 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1267,11 +1267,11 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
 	desc->base2 = 0x00;
 #endif /* CONFIG_X86_64 */
 
+	asm volatile("cli");
+
 	asm volatile ("lidt %0" : : "m" (*idt));
 	asm volatile ("lgdt %0" : : "m" (*gdt));
 
-	asm volatile("cli");
-
 	return boot_params;
 fail:
 	return NULL;
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86 efi: bugfix interrupt disabling sequence
       [not found] ` <1379525333-4373-1-git-send-email-bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2013-09-20 15:28   ` Matt Fleming
  2013-09-20 20:21     ` Bart Kuivenhoven
  0 siblings, 1 reply; 8+ messages in thread
From: Matt Fleming @ 2013-09-20 15:28 UTC (permalink / raw)
  To: Bart Kuivenhoven
  Cc: matt.fleming-ral2JQCrhuEAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	tglx-hfZtesqFncYOwBW4kG4KsQ, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	msalter-H+wXaHxf7aLQT0dZR+AlfA

On Wed, 18 Sep, at 07:28:53PM, Bart Kuivenhoven wrote:
> 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.

Just to be clear, you haven't witnessed a triple fault, correct?

> This patch fixes this by clearing the interrupt bit before the lidt
> instruction.

I think we can go even further than this and get rid of all of the IDT
code in the EFI boot stub. The kernel maintains its own IDT anyway.

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86 efi: bugfix interrupt disabling sequence
  2013-09-20 15:28   ` Matt Fleming
@ 2013-09-20 20:21     ` Bart Kuivenhoven
       [not found]       ` <1379708486.12705.131.camel-0VdLhd/A9PkhetGgFr3ssPXAX3CI6PSWQQ4Iyu8u01E@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Bart Kuivenhoven @ 2013-09-20 20:21 UTC (permalink / raw)
  To: Matt Fleming
  Cc: matt.fleming, hpa, tglx, mingo, x86, linux-efi, linux-kernel, jcm,
	msalter

On Fri, 2013-09-20 at 16:28 +0100, Matt Fleming wrote:
> On Wed, 18 Sep, at 07:28:53PM, Bart Kuivenhoven wrote:
> > 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.
> 
> Just to be clear, you haven't witnessed a triple fault, correct?
> 
> > This patch fixes this by clearing the interrupt bit before the lidt
> > instruction.
> 
> I think we can go even further than this and get rid of all of the IDT
> code in the EFI boot stub. The kernel maintains its own IDT anyway.
> 

Well, isn't it so, that the kernel expects a setup in which interrupts
are disabled before the decompressed image is loaded?

What we can do is remove the lidt instruction and IDT pointer, but that
still doesn't change anything with regards to the kernels expectations.

And no, I haven't witnessed a triple fault, this is purely theoretical,
with a very slim chance of it actually happening. That does not mean
that it can't happen though.

-- 
Kind regards/Met vriendelijke groet,
Bart Kuivenhoven.

Intern Fedora ARM,
Red Hat.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86 efi: bugfix interrupt disabling sequence
       [not found]       ` <1379708486.12705.131.camel-0VdLhd/A9PkhetGgFr3ssPXAX3CI6PSWQQ4Iyu8u01E@public.gmane.org>
@ 2013-09-21  7:50         ` Ingo Molnar
  2013-09-21 15:41         ` Matt Fleming
  1 sibling, 0 replies; 8+ messages in thread
From: Ingo Molnar @ 2013-09-21  7:50 UTC (permalink / raw)
  To: Bart Kuivenhoven
  Cc: Matt Fleming, matt.fleming-ral2JQCrhuEAvxtiuMwx3w,
	hpa-YMNOUZJC4hwAvxtiuMwx3w, tglx-hfZtesqFncYOwBW4kG4KsQ,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	msalter-H+wXaHxf7aLQT0dZR+AlfA


* Bart Kuivenhoven <bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:

> On Fri, 2013-09-20 at 16:28 +0100, Matt Fleming wrote:
> > On Wed, 18 Sep, at 07:28:53PM, Bart Kuivenhoven wrote:
> > > 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.
> > 
> > Just to be clear, you haven't witnessed a triple fault, correct?
> > 
> > > This patch fixes this by clearing the interrupt bit before the lidt
> > > instruction.
> > 
> > I think we can go even further than this and get rid of all of the IDT
> > code in the EFI boot stub. The kernel maintains its own IDT anyway.
> > 
> 
> Well, isn't it so, that the kernel expects a setup in which interrupts 
> are disabled before the decompressed image is loaded?
> 
> What we can do is remove the lidt instruction and IDT pointer, but that 
> still doesn't change anything with regards to the kernels expectations.
> 
> And no, I haven't witnessed a triple fault, this is purely theoretical, 
> with a very slim chance of it actually happening. That does not mean 
> that it can't happen though.

it would also be very hard to prove that it occured (outside of special 
debug environments) - spurious, low probability triple faults are as 
undebuggable as it gets.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86 efi: bugfix interrupt disabling sequence
       [not found]       ` <1379708486.12705.131.camel-0VdLhd/A9PkhetGgFr3ssPXAX3CI6PSWQQ4Iyu8u01E@public.gmane.org>
  2013-09-21  7:50         ` Ingo Molnar
@ 2013-09-21 15:41         ` Matt Fleming
       [not found]           ` <20130921154127.GD21381-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
  1 sibling, 1 reply; 8+ messages in thread
From: Matt Fleming @ 2013-09-21 15:41 UTC (permalink / raw)
  To: Bart Kuivenhoven
  Cc: matt.fleming-ral2JQCrhuEAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	tglx-hfZtesqFncYOwBW4kG4KsQ, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	msalter-H+wXaHxf7aLQT0dZR+AlfA

On Fri, 20 Sep, at 10:21:26PM, Bart Kuivenhoven wrote:
> Well, isn't it so, that the kernel expects a setup in which interrupts
> are disabled before the decompressed image is loaded?
 
Yes, but I wasn't advocating leaving interrupts enabled, rather, because
interrupts are disabled we don't need to build an empty IDT, which will
never be used.

> What we can do is remove the lidt instruction and IDT pointer, but that
> still doesn't change anything with regards to the kernels expectations.
> 
> And no, I haven't witnessed a triple fault, this is purely theoretical,
> with a very slim chance of it actually happening. That does not mean
> that it can't happen though.
 
Right, but the answer to my question will dictate how aggressively we
apply your patch - whether it goes in the 'urgent' queue to be pushed
quickly or whether we give it more testing. Patches that fix serious
issues that users are hitting tend to make it into the next release. For
patches that fix theoretical bugs, we'll usually put it through more
strenuous testing first.

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86 efi: bugfix interrupt disabling sequence
       [not found]           ` <20130921154127.GD21381-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
@ 2013-09-23  9:27             ` Bart Kuivenhoven
  0 siblings, 0 replies; 8+ messages in thread
From: Bart Kuivenhoven @ 2013-09-23  9:27 UTC (permalink / raw)
  To: Matt Fleming
  Cc: matt.fleming-ral2JQCrhuEAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	tglx-hfZtesqFncYOwBW4kG4KsQ, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	msalter-H+wXaHxf7aLQT0dZR+AlfA

On Sat, 2013-09-21 at 16:41 +0100, Matt Fleming wrote:
> On Fri, 20 Sep, at 10:21:26PM, Bart Kuivenhoven wrote:
> > Well, isn't it so, that the kernel expects a setup in which interrupts
> > are disabled before the decompressed image is loaded?
>  
> Yes, but I wasn't advocating leaving interrupts enabled, rather, because
> interrupts are disabled we don't need to build an empty IDT, which will
> never be used.

Ah, well in that case I think you'll like the new version of my patch
that I'll send out soon.

> > What we can do is remove the lidt instruction and IDT pointer, but that
> > still doesn't change anything with regards to the kernels expectations.
> > 
> > And no, I haven't witnessed a triple fault, this is purely theoretical,
> > with a very slim chance of it actually happening. That does not mean
> > that it can't happen though.
>  
> Right, but the answer to my question will dictate how aggressively we
> apply your patch - whether it goes in the 'urgent' queue to be pushed
> quickly or whether we give it more testing. Patches that fix serious
> issues that users are hitting tend to make it into the next release. For
> patches that fix theoretical bugs, we'll usually put it through more
> strenuous testing first.

I haven't seen it happen.

Even if it happens, the CPU will just reset and try again, with a very
high likelihood that it will succeed that time.

Given these circumstances, I'd say you're more than welcome to put my
work through some serious tests rather than giving it 'urgent' status.

-- 
Kind regards/Met vriendelijke groet,
Bart Kuivenhoven.

Intern Fedora ARM,
Red Hat.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] x86 efi: bugfix interrupt disabling sequence
@ 2013-09-23  9:45 Bart Kuivenhoven
       [not found] ` <1379929528-7534-1-git-send-email-bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Bart Kuivenhoven @ 2013-09-23  9:45 UTC (permalink / raw)
  To: matt.fleming-ral2JQCrhuEAvxtiuMwx3w
  Cc: hpa-YMNOUZJC4hwAvxtiuMwx3w, tglx-hfZtesqFncYOwBW4kG4KsQ,
	mingo-H+wXaHxf7aLQT0dZR+AlfA, x86-DgEjT+Ai2ygdnm+yROfE0A,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, Bart Kuivenhoven

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.

Signed-off-by: Bart Kuivenhoven <bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/x86/boot/compressed/eboot.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..689b1ba 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1188,17 +1188,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("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.
@@ -1267,10 +1256,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:
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] x86 efi: bugfix interrupt disabling sequence
       [not found] ` <1379929528-7534-1-git-send-email-bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2013-09-25 13:12   ` Matt Fleming
  0 siblings, 0 replies; 8+ messages in thread
From: Matt Fleming @ 2013-09-25 13:12 UTC (permalink / raw)
  To: Bart Kuivenhoven
  Cc: matt.fleming-ral2JQCrhuEAvxtiuMwx3w, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	tglx-hfZtesqFncYOwBW4kG4KsQ, mingo-H+wXaHxf7aLQT0dZR+AlfA,
	x86-DgEjT+Ai2ygdnm+yROfE0A, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	msalter-H+wXaHxf7aLQT0dZR+AlfA

On Mon, 23 Sep, at 11:45:28AM, Bart Kuivenhoven wrote:
> 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.
> 
> Signed-off-by: Bart Kuivenhoven <bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  arch/x86/boot/compressed/eboot.c | 15 +--------------
>  1 file changed, 1 insertion(+), 14 deletions(-)

Applied, thanks Bart!

-- 
Matt Fleming, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-09-25 13:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-18 17:28 [PATCH] x86 efi: bugfix interrupt disabling sequence Bart Kuivenhoven
     [not found] ` <1379525333-4373-1-git-send-email-bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2013-09-20 15:28   ` Matt Fleming
2013-09-20 20:21     ` Bart Kuivenhoven
     [not found]       ` <1379708486.12705.131.camel-0VdLhd/A9PkhetGgFr3ssPXAX3CI6PSWQQ4Iyu8u01E@public.gmane.org>
2013-09-21  7:50         ` Ingo Molnar
2013-09-21 15:41         ` Matt Fleming
     [not found]           ` <20130921154127.GD21381-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2013-09-23  9:27             ` Bart Kuivenhoven
  -- strict thread matches above, loose matches on Subject: below --
2013-09-23  9:45 Bart Kuivenhoven
     [not found] ` <1379929528-7534-1-git-send-email-bemk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2013-09-25 13:12   ` Matt Fleming

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).