diff options
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r-- | sys/kern/kern_sysctl.c | 13 |
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; |