File ipxe-prefix-Use-.bss16-as-temporary-stac.patch of Package qemu

From aad30f4c85b7126abe25be17916f5a6cdad49397 Mon Sep 17 00:00:00 2001
From: Michael Brown <mcb30@ipxe.org>
Date: Tue, 24 Feb 2015 16:13:55 +0000
Subject: [PATCH 1/3] [prefix] Use .bss16 as temporary stack space for calls to
 install_block

Some decompression algorithms (e.g. LZMA) require large amounts of
temporary stack space, which may not be made available by all
prefixes.  Use .bss16 as a temporary stack for the duration of the
calls to install_block (switching back to the external stack before we
start making calls into code which might access variables in .bss16),
and allow the decompressor to define a global symbol to force a
minimum value on the size of .bss16.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
(cherry picked from commit 3e04f0791e614772f3ffe3663e4c8da71e2bc981)
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
 src/arch/i386/prefix/libprefix.S | 49 +++++++++++++++++++++++++++++++---------
 src/arch/i386/scripts/i386.lds   |  8 +++++++
 2 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S
index 7c1ece7..0be9679 100644
--- a/src/arch/i386/prefix/libprefix.S
+++ b/src/arch/i386/prefix/libprefix.S
@@ -296,11 +296,9 @@ copy_bytes:
  * Zero bytes
  *
  * Parameters:
- *   %ds:esi : source address
  *   %es:edi : destination address
  *   %ecx : length
  * Returns:
- *   %ds:esi : next source address
  *   %es:edi : next destination address
  * Corrupts:
  *   None
@@ -678,12 +676,21 @@ install:
 	.globl install_prealloc
 install_prealloc:
 	progress "install_prealloc:\n"
-	/* Save registers */
+	/* Save registers on external stack */
 	pushal
 	pushw	%ds
 	pushw	%es
 	cld			/* Sanity: clear the direction flag asap */
 
+	/* Switch to temporary stack in .bss16 */
+	pushw	%ss
+	popw	%ds
+	movl	%esp, %ecx
+	movw	%bx, %ss
+	movl	$_data16_memsz, %esp
+	pushw	%ds
+	pushl	%ecx
+
 	/* Set up %ds for (read-only) access to .prefix */
 	pushw	%cs
 	popw	%ds
@@ -710,6 +717,7 @@ install_prealloc:
 	popl	%esi
 
 #ifndef KEEP_IT_REAL
+
 	/* Access high memory by enabling the A20 gate.  (We will
 	 * already have 4GB segment limits as a result of calling
 	 * install_block.)
@@ -778,7 +786,7 @@ payload_death_message:
 	movzwl	%bx, %edi
 	shll	$4, %edi
 	movl	$_data16_filesz, %ecx
-	movl	$_data16_memsz, %edx
+	movl	$_data16_filesz, %edx	/* do not zero our temporary stack */
 	call	install_block		/* .data16 */
 
 	/* Set up %ds for access to .data16 */
@@ -787,11 +795,8 @@ payload_death_message:
 	/* Restore decompression temporary area physical address */
 	popl	%edi
 
-#ifdef KEEP_IT_REAL
-	/* Initialise libkir */
-	movw	%ax, (init_libkir_vector+2)
-	lcall	*init_libkir_vector
-#else
+#ifndef KEEP_IT_REAL
+
 	/* Find a suitable decompression temporary area, if none specified */
 	pushl	%eax
 	testl	%edi, %edi
@@ -823,6 +828,22 @@ payload_death_message:
 	call	install_block
 	popl	%edi
 
+#endif /* KEEP_IT_REAL */
+
+	/* Switch back to original stack and zero .bss16 */
+	lss	%ss:(%esp), %esp
+	pushl	%edi
+	pushw	%es
+	movw	%bx, %es
+	movl	$_data16_filesz, %edi
+	movl	$_data16_memsz, %ecx
+	subl	%edi, %ecx
+	call	zero_bytes
+	popw	%es
+	popl	%edi
+
+#ifndef KEEP_IT_REAL
+
 	/* Initialise librm at current location */
 	progress "  init_librm\n"
 	movw	%ax, (init_librm_vector+2)
@@ -834,7 +855,6 @@ payload_death_message:
 	incb	memmap_post
 	decl	%ebp
 1:
-
 	/* Call relocate() to determine target address for relocation.
 	 * relocate() will return with %esi, %edi and %ecx set up
 	 * ready for the copy to the new location.
@@ -857,7 +877,14 @@ payload_death_message:
 	/* Initialise librm at new location */
 	progress "  init_librm\n"
 	lcall	*init_librm_vector
-#endif
+
+#else /* KEEP_IT_REAL */
+
+	/* Initialise libkir */
+	movw	%ax, (init_libkir_vector+2)
+	lcall	*init_libkir_vector
+
+#endif /* KEEP_IT_REAL */
 
 	/* Close access to payload */
 	progress "  close_payload\n"
diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds
index 98f95cb..348dfef 100644
--- a/src/arch/i386/scripts/i386.lds
+++ b/src/arch/i386/scripts/i386.lds
@@ -27,6 +27,13 @@ SECTIONS {
     PROVIDE ( _max_align = 16 );
 
     /*
+     * Allow decompressor to require a minimum amount of temporary stack
+     * space.
+     *
+     */
+    PROVIDE ( _min_decompress_stack = 0 );
+
+    /*
      * The prefix
      *
      */
@@ -87,6 +94,7 @@ SECTIONS {
 	*(.bss16.*)
 	*(.stack16)
 	*(.stack16.*)
+	. = MAX ( ., _mdata16 + _min_decompress_stack );
 	_edata16 = .;
     }
     _data16_filesz	= ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );
-- 
1.9.0