summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r--sys/kern/kern_sysctl.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 6a64a1a..38fb5dc 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1118,7 +1118,8 @@ int
sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
{
int ret;
- size_t wiredlen;
+ size_t i, wiredlen;
+ char *cp, dummy;
wiredlen = (len > 0 && len < req->oldlen) ? len : req->oldlen;
ret = 0;
@@ -1131,6 +1132,16 @@ sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
return (ret);
wiredlen = 0;
}
+ /*
+ * Touch all the wired pages to avoid PTE modified
+ * bit emulation traps on Alpha while holding locks
+ * in the sysctl handler.
+ */
+ for (i = (wiredlen + PAGE_SIZE - 1) / PAGE_SIZE,
+ cp = req->oldptr; i > 0; i--, cp += PAGE_SIZE) {
+ copyin(cp, &dummy, 1);
+ copyout(&dummy, cp, 1);
+ }
}
req->lock = REQ_WIRED;
req->validlen = wiredlen;
OpenPOWER on IntegriCloud