From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CAAC914A81 for ; Thu, 24 Aug 2023 17:20:29 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4E5B3C433C7; Thu, 24 Aug 2023 17:20:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1692897629; bh=Lhux/+oxpqTY9nto6lQLRim13hsKcUXcDSrTK+p/mk8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OqY/XW03QnczHH55aQOlbQ5DLxoGTlHOgzBQJLpE0BhvuyuVu0qTPsihfBL11aPDF RNyJhg3Am6bGS2qAAyZT/M+qMm0lWnhgp+U3zRWJbZmGysHedx/Un8yD0zV5Mey6SM kBBmhUe6tk1TH4hRivuZ/Y336etkvlxXmJyAF/WY= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Bo YU , Aurelien Jarno , Alexandre Ghiti , =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Palmer Dabbelt , Sasha Levin Subject: [PATCH 5.10 108/135] riscv: uaccess: Return the number of bytes effectively not copied Date: Thu, 24 Aug 2023 19:09:40 +0200 Message-ID: <20230824170621.949237240@linuxfoundation.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230824170617.074557800@linuxfoundation.org> References: <20230824170617.074557800@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Alexandre Ghiti [ Upstream commit 4b05b993900dd3eba0fc83ef5c5ddc7d65d786c6 ] It was reported that the riscv kernel hangs while executing the test in [1]. Indeed, the test hangs when trying to write a buffer to a file. The problem is that the riscv implementation of raw_copy_from_user() does not return the correct number of bytes not written when an exception happens and is fixed up, instead it always returns the initial size to copy, even if some bytes were actually copied. generic_perform_write() pre-faults the user pages and bails out if nothing can be written, otherwise it will access the userspace buffer: here the riscv implementation keeps returning it was not able to copy any byte though the pre-faulting indicates otherwise. So generic_perform_write() keeps retrying to access the user memory and ends up in an infinite loop. Note that before the commit mentioned in [1] that introduced this regression, it worked because generic_perform_write() would bail out if only one byte could not be written. So fix this by returning the number of bytes effectively not written in __asm_copy_[to|from]_user() and __clear_user(), as it is expected. Link: https://lore.kernel.org/linux-riscv/20230309151841.bomov6hq3ybyp42a@debian/ [1] Fixes: ebcbd75e3962 ("riscv: Fix the bug in memory access fixup code") Reported-by: Bo YU Closes: https://lore.kernel.org/linux-riscv/20230309151841.bomov6hq3ybyp42a@debian/#t Reported-by: Aurelien Jarno Closes: https://lore.kernel.org/linux-riscv/ZNOnCakhwIeue3yr@aurel32.net/ Signed-off-by: Alexandre Ghiti Reviewed-by: Björn Töpel Tested-by: Aurelien Jarno Reviewed-by: Aurelien Jarno Link: https://lore.kernel.org/r/20230811150604.1621784-1-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- arch/riscv/lib/uaccess.S | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S index 039050172d083..80866dea07418 100644 --- a/arch/riscv/lib/uaccess.S +++ b/arch/riscv/lib/uaccess.S @@ -19,8 +19,11 @@ ENTRY(__asm_copy_from_user) li t6, SR_SUM csrs CSR_STATUS, t6 - /* Save for return value */ - mv t5, a2 + /* + * Save the terminal address which will be used to compute the number + * of bytes copied in case of a fixup exception. + */ + add t5, a0, a2 /* * Register allocation for code below: @@ -179,7 +182,7 @@ ENTRY(__asm_copy_from_user) 10: /* Disable access to user memory */ csrc CSR_STATUS, t6 - mv a0, t5 + sub a0, t5, a0 ret ENDPROC(__asm_copy_to_user) ENDPROC(__asm_copy_from_user) @@ -231,7 +234,7 @@ ENTRY(__clear_user) 11: /* Disable access to user memory */ csrc CSR_STATUS, t6 - mv a0, a1 + sub a0, a3, a0 ret ENDPROC(__clear_user) EXPORT_SYMBOL(__clear_user) -- 2.40.1