aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2018-03-24 13:51:27 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2018-03-24 13:51:27 +0000
commited9e8bc4681f06db333ea9d4a301de3e18f79ac1 (patch)
tree5395b7ee10496b75e070eea943a4c07d04a19942 /sys
parent63b5d112b6d1fe36adf2f1c12e98df2c35117086 (diff)
downloadsrc-ed9e8bc4681f06db333ea9d4a301de3e18f79ac1.tar.gz
src-ed9e8bc4681f06db333ea9d4a301de3e18f79ac1.zip
Account the size of the vslock-ed memory by the thread.
Assert that all such memory is unwired on return to usermode. The count of the wired memory will be used to detect the copyout mode. Tested by: pho (as part of the larger patch) Sponsored by: The FreeBSD Foundation MFC after: 1 week
Notes
Notes: svn path=/head/; revision=331490
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_thread.c8
-rw-r--r--sys/kern/subr_trap.c2
-rw-r--r--sys/sys/proc.h1
-rw-r--r--sys/vm/vm_glue.c9
4 files changed, 15 insertions, 5 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index d992f2c242aa..4d2f020063e5 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -81,9 +81,9 @@ _Static_assert(offsetof(struct thread, td_flags) == 0xfc,
"struct thread KBI td_flags");
_Static_assert(offsetof(struct thread, td_pflags) == 0x104,
"struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x468,
+_Static_assert(offsetof(struct thread, td_frame) == 0x470,
"struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x510,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x518,
"struct thread KBI td_emuldata");
_Static_assert(offsetof(struct proc, p_flag) == 0xb0,
"struct proc KBI p_flag");
@@ -101,9 +101,9 @@ _Static_assert(offsetof(struct thread, td_flags) == 0x98,
"struct thread KBI td_flags");
_Static_assert(offsetof(struct thread, td_pflags) == 0xa0,
"struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x2e4,
+_Static_assert(offsetof(struct thread, td_frame) == 0x2e8,
"struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x330,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x334,
"struct thread KBI td_emuldata");
_Static_assert(offsetof(struct proc, p_flag) == 0x68,
"struct proc KBI p_flag");
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 6d36b2b92919..9a8b9828737f 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -178,6 +178,8 @@ userret(struct thread *td, struct trapframe *frame)
("userret: Returning with stop signals deferred"));
KASSERT(td->td_su == NULL,
("userret: Returning with SU cleanup request not handled"));
+ KASSERT(td->td_vslock_sz == 0,
+ ("userret: Returning with vslock-wired space"));
#ifdef VIMAGE
/* Unfortunately td_vnet_lpush needs VNET_DEBUG. */
VNET_ASSERT(curvnet == NULL,
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 9bc75db8591a..82b16059dc0d 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -297,6 +297,7 @@ struct thread {
void *td_su; /* (k) FFS SU private */
sbintime_t td_sleeptimo; /* (t) Sleep timeout. */
int td_rtcgen; /* (s) rtc_generation of abs. sleep */
+ size_t td_vslock_sz; /* (k) amount of vslock-ed space */
#define td_endzero td_sigmask
/* Copied during fork1() or create_thread(). */
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 5546822e3a58..25db4ad18a4b 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -196,11 +196,16 @@ vslock(void *addr, size_t len)
#endif
error = vm_map_wire(&curproc->p_vmspace->vm_map, start, end,
VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
+ if (error == KERN_SUCCESS) {
+ curthread->td_vslock_sz += len;
+ return (0);
+ }
+
/*
* Return EFAULT on error to match copy{in,out}() behaviour
* rather than returning ENOMEM like mlock() would.
*/
- return (error == KERN_SUCCESS ? 0 : EFAULT);
+ return (EFAULT);
}
void
@@ -208,6 +213,8 @@ vsunlock(void *addr, size_t len)
{
/* Rely on the parameter sanity checks performed by vslock(). */
+ MPASS(curthread->td_vslock_sz >= len);
+ curthread->td_vslock_sz -= len;
(void)vm_map_unwire(&curproc->p_vmspace->vm_map,
trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len),
VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);