Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] riscv: fix vmemmap and vmalloc offsets in /proc/kcore
@ 2026-02-05 20:31 Omar Sandoval
  2026-04-27 20:48 ` Omar Sandoval
  0 siblings, 1 reply; 2+ messages in thread
From: Omar Sandoval @ 2026-02-05 20:31 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	linux-riscv
  Cc: linux-debuggers, kernel-team

From: Omar Sandoval <osandov@fb.com>

kc_vaddr_to_offset() maps a kernel virtual address to its file offset in
/proc/kcore. The default definition is (address - PAGE_OFFSET). However, on
RISC-V, the vmemmap and vmalloc regions are below PAGE_OFFSET, so the computed
offsets for those regions are negative and wrap around to a large u64:

  # readelf -l /proc/kcore
  ...
  Program Headers:
    Type           Offset             VirtAddr           PhysAddr
                   FileSiz            MemSiz              Flags  Align
  ...
    LOAD           0xffc0000000002000 0xff20000000000000 0xffffffffffffffff
                   0x0040000000000000 0x0040000000000000  RWE    0x1000
  ...

When userspace applications like drgn attempt to read from that offset, it
overflows an loff_t and results in EINVAL.

Fix it by defining an alternate kc_vaddr_to_offset() that masks off the
high bits, which is what x86-64 does, too.

Fixes: 07037db5d479 ("RISC-V: Paging and MMU")
Cc: stable@vger.kernel.org
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
Based on Linus' tree as of 8fdb05de0e2db89d8f56144c60ab784812e8c3b7.

This method doesn't work for riscv32 since VA_BITS == BITS_PER_LONG
there. But, I think riscv32 can get away with the wrapped 32-bit
integers as long as userspace is using _FILE_OFFSET_BITS=64. I don't
have a riscv32 userspace environment available to test it.

Thanks,
Omar

 arch/riscv/include/asm/pgtable-64.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 6e789fa58514..a52d60dd80fc 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -403,4 +403,7 @@ static inline pte_t pmd_pte(pmd_t pmd);
 static inline pte_t pud_pte(pud_t pud);
 #endif
 
+#define kc_vaddr_to_offset(v) ((v) & ((1UL << VA_BITS) - 1))
+#define kc_offset_to_vaddr(o) ((o) | ~((1UL << VA_BITS) - 1))
+
 #endif /* _ASM_RISCV_PGTABLE_64_H */
-- 
2.52.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] riscv: fix vmemmap and vmalloc offsets in /proc/kcore
  2026-02-05 20:31 [PATCH] riscv: fix vmemmap and vmalloc offsets in /proc/kcore Omar Sandoval
@ 2026-04-27 20:48 ` Omar Sandoval
  0 siblings, 0 replies; 2+ messages in thread
From: Omar Sandoval @ 2026-04-27 20:48 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	linux-riscv
  Cc: linux-debuggers, kernel-team

On Thu, Feb 05, 2026 at 12:31:20PM -0800, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
> 
> kc_vaddr_to_offset() maps a kernel virtual address to its file offset in
> /proc/kcore. The default definition is (address - PAGE_OFFSET). However, on
> RISC-V, the vmemmap and vmalloc regions are below PAGE_OFFSET, so the computed
> offsets for those regions are negative and wrap around to a large u64:
> 
>   # readelf -l /proc/kcore
>   ...
>   Program Headers:
>     Type           Offset             VirtAddr           PhysAddr
>                    FileSiz            MemSiz              Flags  Align
>   ...
>     LOAD           0xffc0000000002000 0xff20000000000000 0xffffffffffffffff
>                    0x0040000000000000 0x0040000000000000  RWE    0x1000
>   ...
> 
> When userspace applications like drgn attempt to read from that offset, it
> overflows an loff_t and results in EINVAL.
> 
> Fix it by defining an alternate kc_vaddr_to_offset() that masks off the
> high bits, which is what x86-64 does, too.
> 
> Fixes: 07037db5d479 ("RISC-V: Paging and MMU")
> Cc: stable@vger.kernel.org
> Signed-off-by: Omar Sandoval <osandov@fb.com>
> ---
> Based on Linus' tree as of 8fdb05de0e2db89d8f56144c60ab784812e8c3b7.
> 
> This method doesn't work for riscv32 since VA_BITS == BITS_PER_LONG
> there. But, I think riscv32 can get away with the wrapped 32-bit
> integers as long as userspace is using _FILE_OFFSET_BITS=64. I don't
> have a riscv32 userspace environment available to test it.

Ping. I've been carrying this patch for my test builds for a few
releases with no problems. It'd be great to get it resolved.

Thanks,
Omar

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-04-27 20:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-05 20:31 [PATCH] riscv: fix vmemmap and vmalloc offsets in /proc/kcore Omar Sandoval
2026-04-27 20:48 ` Omar Sandoval

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox