diff options
-rw-r--r-- | sys/amd64/amd64/support.S | 9 | ||||
-rw-r--r-- | sys/amd64/amd64/support.s | 9 | ||||
-rw-r--r-- | sys/i386/i386/support.s | 9 | ||||
-rw-r--r-- | sys/kern/kern_umtx.c | 23 |
4 files changed, 25 insertions, 25 deletions
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index cc53683..cdf78bf 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -1192,12 +1192,11 @@ ENTRY(casuptr) #endif /* !SMP */ /* - * We store the current value regardless of the success of the - * cmpxchg. Calling code checks for new == return to determine - * success. + * The old value is in %eax. If the store succeeded it will be the + * value we expected (old) from before the store, otherwise it will + * be the current value. */ - movl (%edx), %eax - + movl PCPU(CURPCB),%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl $0,PCB_ONFAULT(%ecx) diff --git a/sys/amd64/amd64/support.s b/sys/amd64/amd64/support.s index cc53683..cdf78bf 100644 --- a/sys/amd64/amd64/support.s +++ b/sys/amd64/amd64/support.s @@ -1192,12 +1192,11 @@ ENTRY(casuptr) #endif /* !SMP */ /* - * We store the current value regardless of the success of the - * cmpxchg. Calling code checks for new == return to determine - * success. + * The old value is in %eax. If the store succeeded it will be the + * value we expected (old) from before the store, otherwise it will + * be the current value. */ - movl (%edx), %eax - + movl PCPU(CURPCB),%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl $0,PCB_ONFAULT(%ecx) diff --git a/sys/i386/i386/support.s b/sys/i386/i386/support.s index cc53683..cdf78bf 100644 --- a/sys/i386/i386/support.s +++ b/sys/i386/i386/support.s @@ -1192,12 +1192,11 @@ ENTRY(casuptr) #endif /* !SMP */ /* - * We store the current value regardless of the success of the - * cmpxchg. Calling code checks for new == return to determine - * success. + * The old value is in %eax. If the store succeeded it will be the + * value we expected (old) from before the store, otherwise it will + * be the current value. */ - movl (%edx), %eax - + movl PCPU(CURPCB),%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl $0,PCB_ONFAULT(%ecx) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index a8dfe76..8c01669 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -46,6 +46,7 @@ _umtx_lock(struct thread *td, struct _umtx_lock_args *uap) struct umtx *umtx; struct thread *blocked; intptr_t owner; + intptr_t old; int error; error = 0; @@ -66,7 +67,7 @@ _umtx_lock(struct thread *td, struct _umtx_lock_args *uap) UMTX_UNOWNED, (intptr_t)td); /* The acquire succeeded. */ - if (owner == (intptr_t)td) { + if (owner == UMTX_UNOWNED) { error = 0; goto out; } @@ -86,14 +87,15 @@ _umtx_lock(struct thread *td, struct _umtx_lock_args *uap) * either some one else has acquired the lock or it has been * released. */ - owner = casuptr((intptr_t *)&umtx->u_owner, owner, owner | UMTX_CONTESTED); + old = casuptr((intptr_t *)&umtx->u_owner, owner, + owner | UMTX_CONTESTED); - /* The contested bit was set. */ - if (owner & UMTX_CONTESTED) + /* We set the contested bit. */ + if (old == owner) break; /* The address was invalid. */ - if (owner == -1) { + if (old == -1) { error = EFAULT; goto out; } @@ -182,6 +184,7 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) struct umtx *umtx; intptr_t owner; intptr_t blocked; + intptr_t old; int error; error = 0; @@ -217,7 +220,7 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) * If this failed someone modified the memory without going * through this api. */ - else if (owner != UMTX_UNOWNED) + else if (owner != (intptr_t)td) error = EINVAL; else error = 0; @@ -231,7 +234,7 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) * CONTESTED bit was set. */ blocked = fuword(&umtx->u_blocked); - if (blocked == -1){ + if (blocked == -1) { error = EFAULT; goto out; } @@ -278,17 +281,17 @@ _umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) * Now directly assign this mutex to the first thread that was * blocked on it. */ - owner = casuptr((intptr_t *)&umtx->u_owner, owner, blocked); + old = casuptr((intptr_t *)&umtx->u_owner, owner, blocked); /* * This will only happen if someone modifies the lock without going * through this api. */ - if (owner != blocked) { + if (old != owner) { error = EINVAL; goto out; } - if (owner == -1) { + if (old == -1) { error = EFAULT; goto out; } |