diff options
author | davidxu <davidxu@FreeBSD.org> | 2006-08-28 02:28:15 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2006-08-28 02:28:15 +0000 |
commit | 87b5aa08ee93b317c4d88805ce8e361853411027 (patch) | |
tree | 7be2d51c02f47e64ee8dc4e4ec29bd1716dd3c70 /sys/amd64 | |
parent | f2ccfe95252579f4a77ff68a316f2f07850f0277 (diff) | |
download | FreeBSD-src-87b5aa08ee93b317c4d88805ce8e361853411027.zip FreeBSD-src-87b5aa08ee93b317c4d88805ce8e361853411027.tar.gz |
Implement casuword32, compare and set user integer, thank Marcel Moolenarr
who wrote the IA64 version of casuword32.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/support.S | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index ea547f9..4e8efdf 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -314,6 +314,34 @@ copyin_fault: ret /* + * casuword32. Compare and set user integer. Returns -1 or the current value. + * dst = %rdi, old = %rsi, new = %rdx + */ +ENTRY(casuword32) + movq PCPU(CURPCB),%rcx + movq $fusufault,PCB_ONFAULT(%rcx) + + movq $VM_MAXUSER_ADDRESS-4,%rax + cmpq %rax,%rdi /* verify address is valid */ + ja fusufault + + movl %esi,%eax /* old */ +#ifdef SMP + lock +#endif + cmpxchgl %edx,(%rdi) /* new = %edx */ + + /* + * 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. + */ + + movq PCPU(CURPCB),%rcx + movq $0,PCB_ONFAULT(%rcx) + ret + +/* * casuptr. Compare and set user pointer. Returns -1 or the current value. * dst = %rdi, old = %rsi, new = %rdx */ |