From f54234d1427189ccb317ea0bb77b286990f110c1 Mon Sep 17 00:00:00 2001 From: rmind Date: Mon, 23 Feb 2009 20:28:58 +0000 Subject: [PATCH] Switch Linux futex emulation to native ucas_int(), remove unecessary futex-specific assembler routines. Fixes PR/40490. Reviewed by . --- sys/compat/linux/arch/amd64/files.linux_amd64 | 3 +- sys/compat/linux/arch/amd64/linux_support.S | 125 ----------------- sys/compat/linux/arch/i386/files.linux_i386 | 3 +- sys/compat/linux/arch/i386/linux_support.S | 126 ------------------ sys/compat/linux/common/linux_futex.c | 73 +++++----- 5 files changed, 41 insertions(+), 289 deletions(-) delete mode 100644 sys/compat/linux/arch/amd64/linux_support.S delete mode 100644 sys/compat/linux/arch/i386/linux_support.S diff --git a/sys/compat/linux/arch/amd64/files.linux_amd64 b/sys/compat/linux/arch/amd64/files.linux_amd64 index 875cb0e57a47..67be34ecb415 100644 --- a/sys/compat/linux/arch/amd64/files.linux_amd64 +++ b/sys/compat/linux/arch/amd64/files.linux_amd64 @@ -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. @@ -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_syscalls.c compat_linux file compat/linux/arch/amd64/linux_sysent.c compat_linux -file compat/linux/arch/amd64/linux_support.S compat_linux diff --git a/sys/compat/linux/arch/amd64/linux_support.S b/sys/compat/linux/arch/amd64/linux_support.S deleted file mode 100644 index 596031b74b50..000000000000 --- a/sys/compat/linux/arch/amd64/linux_support.S +++ /dev/null @@ -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 - -#include "assym.h" - -#include -#include - -#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 diff --git a/sys/compat/linux/arch/i386/files.linux_i386 b/sys/compat/linux/arch/i386/files.linux_i386 index 8cc2527d8ccf..bbd606ef3d3e 100644 --- a/sys/compat/linux/arch/i386/files.linux_i386 +++ b/sys/compat/linux/arch/i386/files.linux_i386 @@ -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. @@ -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_ptrace.c compat_linux & ptrace file compat/linux/arch/i386/linux_exec_machdep.c compat_linux -file compat/linux/arch/i386/linux_support.S compat_linux diff --git a/sys/compat/linux/arch/i386/linux_support.S b/sys/compat/linux/arch/i386/linux_support.S deleted file mode 100644 index 954ec6a5783f..000000000000 --- a/sys/compat/linux/arch/i386/linux_support.S +++ /dev/null @@ -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 - -#include "assym.h" - -#include -#include - -#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 diff --git a/sys/compat/linux/common/linux_futex.c b/sys/compat/linux/common/linux_futex.c index 6c0b7d97897e..2387649517bb 100644 --- a/sys/compat/linux/common/linux_futex.c +++ b/sys/compat/linux/common/linux_futex.c @@ -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. @@ -32,7 +32,7 @@ */ #include -__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 #include @@ -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_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 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 futex_atomic_op(lwp_t *l, int encoded_op, void *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; + const int op = (encoded_op >> 28) & 7; + const int cmp = (encoded_op >> 24) & 15; + const int cmparg = (encoded_op << 20) >> 20; int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; - int oldval = 0, ret; + int error, oldval, cval; if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; /* XXX: linux verifies access here and returns EFAULT */ - switch (op) { - case FUTEX_OP_SET: - ret = futex_xchgl(oparg, uaddr, &oldval); - break; - case FUTEX_OP_ADD: - ret = futex_addl(oparg, uaddr, &oldval); - break; - case FUTEX_OP_OR: - ret = futex_orl(oparg, uaddr, &oldval); - break; - case FUTEX_OP_ANDN: - ret = futex_andl(~oparg, uaddr, &oldval); - break; - case FUTEX_OP_XOR: - ret = futex_xorl(oparg, uaddr, &oldval); - break; - default: - ret = -ENOSYS; - break; + if (copyin(uaddr, &cval, sizeof(int)) != 0) + return -EFAULT; + + for (;;) { + int nval; + + switch (op) { + case FUTEX_OP_SET: + nval = oparg; + break; + case FUTEX_OP_ADD: + nval = cval + oparg; + break; + case FUTEX_OP_OR: + nval = cval | oparg; + break; + case FUTEX_OP_ANDN: + nval = cval & ~oparg; + 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) - return ret; + if (error) + return -EFAULT; switch (cmp) { case FUTEX_OP_CMP_EQ: