From patchwork Thu Aug 21 05:29:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: vkamensky X-Patchwork-Id: 35721 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f200.google.com (mail-qc0-f200.google.com [209.85.216.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id D05192055D for ; Thu, 21 Aug 2014 05:31:50 +0000 (UTC) Received: by mail-qc0-f200.google.com with SMTP id w7sf27398513qcr.7 for ; Wed, 20 Aug 2014 22:31:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id:cc :precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:mime-version:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list :content-type:content-transfer-encoding; bh=bFdOFKpKfvBMSCkPnJE95d1xxQeCnmOEIrKGahPkGAM=; b=FkyMwgd8SpOQF4KxwfJUFHMaYHN033Dy22I5uzYrpHhH6jccb2TCzIEJ7iuTM+I+C9 w+5tFJDiKCXuK0HV71r3Fk+2VjIqLuKG8ejt/Bp0BefzeGUwBR93EB8CZsauSzQeBSHh +qcH02bPkmVnr/Spy4nbiLyWEgm/axp7nzNTtAEHNRGa58ls2llgh9HuJaxG97rKE052 givbWfl4Xg1eRBOCb97YJZyB9s5oASiSWYUX8dw0XN56sOaoQ9sZBmJFg3RBkwseuT6I qHHw3+Y/bQj06gMMvFgd7N4XI70CHhkXj1/crGZ74mW2YhtXONhMuiQNDBIQ5ziqX+n9 Hl5Q== X-Gm-Message-State: ALoCoQnEtK2srrbQLdhWtN3Y1XQy7vZPJOm820xUeqjAGbvmFj5wGHlJjsNPHLXR7H75/HqVLAK0 X-Received: by 10.236.216.67 with SMTP id f63mr24591685yhp.10.1408599110714; Wed, 20 Aug 2014 22:31:50 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.92.228 with SMTP id b91ls537291qge.88.gmail; Wed, 20 Aug 2014 22:31:50 -0700 (PDT) X-Received: by 10.220.182.1 with SMTP id ca1mr40346444vcb.21.1408599110641; Wed, 20 Aug 2014 22:31:50 -0700 (PDT) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id jv1si11263325vdb.16.2014.08.20.22.31.50 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 20 Aug 2014 22:31:50 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) client-ip=209.85.220.181; Received: by mail-vc0-f181.google.com with SMTP id lf12so10334813vcb.12 for ; Wed, 20 Aug 2014 22:31:50 -0700 (PDT) X-Received: by 10.52.61.136 with SMTP id p8mr2166870vdr.15.1408599110527; Wed, 20 Aug 2014 22:31:50 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.45.67 with SMTP id uj3csp107446vcb; Wed, 20 Aug 2014 22:31:50 -0700 (PDT) X-Received: by 10.68.111.193 with SMTP id ik1mr58195323pbb.145.1408599109639; Wed, 20 Aug 2014 22:31:49 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id et4si16180300pbc.51.2014.08.20.22.31.49 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Aug 2014 22:31:49 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XKKwo-00048P-4v; Thu, 21 Aug 2014 05:30:06 +0000 Received: from mail-pd0-f177.google.com ([209.85.192.177]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XKKwk-00038w-TO for linux-arm-kernel@lists.infradead.org; Thu, 21 Aug 2014 05:30:03 +0000 Received: by mail-pd0-f177.google.com with SMTP id p10so12748948pdj.8 for ; Wed, 20 Aug 2014 22:29:40 -0700 (PDT) X-Received: by 10.68.186.33 with SMTP id fh1mr58371454pbc.105.1408598980547; Wed, 20 Aug 2014 22:29:40 -0700 (PDT) Received: from kamensky-w530.cisco.com (128-107-239-233.cisco.com. [128.107.239.233]) by mx.google.com with ESMTPSA id oz7sm36872569pdb.77.2014.08.20.22.29.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Aug 2014 22:29:39 -0700 (PDT) From: Victor Kamensky To: linux-arm-kernel@lists.infradead.org, daniel.thompson@linaro.org, rmk@arm.linux.org.uk Subject: [RFC PATCH] arm: fix get_user BE behavior for target variable with size of 8 bytes Date: Wed, 20 Aug 2014 22:29:09 -0700 Message-Id: <1408598949-23050-1-git-send-email-victor.kamensky@linaro.org> X-Mailer: git-send-email 1.8.1.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140820_223002_979412_5F26C1BC X-CRM114-Status: GOOD ( 14.72 ) X-Spam-Score: -1.4 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.192.177 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.192.177 listed in wl.mailspike.net] Cc: nicolas.pitre@linaro.org, Victor Kamensky , marc.zyngier@arm.com, will.deacon@arm.com, arnd.bergmann@linaro.org, christoffer.dall@linaro.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: victor.kamensky@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 e38361d 'ARM: 8091/2: add get_user() support for 8 byte types' commit broke V7 BE get_user call when target var size is 64 bit, but '*ptr' size is 32 bit or smaller. e38361d changed type of __r2 from 'register unsigned long' to 'register typeof(x) __r2 asm("r2")' i.e before the change even when target variable size was 64 bit, __r2 was still 32 bit. But after e38361d commit, for target var of 64 bit size, __r2 became 64 bit and now it should occupy 2 registers r2, and r3. The issue in BE case that r3 register is least significant word of __r2 and r2 register is most significant word of __r2. But __get_user_4 still copies result into r2 (most significant word of __r2). Subsequent code copies from __r2 into x, but for situation described it will pick up only garbage from r3 register. It was discovered during 3.17-rc1 V7 BE KVM testing. Simple test case below. Note it works in LE case because r2 in LE case is still least significant word. Proposed fix uninspiringly restores previous code but now in individual branches of switch statement for '*(__p)' byte sizes 1, 2, 4 and have newer code only for sizeof(*(__p)) == 8. Looking for may be better ideas how to fix the issue. Small test case C code char gut_lower_v64_p32 (int *ptr) { long long value = 0; get_user(value, ptr); return 0xff & value; } the following code in BE V7 image will be generated. Note uxtb access to r3 register, but __get_user_4 retrieves data into r2. (gdb) disassemble gut_lower_v64_p32 Dump of assembler code for function gut_lower_v64_p32: 0xc0022ec8 <+0>: push {lr} ; (str lr, [sp, #-4]!) 0xc0022ecc <+4>: mov r2, sp 0xc0022ed0 <+8>: bic r3, r2, #8128 ; 0x1fc0 0xc0022ed4 <+12>: bic r3, r3, #63 ; 0x3f 0xc0022ed8 <+16>: ldr r1, [r3, #8] 0xc0022edc <+20>: sub r1, r1, #1 0xc0022ee0 <+24>: bl 0xc03792ac <__get_user_4> 0xc0022ee4 <+28>: uxtb r0, r3 0xc0022ee8 <+32>: pop {pc} ; (ldr pc, [sp], #4) End of assembler dump. (gdb) disassemble __get_user_4 Dump of assembler code for function __get_user_4: 0xc03792ac <+0>: adds r2, r0, #3 0xc03792b0 <+4>: sbcscc r2, r2, r1 0xc03792b4 <+8>: bcs 0xc03792fc <__get_user_bad> 0xc03792b8 <+12>: ldr r2, [r0] 0xc03792bc <+16>: mov r0, #0 0xc03792c0 <+20>: bx lr End of assembler dump. Signed-off-by: Victor Kamensky --- arch/arm/include/asm/uaccess.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index a4cd7af..69b9292 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -141,28 +141,42 @@ extern int __get_user_8(void *); ({ \ unsigned long __limit = current_thread_info()->addr_limit - 1; \ register const typeof(*(p)) __user *__p asm("r0") = (p);\ - register typeof(x) __r2 asm("r2"); \ register unsigned long __l asm("r1") = __limit; \ register int __e asm("r0"); \ switch (sizeof(*(__p))) { \ case 1: \ + { \ + register unsigned long __r2 asm("r2"); \ __get_user_x(__r2, __p, __e, __l, 1); \ + x = (typeof(*(p))) __r2; \ break; \ + } \ case 2: \ + { \ + register unsigned long __r2 asm("r2"); \ __get_user_x(__r2, __p, __e, __l, 2); \ + x = (typeof(*(p))) __r2; \ break; \ + } \ case 4: \ + { \ + register unsigned long __r2 asm("r2"); \ __get_user_x(__r2, __p, __e, __l, 4); \ + x = (typeof(*(p))) __r2; \ break; \ + } \ case 8: \ + { \ + register typeof(x) __r2 asm("r2"); \ if (sizeof((x)) < 8) \ __get_user_xb(__r2, __p, __e, __l, 4); \ else \ __get_user_x(__r2, __p, __e, __l, 8); \ + x = (typeof(*(p))) __r2; \ break; \ + } \ default: __e = __get_user_bad(); break; \ } \ - x = (typeof(*(p))) __r2; \ __e; \ })