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:
parent
f7d3fa20ef
commit
f54234d142
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue