ref: 232acbe591e259fa75c78d454c9a39156896a31b
parent: 900afc0e8347e06b0d78a9cf089dcb9155e5f497
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Nov 19 13:42:01 EST 2018
pc, pc64: park application processors in rebootcode with mmu off instead of having application processors spin in mpshutdown() with mmu on, and be subject to reboot() overriding kernel text and modifying page tables, park the application processors in rebootcode idle loop with the mmu off.
--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -701,34 +701,13 @@
mmuflushtlb(PADDR(m->pdb));
}
-void
-reboot(void *entry, void *code, ulong size)
+static void
+rebootjump(uintptr entry, uintptr code, ulong size)
{- void (*f)(ulong, ulong, ulong);
+ void (*f)(uintptr, uintptr, ulong);
ulong *pdb;
- writeconf();
- vmxshutdown();
-
- /*
- * the boot processor is cpu0. execute this function on it
- * so that the new kernel has the same cpu0. this only matters
- * because the hardware has a notion of which processor was the
- * boot processor and we look at it at start up.
- */
- if (m->machno != 0) {- procwired(up, 0);
- sched();
- }
- cpushutdown();
-
splhi();
-
- /* turn off buffered serial console */
- serialoq = nil;
-
- /* shutdown devices */
- chandevshutdown();
arch->introff();
/*
@@ -745,7 +724,8 @@
/* off we go - never to return */
coherence();
- (*f)((ulong)entry & ~0xF0000000UL, PADDR(code), size);
+ (*f)(entry, code, size);
+ for(;;);
}
@@ -753,5 +733,36 @@
exit(int)
{cpushutdown();
+ if(m->machno)
+ rebootjump(0, 0, 0);
arch->reset();
+}
+
+void
+reboot(void *entry, void *code, ulong size)
+{+ writeconf();
+ vmxshutdown();
+
+ /*
+ * the boot processor is cpu0. execute this function on it
+ * so that the new kernel has the same cpu0. this only matters
+ * because the hardware has a notion of which processor was the
+ * boot processor and we look at it at start up.
+ */
+ if (m->machno != 0) {+ procwired(up, 0);
+ sched();
+ }
+ cpushutdown();
+ delay(1000);
+ splhi();
+
+ /* turn off buffered serial console */
+ serialoq = nil;
+
+ /* shutdown devices */
+ chandevshutdown();
+
+ rebootjump((ulong)entry & ~0xF0000000UL, PADDR(code), size);
}
--- a/sys/src/9/pc/rebootcode.s
+++ b/sys/src/9/pc/rebootcode.s
@@ -20,6 +20,13 @@
MOVL $0, DX
MOVL DX, CR3
+ /* stack below entry point */
+ MOVL AX, SP
+
+ /* park cpu for zero entry point */
+ ORL AX, AX
+ JZ _idle
+
/*
* the source and destination may overlap.
* determine whether to copy forward or backwards
@@ -52,3 +59,7 @@
_startkernel:
ORL AX, AX /* NOP: avoid link bug */
JMP* AX
+
+_idle:
+ HLT
+ JMP _idle
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -336,10 +336,39 @@
schedinit();
}
+static void
+rebootjump(uintptr entry, uintptr code, ulong size)
+{+ void (*f)(uintptr, uintptr, ulong);
+
+ splhi();
+ arch->introff();
+
+ /*
+ * This allows the reboot code to turn off the page mapping
+ */
+ *mmuwalk(m->pml4, 0, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
+ *mmuwalk(m->pml4, 0, 2, 0) = *mmuwalk(m->pml4, KZERO, 2, 0);
+ mmuflushtlb();
+
+ /* setup reboot trampoline function */
+ f = (void*)REBOOTADDR;
+ memmove(f, rebootcode, sizeof(rebootcode));
+
+ /* off we go - never to return */
+ coherence();
+ (*f)(entry, code, size);
+
+ for(;;);
+}
+
+
void
exit(int)
{cpushutdown();
+ if(m->machno)
+ rebootjump(0, 0, 0);
arch->reset();
}
@@ -346,8 +375,6 @@
void
reboot(void *entry, void *code, ulong size)
{- void (*f)(uintptr, uintptr, ulong);
-
writeconf();
vmxshutdown();
@@ -362,7 +389,7 @@
sched();
}
cpushutdown();
-
+ delay(1000);
splhi();
/* turn off buffered serial console */
@@ -370,22 +397,8 @@
/* shutdown devices */
chandevshutdown();
- arch->introff();
- /*
- * This allows the reboot code to turn off the page mapping
- */
- *mmuwalk(m->pml4, 0, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
- *mmuwalk(m->pml4, 0, 2, 0) = *mmuwalk(m->pml4, KZERO, 2, 0);
- mmuflushtlb();
-
- /* setup reboot trampoline function */
- f = (void*)REBOOTADDR;
- memmove(f, rebootcode, sizeof(rebootcode));
-
- /* off we go - never to return */
- coherence();
- (*f)((uintptr)entry & ~0xF0000000UL, (uintptr)PADDR(code), size);
+ rebootjump((uintptr)entry & ~0xF0000000UL, PADDR(code), size);
}
/*
--- a/sys/src/9/pc64/rebootcode.s
+++ b/sys/src/9/pc64/rebootcode.s
@@ -20,9 +20,6 @@
MOVL $_gdtptr64p<>(SB), AX
MOVL (AX), GDTR
- /* move stack below destination */
- MOVL DI, SP
-
/* load CS with 32bit code segment */
PUSHQ $SELECTOR(3, SELGDT, 0)
PUSHQ $_warp32<>(SB)
@@ -61,7 +58,13 @@
MOVL BX, CX /* byte count */
MOVL DI, AX /* save entry point */
+ MOVL AX, SP /* move stack below entry */
+ /* park cpu for zero entry point */
+ ORL AX, AX
+ JZ _idle
+
+
/*
* the source and destination may overlap.
* determine whether to copy forward or backwards
@@ -89,6 +92,10 @@
STD
REP; MOVSB
JMP _startkernel
+
+_idle:
+ HLT
+ JMP _idle
TEXT _gdt<>(SB), 1, $-4
/* null descriptor */
--
⑨