aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2025-11-21 08:34:51 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2025-11-21 15:02:21 +0000
commitd8bfcacd12aba73188c44a157c707908e275825d (patch)
tree6a824d29ad4e21b67b24a0140ec5050cd9e14f8b
parentb9fc7628dbb24b55cbb8791c83bd69f73cfadf23 (diff)
vm_fault: add a verifier that the PG_ZERO page is indeed zeroed
Compiled under INVARIANTS, activated by the same sysctl debug.vm_check_pg_zero. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D53850
-rw-r--r--sys/vm/vm_fault.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 2e150b368d71..3bf16778d987 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -85,6 +85,8 @@
#include <sys/refcount.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
+#include <sys/sched.h>
+#include <sys/sf_buf.h>
#include <sys/signalvar.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
@@ -1220,6 +1222,24 @@ vm_fault_zerofill(struct faultstate *fs)
if ((fs->m->flags & PG_ZERO) == 0) {
pmap_zero_page(fs->m);
} else {
+#ifdef INVARIANTS
+ if (vm_check_pg_zero) {
+ struct sf_buf *sf;
+ unsigned long *p;
+ int i;
+
+ sched_pin();
+ sf = sf_buf_alloc(fs->m, SFB_CPUPRIVATE);
+ p = (unsigned long *)sf_buf_kva(sf);
+ for (i = 0; i < PAGE_SIZE / sizeof(*p); i++, p++) {
+ KASSERT(*p == 0,
+ ("zerocheck failed page %p PG_ZERO %d %jx",
+ fs->m, i, (uintmax_t)*p));
+ }
+ sf_buf_free(sf);
+ sched_unpin();
+ }
+#endif
VM_CNT_INC(v_ozfod);
}
VM_CNT_INC(v_zfod);