* [PATCH -fixes v2] riscv: uaccess: Return the number of bytes effectively not copied
@ 2023-08-11 15:06 Alexandre Ghiti
2023-08-17 15:20 ` patchwork-bot+linux-riscv
0 siblings, 1 reply; 2+ messages in thread
From: Alexandre Ghiti @ 2023-08-11 15:06 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alan Kao, linux-riscv,
linux-kernel
Cc: Alexandre Ghiti, Bo YU, Aurelien Jarno, Björn Töpel
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 <tsu.yubo@gmail.com>
Closes: https://lore.kernel.org/linux-riscv/20230309151841.bomov6hq3ybyp42a@debian/#t
Reported-by: Aurelien Jarno <aurelien@aurel32.net>
Closes: https://lore.kernel.org/linux-riscv/ZNOnCakhwIeue3yr@aurel32.net/
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
Tested-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Add RB/TB from Bjorn and Aurelien
- Fix commit changelog as it incorrectly stated the functions should
return the number of bytes copied, whereas it is actually the number
of bytes *not* written
- Improved changelog a bit in the 2nd paragraph
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 ec486e5369d9..09b47ebacf2e 100644
--- a/arch/riscv/lib/uaccess.S
+++ b/arch/riscv/lib/uaccess.S
@@ -17,8 +17,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:
@@ -176,7 +179,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)
@@ -228,7 +231,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.39.2
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH -fixes v2] riscv: uaccess: Return the number of bytes effectively not copied
2023-08-11 15:06 [PATCH -fixes v2] riscv: uaccess: Return the number of bytes effectively not copied Alexandre Ghiti
@ 2023-08-17 15:20 ` patchwork-bot+linux-riscv
0 siblings, 0 replies; 2+ messages in thread
From: patchwork-bot+linux-riscv @ 2023-08-17 15:20 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: linux-riscv, paul.walmsley, palmer, aou, alankao, linux-kernel,
tsu.yubo, aurelien, bjorn
Hello:
This patch was applied to riscv/linux.git (fixes)
by Palmer Dabbelt <palmer@rivosinc.com>:
On Fri, 11 Aug 2023 17:06:04 +0200 you wrote:
> 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.
>
> [...]
Here is the summary with links:
- [-fixes,v2] riscv: uaccess: Return the number of bytes effectively not copied
https://git.kernel.org/riscv/c/4b05b993900d
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-08-17 15:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-11 15:06 [PATCH -fixes v2] riscv: uaccess: Return the number of bytes effectively not copied Alexandre Ghiti
2023-08-17 15:20 ` patchwork-bot+linux-riscv
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox