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
179 " bnez %1, 0b\n" \179 " bnez %1, 0b\n" \
180 "1:\n" \180 "1:\n" \
181 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \181 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
182 : "rJ" (__old), "rJ" (__new) \182 : "rJ" ((long)__old), "rJ" (__new) \
183 : "memory"); \183 : "memory"); \
184 break; \184 break; \
185 case 8: \185 case 8: \
@@ -224,7 +224,7 @@ · 38 unmodified lines
224 RISCV_ACQUIRE_BARRIER \224 RISCV_ACQUIRE_BARRIER \
225 "1:\n" \225 "1:\n" \
226 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \226 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
227 : "rJ" (__old), "rJ" (__new) \227 : "rJ" ((long)__old), "rJ" (__new) \
228 : "memory"); \228 : "memory"); \
229 break; \229 break; \
230 case 8: \230 case 8: \
@@ -270,7 +270,7 @@ · 39 unmodified lines
270 " bnez %1, 0b\n" \270 " bnez %1, 0b\n" \
271 "1:\n" \271 "1:\n" \
272 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \272 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
273 : "rJ" (__old), "rJ" (__new) \273 : "rJ" ((long)__old), "rJ" (__new) \
274 : "memory"); \274 : "memory"); \
275 break; \275 break; \
276 case 8: \276 case 8: \
@@ -316,7 +316,7 @@ · 39 unmodified lines
316 " fence rw, rw\n" \316 " fence rw, rw\n" \
317 "1:\n" \317 "1:\n" \
318 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \318 : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
319 : "rJ" (__old), "rJ" (__new) \319 : "rJ" ((long)__old), "rJ" (__new) \
320 : "memory"); \320 : "memory"); \
321 break; \321 break; \
322 case 8: \322 case 8: \
arch/riscv/kernel/sys_riscv.c+6−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#include <linux/syscalls.h>8#include <linux/syscalls.h>
9#include <asm/unistd.h>9#include <asm/unistd.h>
10#include <asm/cacheflush.h>10#include <asm/cacheflush.h>
11#include <asm-generic/mman-common.h>
11 12
12static long riscv_sys_mmap(unsigned long addr, unsigned long len,13static long riscv_sys_mmap(unsigned long addr, unsigned long len,
13 unsigned long prot, unsigned long flags,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 if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))18 if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
18 return -EINVAL;19 return -EINVAL;
20
21 if ((prot & PROT_WRITE) && (prot & PROT_EXEC))
22 if (unlikely(!(prot & PROT_READ)))
23 return -EINVAL;
24
19 return ksys_mmap_pgoff(addr, len, prot, flags, fd,25 return ksys_mmap_pgoff(addr, len, prot, flags, fd,
20 offset >> (PAGE_SHIFT - page_shift_offset));26 offset >> (PAGE_SHIFT - page_shift_offset));
21}27}
arch/riscv/mm/pageattr.c+12−2
@@ -151,6 +151,7 @@ int set_memory_nx(unsigned long addr, int numpages) · 150 unmodified lines
151 151
152int set_direct_map_invalid_noflush(struct page *page)152int set_direct_map_invalid_noflush(struct page *page)
153{153{
154 int ret;
154 unsigned long start = (unsigned long)page_address(page);155 unsigned long start = (unsigned long)page_address(page);
155 unsigned long end = start + PAGE_SIZE;156 unsigned long end = start + PAGE_SIZE;
156 struct pageattr_masks masks = {157 struct pageattr_masks masks = {
@@ -158,11 +159,16 @@ int set_direct_map_invalid_noflush(struct page *page) · 1 unmodified line
158 .clear_mask = __pgprot(_PAGE_PRESENT)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
164int set_direct_map_default_noflush(struct page *page)169int set_direct_map_default_noflush(struct page *page)
165{170{
171 int ret;
166 unsigned long start = (unsigned long)page_address(page);172 unsigned long start = (unsigned long)page_address(page);
167 unsigned long end = start + PAGE_SIZE;173 unsigned long end = start + PAGE_SIZE;
168 struct pageattr_masks masks = {174 struct pageattr_masks masks = {
@@ -170,7 +176,11 @@ int set_direct_map_default_noflush(struct page *page) · 1 unmodified line
170 .clear_mask = __pgprot(0)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
176void __kernel_map_pages(struct page *page, int numpages, int enable)186void __kernel_map_pages(struct page *page, int numpages, int enable)