summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorariane <ariane@openbsd.org>2011-07-08 21:00:53 +0000
committerariane <ariane@openbsd.org>2011-07-08 21:00:53 +0000
commit0547f1a4d8730cec4a8c3308eefdad21983bb9ad (patch)
treee88a4359044ce7e5ad5fcd7be94ad4631cba8023
parentunlink compat_aout, spotted by jmc (diff)
downloadwireguard-openbsd-0547f1a4d8730cec4a8c3308eefdad21983bb9ad.tar.xz
wireguard-openbsd-0547f1a4d8730cec4a8c3308eefdad21983bb9ad.zip
Ensure all pages in pmemrange can be marked as dirty.
It'd be a very bad idea to hand out dirty pages as zeroed, just because we came back from hibernate. No callers at the moment, will be called on hibernate resume path.
-rw-r--r--sys/kern/subr_hibernate.c43
-rw-r--r--sys/sys/hibernate.h3
2 files changed, 44 insertions, 2 deletions
diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c
index c622e1a2cb8..7ac3bf26277 100644
--- a/sys/kern/subr_hibernate.c
+++ b/sys/kern/subr_hibernate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_hibernate.c,v 1.5 2011/07/08 18:34:46 ariane Exp $ */
+/* $OpenBSD: subr_hibernate.c,v 1.6 2011/07/08 21:00:53 ariane Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@@ -264,6 +264,47 @@ uvm_pmr_zero_everything(void)
}
/*
+ * Mark all memory as dirty.
+ *
+ * Used to inform the system that the clean memory isn't clean for some
+ * reason, for example because we just came back from hibernate.
+ */
+void
+uvm_pmr_dirty_everything(void)
+{
+ struct uvm_pmemrange *pmr;
+ struct vm_page *pg;
+ int i;
+
+ uvm_lock_fpageq();
+ TAILQ_FOREACH(pmr, &uvm.pmr_control.use, pmr_use) {
+ /* Dirty single pages. */
+ while ((pg = TAILQ_FIRST(&pmr->single[UVM_PMR_MEMTYPE_ZERO]))
+ != NULL) {
+ uvm_pmr_remove(pmr, pg);
+ uvm_pagezero(pg);
+ atomic_clearbits_int(&pg->pg_flags, PG_ZERO);
+ uvm_pmr_insert(pmr, pg, 0);
+ }
+
+ /* Dirty multi page ranges. */
+ while ((pg = RB_ROOT(&pmr->size[UVM_PMR_MEMTYPE_ZEOR]))
+ != NULL) {
+ pg--; /* Size tree always has second page. */
+ uvm_pmr_remove(pmr, pg);
+ for (i = 0; i < pg->fpgsz; i++) {
+ uvm_pagezero(&pg[i]);
+ atomic_clearbits_int(&pg[i].pg_flags, PG_ZERO);
+ }
+ uvm_pmr_insert(pmr, pg, 0);
+ }
+ }
+
+ uvmexp.zeropages = 0;
+ uvm_unlock_fpageq();
+}
+
+/*
* Allocate the highest address that can hold sz.
*
* sz in bytes.
diff --git a/sys/sys/hibernate.h b/sys/sys/hibernate.h
index 64fb36f9fee..8bf90a3ccb5 100644
--- a/sys/sys/hibernate.h
+++ b/sys/sys/hibernate.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hibernate.h,v 1.5 2011/07/08 18:34:46 ariane Exp $ */
+/* $OpenBSD: hibernate.h,v 1.6 2011/07/08 21:00:53 ariane Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@@ -39,6 +39,7 @@ void *hib_alloc(struct hiballoc_arena*, size_t);
void hib_free(struct hiballoc_arena*, void*);
int hiballoc_init(struct hiballoc_arena*, void*, size_t len);
void uvm_pmr_zero_everything(void);
+void uvm_pmr_dirty_everything(void);
int uvm_pmr_alloc_pig(paddr_t*, psize_t);
int uvm_pmr_alloc_piglet(paddr_t*, psize_t, paddr_t);
psize_t uvm_page_rle(paddr_t);