On Wed, 2024-01-24 at 14:10 -0800, Linus Torvalds wrote: > On Wed, 24 Jan 2024 at 13:54, Linus Torvalds > <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > > > > > > And I think the "fails with any integer in [1, 8)" is because the MIPS > > "copy_from_user()" code is likely doing something special for those > > small copies. > > .Lcopy_bytes_checklen\@: does COPY_BYTE(0) for the first access, which is > > #define COPY_BYTE(N) \ > LOADB(t0, N(src), .Ll_exc\@); \ > SUB len, len, 1; \ > beqz len, .Ldone\@; \ > STOREB(t0, N(dst), .Ls_exc_p1\@) > > so yeah, for 'copy_to_user()" (which is what that "read (fd, buf, 7)" > will do, we have that user space write ("STOREB()") in the branch > delay slot of the length test. > > So that matches. > > And it only fails when > > (a) you're unlucky, and that stack buffer > > char buf[16] = {}; > > happens to be just under the last page that has been accessed, so > you get a page fault > > (b) you hit a mmap_sem already being locked, presumably because > another thread is doing that fork(). So I added a stupid hack: diff --git a/mm/memory.c b/mm/memory.c index 7e1f4849463a..e663eb517bbf 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -92,6 +92,12 @@ #include "internal.h" #include "swap.h" +#ifdef __mips__ +#include "asm/branch.h" +#undef instruction_pointer +#define instruction_pointer(x) exception_epc(x) +#endif + #if defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS) && !defined(CONFIG_COMPILE_TEST) #warning Unfortunate NUMA and NUMA Balancing config, growing page-frame for last_cpupid. #endif and it indeed "solved" the problem. > Anyway, I'm pretty sure this is the bug, now some MIPS person just > needs to fix the MIPS version of "instruction_pointer()" to do what > "exception_epc()" already does. Agree. -- Xi Ruoyao <xry111@xxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University