Am Mittwoch 06 Juli 2011, 00:17:03 schrieben Sie: > On Tue, Jul 5, 2011 at 1:51 PM, Rolf Eike Beer <eike@xxxxxxxxxx> wrote: > > Am Dienstag 05 Juli 2011, 19:28:35 schrieben Sie: > >> On Mon, Jul 4, 2011 at 2:59 PM, Carlos O'Donell > >> <carlos@xxxxxxxxxxxxxxxx> > > > > wrote: > >> > On Mon, Jul 4, 2011 at 2:50 PM, John David Anglin > >> > <dave.anglin@xxxxxxxx> > > > > wrote: > >> >> The Linux man page says the mprotect addr must be a valid pointer or > >> >> a multiple of PAGESIZE. > >> >> It's not clear what the mprotect call is trying to protect but it is > >> >> definitely not page aligned. > >> > > >> > It's trying to protect the new stack for the thread, which is > >> > obviously in the wrong spot. > >> > >> Good news. > >> > >> I have fixed tst-cputimer1. > > > > You also wrote "OK, fixed the kernel." So where an when will these fixes > > show up? > > Unfortunately I hosed my setup and I didn't have git installed to make > a proper diff so here's a diff versus a somewhat recent tree. > > WIP patch: http://www.parisc-linux.org/~carlos/futex.diff Half of your diff (e.g. the int->u32 conversion) is already in upstream. I've rediffed it against Linus tree and fixed some of the whitespace damage. Eike
From 26950303065f2d1d5e36bbb818d3ee8621a6fc2c Mon Sep 17 00:00:00 2001 From: Carlos O'Donell <carlos@xxxxxxxxxxxxxxxx> Date: Fri, 8 Jul 2011 09:42:31 +0200 Subject: [PATCH] fix futexes Signed-off-by: Carlos O'Donell <carlos@xxxxxxxxxxxxxxxx> Signed-off-by: Rolf Eike Beer <eike-kernel@xxxxxxxxx> --- arch/parisc/include/asm/futex.h | 65 ++++++++++++++++++++++++++++++++++++--- 1 files changed, 60 insertions(+), 5 deletions(-) diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 67a33cc..3008d06 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -5,11 +5,14 @@ #include <linux/futex.h> #include <linux/uaccess.h> +#include <asm/atomic.h> #include <asm/errno.h> static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) { + unsigned long int flags; + u32 val; int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; int oparg = (encoded_op << 8) >> 20; @@ -23,16 +26,53 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_disable(); + _atomic_spin_lock_irqsave(uaddr, flags); + switch (op) { case FUTEX_OP_SET: + /* *(int *)UADDR2 = OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) + ret = put_user(oparg, uaddr); + break; case FUTEX_OP_ADD: + /* *(int *)UADDR2 += OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval + oparg; + ret = put_user(val, uaddr); + } + break; case FUTEX_OP_OR: + /* *(int *)UADDR2 |= OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval | oparg; + ret = put_user(val, uaddr); + } + break; case FUTEX_OP_ANDN: + /* *(int *)UADDR2 &= ~OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval & ~oparg; + ret = put_user(val, uaddr); + } + break; case FUTEX_OP_XOR: + /* *(int *)UADDR2 ^= OPARG; */ + ret = get_user(oldval, uaddr); + if (!ret) { + val = oldval ^ oparg; + ret = put_user(val, uaddr); + } + break; default: ret = -ENOSYS; } + _atomic_spin_unlock_irqrestore(uaddr, flags); + pagefault_enable(); if (!ret) { @@ -54,7 +94,9 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { + int ret; u32 val; + unsigned long flags; /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is * our gateway page, and causes no end of trouble... @@ -65,12 +107,25 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; - if (get_user(val, uaddr)) - return -EFAULT; - if (val == oldval && put_user(newval, uaddr)) - return -EFAULT; + /* HPPA has no cmpxchg in hardware and therefore the + * best we can do here is use an array of locks. The + * lock selected is based on a hash of the userspace + * address. This should scale to a couple of CPUs. + */ + + _atomic_spin_lock_irqsave(uaddr, flags); + + ret = get_user(val, uaddr); + + if (!ret) + if (val == oldval) + ret = put_user(newval, uaddr); + *uval = val; - return 0; + + _atomic_spin_unlock_irqrestore(uaddr, flags); + + return ret; } #endif /*__KERNEL__*/ -- 1.7.6
Attachment:
signature.asc
Description: This is a digitally signed message part.