Add ucas (CAS for user-space address) support for i386 and amd64.
API provides ucas_int() and ucas_ptr() for now. Reviewed by <ad>.
This commit is contained in:
parent
3f2d5fc9ad
commit
f7d3fa20ef
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: copy.S,v 1.12 2008/09/18 21:35:17 dsl Exp $ */
|
||||
/* $NetBSD: copy.S,v 1.13 2009/02/23 20:27:59 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wasabi Systems, Inc.
|
||||
|
@ -515,4 +515,81 @@ ENTRY(fusuaddrfault)
|
|||
movl $-1,%eax
|
||||
ret
|
||||
|
||||
/*
|
||||
* Compare-and-swap the 64-bit integer in the user-space.
|
||||
*
|
||||
* int ucas_64(volatile int64_t *uptr, int64_t old, int64_t new, int64_t *ret);
|
||||
*/
|
||||
ENTRY(ucas_64)
|
||||
DEFERRED_SWITCH_CHECK
|
||||
/* Fail if kernel-space */
|
||||
movq $VM_MAXUSER_ADDRESS-8, %r8
|
||||
cmpq %r8, %rdi
|
||||
ja 1f
|
||||
/* Set the fault handler */
|
||||
GET_CURPCB(%r8)
|
||||
leaq _C_LABEL(ucas_fault)(%rip), %r9
|
||||
movq %r9, PCB_ONFAULT(%r8)
|
||||
/* Perform the CAS */
|
||||
lock
|
||||
cmpxchgq %rdx, (%rdi)
|
||||
/* Clear the fault handler */
|
||||
movq %rax, PCB_ONFAULT(%r8)
|
||||
/*
|
||||
* Note: %rax is "old" value.
|
||||
* Set the return values.
|
||||
*/
|
||||
movq %rax, (%rcx)
|
||||
xorq %rax, %rax
|
||||
/* Clear the fault handler */
|
||||
movq %rax, PCB_ONFAULT(%r8)
|
||||
1:
|
||||
/* Failure case */
|
||||
movq $EFAULT, %rax
|
||||
ret
|
||||
DEFERRED_SWITCH_CALL
|
||||
|
||||
/*
|
||||
* int ucas_32(volatile int32_t *uptr, int32_t old, int32_t new, int32_t *ret);
|
||||
*/
|
||||
ENTRY(ucas_32)
|
||||
DEFERRED_SWITCH_CHECK
|
||||
/* Fail if kernel-space */
|
||||
movq $VM_MAXUSER_ADDRESS-4, %r8
|
||||
cmpq %r8, %rdi
|
||||
ja 1f
|
||||
/* Set the fault handler */
|
||||
GET_CURPCB(%r8)
|
||||
leaq _C_LABEL(ucas_fault)(%rip), %r9
|
||||
movq %r9, PCB_ONFAULT(%r8)
|
||||
/* Perform the CAS */
|
||||
lock
|
||||
cmpxchgl %edx, (%rdi)
|
||||
/*
|
||||
* Note: %eax is "old" value.
|
||||
* Set the return values.
|
||||
*/
|
||||
movl %eax, (%rcx)
|
||||
xorq %rax, %rax
|
||||
1:
|
||||
/* Failure case */
|
||||
movq $EFAULT, %rax
|
||||
ret
|
||||
DEFERRED_SWITCH_CALL
|
||||
|
||||
/*
|
||||
* Fault handler for ucas_32() and ucas_64().
|
||||
* Unset the handler and return the failure.
|
||||
*/
|
||||
NENTRY(ucas_fault)
|
||||
movq $0, PCB_ONFAULT(%r8)
|
||||
movq $EFAULT, %rax
|
||||
ret
|
||||
|
||||
/*
|
||||
* int ucas_ptr(volatile void *uptr, void *old, void *new, void *ret);
|
||||
*/
|
||||
STRONG_ALIAS(ucas_ptr, ucas_64)
|
||||
STRONG_ALIAS(ucas_int, ucas_32)
|
||||
|
||||
x86_copyfunc_end: .globl x86_copyfunc_end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: copy.S,v 1.16 2008/04/28 20:23:24 martin Exp $ */
|
||||
/* $NetBSD: copy.S,v 1.17 2009/02/23 20:27:59 rmind Exp $ */
|
||||
/* NetBSD: locore.S,v 1.34 2005/04/01 11:59:31 yamt Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -65,7 +65,7 @@
|
|||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: copy.S,v 1.16 2008/04/28 20:23:24 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: copy.S,v 1.17 2009/02/23 20:27:59 rmind Exp $");
|
||||
|
||||
#include "assym.h"
|
||||
|
||||
|
@ -644,6 +644,49 @@ ENTRY(subyte)
|
|||
ret
|
||||
DEFERRED_SWITCH_CALL
|
||||
|
||||
/*
|
||||
* Compare-and-swap the 32-bit integer in the user-space.
|
||||
*
|
||||
* int ucas_32(volatile int32_t *uptr, int32_t old, int32_t new, int32_t *ret);
|
||||
*/
|
||||
ENTRY(ucas_32)
|
||||
DEFERRED_SWITCH_CHECK
|
||||
movl 4(%esp), %edx
|
||||
movl 8(%esp), %eax
|
||||
movl 12(%esp), %ecx
|
||||
/* Fail if kernel-space */
|
||||
cmpl $VM_MAXUSER_ADDRESS-4, %edx
|
||||
ja _C_LABEL(ucas_fault)
|
||||
/* Label for fault handler */
|
||||
.Lucas32_start:
|
||||
/* Perform the CAS */
|
||||
lock
|
||||
cmpxchgl %ecx, (%edx)
|
||||
.Lucas32_end:
|
||||
/*
|
||||
* Note: %eax is "old" value.
|
||||
* Set the return values.
|
||||
*/
|
||||
movl 16(%esp), %edx
|
||||
movl %eax, (%edx)
|
||||
xorl %eax, %eax
|
||||
ret
|
||||
DEFERRED_SWITCH_CALL
|
||||
|
||||
/*
|
||||
* Fault handler for ucas_32().
|
||||
* Unset the handler and return the failure.
|
||||
*/
|
||||
NENTRY(ucas_fault)
|
||||
movl $EFAULT, %eax
|
||||
ret
|
||||
|
||||
/*
|
||||
* int ucas_int(volatile int *uptr, int old, int new, int *ret);
|
||||
*/
|
||||
STRONG_ALIAS(ucas_ptr, ucas_32)
|
||||
STRONG_ALIAS(ucas_int, ucas_32)
|
||||
|
||||
/*
|
||||
* copyin() optimised for bringing in syscall arguments.
|
||||
*/
|
||||
|
@ -731,6 +774,10 @@ _C_LABEL(onfault_table):
|
|||
.long .Lcopyinstr_end
|
||||
.long _C_LABEL(copystr_fault)
|
||||
|
||||
.long .Lucas32_start
|
||||
.long .Lucas32_end
|
||||
.long _C_LABEL(ucas_fault)
|
||||
|
||||
.long .Lx86_copyargs_start
|
||||
.long .Lx86_copyargs_end
|
||||
.long _C_LABEL(x86_copyargs_fault)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: systm.h,v 1.233 2009/02/12 18:24:18 christos Exp $ */
|
||||
/* $NetBSD: systm.h,v 1.234 2009/02/23 20:27:59 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1988, 1991, 1993
|
||||
|
@ -258,6 +258,9 @@ int copyout_vmspace(struct vmspace *, const void *, void *, size_t);
|
|||
int ioctl_copyin(int ioctlflags, const void *src, void *dst, size_t len);
|
||||
int ioctl_copyout(int ioctlflags, const void *src, void *dst, size_t len);
|
||||
|
||||
int ucas_ptr(volatile void *, void *, void *, void *);
|
||||
int ucas_int(volatile int *, int, int, int *);
|
||||
|
||||
int subyte(void *, int);
|
||||
int suibyte(void *, int);
|
||||
int susword(void *, short);
|
||||
|
|
Loading…
Reference in New Issue