Switch Linux futex emulation to native ucas_int(), remove unecessary

futex-specific assembler routines.

Fixes PR/40490.  Reviewed by <ad>.
This commit is contained in:
rmind 2009-02-23 20:28:58 +00:00
parent f7d3fa20ef
commit f54234d142
5 changed files with 41 additions and 289 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files.linux_amd64,v 1.3 2008/10/26 20:25:49 christos Exp $ # $NetBSD: files.linux_amd64,v 1.4 2009/02/23 20:28:58 rmind Exp $
# #
# Config file description for amd64-dependent Linux compat code. # Config file description for amd64-dependent Linux compat code.
@ -7,4 +7,3 @@ file compat/linux/arch/amd64/linux_exec_machdep.c compat_linux
file compat/linux/arch/amd64/linux_machdep.c compat_linux file compat/linux/arch/amd64/linux_machdep.c compat_linux
file compat/linux/arch/amd64/linux_syscalls.c compat_linux file compat/linux/arch/amd64/linux_syscalls.c compat_linux
file compat/linux/arch/amd64/linux_sysent.c compat_linux file compat/linux/arch/amd64/linux_sysent.c compat_linux
file compat/linux/arch/amd64/linux_support.S compat_linux

View File

@ -1,125 +0,0 @@
/* $NetBSD: linux_support.S,v 1.2 2008/11/20 09:26:06 ad Exp $ */
/*-
* Copyright (c) 2007 Konstantin Belousov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/amd64/linux32/linux32_support.s,v 1.1 2007/05/23 08:33:05 kib Exp $
*/
#include <machine/asm.h>
#include "assym.h"
#include <sys/errno.h>
#include <machine/frameasm.h>
#define GET_CURPCB(reg) \
movq CPUVAR(CURLWP), reg; \
movq L_ADDR(reg), reg
futex_fault_decx:
GET_CURPCB(%r8)
futex_fault:
movq $0,PCB_ONFAULT(%r8)
movl $-EFAULT,%eax
ret
ENTRY(futex_xchgl)
GET_CURPCB(%r8)
movq $futex_fault,PCB_ONFAULT(%r8)
movq $VM_MAXUSER_ADDRESS-4,%rax
cmpq %rax,%rsi
ja futex_fault
xchgl %edi,(%rsi)
movl %edi,(%rdx)
xorl %eax,%eax
movq %rax,PCB_ONFAULT(%r8)
ret
ENTRY(futex_addl)
GET_CURPCB(%r8)
movq $futex_fault,PCB_ONFAULT(%r8)
movq $VM_MAXUSER_ADDRESS-4,%rax
cmpq %rax,%rsi
ja futex_fault
lock
xaddl %edi,(%rsi)
movl %edi,(%rdx)
xorl %eax,%eax
movq %rax,PCB_ONFAULT(%r8)
ret
ENTRY(futex_orl)
GET_CURPCB(%r8)
movq $futex_fault,PCB_ONFAULT(%r8)
movq $VM_MAXUSER_ADDRESS-4,%rax
cmpq %rax,%rsi
ja futex_fault
movl (%rsi),%eax
1: movl %eax,%ecx
orl %edi,%ecx
lock
cmpxchgl %ecx,(%rsi)
jnz 1b
movl %eax,(%rdx)
xorl %eax,%eax
movq %rax,PCB_ONFAULT(%r8)
ret
ENTRY(futex_andl)
GET_CURPCB(%r8)
movq $futex_fault,PCB_ONFAULT(%r8)
movq $VM_MAXUSER_ADDRESS-4,%rax
cmpq %rax,%rsi
ja futex_fault
movl (%rsi),%eax
1: movl %eax,%ecx
andl %edi,%ecx
lock
cmpxchgl %ecx,(%rsi)
jnz 1b
movl %eax,(%rdx)
xorl %eax,%eax
movq %rax,PCB_ONFAULT(%r8)
ret
ENTRY(futex_xorl)
GET_CURPCB(%r8)
movq $futex_fault,PCB_ONFAULT(%r8)
movq $VM_MAXUSER_ADDRESS-4,%rax
cmpq %rax,%rsi
ja futex_fault
movl (%rsi),%eax
1: movl %eax,%ecx
xorl %edi,%ecx
lock
cmpxchgl %ecx,(%rsi)
jnz 1b
movl %eax,(%rdx)
xorl %eax,%eax
movq %rax,PCB_ONFAULT(%r8)
ret

