]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
2 2.6.23 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 13 Nov 2007 23:13:52 +0000 (15:13 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 13 Nov 2007 23:13:52 +0000 (15:13 -0800)
queue-2.6.23/series
queue-2.6.23/x86-setup-handle-boot-loaders-which-set-up-the-stack-incorrectly.patch [new file with mode: 0644]
queue-2.6.23/x86-setup-sizeof-is-unsigned-unbreak-comparisons.patch [new file with mode: 0644]

index 4d4800c29423e5498abe80a865c62efd0868ba31..a24cfd69ece2a011ca46083d9370cdd0c60d3707 100644 (file)
@@ -36,3 +36,5 @@ usb-mutual-exclusion-for-ehci-init-and-port-resets.patch
 mips-mt-fix-bug-in-multithreaded-kernels.patch
 mips-r1-fix-hazard-barriers-to-make-kernels-work-on-r2-also.patch
 slub-fix-memory-leak-by-not-reusing-cpu_slab.patch
+x86-setup-handle-boot-loaders-which-set-up-the-stack-incorrectly.patch
+x86-setup-sizeof-is-unsigned-unbreak-comparisons.patch
diff --git a/queue-2.6.23/x86-setup-handle-boot-loaders-which-set-up-the-stack-incorrectly.patch b/queue-2.6.23/x86-setup-handle-boot-loaders-which-set-up-the-stack-incorrectly.patch
new file mode 100644 (file)
index 0000000..b1adea8
--- /dev/null
@@ -0,0 +1,125 @@
+From 6b6815c6d5d1dc209701d1661a7a0e09a295db2f Mon Sep 17 00:00:00 2001
+From: H. Peter Anvin <hpa@zytor.com>
+Date: Thu, 25 Oct 2007 16:11:33 -0700
+Subject: x86 setup: handle boot loaders which set up the stack incorrectly
+Message-ID: <472BBA17.6080207@zytor.com>
+
+From: H. Peter Anvin <hpa@zytor.com>
+
+patch 6b6815c6d5d1dc209701d1661a7a0e09a295db2f in mainline.
+
+Apparently some specific versions of LILO enter the kernel with a
+stack pointer that doesn't match the rest of the segments.  Make our
+best attempt at untangling the resulting mess.
+
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/i386/boot/boot.h   |    4 +--
+ arch/i386/boot/header.S |   62 ++++++++++++++++++++++++++++++++++--------------
+ 2 files changed, 46 insertions(+), 20 deletions(-)
+
+--- a/arch/i386/boot/boot.h
++++ b/arch/i386/boot/boot.h
+@@ -17,6 +17,8 @@
+ #ifndef BOOT_BOOT_H
+ #define BOOT_BOOT_H
++#define STACK_SIZE    512     /* Minimum number of bytes for stack */
++
+ #ifndef __ASSEMBLY__
+ #include <stdarg.h>
+@@ -198,8 +200,6 @@ static inline int isdigit(int ch)
+ }
+ /* Heap -- available for dynamic lists. */
+-#define STACK_SIZE    512     /* Minimum number of bytes for stack */
+-
+ extern char _end[];
+ extern char *HEAP;
+ extern char *heap_end;
+--- a/arch/i386/boot/header.S
++++ b/arch/i386/boot/header.S
+@@ -173,7 +173,8 @@ ramdisk_size:      .long   0               # its size in byt
+ bootsect_kludge:
+               .long   0               # obsolete
+-heap_end_ptr: .word   _end+1024       # (Header version 0x0201 or later)
++heap_end_ptr: .word   _end+STACK_SIZE-512
++                                      # (Header version 0x0201 or later)
+                                       # space from here (exclusive) down to
+                                       # end of setup code can be used by setup
+                                       # for local heap purposes.
+@@ -225,28 +226,53 @@ start_of_setup:
+       int     $0x13
+ #endif
+-# We will have entered with %cs = %ds+0x20, normalize %cs so
+-# it is on par with the other segments.
+-      pushw   %ds
+-      pushw   $setup2
+-      lretw
+-
+-setup2:
+ # Force %es = %ds
+       movw    %ds, %ax
+       movw    %ax, %es
+       cld
+-# Stack paranoia: align the stack and make sure it is good
+-# for both 16- and 32-bit references.  In particular, if we
+-# were meant to have been using the full 16-bit segment, the
+-# caller might have set %sp to zero, which breaks %esp-based
+-# references.
+-      andw    $~3, %sp        # dword align (might as well...)
+-      jnz     1f
+-      movw    $0xfffc, %sp    # Make sure we're not zero
+-1:    movzwl  %sp, %esp       # Clear upper half of %esp
+-      sti
++# Apparently some ancient versions of LILO invoked the kernel
++# with %ss != %ds, which happened to work by accident for the
++# old code.  If the CAN_USE_HEAP flag is set in loadflags, or
++# %ss != %ds, then adjust the stack pointer.
++
++      # Smallest possible stack we can tolerate
++      movw    $(_end+STACK_SIZE), %cx
++
++      movw    heap_end_ptr, %dx
++      addw    $512, %dx
++      jnc     1f
++      xorw    %dx, %dx        # Wraparound - whole segment available
++1:    testb   $CAN_USE_HEAP, loadflags
++      jnz     2f
++
++      # No CAN_USE_HEAP
++      movw    %ss, %dx
++      cmpw    %ax, %dx        # %ds == %ss?
++      movw    %sp, %dx
++      # If so, assume %sp is reasonably set, otherwise use
++      # the smallest possible stack.
++      jne     4f              # -> Smallest possible stack...
++
++      # Make sure the stack is at least minimum size.  Take a value
++      # of zero to mean "full segment."
++2:
++      andw    $~3, %dx        # dword align (might as well...)
++      jnz     3f
++      movw    $0xfffc, %dx    # Make sure we're not zero
++3:    cmpw    %cx, %dx
++      jnb     5f
++4:    movw    %cx, %dx        # Minimum value we can possibly use
++5:    movw    %ax, %ss
++      movzwl  %dx, %esp       # Clear upper half of %esp
++      sti                     # Now we should have a working stack
++
++# We will have entered with %cs = %ds+0x20, normalize %cs so
++# it is on par with the other segments.
++      pushw   %ds
++      pushw   $6f
++      lretw
++6:
+ # Check signature at end of setup
+       cmpl    $0x5a5aaa55, setup_sig
diff --git a/queue-2.6.23/x86-setup-sizeof-is-unsigned-unbreak-comparisons.patch b/queue-2.6.23/x86-setup-sizeof-is-unsigned-unbreak-comparisons.patch
new file mode 100644 (file)
index 0000000..a33fd0e
--- /dev/null
@@ -0,0 +1,73 @@
+From e6e1ace9904b72478f0c5a5aa7bd174cb6f62561 Mon Sep 17 00:00:00 2001
+From: H. Peter Anvin <hpa@zytor.com>
+Date: Thu, 25 Oct 2007 16:09:38 -0700
+Subject: x86 setup: sizeof() is unsigned, unbreak comparisons
+Message-ID: <472BBA17.6080207@zytor.com>
+
+From: H. Peter Anvin <hpa@zytor.com>
+
+patch e6e1ace9904b72478f0c5a5aa7bd174cb6f62561 in mainline.
+
+
+We use signed values for limit checking since the values can go
+negative under certain circumstances.  However, sizeof() is unsigned
+and forces the comparison to be unsigned, so move the comparison into
+the heap_free() macros so we can ensure it is a signed comparison.
+
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/i386/boot/boot.h       |    4 ++--
+ arch/i386/boot/video-bios.c |    2 +-
+ arch/i386/boot/video-vesa.c |    2 +-
+ arch/i386/boot/video.c      |    2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/arch/i386/boot/boot.h
++++ b/arch/i386/boot/boot.h
+@@ -216,9 +216,9 @@ static inline char *__get_heap(size_t s,
+ #define GET_HEAP(type, n) \
+       ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
+-static inline int heap_free(void)
++static inline bool heap_free(size_t n)
+ {
+-      return heap_end-HEAP;
++      return (int)(heap_end-HEAP) >= (int)n;
+ }
+ /* copy.S */
+--- a/arch/i386/boot/video-bios.c
++++ b/arch/i386/boot/video-bios.c
+@@ -79,7 +79,7 @@ static int bios_probe(void)
+       video_bios.modes = GET_HEAP(struct mode_info, 0);
+       for (mode = 0x14; mode <= 0x7f; mode++) {
+-              if (heap_free() < sizeof(struct mode_info))
++              if (!heap_free(sizeof(struct mode_info)))
+                       break;
+               if (mode_defined(VIDEO_FIRST_BIOS+mode))
+--- a/arch/i386/boot/video-vesa.c
++++ b/arch/i386/boot/video-vesa.c
+@@ -57,7 +57,7 @@ static int vesa_probe(void)
+       while ((mode = rdfs16(mode_ptr)) != 0xffff) {
+               mode_ptr += 2;
+-              if (heap_free() < sizeof(struct mode_info))
++              if (!heap_free(sizeof(struct mode_info)))
+                       break;  /* Heap full, can't save mode info */
+               if (mode & ~0x1ff)
+--- a/arch/i386/boot/video.c
++++ b/arch/i386/boot/video.c
+@@ -371,7 +371,7 @@ static void save_screen(void)
+       saved.curx = boot_params.screen_info.orig_x;
+       saved.cury = boot_params.screen_info.orig_y;
+-      if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
++      if (!heap_free(saved.x*saved.y*sizeof(u16)+512))
+               return;         /* Not enough heap to save the screen */
+       saved.data = GET_HEAP(u16, saved.x*saved.y);