Pull RISC-V fixes from Palmer Dabbelt: - a workaround for a compiler surprise related to the "r" inline assembly that allows LLVM to boot. - a fix to avoid WX-only mappings, which the ISA does not allow. While this probably manifests in many ways, the bug was found in stress-ng. - a missing lock in set_direct_map_*(), which due to a recent lockdep change started asserting. * tag 'riscv-for-linus-5.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: RISC-V: Acquire mmap lock before invoking walk_page_range RISC-V: Don't allow write+exec only page mapping request in mmap riscv/atomic: Fix sign extension for RV64I
Unified · Split
| @@ -179,7 +179,7 @@ · 178 unmodified lines | ||
| 179 | 179 | " bnez %1, 0b\n" \ |
| 180 | 180 | "1:\n" \ |
| 181 | 181 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 182 | − : "rJ" (__old), "rJ" (__new) \ | |
| 182 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 183 | 183 | : "memory"); \ |
| 184 | 184 | break; \ |
| 185 | 185 | case 8: \ |
| @@ -224,7 +224,7 @@ · 38 unmodified lines | ||
| 224 | 224 | RISCV_ACQUIRE_BARRIER \ |
| 225 | 225 | "1:\n" \ |
| 226 | 226 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 227 | − : "rJ" (__old), "rJ" (__new) \ | |
| 227 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 228 | 228 | : "memory"); \ |
| 229 | 229 | break; \ |
| 230 | 230 | case 8: \ |
| @@ -270,7 +270,7 @@ · 39 unmodified lines | ||
| 270 | 270 | " bnez %1, 0b\n" \ |
| 271 | 271 | "1:\n" \ |
| 272 | 272 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 273 | − : "rJ" (__old), "rJ" (__new) \ | |
| 273 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 274 | 274 | : "memory"); \ |
| 275 | 275 | break; \ |
| 276 | 276 | case 8: \ |
| @@ -316,7 +316,7 @@ · 39 unmodified lines | ||
| 316 | 316 | " fence rw, rw\n" \ |
| 317 | 317 | "1:\n" \ |
| 318 | 318 | : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ |
| 319 | − : "rJ" (__old), "rJ" (__new) \ | |
| 319 | + : "rJ" ((long)__old), "rJ" (__new) \ | |
| 320 | 320 | : "memory"); \ |
| 321 | 321 | break; \ |
| 322 | 322 | case 8: \ |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/syscalls.h> |
| 9 | 9 | #include <asm/unistd.h> |
| 10 | 10 | #include <asm/cacheflush.h> |
| 11 | +#include <asm-generic/mman-common.h> | |
| 11 | 12 | |
| 12 | 13 | static long riscv_sys_mmap(unsigned long addr, unsigned long len, |
| 13 | 14 | unsigned long prot, unsigned long flags, |
| @@ -16,6 +17,11 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, · 2 unmodified lines | ||
| 16 | 17 | { |
| 17 | 18 | if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) |
| 18 | 19 | return -EINVAL; |
| 20 | + | |
| 21 | + if ((prot & PROT_WRITE) && (prot & PROT_EXEC)) | |
| 22 | + if (unlikely(!(prot & PROT_READ))) | |
| 23 | + return -EINVAL; | |
| 24 | + | |
| 19 | 25 | return ksys_mmap_pgoff(addr, len, prot, flags, fd, |
| 20 | 26 | offset >> (PAGE_SHIFT - page_shift_offset)); |
| 21 | 27 | } |
| @@ -151,6 +151,7 @@ int set_memory_nx(unsigned long addr, int numpages) · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | int set_direct_map_invalid_noflush(struct page *page) |
| 153 | 153 | { |
| 154 | + int ret; | |
| 154 | 155 | unsigned long start = (unsigned long)page_address(page); |
| 155 | 156 | unsigned long end = start + PAGE_SIZE; |
| 156 | 157 | struct pageattr_masks masks = { |
| @@ -158,11 +159,16 @@ int set_direct_map_invalid_noflush(struct page *page) · 1 unmodified line | ||
| 158 | 159 | .clear_mask = __pgprot(_PAGE_PRESENT) |
| 159 | 160 | }; |
| 160 | 161 | |
| 161 | − return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 162 | + mmap_read_lock(&init_mm); | |
| 163 | + ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 164 | + mmap_read_unlock(&init_mm); | |
| 165 | + | |
| 166 | + return ret; | |
| 162 | 167 | } |
| 163 | 168 | |
| 164 | 169 | int set_direct_map_default_noflush(struct page *page) |
| 165 | 170 | { |
| 171 | + int ret; | |
| 166 | 172 | unsigned long start = (unsigned long)page_address(page); |
| 167 | 173 | unsigned long end = start + PAGE_SIZE; |
| 168 | 174 | struct pageattr_masks masks = { |
| @@ -170,7 +176,11 @@ int set_direct_map_default_noflush(struct page *page) · 1 unmodified line | ||
| 170 | 176 | .clear_mask = __pgprot(0) |
| 171 | 177 | }; |
| 172 | 178 | |
| 173 | − return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 179 | + mmap_read_lock(&init_mm); | |
| 180 | + ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); | |
| 181 | + mmap_read_unlock(&init_mm); | |
| 182 | + | |
| 183 | + return ret; | |
| 174 | 184 | } |
| 175 | 185 | |
| 176 | 186 | void __kernel_map_pages(struct page *page, int numpages, int enable) |