git: 83d988288675 - main - sys: do not allow entering vm_fault() on boot until VM is initialized
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 19 Jan 2026 16:20:46 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=83d98828867591b5d842573ed6edcec7392f82df
commit 83d98828867591b5d842573ed6edcec7392f82df
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-01-18 21:14:59 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-01-19 16:20:36 +0000
sys: do not allow entering vm_fault() on boot until VM is initialized
On amd64, a hack sets td_critnest to 1 in hammer_time(), and then clear
it before returning from hammer_time(), which is too early. Instead,
set TDP_NOFAULTING for thread0, and clear the flag after vm_init() finished.
Noted by: adrian
Reviewed by: adrian (previous version), markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D54768
---
sys/amd64/amd64/machdep.c | 5 +----
sys/kern/init_main.c | 12 +++++++++++-
sys/vm/vm_init.c | 8 ++++++++
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 2fce1a7e64b6..cae58181000f 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1518,13 +1518,11 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
/*
* We initialize the PCB pointer early so that exception
- * handlers will work. Also set up td_critnest to short-cut
- * the page fault handler.
+ * handlers will work.
*/
cpu_max_ext_state_size = sizeof(struct savefpu);
set_top_of_stack_td(&thread0);
thread0.td_pcb = get_pcb_td(&thread0);
- thread0.td_critnest = 1;
/*
* The console and kdb should be initialized even earlier than here,
@@ -1615,7 +1613,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
#ifdef FDT
x86_init_fdt();
#endif
- thread0.td_critnest = 0;
kasan_init();
kmsan_init();
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 4144297d674c..39357b8d4440 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -104,7 +104,17 @@ void mi_startup(void); /* Should be elsewhere */
static struct session session0;
static struct pgrp pgrp0;
struct proc proc0;
-struct thread0_storage thread0_st __aligned(32);
+struct thread0_storage thread0_st __aligned(32) = {
+ .t0st_thread = {
+ /*
+ * thread0.td_pflags is set with TDP_NOFAULTING to
+ * short-cut the vm page fault handler until it is
+ * ready. It is cleared in vm_init() after VM
+ * initialization.
+ */
+ .td_pflags = TDP_NOFAULTING,
+ },
+};
struct vmspace vmspace0;
struct proc *initproc;
diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
index a0d3651ba266..2764b438d27b 100644
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -159,6 +159,14 @@ vm_mem_init(void *dummy)
pmap_init();
vm_pager_init();
+ /*
+ * Now we can properly handle calls into vm_fault() from
+ * kernel page faults during initialization, typically to
+ * panic. Clear the nofaulting flag set for thread0 in the
+ * image, see kern/init_main.c
+ */
+ curthread->td_pflags &= ~TDP_NOFAULTING;
+
#ifdef INVARIANTS
vm_check_pagesizes();
#endif