Apply upstream bug fixes for EFI stub support
svn path=/dists/sid/linux-2.6/; revision=18956
This commit is contained in:
parent
c5f48a38f4
commit
1b923af2ff
125
debian/patches/features/x86/efi-stub/0012-x86-efi-Fix-endian-issues-and-unaligned-accesses.patch
vendored
Normal file
125
debian/patches/features/x86/efi-stub/0012-x86-efi-Fix-endian-issues-and-unaligned-accesses.patch
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
From: Matt Fleming <matt.fleming@intel.com>
|
||||
Date: Tue, 28 Feb 2012 13:37:24 +0000
|
||||
Subject: [PATCH 12/13] x86, efi: Fix endian issues and unaligned accesses
|
||||
|
||||
commit 92f42c50f227ad228f815a8f4eec872524dae3a5 upstream.
|
||||
|
||||
We may need to convert the endianness of the data we read from/write
|
||||
to 'buf', so let's use {get,put}_unaligned_le32() to do that. Failure
|
||||
to do so can result in accessing invalid memory, leading to a
|
||||
segfault. Stephen Rothwell noticed this bug while cross-building an
|
||||
x86_64 allmodconfig kernel on PowerPC.
|
||||
|
||||
We need to read from and write to 'buf' a byte at a time otherwise
|
||||
it's possible we'll perform an unaligned access, which can lead to bus
|
||||
errors when cross-building an x86 kernel on risc architectures.
|
||||
|
||||
Cc: H. Peter Anvin <hpa@zytor.com>
|
||||
Cc: Nick Bowler <nbowler@elliptictech.com>
|
||||
Tested-by: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
|
||||
Link: http://lkml.kernel.org/r/1330436245-24875-6-git-send-email-matt@console-pimps.org
|
||||
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
|
||||
---
|
||||
arch/x86/boot/tools/build.c | 31 +++++++++++++++----------------
|
||||
1 file changed, 15 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
|
||||
index 4e9bd6b..f2ac95e 100644
|
||||
--- a/arch/x86/boot/tools/build.c
|
||||
+++ b/arch/x86/boot/tools/build.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <asm/boot.h>
|
||||
+#include <tools/le_byteshift.h>
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
@@ -41,6 +42,7 @@ typedef unsigned long u32;
|
||||
|
||||
#define DEFAULT_MAJOR_ROOT 0
|
||||
#define DEFAULT_MINOR_ROOT 0
|
||||
+#define DEFAULT_ROOT_DEV (DEFAULT_MAJOR_ROOT << 8 | DEFAULT_MINOR_ROOT)
|
||||
|
||||
/* Minimal number of setup sectors */
|
||||
#define SETUP_SECT_MIN 5
|
||||
@@ -159,7 +161,7 @@ int main(int argc, char ** argv)
|
||||
die("read-error on `setup'");
|
||||
if (c < 1024)
|
||||
die("The setup must be at least 1024 bytes");
|
||||
- if (buf[510] != 0x55 || buf[511] != 0xaa)
|
||||
+ if (get_unaligned_le16(&buf[510]) != 0xAA55)
|
||||
die("Boot block hasn't got boot flag (0xAA55)");
|
||||
fclose(file);
|
||||
|
||||
@@ -171,8 +173,7 @@ int main(int argc, char ** argv)
|
||||
memset(buf+c, 0, i-c);
|
||||
|
||||
/* Set the default root device */
|
||||
- buf[508] = DEFAULT_MINOR_ROOT;
|
||||
- buf[509] = DEFAULT_MAJOR_ROOT;
|
||||
+ put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
|
||||
|
||||
fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
|
||||
|
||||
@@ -192,44 +193,42 @@ int main(int argc, char ** argv)
|
||||
|
||||
/* Patch the setup code with the appropriate size parameters */
|
||||
buf[0x1f1] = setup_sectors-1;
|
||||
- buf[0x1f4] = sys_size;
|
||||
- buf[0x1f5] = sys_size >> 8;
|
||||
- buf[0x1f6] = sys_size >> 16;
|
||||
- buf[0x1f7] = sys_size >> 24;
|
||||
+ put_unaligned_le32(sys_size, &buf[0x1f4]);
|
||||
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
file_sz = sz + i + ((sys_size * 16) - sz);
|
||||
|
||||
- pe_header = *(unsigned int *)&buf[0x3c];
|
||||
+ pe_header = get_unaligned_le32(&buf[0x3c]);
|
||||
|
||||
/* Size of code */
|
||||
- *(unsigned int *)&buf[pe_header + 0x1c] = file_sz;
|
||||
+ put_unaligned_le32(file_sz, &buf[pe_header + 0x1c]);
|
||||
|
||||
/* Size of image */
|
||||
- *(unsigned int *)&buf[pe_header + 0x50] = file_sz;
|
||||
+ put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/* Address of entry point */
|
||||
- *(unsigned int *)&buf[pe_header + 0x28] = i;
|
||||
+ put_unaligned_le32(i, &buf[pe_header + 0x28]);
|
||||
|
||||
/* .text size */
|
||||
- *(unsigned int *)&buf[pe_header + 0xb0] = file_sz;
|
||||
+ put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]);
|
||||
|
||||
/* .text size of initialised data */
|
||||
- *(unsigned int *)&buf[pe_header + 0xb8] = file_sz;
|
||||
+ put_unaligned_le32(file_sz, &buf[pe_header + 0xb8]);
|
||||
#else
|
||||
/*
|
||||
* Address of entry point. startup_32 is at the beginning and
|
||||
* the 64-bit entry point (startup_64) is always 512 bytes
|
||||
* after.
|
||||
*/
|
||||
- *(unsigned int *)&buf[pe_header + 0x28] = i + 512;
|
||||
+ put_unaligned_le32(i + 512, &buf[pe_header + 0x28]);
|
||||
|
||||
/* .text size */
|
||||
- *(unsigned int *)&buf[pe_header + 0xc0] = file_sz;
|
||||
+ put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]);
|
||||
|
||||
/* .text size of initialised data */
|
||||
- *(unsigned int *)&buf[pe_header + 0xc8] = file_sz;
|
||||
+ put_unaligned_le32(file_sz, &buf[pe_header + 0xc8]);
|
||||
+
|
||||
#endif /* CONFIG_X86_32 */
|
||||
#endif /* CONFIG_EFI_STUB */
|
||||
|
||||
--
|
||||
1.7.10
|
||||
|
143
debian/patches/features/x86/efi-stub/0013-x86-efi-Add-dedicated-EFI-stub-entry-point.patch
vendored
Normal file
143
debian/patches/features/x86/efi-stub/0013-x86-efi-Add-dedicated-EFI-stub-entry-point.patch
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
From: Matt Fleming <matt.fleming@intel.com>
|
||||
Date: Sun, 15 Apr 2012 16:06:04 +0100
|
||||
Subject: [PATCH 13/13] x86, efi: Add dedicated EFI stub entry point
|
||||
|
||||
commit b1994304fc399f5d3a5368c81111d713490c4799 upstream.
|
||||
|
||||
The method used to work out whether we were booted by EFI firmware or
|
||||
via a boot loader is broken. Because efi_main() is always executed
|
||||
when booting from a boot loader we will dereference invalid pointers
|
||||
either on the stack (CONFIG_X86_32) or contained in %rdx
|
||||
(CONFIG_X86_64) when searching for an EFI System Table signature.
|
||||
|
||||
Instead of dereferencing these invalid system table pointers, add a
|
||||
new entry point that is only used when booting from EFI firmware, when
|
||||
we know the pointer arguments will be valid. With this change legacy
|
||||
boot loaders will no longer execute efi_main(), but will instead skip
|
||||
EFI stub initialisation completely.
|
||||
|
||||
[ hpa: Marking this for urgent/stable since it is a regression when
|
||||
the option is enabled; without the option the patch has no effect ]
|
||||
|
||||
Signed-off-by: Matt Fleming <matt.hfleming@intel.com>
|
||||
Link: http://lkml.kernel.org/r/1334584744.26997.14.camel@mfleming-mobl1.ger.corp.intel.com
|
||||
Reported-by: Jordan Justen <jordan.l.justen@intel.com>
|
||||
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
|
||||
Cc: <stable@vger.kernel.org> v3.3
|
||||
---
|
||||
arch/x86/boot/compressed/head_32.S | 14 +++++++++++---
|
||||
arch/x86/boot/compressed/head_64.S | 22 ++++++++++++++++------
|
||||
arch/x86/boot/tools/build.c | 15 +++++++++++----
|
||||
3 files changed, 38 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
|
||||
index a055993..c85e3ac 100644
|
||||
--- a/arch/x86/boot/compressed/head_32.S
|
||||
+++ b/arch/x86/boot/compressed/head_32.S
|
||||
@@ -33,6 +33,9 @@
|
||||
__HEAD
|
||||
ENTRY(startup_32)
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
+ jmp preferred_addr
|
||||
+
|
||||
+ .balign 0x10
|
||||
/*
|
||||
* We don't need the return address, so set up the stack so
|
||||
* efi_main() can find its arugments.
|
||||
@@ -41,12 +44,17 @@ ENTRY(startup_32)
|
||||
|
||||
call efi_main
|
||||
cmpl $0, %eax
|
||||
- je preferred_addr
|
||||
movl %eax, %esi
|
||||
- call 1f
|
||||
+ jne 2f
|
||||
1:
|
||||
+ /* EFI init failed, so hang. */
|
||||
+ hlt
|
||||
+ jmp 1b
|
||||
+2:
|
||||
+ call 3f
|
||||
+3:
|
||||
popl %eax
|
||||
- subl $1b, %eax
|
||||
+ subl $3b, %eax
|
||||
subl BP_pref_address(%esi), %eax
|
||||
add BP_code32_start(%esi), %eax
|
||||
leal preferred_addr(%eax), %eax
|
||||
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
|
||||
index 558d76c..87e03a1 100644
|
||||
--- a/arch/x86/boot/compressed/head_64.S
|
||||
+++ b/arch/x86/boot/compressed/head_64.S
|
||||
@@ -200,18 +200,28 @@ ENTRY(startup_64)
|
||||
* entire text+data+bss and hopefully all of memory.
|
||||
*/
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
- pushq %rsi
|
||||
+ /*
|
||||
+ * The entry point for the PE/COFF executable is 0x210, so only
|
||||
+ * legacy boot loaders will execute this jmp.
|
||||
+ */
|
||||
+ jmp preferred_addr
|
||||
+
|
||||
+ .org 0x210
|
||||
mov %rcx, %rdi
|
||||
mov %rdx, %rsi
|
||||
call efi_main
|
||||
- popq %rsi
|
||||
- cmpq $0,%rax
|
||||
- je preferred_addr
|
||||
movq %rax,%rsi
|
||||
- call 1f
|
||||
+ cmpq $0,%rax
|
||||
+ jne 2f
|
||||
1:
|
||||
+ /* EFI init failed, so hang. */
|
||||
+ hlt
|
||||
+ jmp 1b
|
||||
+2:
|
||||
+ call 3f
|
||||
+3:
|
||||
popq %rax
|
||||
- subq $1b, %rax
|
||||
+ subq $3b, %rax
|
||||
subq BP_pref_address(%rsi), %rax
|
||||
add BP_code32_start(%esi), %eax
|
||||
leaq preferred_addr(%rax), %rax
|
||||
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
|
||||
index ed54976..24443a3 100644
|
||||
--- a/arch/x86/boot/tools/build.c
|
||||
+++ b/arch/x86/boot/tools/build.c
|
||||
@@ -205,8 +205,13 @@ int main(int argc, char ** argv)
|
||||
put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
- /* Address of entry point */
|
||||
- put_unaligned_le32(i, &buf[pe_header + 0x28]);
|
||||
+ /*
|
||||
+ * Address of entry point.
|
||||
+ *
|
||||
+ * The EFI stub entry point is +16 bytes from the start of
|
||||
+ * the .text section.
|
||||
+ */
|
||||
+ put_unaligned_le32(i + 16, &buf[pe_header + 0x28]);
|
||||
|
||||
/* .text size */
|
||||
put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]);
|
||||
@@ -217,9 +222,11 @@ int main(int argc, char ** argv)
|
||||
/*
|
||||
* Address of entry point. startup_32 is at the beginning and
|
||||
* the 64-bit entry point (startup_64) is always 512 bytes
|
||||
- * after.
|
||||
+ * after. The EFI stub entry point is 16 bytes after that, as
|
||||
+ * the first instruction allows legacy loaders to jump over
|
||||
+ * the EFI stub initialisation
|
||||
*/
|
||||
- put_unaligned_le32(i + 512, &buf[pe_header + 0x28]);
|
||||
+ put_unaligned_le32(i + 528, &buf[pe_header + 0x28]);
|
||||
|
||||
/* .text size */
|
||||
put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]);
|
||||
--
|
||||
1.7.10
|
||||
|
|
@ -183,6 +183,9 @@
|
|||
+ features/x86/efi-stub/0009-x86-efi-EFI-boot-stub-support.patch
|
||||
+ features/x86/efi-stub/0010-x86-efi-Break-up-large-initrd-reads.patch
|
||||
+ features/x86/efi-stub/0011-x86-efi-Fix-pointer-math-issue-in-handle_ramdisks.patch
|
||||
+ features/x86/efi-stub/0012-x86-efi-Fix-endian-issues-and-unaligned-accesses.patch
|
||||
+ features/x86/efi-stub/0013-x86-efi-Add-dedicated-EFI-stub-entry-point.patch
|
||||
|
||||
+ bugfix/all/brcmsmac-INTERMEDIATE-but-not-AMPDU-only-when-tracin.patch
|
||||
+ bugfix/all/NFSv4-Rate-limit-the-state-manager-for-lock-reclaim-.patch
|
||||
+ bugfix/all/NFSv4-Ensure-that-the-LOCK-code-sets-exception-inode.patch
|
||||
|
|
Loading…
Reference in New Issue