From d3f209631e199d996ce7c666a904ab34c131106f Mon Sep 17 00:00:00 2001
From: Bruce Evans <bde@FreeBSD.org>
Date: Wed, 13 Sep 2000 14:08:50 +0000
Subject: [PATCH] Be more careful about cleaning up the stack after function
 calls early in the boot.  The cleanup must be done in one of the few ways
 that db_numargs() understands, so that early backtraces in ddb don't underrun
 the stack.  The underruns caused reboots a few years ago when there was an
 unmapped page above the stack (trapping to abort the command doesn't work
 early).

Cleaned up some nearby code.
---
 sys/amd64/amd64/locore.S | 27 ++++++++++++++++-----------
 sys/amd64/amd64/locore.s | 27 ++++++++++++++++-----------
 sys/i386/i386/locore.s   | 27 ++++++++++++++++-----------
 3 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S
index fa95fb0d6b53..f3e4cdebbdb5 100644
--- a/sys/amd64/amd64/locore.S
+++ b/sys/amd64/amd64/locore.S
@@ -348,22 +348,27 @@ NON_GPROF_ENTRY(btext)
 /* now running relocated at KERNBASE where the system is linked to run */
 begin:
 	/* set up bootstrap stack */
-	movl	_proc0paddr,%esp	/* location of in-kernel pages */
-	addl	$UPAGES*PAGE_SIZE,%esp	/* bootstrap stack end location */
-	xorl	%eax,%eax			/* mark end of frames */
-	movl	%eax,%ebp
-	movl	_proc0paddr,%eax
-	movl	_IdlePTD, %esi
+	movl	_proc0paddr,%eax		/* location of in-kernel pages */
+	leal	UPAGES*PAGE_SIZE(%eax),%esp	/* bootstrap stack end location */
+
+	xorl	%ebp,%ebp			/* mark end of frames */
+
+	movl	_IdlePTD,%esi
 	movl	%esi,PCB_CR3(%eax)
 
-	movl	physfree, %esi
-	pushl	%esi				/* value of first for init386(first) */
+	pushl	physfree			/* value of first for init386(first) */
 	call	_init386			/* wire 386 chip for unix operation */
-	popl	%esi
+
+	/*
+	 * Clean up the stack in a way that db_numargs() understands, so
+	 * that backtraces in ddb don't underrun the stack.  Traps for
+	 * inaccessible memory are more fatal than usual this early.
+	 */
+	addl	$4,%esp
 
 	call	_mi_startup			/* autoconfiguration, mountroot etc */
-
-	hlt		/* never returns to here */
+	/* NOTREACHED */
+	addl	$0,%esp				/* for db_numargs() again */
 
 /*
  * Signal trampoline, copied to top of user stack
diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s
index fa95fb0d6b53..f3e4cdebbdb5 100644
--- a/sys/amd64/amd64/locore.s
+++ b/sys/amd64/amd64/locore.s
@@ -348,22 +348,27 @@ NON_GPROF_ENTRY(btext)
 /* now running relocated at KERNBASE where the system is linked to run */
 begin:
 	/* set up bootstrap stack */
-	movl	_proc0paddr,%esp	/* location of in-kernel pages */
-	addl	$UPAGES*PAGE_SIZE,%esp	/* bootstrap stack end location */
-	xorl	%eax,%eax			/* mark end of frames */
-	movl	%eax,%ebp
-	movl	_proc0paddr,%eax
-	movl	_IdlePTD, %esi
+	movl	_proc0paddr,%eax		/* location of in-kernel pages */
+	leal	UPAGES*PAGE_SIZE(%eax),%esp	/* bootstrap stack end location */
+
+	xorl	%ebp,%ebp			/* mark end of frames */
+
+	movl	_IdlePTD,%esi
 	movl	%esi,PCB_CR3(%eax)
 
-	movl	physfree, %esi
-	pushl	%esi				/* value of first for init386(first) */
+	pushl	physfree			/* value of first for init386(first) */
 	call	_init386			/* wire 386 chip for unix operation */
-	popl	%esi
+
+	/*
+	 * Clean up the stack in a way that db_numargs() understands, so
+	 * that backtraces in ddb don't underrun the stack.  Traps for
+	 * inaccessible memory are more fatal than usual this early.
+	 */
+	addl	$4,%esp
 
 	call	_mi_startup			/* autoconfiguration, mountroot etc */
-
-	hlt		/* never returns to here */
+	/* NOTREACHED */
+	addl	$0,%esp				/* for db_numargs() again */
 
 /*
  * Signal trampoline, copied to top of user stack
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index fa95fb0d6b53..f3e4cdebbdb5 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -348,22 +348,27 @@ NON_GPROF_ENTRY(btext)
 /* now running relocated at KERNBASE where the system is linked to run */
 begin:
 	/* set up bootstrap stack */
-	movl	_proc0paddr,%esp	/* location of in-kernel pages */
-	addl	$UPAGES*PAGE_SIZE,%esp	/* bootstrap stack end location */
-	xorl	%eax,%eax			/* mark end of frames */
-	movl	%eax,%ebp
-	movl	_proc0paddr,%eax
-	movl	_IdlePTD, %esi
+	movl	_proc0paddr,%eax		/* location of in-kernel pages */
+	leal	UPAGES*PAGE_SIZE(%eax),%esp	/* bootstrap stack end location */
+
+	xorl	%ebp,%ebp			/* mark end of frames */
+
+	movl	_IdlePTD,%esi
 	movl	%esi,PCB_CR3(%eax)
 
-	movl	physfree, %esi
-	pushl	%esi				/* value of first for init386(first) */
+	pushl	physfree			/* value of first for init386(first) */
 	call	_init386			/* wire 386 chip for unix operation */
-	popl	%esi
+
+	/*
+	 * Clean up the stack in a way that db_numargs() understands, so
+	 * that backtraces in ddb don't underrun the stack.  Traps for
+	 * inaccessible memory are more fatal than usual this early.
+	 */
+	addl	$4,%esp
 
 	call	_mi_startup			/* autoconfiguration, mountroot etc */
-
-	hlt		/* never returns to here */
+	/* NOTREACHED */
+	addl	$0,%esp				/* for db_numargs() again */
 
 /*
  * Signal trampoline, copied to top of user stack