Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'riscv-for-linus-6.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fixes from Palmer Dabbelt:

- A revert for the mmap() change that ties the allocation range to the
hint adress, as what we tried to do ended up regressing on other
userspace workloads.

- A fix to avoid a kernel memory leak when emulating misaligned
accesses from userspace.

- A Kconfig fix for toolchain vector detection, which now correctly
detects vector support on toolchains where the V extension depends on
the M extension.

- A fix to avoid failing the linear mapping bootmem bounds check on
NOMMU systems.

- A fix for early alternatives on relocatable kernels.

* tag 'riscv-for-linus-6.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
riscv: Fix RISCV_ALTERNATIVE_EARLY
riscv: Do not restrict memory size because of linear mapping on nommu
riscv: Fix toolchain vector detection
riscv: misaligned: Restrict user access to kernel memory
riscv: mm: Do not restrict mmap address based on hint
riscv: selftests: Remove mmap hint address checks
Revert "RISC-V: mm: Document mmap changes"

+79 -181
-16
Documentation/arch/riscv/vm-layout.rst
··· 134 134 ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | modules, BPF 135 135 ffffffff80000000 | -2 GB | ffffffffffffffff | 2 GB | kernel 136 136 __________________|____________|__________________|_________|____________________________________________________________ 137 - 138 - 139 - Userspace VAs 140 - -------------------- 141 - To maintain compatibility with software that relies on the VA space with a 142 - maximum of 48 bits the kernel will, by default, return virtual addresses to 143 - userspace from a 48-bit range (sv48). This default behavior is achieved by 144 - passing 0 into the hint address parameter of mmap. On CPUs with an address space 145 - smaller than sv48, the CPU maximum supported address space will be the default. 146 - 147 - Software can "opt-in" to receiving VAs from another VA space by providing 148 - a hint address to mmap. When a hint address is passed to mmap, the returned 149 - address will never use more bits than the hint address. For example, if a hint 150 - address of `1 << 40` is passed to mmap, a valid returned address will never use 151 - bits 41 through 63. If no mappable addresses are available in that range, mmap 152 - will return `MAP_FAILED`.
+2 -2
arch/riscv/Kconfig
··· 552 552 config TOOLCHAIN_HAS_V 553 553 bool 554 554 default y 555 - depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv) 556 - depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv) 555 + depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64imv) 556 + depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32imv) 557 557 depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800 558 558 depends on AS_HAS_OPTION_ARCH 559 559
+2 -24
arch/riscv/include/asm/processor.h
··· 14 14 15 15 #include <asm/ptrace.h> 16 16 17 - /* 18 - * addr is a hint to the maximum userspace address that mmap should provide, so 19 - * this macro needs to return the largest address space available so that 20 - * mmap_end < addr, being mmap_end the top of that address space. 21 - * See Documentation/arch/riscv/vm-layout.rst for more details. 22 - */ 23 17 #define arch_get_mmap_end(addr, len, flags) \ 24 18 ({ \ 25 - unsigned long mmap_end; \ 26 - typeof(addr) _addr = (addr); \ 27 - if ((_addr) == 0 || is_compat_task() || \ 28 - ((_addr + len) > BIT(VA_BITS - 1))) \ 29 - mmap_end = STACK_TOP_MAX; \ 30 - else \ 31 - mmap_end = (_addr + len); \ 32 - mmap_end; \ 19 + STACK_TOP_MAX; \ 33 20 }) 34 21 35 22 #define arch_get_mmap_base(addr, base) \ 36 23 ({ \ 37 - unsigned long mmap_base; \ 38 - typeof(addr) _addr = (addr); \ 39 - typeof(base) _base = (base); \ 40 - unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \ 41 - if ((_addr) == 0 || is_compat_task() || \ 42 - ((_addr + len) > BIT(VA_BITS - 1))) \ 43 - mmap_base = (_base); \ 44 - else \ 45 - mmap_base = (_addr + len) - rnd_gap; \ 46 - mmap_base; \ 24 + base; \ 47 25 }) 48 26 49 27 #ifdef CONFIG_64BIT
+19 -1
arch/riscv/include/asm/sbi.h
··· 9 9 10 10 #include <linux/types.h> 11 11 #include <linux/cpumask.h> 12 + #include <linux/jump_label.h> 12 13 13 14 #ifdef CONFIG_RISCV_SBI 14 15 enum sbi_ext_id { ··· 305 304 }; 306 305 307 306 void sbi_init(void); 307 + long __sbi_base_ecall(int fid); 308 308 struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, 309 309 unsigned long arg2, unsigned long arg3, 310 310 unsigned long arg4, unsigned long arg5, ··· 375 373 | (minor & SBI_SPEC_VERSION_MINOR_MASK); 376 374 } 377 375 378 - int sbi_err_map_linux_errno(int err); 376 + static inline int sbi_err_map_linux_errno(int err) 377 + { 378 + switch (err) { 379 + case SBI_SUCCESS: 380 + return 0; 381 + case SBI_ERR_DENIED: 382 + return -EPERM; 383 + case SBI_ERR_INVALID_PARAM: 384 + return -EINVAL; 385 + case SBI_ERR_INVALID_ADDRESS: 386 + return -EFAULT; 387 + case SBI_ERR_NOT_SUPPORTED: 388 + case SBI_ERR_FAILURE: 389 + default: 390 + return -ENOTSUPP; 391 + }; 392 + } 379 393 380 394 extern bool sbi_debug_console_available; 381 395 int sbi_debug_console_write(const char *bytes, unsigned int num_bytes);
+5 -1
arch/riscv/kernel/Makefile
··· 20 20 ifdef CONFIG_RISCV_ALTERNATIVE_EARLY 21 21 CFLAGS_alternative.o := -mcmodel=medany 22 22 CFLAGS_cpufeature.o := -mcmodel=medany 23 + CFLAGS_sbi_ecall.o := -mcmodel=medany 23 24 ifdef CONFIG_FTRACE 24 25 CFLAGS_REMOVE_alternative.o = $(CC_FLAGS_FTRACE) 25 26 CFLAGS_REMOVE_cpufeature.o = $(CC_FLAGS_FTRACE) 27 + CFLAGS_REMOVE_sbi_ecall.o = $(CC_FLAGS_FTRACE) 26 28 endif 27 29 ifdef CONFIG_RELOCATABLE 28 30 CFLAGS_alternative.o += -fno-pie 29 31 CFLAGS_cpufeature.o += -fno-pie 32 + CFLAGS_sbi_ecall.o += -fno-pie 30 33 endif 31 34 ifdef CONFIG_KASAN 32 35 KASAN_SANITIZE_alternative.o := n 33 36 KASAN_SANITIZE_cpufeature.o := n 37 + KASAN_SANITIZE_sbi_ecall.o := n 34 38 endif 35 39 endif 36 40 ··· 92 88 93 89 obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o 94 90 obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o 95 - obj-$(CONFIG_RISCV_SBI) += sbi.o 91 + obj-$(CONFIG_RISCV_SBI) += sbi.o sbi_ecall.o 96 92 ifeq ($(CONFIG_RISCV_SBI), y) 97 93 obj-$(CONFIG_SMP) += sbi-ipi.o 98 94 obj-$(CONFIG_SMP) += cpu_ops_sbi.o
-63
arch/riscv/kernel/sbi.c
··· 14 14 #include <asm/smp.h> 15 15 #include <asm/tlbflush.h> 16 16 17 - #define CREATE_TRACE_POINTS 18 - #include <asm/trace.h> 19 - 20 17 /* default SBI version is 0.1 */ 21 18 unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; 22 19 EXPORT_SYMBOL(sbi_spec_version); ··· 23 26 static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask, 24 27 unsigned long start, unsigned long size, 25 28 unsigned long arg4, unsigned long arg5) __ro_after_init; 26 - 27 - struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, 28 - unsigned long arg2, unsigned long arg3, 29 - unsigned long arg4, unsigned long arg5, 30 - int fid, int ext) 31 - { 32 - struct sbiret ret; 33 - 34 - trace_sbi_call(ext, fid); 35 - 36 - register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); 37 - register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); 38 - register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); 39 - register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); 40 - register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); 41 - register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); 42 - register uintptr_t a6 asm ("a6") = (uintptr_t)(fid); 43 - register uintptr_t a7 asm ("a7") = (uintptr_t)(ext); 44 - asm volatile ("ecall" 45 - : "+r" (a0), "+r" (a1) 46 - : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) 47 - : "memory"); 48 - ret.error = a0; 49 - ret.value = a1; 50 - 51 - trace_sbi_return(ext, ret.error, ret.value); 52 - 53 - return ret; 54 - } 55 - EXPORT_SYMBOL(__sbi_ecall); 56 - 57 - int sbi_err_map_linux_errno(int err) 58 - { 59 - switch (err) { 60 - case SBI_SUCCESS: 61 - return 0; 62 - case SBI_ERR_DENIED: 63 - return -EPERM; 64 - case SBI_ERR_INVALID_PARAM: 65 - return -EINVAL; 66 - case SBI_ERR_INVALID_ADDRESS: 67 - return -EFAULT; 68 - case SBI_ERR_NOT_SUPPORTED: 69 - case SBI_ERR_FAILURE: 70 - default: 71 - return -ENOTSUPP; 72 - }; 73 - } 74 - EXPORT_SYMBOL(sbi_err_map_linux_errno); 75 29 76 30 #ifdef CONFIG_RISCV_SBI_V01 77 31 static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mask) ··· 482 534 return 0; 483 535 } 484 536 EXPORT_SYMBOL(sbi_probe_extension); 485 - 486 - static long __sbi_base_ecall(int fid) 487 - { 488 - struct sbiret ret; 489 - 490 - ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); 491 - if (!ret.error) 492 - return ret.value; 493 - else 494 - return sbi_err_map_linux_errno(ret.error); 495 - } 496 537 497 538 static inline long sbi_get_spec_version(void) 498 539 {
+48
arch/riscv/kernel/sbi_ecall.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Rivos Inc. */ 3 + 4 + #include <asm/sbi.h> 5 + #define CREATE_TRACE_POINTS 6 + #include <asm/trace.h> 7 + 8 + long __sbi_base_ecall(int fid) 9 + { 10 + struct sbiret ret; 11 + 12 + ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); 13 + if (!ret.error) 14 + return ret.value; 15 + else 16 + return sbi_err_map_linux_errno(ret.error); 17 + } 18 + EXPORT_SYMBOL(__sbi_base_ecall); 19 + 20 + struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, 21 + unsigned long arg2, unsigned long arg3, 22 + unsigned long arg4, unsigned long arg5, 23 + int fid, int ext) 24 + { 25 + struct sbiret ret; 26 + 27 + trace_sbi_call(ext, fid); 28 + 29 + register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); 30 + register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); 31 + register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); 32 + register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); 33 + register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); 34 + register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); 35 + register uintptr_t a6 asm ("a6") = (uintptr_t)(fid); 36 + register uintptr_t a7 asm ("a7") = (uintptr_t)(ext); 37 + asm volatile ("ecall" 38 + : "+r" (a0), "+r" (a1) 39 + : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) 40 + : "memory"); 41 + ret.error = a0; 42 + ret.value = a1; 43 + 44 + trace_sbi_return(ext, ret.error, ret.value); 45 + 46 + return ret; 47 + } 48 + EXPORT_SYMBOL(__sbi_ecall);
+2 -2
arch/riscv/kernel/traps_misaligned.c
··· 417 417 418 418 val.data_u64 = 0; 419 419 if (user_mode(regs)) { 420 - if (raw_copy_from_user(&val, (u8 __user *)addr, len)) 420 + if (copy_from_user(&val, (u8 __user *)addr, len)) 421 421 return -1; 422 422 } else { 423 423 memcpy(&val, (u8 *)addr, len); ··· 515 515 return -EOPNOTSUPP; 516 516 517 517 if (user_mode(regs)) { 518 - if (raw_copy_to_user((u8 __user *)addr, &val, len)) 518 + if (copy_to_user((u8 __user *)addr, &val, len)) 519 519 return -1; 520 520 } else { 521 521 memcpy((u8 *)addr, &val, len);
+1 -1
arch/riscv/mm/init.c
··· 252 252 * The size of the linear page mapping may restrict the amount of 253 253 * usable RAM. 254 254 */ 255 - if (IS_ENABLED(CONFIG_64BIT)) { 255 + if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) { 256 256 max_mapped_addr = __pa(PAGE_OFFSET) + KERN_VIRT_SIZE; 257 257 memblock_cap_memory_range(phys_ram_base, 258 258 max_mapped_addr - phys_ram_base);
-2
tools/testing/selftests/riscv/mm/mmap_bottomup.c
··· 7 7 TEST(infinite_rlimit) 8 8 { 9 9 EXPECT_EQ(BOTTOM_UP, memory_layout()); 10 - 11 - TEST_MMAPS; 12 10 } 13 11 14 12 TEST_HARNESS_MAIN
-2
tools/testing/selftests/riscv/mm/mmap_default.c
··· 7 7 TEST(default_rlimit) 8 8 { 9 9 EXPECT_EQ(TOP_DOWN, memory_layout()); 10 - 11 - TEST_MMAPS; 12 10 } 13 11 14 12 TEST_HARNESS_MAIN
-67
tools/testing/selftests/riscv/mm/mmap_test.h
··· 10 10 #define TOP_DOWN 0 11 11 #define BOTTOM_UP 1 12 12 13 - #if __riscv_xlen == 64 14 - uint64_t random_addresses[] = { 15 - 0x19764f0d73b3a9f0, 0x016049584cecef59, 0x3580bdd3562f4acd, 16 - 0x1164219f20b17da0, 0x07d97fcb40ff2373, 0x76ec528921272ee7, 17 - 0x4dd48c38a3de3f70, 0x2e11415055f6997d, 0x14b43334ac476c02, 18 - 0x375a60795aff19f6, 0x47f3051725b8ee1a, 0x4e697cf240494a9f, 19 - 0x456b59b5c2f9e9d1, 0x101724379d63cb96, 0x7fe9ad31619528c1, 20 - 0x2f417247c495c2ea, 0x329a5a5b82943a5e, 0x06d7a9d6adcd3827, 21 - 0x327b0b9ee37f62d5, 0x17c7b1851dfd9b76, 0x006ebb6456ec2cd9, 22 - 0x00836cd14146a134, 0x00e5c4dcde7126db, 0x004c29feadf75753, 23 - 0x00d8b20149ed930c, 0x00d71574c269387a, 0x0006ebe4a82acb7a, 24 - 0x0016135df51f471b, 0x00758bdb55455160, 0x00d0bdd949b13b32, 25 - 0x00ecea01e7c5f54b, 0x00e37b071b9948b1, 0x0011fdd00ff57ab3, 26 - 0x00e407294b52f5ea, 0x00567748c200ed20, 0x000d073084651046, 27 - 0x00ac896f4365463c, 0x00eb0d49a0b26216, 0x0066a2564a982a31, 28 - 0x002e0d20237784ae, 0x0000554ff8a77a76, 0x00006ce07a54c012, 29 - 0x000009570516d799, 0x00000954ca15b84d, 0x0000684f0d453379, 30 - 0x00002ae5816302b5, 0x0000042403fb54bf, 0x00004bad7392bf30, 31 - 0x00003e73bfa4b5e3, 0x00005442c29978e0, 0x00002803f11286b6, 32 - 0x000073875d745fc6, 0x00007cede9cb8240, 0x000027df84cc6a4f, 33 - 0x00006d7e0e74242a, 0x00004afd0b836e02, 0x000047d0e837cd82, 34 - 0x00003b42405efeda, 0x00001531bafa4c95, 0x00007172cae34ac4, 35 - }; 36 - #else 37 - uint32_t random_addresses[] = { 38 - 0x8dc302e0, 0x929ab1e0, 0xb47683ba, 0xea519c73, 0xa19f1c90, 0xc49ba213, 39 - 0x8f57c625, 0xadfe5137, 0x874d4d95, 0xaa20f09d, 0xcf21ebfc, 0xda7737f1, 40 - 0xcedf392a, 0x83026c14, 0xccedca52, 0xc6ccf826, 0xe0cd9415, 0x997472ca, 41 - 0xa21a44c1, 0xe82196f5, 0xa23fd66b, 0xc28d5590, 0xd009cdce, 0xcf0be646, 42 - 0x8fc8c7ff, 0xe2a85984, 0xa3d3236b, 0x89a0619d, 0xc03db924, 0xb5d4cc1b, 43 - 0xb96ee04c, 0xd191da48, 0xb432a000, 0xaa2bebbc, 0xa2fcb289, 0xb0cca89b, 44 - 0xb0c18d6a, 0x88f58deb, 0xa4d42d1c, 0xe4d74e86, 0x99902b09, 0x8f786d31, 45 - 0xbec5e381, 0x9a727e65, 0xa9a65040, 0xa880d789, 0x8f1b335e, 0xfc821c1e, 46 - 0x97e34be4, 0xbbef84ed, 0xf447d197, 0xfd7ceee2, 0xe632348d, 0xee4590f4, 47 - 0x958992a5, 0xd57e05d6, 0xfd240970, 0xc5b0dcff, 0xd96da2c2, 0xa7ae041d, 48 - }; 49 - #endif 50 - 51 - // Only works on 64 bit 52 - #if __riscv_xlen == 64 53 13 #define PROT (PROT_READ | PROT_WRITE) 54 14 #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS) 55 - 56 - /* mmap must return a value that doesn't use more bits than the hint address. */ 57 - static inline unsigned long get_max_value(unsigned long input) 58 - { 59 - unsigned long max_bit = (1UL << (((sizeof(unsigned long) * 8) - 1 - 60 - __builtin_clzl(input)))); 61 - 62 - return max_bit + (max_bit - 1); 63 - } 64 - 65 - #define TEST_MMAPS \ 66 - ({ \ 67 - void *mmap_addr; \ 68 - for (int i = 0; i < ARRAY_SIZE(random_addresses); i++) { \ 69 - mmap_addr = mmap((void *)random_addresses[i], \ 70 - 5 * sizeof(int), PROT, FLAGS, 0, 0); \ 71 - EXPECT_NE(MAP_FAILED, mmap_addr); \ 72 - EXPECT_GE((void *)get_max_value(random_addresses[i]), \ 73 - mmap_addr); \ 74 - mmap_addr = mmap((void *)random_addresses[i], \ 75 - 5 * sizeof(int), PROT, FLAGS, 0, 0); \ 76 - EXPECT_NE(MAP_FAILED, mmap_addr); \ 77 - EXPECT_GE((void *)get_max_value(random_addresses[i]), \ 78 - mmap_addr); \ 79 - } \ 80 - }) 81 - #endif /* __riscv_xlen == 64 */ 82 15 83 16 static inline int memory_layout(void) 84 17 {