Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp857287imm; Wed, 23 May 2018 06:41:31 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpiWXSWO4XAoZEOGuoi2DEIYRhOw5VpUhQ8ycbZ0cJzKFjlEVlFiPZEELxyuP7y1o95WY48 X-Received: by 2002:a17:902:7283:: with SMTP id d3-v6mr3104154pll.192.1527082891532; Wed, 23 May 2018 06:41:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527082891; cv=none; d=google.com; s=arc-20160816; b=ApgBYpC8c5evfwgZPsQfcKtDv1D5LulS7QBe0tZ+RHKaEi/KqGdpMgiC3Vugvej5e9 m6k0I3pJNTZgQBK1+brJPevUnAPbQ/8MIsm3wYUbSZi7/6YZtSqOTd+4weyeuBGOE4wF XY1UCxO7JeX4SD5yfNCmA59BISpqK/ubAR+0umqenLErHGPE0QnjvtQMnT7jUTe7rG5U WpdcKfPe6rvG3ZUyxu85YRuuZPIYjekfEyTC8EGAizGVZ25I3zY1Tz717v/TCsikbcaj FbuYq1WZUoHz4MC1gY2W3QUzCpO2HuOUc+nBaXXsrbifbuX9yG1N/6vqiOmHkDloii+x 4XAg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from:arc-authentication-results; bh=Fi6n7W/BSLClVcB6eVefbnIOSv/NltInLPAybino8F4=; b=XO/ZQ9GZGjwWMIl9h0YTxJWKJ23aL4IbwlZqyUOLWqccoR/0f1lvRT7CebVufLU20a 0ayzonDmX2MwNDUQLkii2HzScBV0m7Cybzz9lZ53fK+toNBvNynf0I0qXS6yJu0QPoSF y2dLYiFhEftPmHoheIKq9GbGwoeBfBrhzD1jzcr2pm45koB/FQ2TVlmtcMbvIuO4pvKH FeNRd+5Hb1Z4fiikuA8Tz2vNWbPrCFA5JEV79BD8/UMLxEif1mV2TCf7BR1zIvgOXuUA VT2/6wMkeiV8agvQkayOU1efjafFW1I1KmB73jKa7nYl+ZvrHfJ6+V5aZkAF9Mg/JVAW B+Fw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f1-v6si19274824plf.453.2018.05.23.06.41.06; Wed, 23 May 2018 06:41:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933080AbeEWNkP (ORCPT + 99 others); Wed, 23 May 2018 09:40:15 -0400 Received: from 9pmail.ess.barracuda.com ([64.235.150.224]:33087 "EHLO 9pmail.ess.barracuda.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932942AbeEWNkN (ORCPT ); Wed, 23 May 2018 09:40:13 -0400 Received: from mipsdag02.mipstec.com (mail2.mips.com [12.201.5.32]) by mx26.ess.sfj.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=NO); Wed, 23 May 2018 13:40:07 +0000 Received: from mredfearn-linux.mipstec.com (192.168.155.41) by mipsdag02.mipstec.com (10.20.40.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1415.2; Wed, 23 May 2018 06:40:07 -0700 From: Matt Redfearn To: James Hogan , Ralf Baechle CC: , Matt Redfearn , , Subject: [PATCH v3 1/2] MIPS: memset.S: Fix byte_fixup for MIPSr6 Date: Wed, 23 May 2018 14:39:58 +0100 Message-ID: <1527082799-14704-1-git-send-email-matt.redfearn@mips.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [192.168.155.41] X-ClientProxiedBy: mipsdag03.mipstec.com (10.20.40.48) To mipsdag02.mipstec.com (10.20.40.47) X-BESS-ID: 1527082806-853316-30554-232848-1 X-BESS-VER: 2018.6-r1805181819 X-BESS-Apparent-Source-IP: 12.201.5.32 X-BESS-Outbound-Spam-Score: 0.00 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.193286 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------- 0.00 BSF_BESS_OUTBOUND META: BESS Outbound X-BESS-Outbound-Spam-Status: SCORE=0.00 using account:ESS59374 scores of KILL_LEVEL=7.0 tests=BSF_BESS_OUTBOUND X-BESS-BRTS-Status: 1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The __clear_user function is defined to return the number of bytes that could not be cleared. From the underlying memset / bzero implementation this means setting register a2 to that number on return. Currently if a page fault is triggered within the MIPSr6 version of setting of initial unaligned bytes, the value loaded into a2 on return is meaningless. During the MIPSr6 version of the initial unaligned bytes block, register a2 contains the number of bytes to be set beyond the initial unaligned bytes. The t0 register is initally set to the number of unaligned bytes - STORSIZE, effectively a negative version of the number of unaligned bytes. This is then incremented before each byte is saved. The label .Lbyte_fixup\@ is jumped to on page fault. Currently the value in a2 is incorrectly replaced by 0 - t0 + 1, effectively the number of unaligned bytes remaining. This leads to the failures being reported by the following test code: static int __init test_clear_user(void) { int j, k; pr_info("\n\n\nTesting clear_user\n"); for (j = 0; j < 512; j++) { if ((k = clear_user(NULL+3, j)) != j) { pr_err("clear_user (NULL %d) returned %d\n", j, k); } } return 0; } late_initcall(test_clear_user); Which reports: [ 3.965439] Testing clear_user [ 3.973169] clear_user (NULL 8) returned 6 [ 3.976782] clear_user (NULL 9) returned 6 [ 3.980390] clear_user (NULL 10) returned 6 [ 3.984052] clear_user (NULL 11) returned 6 [ 3.987524] clear_user (NULL 12) returned 6 Fix this by subtracting t0 from a2 (rather than $0), effectivey giving: unset_bytes = (#bytes - (#unaligned bytes)) - (-#unaligned bytes remaining + 1) + 1 a2 = a2 - t0 + 1 This fixes the value returned from __clear user when the number of bytes to set is > LONGSIZE and the address is invalid and unaligned. Unfortunately, this breaks the fixup handling for unaligned bytes after the final long, where register a2 still contains the number of bytes remaining to be set and the t0 register is to 0 - the number of unaligned bytes remaining. Because t0 is now is now subtracted from a2 rather than 0, the number of bytes unset is reported incorrectly: static int __init test_clear_user(void) { char *test; int j, k; pr_info("\n\n\nTesting clear_user\n"); test = vmalloc(PAGE_SIZE); for (j = 256; j < 512; j++) { if ((k = clear_user(test + PAGE_SIZE - 254, j)) != j - 254) { pr_err("clear_user (%px %d) returned %d\n", test + PAGE_SIZE - 254, j, k); } } return 0; } late_initcall(test_clear_user); [ 3.976775] clear_user (c00000000000df02 256) returned 4 [ 3.981957] clear_user (c00000000000df02 257) returned 6 [ 3.986425] clear_user (c00000000000df02 258) returned 8 [ 3.990850] clear_user (c00000000000df02 259) returned 10 [ 3.995332] clear_user (c00000000000df02 260) returned 12 [ 3.999815] clear_user (c00000000000df02 261) returned 14 Fix this by ensuring that a2 is set to 0 during the set of final unaligned bytes. Fixes: 8c56208aff77 ("MIPS: lib: memset: Add MIPS R6 support") Cc: stable@vger.kernel.org Signed-off-by: Matt Redfearn --- Changes in v3: New patch to fix fault handling during MIPSr6 version of setting unaligned bytes. Changes in v2: None arch/mips/lib/memset.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 1cc306520a5..fac26ce64b2 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S @@ -195,6 +195,7 @@ #endif #else PTR_SUBU t0, $0, a2 + move a2, zero /* No remaining longs */ PTR_ADDIU t0, 1 STORE_BYTE(0) STORE_BYTE(1) @@ -231,7 +232,7 @@ #ifdef CONFIG_CPU_MIPSR6 .Lbyte_fixup\@: - PTR_SUBU a2, $0, t0 + PTR_SUBU a2, t0 jr ra PTR_ADDIU a2, 1 #endif /* CONFIG_CPU_MIPSR6 */ -- 2.7.4