History

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

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

Linus Torvalds committed 6 years ago

Commit 7fdfbe02 parents 27c2760 0e2c0903 files · +22 −6Browse files

Unified · Split

3 files
  1. arch/riscv/include/asm/cmpxchg.h +4 −4
  2. arch/riscv/kernel/sys_riscv.c +6 −0
  3. arch/riscv/mm/pageattr.c +12 −2
arch/riscv/include/asm/cmpxchg.h+4−4
@@ -179,7 +179,7 @@ · 178 unmodified lines
179179 " bnez %1, 0b\n" \
180180 "1:\n" \
181181 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
182− : "rJ" (__old), "rJ" (__new) \
182+ : "rJ" ((long)__old), "rJ" (__new) \
183183 : "memory"); \
184184 break; \
185185 case 8: \
@@ -224,7 +224,7 @@ · 38 unmodified lines
224224 RISCV_ACQUIRE_BARRIER \
225225 "1:\n" \
226226 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
227− : "rJ" (__old), "rJ" (__new) \
227+ : "rJ" ((long)__old), "rJ" (__new) \
228228 : "memory"); \
229229 break; \
230230 case 8: \
@@ -270,7 +270,7 @@ · 39 unmodified lines
270270 " bnez %1, 0b\n" \
271271 "1:\n" \
272272 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
273− : "rJ" (__old), "rJ" (__new) \
273+ : "rJ" ((long)__old), "rJ" (__new) \
274274 : "memory"); \
275275 break; \
276276 case 8: \
@@ -316,7 +316,7 @@ · 39 unmodified lines
316316 " fence rw, rw\n" \
317317 "1:\n" \
318318 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
319− : "rJ" (__old), "rJ" (__new) \
319+ : "rJ" ((long)__old), "rJ" (__new) \
320320 : "memory"); \
321321 break; \
322322 case 8: \
arch/riscv/kernel/sys_riscv.c+6−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/syscalls.h>
99 #include <asm/unistd.h>
1010 #include <asm/cacheflush.h>
11+#include <asm-generic/mman-common.h>
1112
1213 static long riscv_sys_mmap(unsigned long addr, unsigned long len,
1314 unsigned long prot, unsigned long flags,
@@ -16,6 +17,11 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, · 2 unmodified lines
1617 {
1718 if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
1819 return -EINVAL;
20+
21+ if ((prot & PROT_WRITE) && (prot & PROT_EXEC))
22+ if (unlikely(!(prot & PROT_READ)))
23+ return -EINVAL;
24+
1925 return ksys_mmap_pgoff(addr, len, prot, flags, fd,
2026 offset >> (PAGE_SHIFT - page_shift_offset));
2127 }
arch/riscv/mm/pageattr.c+12−2
@@ -151,6 +151,7 @@ int set_memory_nx(unsigned long addr, int numpages) · 150 unmodified lines
151151
152152 int set_direct_map_invalid_noflush(struct page *page)
153153 {
154+ int ret;
154155 unsigned long start = (unsigned long)page_address(page);
155156 unsigned long end = start + PAGE_SIZE;
156157 struct pageattr_masks masks = {
@@ -158,11 +159,16 @@ int set_direct_map_invalid_noflush(struct page *page) · 1 unmodified line
158159 .clear_mask = __pgprot(_PAGE_PRESENT)
159160 };
160161
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;
162167 }
163168
164169 int set_direct_map_default_noflush(struct page *page)
165170 {
171+ int ret;
166172 unsigned long start = (unsigned long)page_address(page);
167173 unsigned long end = start + PAGE_SIZE;
168174 struct pageattr_masks masks = {
@@ -170,7 +176,11 @@ int set_direct_map_default_noflush(struct page *page) · 1 unmodified line
170176 .clear_mask = __pgprot(0)
171177 };
172178
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;
174184 }
175185
176186 void __kernel_map_pages(struct page *page, int numpages, int enable)