From patchwork Fri Jul 8 21:27:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlos O'Donell X-Patchwork-Id: 957452 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p68LR5Uo024281 for ; Fri, 8 Jul 2011 21:27:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753939Ab1GHV1F (ORCPT ); Fri, 8 Jul 2011 17:27:05 -0400 Received: from mail-pv0-f174.google.com ([74.125.83.174]:44836 "EHLO mail-pv0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753763Ab1GHV1E (ORCPT ); Fri, 8 Jul 2011 17:27:04 -0400 Received: by pvg12 with SMTP id 12so1379784pvg.19 for ; Fri, 08 Jul 2011 14:27:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding; bh=LEuFRP5p2U69XtI6Dxy/Mr4JQzmCdWcM5FGrCMMgLO4=; b=lB/+OE4z8cSM/CKtxX83R2W4b2WhcevJ9vgR+Mb9UACxH/fOrE/oGmQqqT44w8vh8Z i5G6JhftV9S5G1gg+VY4+xmpp0WrnRfq95tvQdWxhPqcDU/n5Zv3Qc5jyeGxpyTGakIr OkP9c4ceTQhOgK5IjhMrE+dqo/1zAUzDiFmao= Received: by 10.68.49.226 with SMTP id x2mr3377779pbn.27.1310160424266; Fri, 08 Jul 2011 14:27:04 -0700 (PDT) Received: from [192.168.2.18] (bas3-ottawa23-1177760865.dsl.bell.ca [70.51.52.97]) by mx.google.com with ESMTPS id p7sm4686563pbn.49.2011.07.08.14.27.01 (version=SSLv3 cipher=OTHER); Fri, 08 Jul 2011 14:27:03 -0700 (PDT) Message-ID: <4E177624.1030500@systemhalted.org> Date: Fri, 08 Jul 2011 17:27:00 -0400 From: "Carlos O'Donell" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.18) Gecko/20110616 Lightning/1.0b2 Thunderbird/3.1.11 MIME-Version: 1.0 To: James Bottomley , linux-parisc Subject: [PATCH 2.6.39-rc3] parsic: Fix futex support Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 08 Jul 2011 21:27:06 +0000 (UTC) Implements futex op support and makes futex cmpxchg atomic. Tested on 64-bit SMP kernel running on 2 x PA8700s. Signed-off-by: Carlos O'Donell Tested-by: John David Anglin --- futex.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 5 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-parisc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 67a33cc..94f2f4d 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -5,11 +5,14 @@ #include #include +#include #include 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,24 @@ 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 && val == oldval) + ret = put_user (newval, uaddr); + *uval = val; - return 0; + + _atomic_spin_unlock_irqrestore (uaddr, flags); + + return ret; } #endif /*__KERNEL__*/