View File

@ -1,4 +1,4 @@
# $NetBSD: files.linux_i386,v 1.9 2008/10/26 16:38:22 christos Exp $ # $NetBSD: files.linux_i386,v 1.10 2009/02/23 20:28:58 rmind Exp $
# #
# Config file description for i386-dependent Linux compat code. # Config file description for i386-dependent Linux compat code.
@ -8,4 +8,3 @@ file compat/linux/arch/i386/linux_sysent.c compat_linux
file compat/linux/arch/i386/linux_commons.c compat_linux file compat/linux/arch/i386/linux_commons.c compat_linux
file compat/linux/arch/i386/linux_ptrace.c compat_linux & ptrace file compat/linux/arch/i386/linux_ptrace.c compat_linux & ptrace
file compat/linux/arch/i386/linux_exec_machdep.c compat_linux file compat/linux/arch/i386/linux_exec_machdep.c compat_linux
file compat/linux/arch/i386/linux_support.S compat_linux

View File

@ -1,126 +0,0 @@
/* $NetBSD: linux_support.S,v 1.4 2008/11/14 15:56:17 ad Exp $ */
/*-
* Copyright (c) 2006,2007 Konstantin Belousov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/linux/linux_support.s,v 1.1 2007/05/23 08:33:06 kib Exp $
*/
#include <machine/asm.h>
#include "assym.h"
#include <sys/errno.h>
#include <machine/frameasm.h>
#define GET_CURPCB(reg) \
movl CPUVAR(CURLWP), reg; \
movl L_ADDR(reg), reg
futex_fault_decx:
GET_CURPCB(%ecx)
futex_fault:
movl $0,PCB_ONFAULT(%ecx)
movl $-EFAULT,%eax
ret
ENTRY(futex_xchgl)
GET_CURPCB(%ecx)
movl $futex_fault,PCB_ONFAULT(%ecx)
movl 4(%esp),%eax
movl 8(%esp),%edx
cmpl $VM_MAXUSER_ADDRESS-4,%edx
ja futex_fault
xchgl %eax,(%edx)
movl 12(%esp),%edx
movl %eax,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx)
ret
ENTRY(futex_addl)
GET_CURPCB(%ecx)
movl $futex_fault,PCB_ONFAULT(%ecx)
movl 4(%esp),%eax
movl 8(%esp),%edx
cmpl $VM_MAXUSER_ADDRESS-4,%edx
ja futex_fault
lock
xaddl %eax,(%edx)
movl 12(%esp),%edx
movl %eax,(%edx)
xorl %eax,%eax
movl %eax,PCB_ONFAULT(%ecx)
ret
ENTRY(futex_orl)
GET_CURPCB(%ecx)
movl $futex_fault_decx,PCB_ONFAULT(%ecx)
movl 8(%esp),%edx
cmpl $VM_MAXUSER_ADDRESS-4,%edx
ja futex_fault
movl (%edx),%eax
1: movl %eax,%ecx
orl 4(%esp),%ecx
lock
cmpxchgl %ecx,(%edx)
jnz 1b
futex_tail:
movl 12(%esp),%edx
movl %eax,(%edx)
xorl %eax,%eax
GET_CURPCB(%ecx)
movl %eax,PCB_ONFAULT(%ecx)
ret
ENTRY(futex_andl)
GET_CURPCB(%ecx)
movl $futex_fault_decx,PCB_ONFAULT(%ecx)
movl 8(%esp),%edx
cmpl $VM_MAXUSER_ADDRESS-4,%edx
ja futex_fault
movl (%edx),%eax
1: movl %eax,%ecx
andl 4(%esp),%ecx
lock
cmpxchgl %ecx,(%edx)
jnz 1b
jmp futex_tail
ENTRY(futex_xorl)
GET_CURPCB(%ecx)
movl $futex_fault_decx,PCB_ONFAULT(%ecx)
movl 8(%esp),%edx
cmpl $VM_MAXUSER_ADDRESS-4,%edx
ja futex_fault
movl (%edx),%eax
1: movl %eax,%ecx
xorl 4(%esp),%ecx
lock
cmpxchgl %ecx,(%edx)
jnz 1b
jmp futex_tail

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_futex.c,v 1.22 2009/01/08 12:46:23 njoly Exp $ */ /* $NetBSD: linux_futex.c,v 1.23 2009/02/23 20:28:58 rmind Exp $ */
/*- /*-
* Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved. * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved.
@ -32,7 +32,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.22 2009/01/08 12:46:23 njoly Exp $"); __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.23 2009/02/23 20:28:58 rmind Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
@ -108,13 +108,6 @@ static int futex_sleep(struct futex *, lwp_t *, unsigned long);
static int futex_wake(struct futex *, int, struct futex *, int); static int futex_wake(struct futex *, int, struct futex *, int);
static int futex_atomic_op(lwp_t *, int, void *); static int futex_atomic_op(lwp_t *, int, void *);
/* from linux_support.S */
int futex_xchgl(int, void *, int *);
int futex_addl(int, void *, int *);
int futex_orl(int, void *, int *);
int futex_andl(int, void *, int *);
int futex_xorl(int, void *, int *);
int int
linux_sys_futex(struct lwp *l, const struct linux_sys_futex_args *uap, register_t *retval) linux_sys_futex(struct lwp *l, const struct linux_sys_futex_args *uap, register_t *retval)
{ {
@ -436,40 +429,52 @@ futex_wake(struct futex *f, int n, struct futex *newf, int n2)
static int static int
futex_atomic_op(lwp_t *l, int encoded_op, void *uaddr) futex_atomic_op(lwp_t *l, int encoded_op, void *uaddr)
{ {
int op = (encoded_op >> 28) & 7; const int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15; const int cmp = (encoded_op >> 24) & 15;
const int cmparg = (encoded_op << 20) >> 20;
int oparg = (encoded_op << 8) >> 20; int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20; int error, oldval, cval;
int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg; oparg = 1 << oparg;
/* XXX: linux verifies access here and returns EFAULT */ /* XXX: linux verifies access here and returns EFAULT */
switch (op) { if (copyin(uaddr, &cval, sizeof(int)) != 0)
case FUTEX_OP_SET: return -EFAULT;
ret = futex_xchgl(oparg, uaddr, &oldval);
break; for (;;) {
case FUTEX_OP_ADD: int nval;
ret = futex_addl(oparg, uaddr, &oldval);
break; switch (op) {
case FUTEX_OP_OR: case FUTEX_OP_SET:
ret = futex_orl(oparg, uaddr, &oldval); nval = oparg;
break; break;
case FUTEX_OP_ANDN: case FUTEX_OP_ADD:
ret = futex_andl(~oparg, uaddr, &oldval); nval = cval + oparg;
break; break;
case FUTEX_OP_XOR: case FUTEX_OP_OR:
ret = futex_xorl(oparg, uaddr, &oldval); nval = cval | oparg;
break; break;
default: case FUTEX_OP_ANDN:
ret = -ENOSYS; nval = cval & ~oparg;
break; break;
case FUTEX_OP_XOR:
nval = cval ^ oparg;
break;
default:
return -ENOSYS;
}
error = ucas_int(uaddr, cval, nval, &oldval);
if (oldval == cval || error) {
break;
}
cval = oldval;
} }
if (ret) if (error)
return ret; return -EFAULT;
switch (cmp) { switch (cmp) {
case FUTEX_OP_CMP_EQ: case FUTEX_OP_CMP_EQ: