Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp1835677imm; Mon, 3 Sep 2018 10:40:16 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbnYT8ZpRvRFjpu/V4BWW+FecxyLh3/WHvFJCu7+WXQf3rjhXzkEUqH7IIeSJoy+k1eik/b X-Received: by 2002:a62:23c2:: with SMTP id q63-v6mr30652820pfj.116.1535996416507; Mon, 03 Sep 2018 10:40:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535996416; cv=none; d=google.com; s=arc-20160816; b=gWLXcy7DGI9lnwXZc7KZauRqOLs8JEvHAZpH1AjKljfaxxa4mSDTUm+QigQuVjJGhh t2E4SsO7w2M5U7mVmfqW7ui48LeZzqNEl47H9P/EEe5xp8mDS19AOAiePbT906zYIPOe AmOKifp6rhnwnG4mw8cZEUX9NgOu5k7/jKVgGGAwmLaj7olgzstF8Zpgy7QOlFRDHyK0 o/y9p1441/ZtfDN9Fcg8dniyB1lYST8L2paXdk/xWHzuNm7dMXp7H0BmFloTBgHn0Jo0 1e6G38CHnM7Y5npFYRPL5FTn7bCh0T7jI2gnR2nqOu0t+PrWdv0gKnkZT5Lod4oriLBk RoaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=7rnoY4mgJotJzBz5ok/Qoc7uFVzLs8BjfmNZPBsHfIY=; b=h7Wqc0mODJwxgNUoLYO91mbq6j8Q33Z5SP2Fx9F6vamvlN+tW3yp3ep83wmGy+8KxE eXmGEVyXv0JD7xMtTSXfCDy5xQ5zASDHZPsPyxOkf4pKjlwyQsw4KCbDvdEIinOygoAQ /8hMQbwdGoDQ/KfP4SnWNbee/RTMlYCGhWqQFPLyysX1Qj9PLpj9gSUnyALCIZ7OI8VW U9S4/7nVRpBIL2c7G0yYN13D4ODxzfTynICgGF8sSslJBUyktfLlqBolLv5PchBv+lUI jdhUemE5v7g+6m6j/Adngn4W13PMsATcw9PhF/fFsqkXwM9VXIPygChNqsk3Tm5sHHti TN2w== 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 w26-v6si19239408pgk.372.2018.09.03.10.40.00; Mon, 03 Sep 2018 10:40:16 -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 S1731828AbeICV7m (ORCPT + 99 others); Mon, 3 Sep 2018 17:59:42 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:48954 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726384AbeICV7l (ORCPT ); Mon, 3 Sep 2018 17:59:41 -0400 Received: from localhost (ip-213-127-74-90.ip.prioritytelecom.net [213.127.74.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id CDA20BC4; Mon, 3 Sep 2018 17:38:29 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Matt Redfearn , Paul Burton , James Hogan , Ralf Baechle , linux-mips@linux-mips.org Subject: [PATCH 4.18 100/123] MIPS: memset.S: Fix byte_fixup for MIPSr6 Date: Mon, 3 Sep 2018 18:57:24 +0200 Message-Id: <20180903165723.741516165@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180903165719.499675257@linuxfoundation.org> References: <20180903165719.499675257@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Matt Redfearn commit b1c03f1ef48d36ff28afb06e8f0c1233ef072f1d upstream. 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. Signed-off-by: Matt Redfearn Signed-off-by: Paul Burton Fixes: 8c56208aff77 ("MIPS: lib: memset: Add MIPS R6 support") Patchwork: https://patchwork.linux-mips.org/patch/19338/ Cc: James Hogan Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # v4.0+ Signed-off-by: Greg Kroah-Hartman --- arch/mips/lib/memset.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- 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 */