Pull x86 cleanups from Ingo Molnar: "This topic tree contains more commits than usual: - most of it are uaccess cleanups/reorganization by Al - there's a bunch of prototype declaration (--Wmissing-prototypes) cleanups - misc other cleanups all around the map" * 'x86-cleanups-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits) x86/mm/set_memory: Fix -Wmissing-prototypes warnings x86/efi: Add a prototype for efi_arch_mem_reserve() x86/mm: Mark setup_emu2phys_nid() static x86/jump_label: Move 'inline' keyword placement x86/platform/uv: Add a missing prototype for uv_bau_message_interrupt() kill uaccess_try() x86: unsafe_put-style macro for sigmask x86: x32_setup_rt_frame(): consolidate uaccess areas x86: __setup_rt_frame(): consolidate uaccess areas x86: __setup_frame(): consolidate uaccess areas x86: setup_sigcontext(): list user_access_{begin,end}() into callers x86: get rid of put_user_try in __setup_rt_frame() (both 32bit and 64bit) x86: ia32_setup_rt_frame(): consolidate uaccess areas x86: ia32_setup_frame(): consolidate uaccess areas x86: ia32_setup_sigcontext(): lift user_access_{begin,end}() into the callers x86/alternatives: Mark text_poke_loc_init() static x86/cpu: Fix a -Wmissing-prototypes warning for init_ia32_feat_ctl() x86/mm: Drop pud_mknotpresent() x86: Replace setup_irq() by request_irq() x86/configs: Slightly reduce defconfigs ...
Unified · Split
| @@ -340,12 +340,6 @@ pointer which points to one of: · 339 unmodified lines | ||
| 340 | 340 | entry->insn. It is used to distinguish page faults from machine |
| 341 | 341 | check. |
| 342 | 342 | |
| 343 | −3) ``int ex_handler_ext(const struct exception_table_entry *fixup)`` | |
| 344 | − This case is used for uaccess_err ... we need to set a flag | |
| 345 | − in the task structure. Before the handler functions existed this | |
| 346 | − case was handled by adding a large offset to the fixup to tag | |
| 347 | − it as special. | |
| 348 | − | |
| 349 | 343 | More functions can easily be added. |
| 350 | 344 | |
| 351 | 345 | CONFIG_BUILDTIME_TABLE_SORT allows the __ex_table section to be sorted post |
| @@ -125,7 +125,6 @@ CONFIG_IP6_NF_MANGLE=y · 124 unmodified lines | ||
| 125 | 125 | CONFIG_NET_SCHED=y |
| 126 | 126 | CONFIG_NET_EMATCH=y |
| 127 | 127 | CONFIG_NET_CLS_ACT=y |
| 128 | −CONFIG_HAMRADIO=y | |
| 129 | 128 | CONFIG_CFG80211=y |
| 130 | 129 | CONFIG_MAC80211=y |
| 131 | 130 | CONFIG_MAC80211_LEDS=y |
| @@ -171,7 +170,6 @@ CONFIG_FORCEDETH=y · 39 unmodified lines | ||
| 171 | 170 | CONFIG_8139TOO=y |
| 172 | 171 | # CONFIG_8139TOO_PIO is not set |
| 173 | 172 | CONFIG_R8169=y |
| 174 | −CONFIG_FDDI=y | |
| 175 | 173 | CONFIG_INPUT_POLLDEV=y |
| 176 | 174 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
| 177 | 175 | CONFIG_INPUT_EVDEV=y |
| @@ -123,7 +123,6 @@ CONFIG_IP6_NF_MANGLE=y · 122 unmodified lines | ||
| 123 | 123 | CONFIG_NET_SCHED=y |
| 124 | 124 | CONFIG_NET_EMATCH=y |
| 125 | 125 | CONFIG_NET_CLS_ACT=y |
| 126 | −CONFIG_HAMRADIO=y | |
| 127 | 126 | CONFIG_CFG80211=y |
| 128 | 127 | CONFIG_MAC80211=y |
| 129 | 128 | CONFIG_MAC80211_LEDS=y |
| @@ -164,7 +163,6 @@ CONFIG_SKY2=y · 34 unmodified lines | ||
| 164 | 163 | CONFIG_FORCEDETH=y |
| 165 | 164 | CONFIG_8139TOO=y |
| 166 | 165 | CONFIG_R8169=y |
| 167 | −CONFIG_FDDI=y | |
| 168 | 166 | CONFIG_INPUT_POLLDEV=y |
| 169 | 167 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
| 170 | 168 | CONFIG_INPUT_EVDEV=y |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <asm/fpu/api.h> |
| 35 | 35 | #include <asm/nospec-branch.h> |
| 36 | 36 | #include <asm/io_bitmap.h> |
| 37 | +#include <asm/syscall.h> | |
| 37 | 38 | |
| 38 | 39 | #define CREATE_TRACE_POINTS |
| 39 | 40 | #include <trace/events/syscalls.h> |
| @@ -2490,7 +2490,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent · 2489 unmodified lines | ||
| 2490 | 2490 | /* 32-bit process in 64-bit kernel. */ |
| 2491 | 2491 | unsigned long ss_base, cs_base; |
| 2492 | 2492 | struct stack_frame_ia32 frame; |
| 2493 | − const void __user *fp; | |
| 2493 | + const struct stack_frame_ia32 __user *fp; | |
| 2494 | 2494 | |
| 2495 | 2495 | if (!test_thread_flag(TIF_IA32)) |
| 2496 | 2496 | return 0; |
| @@ -2501,18 +2501,12 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent · 4 unmodified lines | ||
| 2501 | 2501 | fp = compat_ptr(ss_base + regs->bp); |
| 2502 | 2502 | pagefault_disable(); |
| 2503 | 2503 | while (entry->nr < entry->max_stack) { |
| 2504 | − unsigned long bytes; | |
| 2505 | − frame.next_frame = 0; | |
| 2506 | − frame.return_address = 0; | |
| 2507 | − | |
| 2508 | 2504 | if (!valid_user_frame(fp, sizeof(frame))) |
| 2509 | 2505 | break; |
| 2510 | 2506 | |
| 2511 | − bytes = __copy_from_user_nmi(&frame.next_frame, fp, 4); | |
| 2512 | − if (bytes != 0) | |
| 2507 | + if (__get_user(frame.next_frame, &fp->next_frame)) | |
| 2513 | 2508 | break; |
| 2514 | − bytes = __copy_from_user_nmi(&frame.return_address, fp+4, 4); | |
| 2515 | − if (bytes != 0) | |
| 2509 | + if (__get_user(frame.return_address, &fp->return_address)) | |
| 2516 | 2510 | break; |
| 2517 | 2511 | |
| 2518 | 2512 | perf_callchain_store(entry, cs_base + frame.return_address); |
| @@ -2533,7 +2527,7 @@ void · 14 unmodified lines | ||
| 2533 | 2527 | perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) |
| 2534 | 2528 | { |
| 2535 | 2529 | struct stack_frame frame; |
| 2536 | − const unsigned long __user *fp; | |
| 2530 | + const struct stack_frame __user *fp; | |
| 2537 | 2531 | |
| 2538 | 2532 | if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { |
| 2539 | 2533 | /* TODO: We don't support guest os callchain now */ |
| @@ -2546,7 +2540,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs · 6 unmodified lines | ||
| 2546 | 2540 | if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM)) |
| 2547 | 2541 | return; |
| 2548 | 2542 | |
| 2549 | − fp = (unsigned long __user *)regs->bp; | |
| 2543 | + fp = (void __user *)regs->bp; | |
| 2550 | 2544 | |
| 2551 | 2545 | perf_callchain_store(entry, regs->ip); |
| 2552 | 2546 | |
| @@ -2558,19 +2552,12 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs · 5 unmodified lines | ||
| 2558 | 2552 | |
| 2559 | 2553 | pagefault_disable(); |
| 2560 | 2554 | while (entry->nr < entry->max_stack) { |
| 2561 | − unsigned long bytes; | |
| 2562 | − | |
| 2563 | − frame.next_frame = NULL; | |
| 2564 | − frame.return_address = 0; | |
| 2565 | − | |
| 2566 | 2555 | if (!valid_user_frame(fp, sizeof(frame))) |
| 2567 | 2556 | break; |
| 2568 | 2557 | |
| 2569 | − bytes = __copy_from_user_nmi(&frame.next_frame, fp, sizeof(*fp)); | |
| 2570 | − if (bytes != 0) | |
| 2558 | + if (__get_user(frame.next_frame, &fp->next_frame)) | |
| 2571 | 2559 | break; |
| 2572 | − bytes = __copy_from_user_nmi(&frame.return_address, fp + 1, sizeof(*fp)); | |
| 2573 | − if (bytes != 0) | |
| 2560 | + if (__get_user(frame.return_address, &fp->return_address)) | |
| 2574 | 2561 | break; |
| 2575 | 2562 | |
| 2576 | 2563 | perf_callchain_store(entry, frame.return_address); |
| @@ -36,70 +36,56 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <asm/sighandling.h> |
| 37 | 37 | #include <asm/smap.h> |
| 38 | 38 | |
| 39 | +static inline void reload_segments(struct sigcontext_32 *sc) | |
| 40 | +{ | |
| 41 | + unsigned int cur; | |
| 42 | + | |
| 43 | + savesegment(gs, cur); | |
| 44 | + if ((sc->gs | 0x03) != cur) | |
| 45 | + load_gs_index(sc->gs | 0x03); | |
| 46 | + savesegment(fs, cur); | |
| 47 | + if ((sc->fs | 0x03) != cur) | |
| 48 | + loadsegment(fs, sc->fs | 0x03); | |
| 49 | + savesegment(ds, cur); | |
| 50 | + if ((sc->ds | 0x03) != cur) | |
| 51 | + loadsegment(ds, sc->ds | 0x03); | |
| 52 | + savesegment(es, cur); | |
| 53 | + if ((sc->es | 0x03) != cur) | |
| 54 | + loadsegment(es, sc->es | 0x03); | |
| 55 | +} | |
| 56 | + | |
| 39 | 57 | /* |
| 40 | 58 | * Do a signal return; undo the signal stack. |
| 41 | 59 | */ |
| 42 | −#define loadsegment_gs(v) load_gs_index(v) | |
| 43 | −#define loadsegment_fs(v) loadsegment(fs, v) | |
| 44 | −#define loadsegment_ds(v) loadsegment(ds, v) | |
| 45 | −#define loadsegment_es(v) loadsegment(es, v) | |
| 46 | − | |
| 47 | −#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; }) | |
| 48 | −#define set_user_seg(seg, v) loadsegment_##seg(v) | |
| 49 | − | |
| 50 | −#define COPY(x) { \ | |
| 51 | − get_user_ex(regs->x, &sc->x); \ | |
| 52 | −} | |
| 53 | − | |
| 54 | −#define GET_SEG(seg) ({ \ | |
| 55 | − unsigned short tmp; \ | |
| 56 | − get_user_ex(tmp, &sc->seg); \ | |
| 57 | − tmp; \ | |
| 58 | −}) | |
| 59 | − | |
| 60 | −#define COPY_SEG_CPL3(seg) do { \ | |
| 61 | − regs->seg = GET_SEG(seg) | 3; \ | |
| 62 | −} while (0) | |
| 63 | − | |
| 64 | −#define RELOAD_SEG(seg) { \ | |
| 65 | − unsigned int pre = (seg) | 3; \ | |
| 66 | − unsigned int cur = get_user_seg(seg); \ | |
| 67 | − if (pre != cur) \ | |
| 68 | − set_user_seg(seg, pre); \ | |
| 69 | −} | |
| 70 | − | |
| 71 | 60 | static int ia32_restore_sigcontext(struct pt_regs *regs, |
| 72 | − struct sigcontext_32 __user *sc) | |
| 61 | + struct sigcontext_32 __user *usc) | |
| 73 | 62 | { |
| 74 | − unsigned int tmpflags, err = 0; | |
| 75 | − u16 gs, fs, es, ds; | |
| 76 | − void __user *buf; | |
| 77 | − u32 tmp; | |
| 63 | + struct sigcontext_32 sc; | |
| 78 | 64 | |
| 79 | 65 | /* Always make any pending restarted system calls return -EINTR */ |
| 80 | 66 | current->restart_block.fn = do_no_restart_syscall; |
| 81 | 67 | |
| 82 | − get_user_try { | |
| 83 | − gs = GET_SEG(gs); | |
| 84 | − fs = GET_SEG(fs); | |
| 85 | − ds = GET_SEG(ds); | |
| 86 | − es = GET_SEG(es); | |
| 87 | − | |
| 88 | − COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); | |
| 89 | − COPY(dx); COPY(cx); COPY(ip); COPY(ax); | |
| 90 | − /* Don't touch extended registers */ | |
| 91 | − | |
| 92 | − COPY_SEG_CPL3(cs); | |
| 93 | − COPY_SEG_CPL3(ss); | |
| 94 | − | |
| 95 | − get_user_ex(tmpflags, &sc->flags); | |
| 96 | − regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); | |
| 97 | − /* disable syscall checks */ | |
| 98 | − regs->orig_ax = -1; | |
| 68 | + if (unlikely(copy_from_user(&sc, usc, sizeof(sc)))) | |
| 69 | + return -EFAULT; | |
| 99 | 70 | |
| 100 | − get_user_ex(tmp, &sc->fpstate); | |
| 101 | − buf = compat_ptr(tmp); | |
| 102 | − } get_user_catch(err); | |
| 71 | + /* Get only the ia32 registers. */ | |
| 72 | + regs->bx = sc.bx; | |
| 73 | + regs->cx = sc.cx; | |
| 74 | + regs->dx = sc.dx; | |
| 75 | + regs->si = sc.si; | |
| 76 | + regs->di = sc.di; | |
| 77 | + regs->bp = sc.bp; | |
| 78 | + regs->ax = sc.ax; | |
| 79 | + regs->sp = sc.sp; | |
| 80 | + regs->ip = sc.ip; | |
| 81 | + | |
| 82 | + /* Get CS/SS and force CPL3 */ | |
| 83 | + regs->cs = sc.cs | 0x03; | |
| 84 | + regs->ss = sc.ss | 0x03; | |
| 85 | + | |
| 86 | + regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS); | |
| 87 | + /* disable syscall checks */ | |
| 88 | + regs->orig_ax = -1; | |
| 103 | 89 | |
| 104 | 90 | /* |
| 105 | 91 | * Reload fs and gs if they have changed in the signal |
| @@ -107,14 +93,8 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, · 1 unmodified line | ||
| 107 | 93 | * the handler, but does not clobber them at least in the |
| 108 | 94 | * normal case. |
| 109 | 95 | */ |
| 110 | − RELOAD_SEG(gs); | |
| 111 | − RELOAD_SEG(fs); | |
| 112 | − RELOAD_SEG(ds); | |
| 113 | − RELOAD_SEG(es); | |
| 114 | − | |
| 115 | − err |= fpu__restore_sig(buf, 1); | |
| 116 | − | |
| 117 | − return err; | |
| 96 | + reload_segments(&sc); | |
| 97 | + return fpu__restore_sig(compat_ptr(sc.fpstate), 1); | |
| 118 | 98 | } |
| 119 | 99 | |
| 120 | 100 | COMPAT_SYSCALL_DEFINE0(sigreturn) |
| @@ -126,10 +106,7 @@ COMPAT_SYSCALL_DEFINE0(sigreturn) · 5 unmodified lines | ||
| 126 | 106 | if (!access_ok(frame, sizeof(*frame))) |
| 127 | 107 | goto badframe; |
| 128 | 108 | if (__get_user(set.sig[0], &frame->sc.oldmask) |
| 129 | − || (_COMPAT_NSIG_WORDS > 1 | |
| 130 | − && __copy_from_user((((char *) &set.sig) + 4), | |
| 131 | − &frame->extramask, | |
| 132 | − sizeof(frame->extramask)))) | |
| 109 | + || __get_user(((__u32 *)&set)[1], &frame->extramask[0])) | |
| 133 | 110 | goto badframe; |
| 134 | 111 | |
| 135 | 112 | set_current_blocked(&set); |
| @@ -153,7 +130,7 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) · 17 unmodified lines | ||
| 153 | 130 | |
| 154 | 131 | if (!access_ok(frame, sizeof(*frame))) |
| 155 | 132 | goto badframe; |
| 156 | − if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | |
| 133 | + if (__get_user(set.sig[0], (__u64 __user *)&frame->uc.uc_sigmask)) | |
| 157 | 134 | goto badframe; |
| 158 | 135 | |
| 159 | 136 | set_current_blocked(&set); |
| @@ -175,44 +152,51 @@ badframe: · 15 unmodified lines | ||
| 175 | 152 | * Set up a signal frame. |
| 176 | 153 | */ |
| 177 | 154 | |
| 178 | −static int ia32_setup_sigcontext(struct sigcontext_32 __user *sc, | |
| 179 | − void __user *fpstate, | |
| 180 | − struct pt_regs *regs, unsigned int mask) | |
| 155 | +#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; }) | |
| 156 | + | |
| 157 | +static __always_inline int | |
| 158 | +__unsafe_setup_sigcontext32(struct sigcontext_32 __user *sc, | |
| 159 | + void __user *fpstate, | |
| 160 | + struct pt_regs *regs, unsigned int mask) | |
| 181 | 161 | { |
| 182 | − int err = 0; | |
| 183 | − | |
| 184 | − put_user_try { | |
| 185 | − put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs); | |
| 186 | − put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs); | |
| 187 | − put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds); | |
| 188 | − put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es); | |
| 189 | − | |
| 190 | − put_user_ex(regs->di, &sc->di); | |
| 191 | − put_user_ex(regs->si, &sc->si); | |
| 192 | − put_user_ex(regs->bp, &sc->bp); | |
| 193 | − put_user_ex(regs->sp, &sc->sp); | |
| 194 | − put_user_ex(regs->bx, &sc->bx); | |
| 195 | − put_user_ex(regs->dx, &sc->dx); | |
| 196 | − put_user_ex(regs->cx, &sc->cx); | |
| 197 | − put_user_ex(regs->ax, &sc->ax); | |
| 198 | − put_user_ex(current->thread.trap_nr, &sc->trapno); | |
| 199 | − put_user_ex(current->thread.error_code, &sc->err); | |
| 200 | − put_user_ex(regs->ip, &sc->ip); | |
| 201 | − put_user_ex(regs->cs, (unsigned int __user *)&sc->cs); | |
| 202 | − put_user_ex(regs->flags, &sc->flags); | |
| 203 | − put_user_ex(regs->sp, &sc->sp_at_signal); | |
| 204 | − put_user_ex(regs->ss, (unsigned int __user *)&sc->ss); | |
| 205 | − | |
| 206 | − put_user_ex(ptr_to_compat(fpstate), &sc->fpstate); | |
| 207 | − | |
| 208 | − /* non-iBCS2 extensions.. */ | |
| 209 | − put_user_ex(mask, &sc->oldmask); | |
| 210 | − put_user_ex(current->thread.cr2, &sc->cr2); | |
| 211 | − } put_user_catch(err); | |
| 212 | − | |
| 213 | − return err; | |
| 162 | + unsafe_put_user(get_user_seg(gs), (unsigned int __user *)&sc->gs, Efault); | |
| 163 | + unsafe_put_user(get_user_seg(fs), (unsigned int __user *)&sc->fs, Efault); | |
| 164 | + unsafe_put_user(get_user_seg(ds), (unsigned int __user *)&sc->ds, Efault); | |
| 165 | + unsafe_put_user(get_user_seg(es), (unsigned int __user *)&sc->es, Efault); | |
| 166 | + | |
| 167 | + unsafe_put_user(regs->di, &sc->di, Efault); | |
| 168 | + unsafe_put_user(regs->si, &sc->si, Efault); | |
| 169 | + unsafe_put_user(regs->bp, &sc->bp, Efault); | |
| 170 | + unsafe_put_user(regs->sp, &sc->sp, Efault); | |
| 171 | + unsafe_put_user(regs->bx, &sc->bx, Efault); | |
| 172 | + unsafe_put_user(regs->dx, &sc->dx, Efault); | |
| 173 | + unsafe_put_user(regs->cx, &sc->cx, Efault); | |
| 174 | + unsafe_put_user(regs->ax, &sc->ax, Efault); | |
| 175 | + unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault); | |
| 176 | + unsafe_put_user(current->thread.error_code, &sc->err, Efault); | |
| 177 | + unsafe_put_user(regs->ip, &sc->ip, Efault); | |
| 178 | + unsafe_put_user(regs->cs, (unsigned int __user *)&sc->cs, Efault); | |
| 179 | + unsafe_put_user(regs->flags, &sc->flags, Efault); | |
| 180 | + unsafe_put_user(regs->sp, &sc->sp_at_signal, Efault); | |
| 181 | + unsafe_put_user(regs->ss, (unsigned int __user *)&sc->ss, Efault); | |
| 182 | + | |
| 183 | + unsafe_put_user(ptr_to_compat(fpstate), &sc->fpstate, Efault); | |
| 184 | + | |
| 185 | + /* non-iBCS2 extensions.. */ | |
| 186 | + unsafe_put_user(mask, &sc->oldmask, Efault); | |
| 187 | + unsafe_put_user(current->thread.cr2, &sc->cr2, Efault); | |
| 188 | + return 0; | |
| 189 | + | |
| 190 | +Efault: | |
| 191 | + return -EFAULT; | |
| 214 | 192 | } |
| 215 | 193 | |
| 194 | +#define unsafe_put_sigcontext32(sc, fp, regs, set, label) \ | |
| 195 | +do { \ | |
| 196 | + if (__unsafe_setup_sigcontext32(sc, fp, regs, set->sig[0])) \ | |
| 197 | + goto label; \ | |
| 198 | +} while(0) | |
| 199 | + | |
| 216 | 200 | /* |
| 217 | 201 | * Determine which stack to use.. |
| 218 | 202 | */ |
| @@ -252,8 +236,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, · 33 unmodified lines | ||
| 252 | 236 | { |
| 253 | 237 | struct sigframe_ia32 __user *frame; |
| 254 | 238 | void __user *restorer; |
| 255 | − int err = 0; | |
| 256 | − void __user *fpstate = NULL; | |
| 239 | + void __user *fp = NULL; | |
| 257 | 240 | |
| 258 | 241 | /* copy_to_user optimizes that into a single 8 byte store */ |
| 259 | 242 | static const struct { |
| @@ -266,22 +249,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, · 6 unmodified lines | ||
| 266 | 249 | 0x80cd, /* int $0x80 */ |
| 267 | 250 | }; |
| 268 | 251 | |
| 269 | − frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate); | |
| 270 | − | |
| 271 | − if (!access_ok(frame, sizeof(*frame))) | |
| 272 | − return -EFAULT; | |
| 273 | − | |
| 274 | − if (__put_user(sig, &frame->sig)) | |
| 275 | − return -EFAULT; | |
| 276 | − | |
| 277 | − if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0])) | |
| 278 | − return -EFAULT; | |
| 279 | − | |
| 280 | − if (_COMPAT_NSIG_WORDS > 1) { | |
| 281 | − if (__copy_to_user(frame->extramask, &set->sig[1], | |
| 282 | − sizeof(frame->extramask))) | |
| 283 | − return -EFAULT; | |
| 284 | − } | |
| 252 | + frame = get_sigframe(ksig, regs, sizeof(*frame), &fp); | |
| 285 | 253 | |
| 286 | 254 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { |
| 287 | 255 | restorer = ksig->ka.sa.sa_restorer; |
| @@ -294,19 +262,20 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, · 6 unmodified lines | ||
| 294 | 262 | restorer = &frame->retcode; |
| 295 | 263 | } |
| 296 | 264 | |
| 297 | − put_user_try { | |
| 298 | − put_user_ex(ptr_to_compat(restorer), &frame->pretcode); | |
| 299 | − | |
| 300 | − /* | |
| 301 | − * These are actually not used anymore, but left because some | |
| 302 | − * gdb versions depend on them as a marker. | |
| 303 | − */ | |
| 304 | − put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode); | |
| 305 | − } put_user_catch(err); | |
| 306 | − | |
| 307 | − if (err) | |
| 265 | + if (!user_access_begin(frame, sizeof(*frame))) | |
| 308 | 266 | return -EFAULT; |
| 309 | 267 | |
| 268 | + unsafe_put_user(sig, &frame->sig, Efault); | |
| 269 | + unsafe_put_sigcontext32(&frame->sc, fp, regs, set, Efault); | |
| 270 | + unsafe_put_user(set->sig[1], &frame->extramask[0], Efault); | |
| 271 | + unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault); | |
| 272 | + /* | |
| 273 | + * These are actually not used anymore, but left because some | |
| 274 | + * gdb versions depend on them as a marker. | |
| 275 | + */ | |
| 276 | + unsafe_put_user(*((u64 *)&code), (u64 __user *)frame->retcode, Efault); | |
| 277 | + user_access_end(); | |
| 278 | + | |
| 310 | 279 | /* Set up registers for signal handler */ |
| 311 | 280 | regs->sp = (unsigned long) frame; |
| 312 | 281 | regs->ip = (unsigned long) ksig->ka.sa.sa_handler; |
| @@ -323,6 +292,9 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, · 10 unmodified lines | ||
| 323 | 292 | regs->ss = __USER32_DS; |
| 324 | 293 | |
| 325 | 294 | return 0; |
| 295 | +Efault: | |
| 296 | + user_access_end(); | |
| 297 | + return -EFAULT; | |
| 326 | 298 | } |
| 327 | 299 | |
| 328 | 300 | int ia32_setup_rt_frame(int sig, struct ksignal *ksig, |
| @@ -330,10 +302,9 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, · 1 unmodified line | ||
| 330 | 302 | { |
| 331 | 303 | struct rt_sigframe_ia32 __user *frame; |
| 332 | 304 | void __user *restorer; |
| 333 | − int err = 0; | |
| 334 | − void __user *fpstate = NULL; | |
| 305 | + void __user *fp = NULL; | |
| 335 | 306 | |
| 336 | − /* __copy_to_user optimizes that into a single 8 byte store */ | |
| 307 | + /* unsafe_put_user optimizes that into a single 8 byte store */ | |
| 337 | 308 | static const struct { |
| 338 | 309 | u8 movl; |
| 339 | 310 | u32 val; |
| @@ -346,44 +317,40 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, · 6 unmodified lines | ||
| 346 | 317 | 0, |
| 347 | 318 | }; |
| 348 | 319 | |
| 349 | − frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate); | |
| 320 | + frame = get_sigframe(ksig, regs, sizeof(*frame), &fp); | |
| 350 | 321 | |
| 351 | − if (!access_ok(frame, sizeof(*frame))) | |
| 322 | + if (!user_access_begin(frame, sizeof(*frame))) | |
| 352 | 323 | return -EFAULT; |
| 353 | 324 | |
| 354 | − put_user_try { | |
| 355 | − put_user_ex(sig, &frame->sig); | |
| 356 | − put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo); | |
| 357 | − put_user_ex(ptr_to_compat(&frame->uc), &frame->puc); | |
| 325 | + unsafe_put_user(sig, &frame->sig, Efault); | |
| 326 | + unsafe_put_user(ptr_to_compat(&frame->info), &frame->pinfo, Efault); | |
| 327 | + unsafe_put_user(ptr_to_compat(&frame->uc), &frame->puc, Efault); | |
| 358 | 328 | |
| 359 | − /* Create the ucontext. */ | |
| 360 | − if (static_cpu_has(X86_FEATURE_XSAVE)) | |
| 361 | − put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags); | |
| 362 | − else | |
| 363 | − put_user_ex(0, &frame->uc.uc_flags); | |
| 364 | − put_user_ex(0, &frame->uc.uc_link); | |
| 365 | − compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); | |
| 329 | + /* Create the ucontext. */ | |
| 330 | + if (static_cpu_has(X86_FEATURE_XSAVE)) | |
| 331 | + unsafe_put_user(UC_FP_XSTATE, &frame->uc.uc_flags, Efault); | |
| 332 | + else | |
| 333 | + unsafe_put_user(0, &frame->uc.uc_flags, Efault); | |
| 334 | + unsafe_put_user(0, &frame->uc.uc_link, Efault); | |
| 335 | + unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); | |
| 366 | 336 | |
| 367 | − if (ksig->ka.sa.sa_flags & SA_RESTORER) | |
| 368 | − restorer = ksig->ka.sa.sa_restorer; | |
| 369 | − else | |
| 370 | − restorer = current->mm->context.vdso + | |
| 371 | − vdso_image_32.sym___kernel_rt_sigreturn; | |
| 372 | − put_user_ex(ptr_to_compat(restorer), &frame->pretcode); | |
| 373 | − | |
| 374 | − /* | |
| 375 | − * Not actually used anymore, but left because some gdb | |
| 376 | − * versions need it. | |
| 377 | − */ | |
| 378 | − put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode); | |
| 379 | − } put_user_catch(err); | |
| 380 | − | |
| 381 | − err |= __copy_siginfo_to_user32(&frame->info, &ksig->info, false); | |
| 382 | − err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate, | |
| 383 | − regs, set->sig[0]); | |
| 384 | − err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | |
| 385 | − | |
| 386 | − if (err) | |
| 337 | + if (ksig->ka.sa.sa_flags & SA_RESTORER) | |
| 338 | + restorer = ksig->ka.sa.sa_restorer; | |
| 339 | + else | |
| 340 | + restorer = current->mm->context.vdso + | |
| 341 | + vdso_image_32.sym___kernel_rt_sigreturn; | |
| 342 | + unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault); | |
| 343 | + | |
| 344 | + /* | |
| 345 | + * Not actually used anymore, but left because some gdb | |
| 346 | + * versions need it. | |
| 347 | + */ | |
| 348 | + unsafe_put_user(*((u64 *)&code), (u64 __user *)frame->retcode, Efault); | |
| 349 | + unsafe_put_sigcontext32(&frame->uc.uc_mcontext, fp, regs, set, Efault); | |
| 350 | + unsafe_put_user(*(__u64 *)set, (__u64 *)&frame->uc.uc_sigmask, Efault); | |
| 351 | + user_access_end(); | |
| 352 | + | |
| 353 | + if (__copy_siginfo_to_user32(&frame->info, &ksig->info, false)) | |
| 387 | 354 | return -EFAULT; |
| 388 | 355 | |
| 389 | 356 | /* Set up registers for signal handler */ |
| @@ -402,4 +369,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, · 12 unmodified lines | ||
| 402 | 369 | regs->ss = __USER32_DS; |
| 403 | 370 | |
| 404 | 371 | return 0; |
| 372 | +Efault: | |
| 373 | + user_access_end(); | |
| 374 | + return -EFAULT; | |
| 405 | 375 | } |
| @@ -138,9 +138,6 @@ · 137 unmodified lines | ||
| 138 | 138 | # define _ASM_EXTABLE_FAULT(from, to) \ |
| 139 | 139 | _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) |
| 140 | 140 | |
| 141 | −# define _ASM_EXTABLE_EX(from, to) \ | |
| 142 | − _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) | |
| 143 | − | |
| 144 | 141 | # define _ASM_NOKPROBE(entry) \ |
| 145 | 142 | .pushsection "_kprobe_blacklist","aw" ; \ |
| 146 | 143 | _ASM_ALIGN ; \ |
| @@ -166,9 +163,6 @@ · 19 unmodified lines | ||
| 166 | 163 | # define _ASM_EXTABLE_FAULT(from, to) \ |
| 167 | 164 | _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) |
| 168 | 165 | |
| 169 | −# define _ASM_EXTABLE_EX(from, to) \ | |
| 170 | − _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) | |
| 171 | − | |
| 172 | 166 | /* For C file, we already have NOKPROBE_SYMBOL macro */ |
| 173 | 167 | #endif |
| 174 | 168 | |
| @@ -23,6 +23,8 @@ · 22 unmodified lines | ||
| 23 | 23 | #define MWAITX_MAX_LOOPS ((u32)-1) |
| 24 | 24 | #define MWAITX_DISABLE_CSTATES 0xf0 |
| 25 | 25 | |
| 26 | +u32 get_umwait_control_msr(void); | |
| 27 | + | |
| 26 | 28 | static inline void __monitor(const void *eax, unsigned long ecx, |
| 27 | 29 | unsigned long edx) |
| 28 | 30 | { |
| @@ -595,12 +595,6 @@ static inline pmd_t pmd_mknotpresent(pmd_t pmd) · 594 unmodified lines | ||
| 595 | 595 | __pgprot(pmd_flags(pmd) & ~(_PAGE_PRESENT|_PAGE_PROTNONE))); |
| 596 | 596 | } |
| 597 | 597 | |
| 598 | −static inline pud_t pud_mknotpresent(pud_t pud) | |
| 599 | −{ | |
| 600 | − return pfn_pud(pud_pfn(pud), | |
| 601 | − __pgprot(pud_flags(pud) & ~(_PAGE_PRESENT|_PAGE_PROTNONE))); | |
| 602 | −} | |
| 603 | − | |
| 604 | 598 | static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask); |
| 605 | 599 | |
| 606 | 600 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| @@ -542,7 +542,6 @@ struct thread_struct { · 541 unmodified lines | ||
| 542 | 542 | mm_segment_t addr_limit; |
| 543 | 543 | |
| 544 | 544 | unsigned int sig_on_uaccess_err:1; |
| 545 | − unsigned int uaccess_err:1; /* uaccess failed */ | |
| 546 | 545 | |
| 547 | 546 | /* Floating point and extended processor state */ |
| 548 | 547 | struct fpu fpu; |
| @@ -46,6 +46,8 @@ int set_memory_4k(unsigned long addr, int numpages); · 45 unmodified lines | ||
| 46 | 46 | int set_memory_encrypted(unsigned long addr, int numpages); |
| 47 | 47 | int set_memory_decrypted(unsigned long addr, int numpages); |
| 48 | 48 | int set_memory_np_noalias(unsigned long addr, int numpages); |
| 49 | +int set_memory_nonglobal(unsigned long addr, int numpages); | |
| 50 | +int set_memory_global(unsigned long addr, int numpages); | |
| 49 | 51 | |
| 50 | 52 | int set_pages_array_uc(struct page **pages, int addrinarray); |
| 51 | 53 | int set_pages_array_wc(struct page **pages, int addrinarray); |
| @@ -33,11 +33,7 @@ struct sigframe_ia32 { · 32 unmodified lines | ||
| 33 | 33 | * legacy application accessing/modifying it. |
| 34 | 34 | */ |
| 35 | 35 | struct _fpstate_32 fpstate_unused; |
| 36 | −#ifdef CONFIG_IA32_EMULATION | |
| 37 | − unsigned int extramask[_COMPAT_NSIG_WORDS-1]; | |
| 38 | −#else /* !CONFIG_IA32_EMULATION */ | |
| 39 | − unsigned long extramask[_NSIG_WORDS-1]; | |
| 40 | −#endif /* CONFIG_IA32_EMULATION */ | |
| 36 | + unsigned int extramask[1]; | |
| 41 | 37 | char retcode[8]; |
| 42 | 38 | /* fp state follows here */ |
| 43 | 39 | }; |
| @@ -14,7 +14,5 @@ · 13 unmodified lines | ||
| 14 | 14 | X86_EFLAGS_CF | X86_EFLAGS_RF) |
| 15 | 15 | |
| 16 | 16 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where); |
| 17 | −int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | |
| 18 | − struct pt_regs *regs, unsigned long mask); | |
| 19 | 17 | |
| 20 | 18 | #endif /* _ASM_X86_SIGHANDLING_H */ |
| @@ -159,6 +159,11 @@ static inline int syscall_get_arch(struct task_struct *task) · 158 unmodified lines | ||
| 159 | 159 | task->thread_info.status & TS_COMPAT) |
| 160 | 160 | ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64; |
| 161 | 161 | } |
| 162 | + | |
| 163 | +void do_syscall_64(unsigned long nr, struct pt_regs *regs); | |
| 164 | +void do_int80_syscall_32(struct pt_regs *regs); | |
| 165 | +long do_fast_syscall_32(struct pt_regs *regs); | |
| 166 | + | |
| 162 | 167 | #endif /* CONFIG_X86_32 */ |
| 163 | 168 | |
| 164 | 169 | #endif /* _ASM_X86_SYSCALL_H */ |
| @@ -193,23 +193,12 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) · 192 unmodified lines | ||
| 193 | 193 | : : "A" (x), "r" (addr) \ |
| 194 | 194 | : : label) |
| 195 | 195 | |
| 196 | −#define __put_user_asm_ex_u64(x, addr) \ | |
| 197 | − asm volatile("\n" \ | |
| 198 | − "1: movl %%eax,0(%1)\n" \ | |
| 199 | − "2: movl %%edx,4(%1)\n" \ | |
| 200 | − "3:" \ | |
| 201 | − _ASM_EXTABLE_EX(1b, 2b) \ | |
| 202 | − _ASM_EXTABLE_EX(2b, 3b) \ | |
| 203 | − : : "A" (x), "r" (addr)) | |
| 204 | − | |
| 205 | 196 | #define __put_user_x8(x, ptr, __ret_pu) \ |
| 206 | 197 | asm volatile("call __put_user_8" : "=a" (__ret_pu) \ |
| 207 | 198 | : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") |
| 208 | 199 | #else |
| 209 | 200 | #define __put_user_goto_u64(x, ptr, label) \ |
| 210 | 201 | __put_user_goto(x, ptr, "q", "", "er", label) |
| 211 | −#define __put_user_asm_ex_u64(x, addr) \ | |
| 212 | − __put_user_asm_ex(x, addr, "q", "", "er") | |
| 213 | 202 | #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) |
| 214 | 203 | #endif |
| 215 | 204 | |
| @@ -289,31 +278,6 @@ do { \ · 73 unmodified lines | ||
| 289 | 278 | } \ |
| 290 | 279 | } while (0) |
| 291 | 280 | |
| 292 | −/* | |
| 293 | − * This doesn't do __uaccess_begin/end - the exception handling | |
| 294 | − * around it must do that. | |
| 295 | − */ | |
| 296 | −#define __put_user_size_ex(x, ptr, size) \ | |
| 297 | −do { \ | |
| 298 | − __chk_user_ptr(ptr); \ | |
| 299 | − switch (size) { \ | |
| 300 | − case 1: \ | |
| 301 | − __put_user_asm_ex(x, ptr, "b", "b", "iq"); \ | |
| 302 | − break; \ | |
| 303 | − case 2: \ | |
| 304 | − __put_user_asm_ex(x, ptr, "w", "w", "ir"); \ | |
| 305 | − break; \ | |
| 306 | − case 4: \ | |
| 307 | − __put_user_asm_ex(x, ptr, "l", "k", "ir"); \ | |
| 308 | − break; \ | |
| 309 | − case 8: \ | |
| 310 | − __put_user_asm_ex_u64((__typeof__(*ptr))(x), ptr); \ | |
| 311 | − break; \ | |
| 312 | − default: \ | |
| 313 | − __put_user_bad(); \ | |
| 314 | − } \ | |
| 315 | −} while (0) | |
| 316 | − | |
| 317 | 281 | #ifdef CONFIG_X86_32 |
| 318 | 282 | #define __get_user_asm_u64(x, ptr, retval, errret) \ |
| 319 | 283 | ({ \ |
| @@ -335,12 +299,9 @@ do { \ · 15 unmodified lines | ||
| 335 | 299 | "i" (errret), "0" (retval)); \ |
| 336 | 300 | }) |
| 337 | 301 | |
| 338 | −#define __get_user_asm_ex_u64(x, ptr) (x) = __get_user_bad() | |
| 339 | 302 | #else |
| 340 | 303 | #define __get_user_asm_u64(x, ptr, retval, errret) \ |
| 341 | 304 | __get_user_asm(x, ptr, retval, "q", "", "=r", errret) |
| 342 | −#define __get_user_asm_ex_u64(x, ptr) \ | |
| 343 | − __get_user_asm_ex(x, ptr, "q", "", "=r") | |
| 344 | 305 | #endif |
| 345 | 306 | |
| 346 | 307 | #define __get_user_size(x, ptr, size, retval, errret) \ |
| @@ -378,53 +339,6 @@ do { \ · 31 unmodified lines | ||
| 378 | 339 | : "=r" (err), ltype(x) \ |
| 379 | 340 | : "m" (__m(addr)), "i" (errret), "0" (err)) |
| 380 | 341 | |
| 381 | −#define __get_user_asm_nozero(x, addr, err, itype, rtype, ltype, errret) \ | |
| 382 | − asm volatile("\n" \ | |
| 383 | − "1: mov"itype" %2,%"rtype"1\n" \ | |
| 384 | − "2:\n" \ | |
| 385 | − ".section .fixup,\"ax\"\n" \ | |
| 386 | − "3: mov %3,%0\n" \ | |
| 387 | − " jmp 2b\n" \ | |
| 388 | − ".previous\n" \ | |
| 389 | − _ASM_EXTABLE_UA(1b, 3b) \ | |
| 390 | − : "=r" (err), ltype(x) \ | |
| 391 | − : "m" (__m(addr)), "i" (errret), "0" (err)) | |
| 392 | − | |
| 393 | −/* | |
| 394 | − * This doesn't do __uaccess_begin/end - the exception handling | |
| 395 | − * around it must do that. | |
| 396 | − */ | |
| 397 | −#define __get_user_size_ex(x, ptr, size) \ | |
| 398 | −do { \ | |
| 399 | − __chk_user_ptr(ptr); \ | |
| 400 | − switch (size) { \ | |
| 401 | − case 1: \ | |
| 402 | − __get_user_asm_ex(x, ptr, "b", "b", "=q"); \ | |
| 403 | − break; \ | |
| 404 | − case 2: \ | |
| 405 | − __get_user_asm_ex(x, ptr, "w", "w", "=r"); \ | |
| 406 | − break; \ | |
| 407 | − case 4: \ | |
| 408 | − __get_user_asm_ex(x, ptr, "l", "k", "=r"); \ | |
| 409 | − break; \ | |
| 410 | − case 8: \ | |
| 411 | − __get_user_asm_ex_u64(x, ptr); \ | |
| 412 | − break; \ | |
| 413 | − default: \ | |
| 414 | − (x) = __get_user_bad(); \ | |
| 415 | − } \ | |
| 416 | −} while (0) | |
| 417 | − | |
| 418 | −#define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ | |
| 419 | − asm volatile("1: mov"itype" %1,%"rtype"0\n" \ | |
| 420 | − "2:\n" \ | |
| 421 | − ".section .fixup,\"ax\"\n" \ | |
| 422 | − "3:xor"itype" %"rtype"0,%"rtype"0\n" \ | |
| 423 | − " jmp 2b\n" \ | |
| 424 | − ".previous\n" \ | |
| 425 | − _ASM_EXTABLE_EX(1b, 3b) \ | |
| 426 | − : ltype(x) : "m" (__m(addr))) | |
| 427 | − | |
| 428 | 342 | #define __put_user_nocheck(x, ptr, size) \ |
| 429 | 343 | ({ \ |
| 430 | 344 | __label__ __pu_label; \ |
| @@ -480,29 +394,6 @@ struct __large_struct { unsigned long buf[100]; }; · 49 unmodified lines | ||
| 480 | 394 | retval = __put_user_failed(x, addr, itype, rtype, ltype, errret); \ |
| 481 | 395 | } while (0) |
| 482 | 396 | |
| 483 | −#define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ | |
| 484 | − asm volatile("1: mov"itype" %"rtype"0,%1\n" \ | |
| 485 | − "2:\n" \ | |
| 486 | − _ASM_EXTABLE_EX(1b, 2b) \ | |
| 487 | − : : ltype(x), "m" (__m(addr))) | |
| 488 | − | |
| 489 | −/* | |
| 490 | − * uaccess_try and catch | |
| 491 | − */ | |
| 492 | −#define uaccess_try do { \ | |
| 493 | − current->thread.uaccess_err = 0; \ | |
| 494 | − __uaccess_begin(); \ | |
| 495 | − barrier(); | |
| 496 | − | |
| 497 | −#define uaccess_try_nospec do { \ | |
| 498 | − current->thread.uaccess_err = 0; \ | |
| 499 | − __uaccess_begin_nospec(); \ | |
| 500 | − | |
| 501 | −#define uaccess_catch(err) \ | |
| 502 | − __uaccess_end(); \ | |
| 503 | − (err) |= (current->thread.uaccess_err ? -EFAULT : 0); \ | |
| 504 | −} while (0) | |
| 505 | − | |
| 506 | 397 | /** |
| 507 | 398 | * __get_user - Get a simple variable from user space, with less checking. |
| 508 | 399 | * @x: Variable to store result. |
| @@ -552,28 +443,6 @@ struct __large_struct { unsigned long buf[100]; }; · 43 unmodified lines | ||
| 552 | 443 | #define __put_user(x, ptr) \ |
| 553 | 444 | __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) |
| 554 | 445 | |
| 555 | −/* | |
| 556 | − * {get|put}_user_try and catch | |
| 557 | − * | |
| 558 | − * get_user_try { | |
| 559 | − * get_user_ex(...); | |
| 560 | − * } get_user_catch(err) | |
| 561 | − */ | |
| 562 | −#define get_user_try uaccess_try_nospec | |
| 563 | −#define get_user_catch(err) uaccess_catch(err) | |
| 564 | − | |
| 565 | −#define get_user_ex(x, ptr) do { \ | |
| 566 | − unsigned long __gue_val; \ | |
| 567 | − __get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr)))); \ | |
| 568 | − (x) = (__force __typeof__(*(ptr)))__gue_val; \ | |
| 569 | −} while (0) | |
| 570 | − | |
| 571 | −#define put_user_try uaccess_try | |
| 572 | −#define put_user_catch(err) uaccess_catch(err) | |
| 573 | − | |
| 574 | −#define put_user_ex(x, ptr) \ | |
| 575 | − __put_user_size_ex((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) | |
| 576 | − | |
| 577 | 446 | extern unsigned long |
| 578 | 447 | copy_from_user_nmi(void *to, const void __user *from, unsigned long n); |
| 579 | 448 | extern __must_check long |
| @@ -601,15 +470,6 @@ extern struct movsl_mask { · 21 unmodified lines | ||
| 601 | 470 | # include <asm/uaccess_64.h> |
| 602 | 471 | #endif |
| 603 | 472 | |
| 604 | −/* | |
| 605 | − * We rely on the nested NMI work to allow atomic faults from the NMI path; the | |
| 606 | − * nested NMI paths are careful to preserve CR2. | |
| 607 | − * | |
| 608 | − * Caller must use pagefault_enable/disable, or run in interrupt context, | |
| 609 | − * and also do a uaccess_ok() check | |
| 610 | − */ | |
| 611 | −#define __copy_from_user_nmi __copy_from_user_inatomic | |
| 612 | − | |
| 613 | 473 | /* |
| 614 | 474 | * The "unsafe" user accesses aren't really "unsafe", but the naming |
| 615 | 475 | * is a big fat warning: you have to not only do the access_ok() |
| @@ -23,33 +23,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n) · 22 unmodified lines | ||
| 23 | 23 | static __always_inline unsigned long |
| 24 | 24 | raw_copy_from_user(void *to, const void __user *from, unsigned long n) |
| 25 | 25 | { |
| 26 | − if (__builtin_constant_p(n)) { | |
| 27 | − unsigned long ret; | |
| 28 | − | |
| 29 | − switch (n) { | |
| 30 | − case 1: | |
| 31 | − ret = 0; | |
| 32 | − __uaccess_begin_nospec(); | |
| 33 | − __get_user_asm_nozero(*(u8 *)to, from, ret, | |
| 34 | − "b", "b", "=q", 1); | |
| 35 | − __uaccess_end(); | |
| 36 | − return ret; | |
| 37 | − case 2: | |
| 38 | − ret = 0; | |
| 39 | − __uaccess_begin_nospec(); | |
| 40 | − __get_user_asm_nozero(*(u16 *)to, from, ret, | |
| 41 | − "w", "w", "=r", 2); | |
| 42 | − __uaccess_end(); | |
| 43 | − return ret; | |
| 44 | − case 4: | |
| 45 | − ret = 0; | |
| 46 | − __uaccess_begin_nospec(); | |
| 47 | − __get_user_asm_nozero(*(u32 *)to, from, ret, | |
| 48 | − "l", "k", "=r", 4); | |
| 49 | − __uaccess_end(); | |
| 50 | − return ret; | |
| 51 | − } | |
| 52 | − } | |
| 53 | 26 | return __copy_user_ll(to, (__force const void *)from, n); |
| 54 | 27 | } |
| 55 | 28 | |
| @@ -65,117 +65,13 @@ copy_to_user_mcsafe(void *to, const void *from, unsigned len) · 64 unmodified lines | ||
| 65 | 65 | static __always_inline __must_check unsigned long |
| 66 | 66 | raw_copy_from_user(void *dst, const void __user *src, unsigned long size) |
| 67 | 67 | { |
| 68 | − int ret = 0; | |
| 69 | − | |
| 70 | − if (!__builtin_constant_p(size)) | |
| 71 | − return copy_user_generic(dst, (__force void *)src, size); | |
| 72 | − switch (size) { | |
| 73 | − case 1: | |
| 74 | − __uaccess_begin_nospec(); | |
| 75 | − __get_user_asm_nozero(*(u8 *)dst, (u8 __user *)src, | |
| 76 | − ret, "b", "b", "=q", 1); | |
| 77 | − __uaccess_end(); | |
| 78 | − return ret; | |
| 79 | − case 2: | |
| 80 | − __uaccess_begin_nospec(); | |
| 81 | − __get_user_asm_nozero(*(u16 *)dst, (u16 __user *)src, | |
| 82 | − ret, "w", "w", "=r", 2); | |
| 83 | − __uaccess_end(); | |
| 84 | − return ret; | |
| 85 | − case 4: | |
| 86 | − __uaccess_begin_nospec(); | |
| 87 | − __get_user_asm_nozero(*(u32 *)dst, (u32 __user *)src, | |
| 88 | − ret, "l", "k", "=r", 4); | |
| 89 | − __uaccess_end(); | |
| 90 | − return ret; | |
| 91 | − case 8: | |
| 92 | − __uaccess_begin_nospec(); | |
| 93 | − __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, | |
| 94 | − ret, "q", "", "=r", 8); | |
| 95 | − __uaccess_end(); | |
| 96 | − return ret; | |
| 97 | − case 10: | |
| 98 | − __uaccess_begin_nospec(); | |
| 99 | − __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, | |
| 100 | − ret, "q", "", "=r", 10); | |
| 101 | − if (likely(!ret)) | |
| 102 | − __get_user_asm_nozero(*(u16 *)(8 + (char *)dst), | |
| 103 | − (u16 __user *)(8 + (char __user *)src), | |
| 104 | − ret, "w", "w", "=r", 2); | |
| 105 | − __uaccess_end(); | |
| 106 | − return ret; | |
| 107 | − case 16: | |
| 108 | − __uaccess_begin_nospec(); | |
| 109 | − __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, | |
| 110 | − ret, "q", "", "=r", 16); | |
| 111 | − if (likely(!ret)) | |
| 112 | − __get_user_asm_nozero(*(u64 *)(8 + (char *)dst), | |
| 113 | − (u64 __user *)(8 + (char __user *)src), | |
| 114 | − ret, "q", "", "=r", 8); | |
| 115 | − __uaccess_end(); | |
| 116 | − return ret; | |
| 117 | − default: | |
| 118 | − return copy_user_generic(dst, (__force void *)src, size); | |
| 119 | − } | |
| 68 | + return copy_user_generic(dst, (__force void *)src, size); | |
| 120 | 69 | } |
| 121 | 70 | |
| 122 | 71 | static __always_inline __must_check unsigned long |
| 123 | 72 | raw_copy_to_user(void __user *dst, const void *src, unsigned long size) |
| 124 | 73 | { |
| 125 | − int ret = 0; | |
| 126 | − | |
| 127 | − if (!__builtin_constant_p(size)) | |
| 128 | − return copy_user_generic((__force void *)dst, src, size); | |
| 129 | − switch (size) { | |
| 130 | − case 1: | |
| 131 | − __uaccess_begin(); | |
| 132 | − __put_user_asm(*(u8 *)src, (u8 __user *)dst, | |
| 133 | − ret, "b", "b", "iq", 1); | |
| 134 | − __uaccess_end(); | |
| 135 | − return ret; | |
| 136 | − case 2: | |
| 137 | − __uaccess_begin(); | |
| 138 | − __put_user_asm(*(u16 *)src, (u16 __user *)dst, | |
| 139 | − ret, "w", "w", "ir", 2); | |
| 140 | − __uaccess_end(); | |
| 141 | − return ret; | |
| 142 | − case 4: | |
| 143 | − __uaccess_begin(); | |
| 144 | − __put_user_asm(*(u32 *)src, (u32 __user *)dst, | |
| 145 | − ret, "l", "k", "ir", 4); | |
| 146 | − __uaccess_end(); | |
| 147 | − return ret; | |
| 148 | − case 8: | |
| 149 | − __uaccess_begin(); | |
| 150 | − __put_user_asm(*(u64 *)src, (u64 __user *)dst, | |
| 151 | − ret, "q", "", "er", 8); | |
| 152 | − __uaccess_end(); | |
| 153 | − return ret; | |
| 154 | − case 10: | |
| 155 | − __uaccess_begin(); | |
| 156 | − __put_user_asm(*(u64 *)src, (u64 __user *)dst, | |
| 157 | − ret, "q", "", "er", 10); | |
| 158 | − if (likely(!ret)) { | |
| 159 | − asm("":::"memory"); | |
| 160 | − __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst, | |
| 161 | − ret, "w", "w", "ir", 2); | |
| 162 | − } | |
| 163 | − __uaccess_end(); | |
| 164 | − return ret; | |
| 165 | − case 16: | |
| 166 | − __uaccess_begin(); | |
| 167 | − __put_user_asm(*(u64 *)src, (u64 __user *)dst, | |
| 168 | − ret, "q", "", "er", 16); | |
| 169 | − if (likely(!ret)) { | |
| 170 | − asm("":::"memory"); | |
| 171 | − __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst, | |
| 172 | − ret, "q", "", "er", 8); | |
| 173 | − } | |
| 174 | − __uaccess_end(); | |
| 175 | − return ret; | |
| 176 | − default: | |
| 177 | − return copy_user_generic((__force void *)dst, src, size); | |
| 178 | − } | |
| 74 | + return copy_user_generic((__force void *)dst, src, size); | |
| 179 | 75 | } |
| 180 | 76 | |
| 181 | 77 | static __always_inline __must_check |
| @@ -858,4 +858,6 @@ static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) · 857 unmodified lines | ||
| 858 | 858 | return 1; |
| 859 | 859 | } |
| 860 | 860 | |
| 861 | +void uv_bau_message_interrupt(struct pt_regs *regs); | |
| 862 | + | |
| 861 | 863 | #endif /* _ASM_X86_UV_UV_BAU_H */ |
| @@ -1167,8 +1167,8 @@ static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries · 1166 unmodified lines | ||
| 1167 | 1167 | atomic_cond_read_acquire(&desc.refs, !VAL); |
| 1168 | 1168 | } |
| 1169 | 1169 | |
| 1170 | −void text_poke_loc_init(struct text_poke_loc *tp, void *addr, | |
| 1171 | − const void *opcode, size_t len, const void *emulate) | |
| 1170 | +static void text_poke_loc_init(struct text_poke_loc *tp, void *addr, | |
| 1171 | + const void *opcode, size_t len, const void *emulate) | |
| 1172 | 1172 | { |
| 1173 | 1173 | struct insn insn; |
| 1174 | 1174 | |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <asm/msr-index.h> |
| 6 | 6 | #include <asm/processor.h> |
| 7 | 7 | #include <asm/vmx.h> |
| 8 | +#include "cpu.h" | |
| 8 | 9 | |
| 9 | 10 | #undef pr_fmt |
| 10 | 11 | #define pr_fmt(fmt) "x86/cpu: " fmt |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/cpu.h> |
| 5 | 5 | |
| 6 | 6 | #include <asm/msr.h> |
| 7 | +#include <asm/mwait.h> | |
| 7 | 8 | |
| 8 | 9 | #define UMWAIT_C02_ENABLE 0 |
| 9 | 10 | |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | #include <asm/io_bitmap.h> |
| 15 | 15 | #include <asm/desc.h> |
| 16 | +#include <asm/syscalls.h> | |
| 16 | 17 | |
| 17 | 18 | #ifdef CONFIG_X86_IOPL_IOPERM |
| 18 | 19 | |
| @@ -44,15 +44,6 @@ · 43 unmodified lines | ||
| 44 | 44 | * (these are usually mapped into the 0x30-0xff vector range) |
| 45 | 45 | */ |
| 46 | 46 | |
| 47 | −/* | |
| 48 | − * IRQ2 is cascade interrupt to second interrupt controller | |
| 49 | − */ | |
| 50 | −static struct irqaction irq2 = { | |
| 51 | − .handler = no_action, | |
| 52 | − .name = "cascade", | |
| 53 | − .flags = IRQF_NO_THREAD, | |
| 54 | −}; | |
| 55 | − | |
| 56 | 47 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
| 57 | 48 | [0 ... NR_VECTORS - 1] = VECTOR_UNUSED, |
| 58 | 49 | }; |
| @@ -84,7 +75,7 @@ void __init init_IRQ(void) · 25 unmodified lines | ||
| 84 | 75 | * On cpu 0, Assign ISA_IRQ_VECTOR(irq) to IRQ 0..15. |
| 85 | 76 | * If these IRQ's are handled by legacy interrupt-controllers like PIC, |
| 86 | 77 | * then this configuration will likely be static after the boot. If |
| 87 | − * these IRQ's are handled by more mordern controllers like IO-APIC, | |
| 78 | + * these IRQs are handled by more modern controllers like IO-APIC, | |
| 88 | 79 | * then this vector space can be freed and re-used dynamically as the |
| 89 | 80 | * irq's migrate etc. |
| 90 | 81 | */ |
| @@ -104,6 +95,9 @@ void __init native_init_IRQ(void) · 13 unmodified lines | ||
| 104 | 95 | idt_setup_apic_and_irq_gates(); |
| 105 | 96 | lapic_assign_system_vectors(); |
| 106 | 97 | |
| 107 | − if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) | |
| 108 | − setup_irq(2, &irq2); | |
| 98 | + if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) { | |
| 99 | + /* IRQ2 is cascade interrupt to second interrupt controller */ | |
| 100 | + if (request_irq(2, no_action, IRQF_NO_THREAD, "cascade", NULL)) | |
| 101 | + pr_err("%s: request_irq() failed\n", "cascade"); | |
| 102 | + } | |
| 109 | 103 | } |
| @@ -58,7 +58,7 @@ __jump_label_set_jump_code(struct jump_entry *entry, enum jump_label_type type, · 57 unmodified lines | ||
| 58 | 58 | return code; |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | −static void inline __jump_label_transform(struct jump_entry *entry, | |
| 61 | +static inline void __jump_label_transform(struct jump_entry *entry, | |
| 62 | 62 | enum jump_label_type type, |
| 63 | 63 | int init) |
| 64 | 64 | { |
| @@ -403,9 +403,9 @@ static void default_do_nmi(struct pt_regs *regs) · 402 unmodified lines | ||
| 403 | 403 | * a 'real' unknown NMI. For example, while processing |
| 404 | 404 | * a perf NMI another perf NMI comes in along with a |
| 405 | 405 | * 'real' unknown NMI. These two NMIs get combined into |
| 406 | − * one (as descibed above). When the next NMI gets | |
| 406 | + * one (as described above). When the next NMI gets | |
| 407 | 407 | * processed, it will be flagged by perf as handled, but |
| 408 | − * noone will know that there was a 'real' unknown NMI sent | |
| 408 | + * no one will know that there was a 'real' unknown NMI sent | |
| 409 | 409 | * also. As a result it gets swallowed. Or if the first |
| 410 | 410 | * perf NMI returns two events handled then the second |
| 411 | 411 | * NMI will get eaten by the logic below, again losing a |
| @@ -531,7 +531,7 @@ static void emergency_vmx_disable_all(void) · 530 unmodified lines | ||
| 531 | 531 | |
| 532 | 532 | /* |
| 533 | 533 | * We need to disable VMX on all CPUs before rebooting, otherwise |
| 534 | − * we risk hanging up the machine, because the CPU ignore INIT | |
| 534 | + * we risk hanging up the machine, because the CPU ignores INIT | |
| 535 | 535 | * signals when VMX is enabled. |
| 536 | 536 | * |
| 537 | 537 | * We can't take any locks and we may be on an inconsistent |
| @@ -45,24 +45,6 @@ · 44 unmodified lines | ||
| 45 | 45 | #include <asm/sigframe.h> |
| 46 | 46 | #include <asm/signal.h> |
| 47 | 47 | |
| 48 | −#define COPY(x) do { \ | |
| 49 | − get_user_ex(regs->x, &sc->x); \ | |
| 50 | −} while (0) | |
| 51 | − | |
| 52 | −#define GET_SEG(seg) ({ \ | |
| 53 | − unsigned short tmp; \ | |
| 54 | − get_user_ex(tmp, &sc->seg); \ | |
| 55 | − tmp; \ | |
| 56 | −}) | |
| 57 | − | |
| 58 | −#define COPY_SEG(seg) do { \ | |
| 59 | − regs->seg = GET_SEG(seg); \ | |
| 60 | −} while (0) | |
| 61 | − | |
| 62 | −#define COPY_SEG_CPL3(seg) do { \ | |
| 63 | − regs->seg = GET_SEG(seg) | 3; \ | |
| 64 | −} while (0) | |
| 65 | − | |
| 66 | 48 | #ifdef CONFIG_X86_64 |
| 67 | 49 | /* |
| 68 | 50 | * If regs->ss will cause an IRET fault, change it. Otherwise leave it |
| @@ -90,53 +72,58 @@ static void force_valid_ss(struct pt_regs *regs) · 21 unmodified lines | ||
| 90 | 72 | ar != (AR_DPL3 | AR_S | AR_P | AR_TYPE_RWDATA_EXPDOWN)) |
| 91 | 73 | regs->ss = __USER_DS; |
| 92 | 74 | } |
| 75 | +# define CONTEXT_COPY_SIZE offsetof(struct sigcontext, reserved1) | |
| 76 | +#else | |
| 77 | +# define CONTEXT_COPY_SIZE sizeof(struct sigcontext) | |
| 93 | 78 | #endif |
| 94 | 79 | |
| 95 | 80 | static int restore_sigcontext(struct pt_regs *regs, |
| 96 | − struct sigcontext __user *sc, | |
| 81 | + struct sigcontext __user *usc, | |
| 97 | 82 | unsigned long uc_flags) |
| 98 | 83 | { |
| 99 | − unsigned long buf_val; | |
| 100 | − void __user *buf; | |
| 101 | − unsigned int tmpflags; | |
| 102 | − unsigned int err = 0; | |
| 84 | + struct sigcontext sc; | |
| 103 | 85 | |
| 104 | 86 | /* Always make any pending restarted system calls return -EINTR */ |
| 105 | 87 | current->restart_block.fn = do_no_restart_syscall; |
| 106 | 88 | |
| 107 | − get_user_try { | |
| 89 | + if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE)) | |
| 90 | + return -EFAULT; | |
| 108 | 91 | |
| 109 | 92 | #ifdef CONFIG_X86_32 |
| 110 | − set_user_gs(regs, GET_SEG(gs)); | |
| 111 | − COPY_SEG(fs); | |
| 112 | − COPY_SEG(es); | |
| 113 | − COPY_SEG(ds); | |
| 93 | + set_user_gs(regs, sc.gs); | |
| 94 | + regs->fs = sc.fs; | |
| 95 | + regs->es = sc.es; | |
| 96 | + regs->ds = sc.ds; | |
| 114 | 97 | #endif /* CONFIG_X86_32 */ |
| 115 | 98 | |
| 116 | − COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); | |
| 117 | − COPY(dx); COPY(cx); COPY(ip); COPY(ax); | |
| 99 | + regs->bx = sc.bx; | |
| 100 | + regs->cx = sc.cx; | |
| 101 | + regs->dx = sc.dx; | |
| 102 | + regs->si = sc.si; | |
| 103 | + regs->di = sc.di; | |
| 104 | + regs->bp = sc.bp; | |
| 105 | + regs->ax = sc.ax; | |
| 106 | + regs->sp = sc.sp; | |
| 107 | + regs->ip = sc.ip; | |
| 118 | 108 | |
| 119 | 109 | #ifdef CONFIG_X86_64 |
| 120 | − COPY(r8); | |
| 121 | − COPY(r9); | |
| 122 | − COPY(r10); | |
| 123 | − COPY(r11); | |
| 124 | − COPY(r12); | |
| 125 | − COPY(r13); | |
| 126 | − COPY(r14); | |
| 127 | − COPY(r15); | |
| 110 | + regs->r8 = sc.r8; | |
| 111 | + regs->r9 = sc.r9; | |
| 112 | + regs->r10 = sc.r10; | |
| 113 | + regs->r11 = sc.r11; | |
| 114 | + regs->r12 = sc.r12; | |
| 115 | + regs->r13 = sc.r13; | |
| 116 | + regs->r14 = sc.r14; | |
| 117 | + regs->r15 = sc.r15; | |
| 128 | 118 | #endif /* CONFIG_X86_64 */ |
| 129 | 119 | |
| 130 | − COPY_SEG_CPL3(cs); | |
| 131 | − COPY_SEG_CPL3(ss); | |
| 132 | − | |
| 133 | − get_user_ex(tmpflags, &sc->flags); | |
| 134 | − regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); | |
| 135 | − regs->orig_ax = -1; /* disable syscall checks */ | |
| 120 | + /* Get CS/SS and force CPL3 */ | |
| 121 | + regs->cs = sc.cs | 0x03; | |
| 122 | + regs->ss = sc.ss | 0x03; | |
| 136 | 123 | |
| 137 | − get_user_ex(buf_val, &sc->fpstate); | |
| 138 | − buf = (void __user *)buf_val; | |
| 139 | − } get_user_catch(err); | |
| 124 | + regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS); | |
| 125 | + /* disable syscall checks */ | |
| 126 | + regs->orig_ax = -1; | |
| 140 | 127 | |
| 141 | 128 | #ifdef CONFIG_X86_64 |
| 142 | 129 | /* |
| @@ -147,70 +134,78 @@ static int restore_sigcontext(struct pt_regs *regs, · 4 unmodified lines | ||
| 147 | 134 | force_valid_ss(regs); |
| 148 | 135 | #endif |
| 149 | 136 | |
| 150 | − err |= fpu__restore_sig(buf, IS_ENABLED(CONFIG_X86_32)); | |
| 151 | − | |
| 152 | − return err; | |
| 137 | + return fpu__restore_sig((void __user *)sc.fpstate, | |
| 138 | + IS_ENABLED(CONFIG_X86_32)); | |
| 153 | 139 | } |
| 154 | 140 | |
| 155 | −int setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | |
| 141 | +static __always_inline int | |
| 142 | +__unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | |
| 156 | 143 | struct pt_regs *regs, unsigned long mask) |
| 157 | 144 | { |
| 158 | − int err = 0; | |
| 159 | − | |
| 160 | − put_user_try { | |
| 161 | − | |
| 162 | 145 | #ifdef CONFIG_X86_32 |
| 163 | − put_user_ex(get_user_gs(regs), (unsigned int __user *)&sc->gs); | |
| 164 | − put_user_ex(regs->fs, (unsigned int __user *)&sc->fs); | |
| 165 | − put_user_ex(regs->es, (unsigned int __user *)&sc->es); | |
| 166 | − put_user_ex(regs->ds, (unsigned int __user *)&sc->ds); | |
| 146 | + unsafe_put_user(get_user_gs(regs), | |
| 147 | + (unsigned int __user *)&sc->gs, Efault); | |
| 148 | + unsafe_put_user(regs->fs, (unsigned int __user *)&sc->fs, Efault); | |
| 149 | + unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault); | |
| 150 | + unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault); | |
| 167 | 151 | #endif /* CONFIG_X86_32 */ |
| 168 | 152 | |
| 169 | − put_user_ex(regs->di, &sc->di); | |
| 170 | − put_user_ex(regs->si, &sc->si); | |
| 171 | − put_user_ex(regs->bp, &sc->bp); | |
| 172 | − put_user_ex(regs->sp, &sc->sp); | |
| 173 | − put_user_ex(regs->bx, &sc->bx); | |
| 174 | − put_user_ex(regs->dx, &sc->dx); | |
| 175 | − put_user_ex(regs->cx, &sc->cx); | |
| 176 | − put_user_ex(regs->ax, &sc->ax); | |
| 153 | + unsafe_put_user(regs->di, &sc->di, Efault); | |
| 154 | + unsafe_put_user(regs->si, &sc->si, Efault); | |
| 155 | + unsafe_put_user(regs->bp, &sc->bp, Efault); | |
| 156 | + unsafe_put_user(regs->sp, &sc->sp, Efault); | |
| 157 | + unsafe_put_user(regs->bx, &sc->bx, Efault); | |
| 158 | + unsafe_put_user(regs->dx, &sc->dx, Efault); | |
| 159 | + unsafe_put_user(regs->cx, &sc->cx, Efault); | |
| 160 | + unsafe_put_user(regs->ax, &sc->ax, Efault); | |
| 177 | 161 | #ifdef CONFIG_X86_64 |
| 178 | − put_user_ex(regs->r8, &sc->r8); | |
| 179 | − put_user_ex(regs->r9, &sc->r9); | |
| 180 | − put_user_ex(regs->r10, &sc->r10); | |
| 181 | − put_user_ex(regs->r11, &sc->r11); | |
| 182 | − put_user_ex(regs->r12, &sc->r12); | |
| 183 | − put_user_ex(regs->r13, &sc->r13); | |
| 184 | − put_user_ex(regs->r14, &sc->r14); | |
| 185 | − put_user_ex(regs->r15, &sc->r15); | |
| 162 | + unsafe_put_user(regs->r8, &sc->r8, Efault); | |
| 163 | + unsafe_put_user(regs->r9, &sc->r9, Efault); | |
| 164 | + unsafe_put_user(regs->r10, &sc->r10, Efault); | |
| 165 | + unsafe_put_user(regs->r11, &sc->r11, Efault); | |
| 166 | + unsafe_put_user(regs->r12, &sc->r12, Efault); | |
| 167 | + unsafe_put_user(regs->r13, &sc->r13, Efault); | |
| 168 | + unsafe_put_user(regs->r14, &sc->r14, Efault); | |
| 169 | + unsafe_put_user(regs->r15, &sc->r15, Efault); | |
| 186 | 170 | #endif /* CONFIG_X86_64 */ |
| 187 | 171 | |
| 188 | − put_user_ex(current->thread.trap_nr, &sc->trapno); | |
| 189 | − put_user_ex(current->thread.error_code, &sc->err); | |
| 190 | − put_user_ex(regs->ip, &sc->ip); | |
| 172 | + unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault); | |
| 173 | + unsafe_put_user(current->thread.error_code, &sc->err, Efault); | |
| 174 | + unsafe_put_user(regs->ip, &sc->ip, Efault); | |
| 191 | 175 | #ifdef CONFIG_X86_32 |
| 192 | − put_user_ex(regs->cs, (unsigned int __user *)&sc->cs); | |
| 193 | − put_user_ex(regs->flags, &sc->flags); | |
| 194 | − put_user_ex(regs->sp, &sc->sp_at_signal); | |
| 195 | − put_user_ex(regs->ss, (unsigned int __user *)&sc->ss); | |
| 176 | + unsafe_put_user(regs->cs, (unsigned int __user *)&sc->cs, Efault); | |
| 177 | + unsafe_put_user(regs->flags, &sc->flags, Efault); | |
| 178 | + unsafe_put_user(regs->sp, &sc->sp_at_signal, Efault); | |
| 179 | + unsafe_put_user(regs->ss, (unsigned int __user *)&sc->ss, Efault); | |
| 196 | 180 | #else /* !CONFIG_X86_32 */ |
| 197 | − put_user_ex(regs->flags, &sc->flags); | |
| 198 | − put_user_ex(regs->cs, &sc->cs); | |
| 199 | − put_user_ex(0, &sc->gs); | |
| 200 | − put_user_ex(0, &sc->fs); | |
| 201 | − put_user_ex(regs->ss, &sc->ss); | |
| 181 | + unsafe_put_user(regs->flags, &sc->flags, Efault); | |
| 182 | + unsafe_put_user(regs->cs, &sc->cs, Efault); | |
| 183 | + unsafe_put_user(0, &sc->gs, Efault); | |
| 184 | + unsafe_put_user(0, &sc->fs, Efault); | |
| 185 | + unsafe_put_user(regs->ss, &sc->ss, Efault); | |
| 202 | 186 | #endif /* CONFIG_X86_32 */ |
| 203 | 187 | |
| 204 | − put_user_ex(fpstate, (unsigned long __user *)&sc->fpstate); | |
| 188 | + unsafe_put_user(fpstate, (unsigned long __user *)&sc->fpstate, Efault); | |
| 205 | 189 | |
| 206 | − /* non-iBCS2 extensions.. */ | |
| 207 | − put_user_ex(mask, &sc->oldmask); | |
| 208 | − put_user_ex(current->thread.cr2, &sc->cr2); | |
| 209 | − } put_user_catch(err); | |
| 210 | − | |
| 211 | − return err; | |
| 190 | + /* non-iBCS2 extensions.. */ | |
| 191 | + unsafe_put_user(mask, &sc->oldmask, Efault); | |
| 192 | + unsafe_put_user(current->thread.cr2, &sc->cr2, Efault); | |
| 193 | + return 0; | |
| 194 | +Efault: | |
| 195 | + return -EFAULT; | |
| 212 | 196 | } |
| 213 | 197 | |
| 198 | +#define unsafe_put_sigcontext(sc, fp, regs, set, label) \ | |
| 199 | +do { \ | |
| 200 | + if (__unsafe_setup_sigcontext(sc, fp, regs, set->sig[0])) \ | |
| 201 | + goto label; \ | |
| 202 | +} while(0); | |
| 203 | + | |
| 204 | +#define unsafe_put_sigmask(set, frame, label) \ | |
| 205 | + unsafe_put_user(*(__u64 *)(set), \ | |
| 206 | + (__u64 __user *)&(frame)->uc.uc_sigmask, \ | |
| 207 | + label) | |
| 208 | + | |
| 214 | 209 | /* |
| 215 | 210 | * Set up a signal frame. |
| 216 | 211 | */ |
| @@ -310,26 +305,16 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set, · 93 unmodified lines | ||
| 310 | 305 | { |
| 311 | 306 | struct sigframe __user *frame; |
| 312 | 307 | void __user *restorer; |
| 313 | − int err = 0; | |
| 314 | − void __user *fpstate = NULL; | |
| 315 | − | |
| 316 | − frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate); | |
| 308 | + void __user *fp = NULL; | |
| 317 | 309 | |
| 318 | − if (!access_ok(frame, sizeof(*frame))) | |
| 319 | − return -EFAULT; | |
| 310 | + frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp); | |
| 320 | 311 | |
| 321 | − if (__put_user(sig, &frame->sig)) | |
| 312 | + if (!user_access_begin(frame, sizeof(*frame))) | |
| 322 | 313 | return -EFAULT; |
| 323 | 314 | |
| 324 | − if (setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0])) | |
| 325 | − return -EFAULT; | |
| 326 | − | |
| 327 | − if (_NSIG_WORDS > 1) { | |
| 328 | − if (__copy_to_user(&frame->extramask, &set->sig[1], | |
| 329 | − sizeof(frame->extramask))) | |
| 330 | − return -EFAULT; | |
| 331 | − } | |
| 332 | − | |
| 315 | + unsafe_put_user(sig, &frame->sig, Efault); | |
| 316 | + unsafe_put_sigcontext(&frame->sc, fp, regs, set, Efault); | |
| 317 | + unsafe_put_user(set->sig[1], &frame->extramask[0], Efault); | |
| 333 | 318 | if (current->mm->context.vdso) |
| 334 | 319 | restorer = current->mm->context.vdso + |
| 335 | 320 | vdso_image_32.sym___kernel_sigreturn; |
| @@ -339,7 +324,7 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set, · 3 unmodified lines | ||
| 339 | 324 | restorer = ksig->ka.sa.sa_restorer; |
| 340 | 325 | |
| 341 | 326 | /* Set up to return from userspace. */ |
| 342 | − err |= __put_user(restorer, &frame->pretcode); | |
| 327 | + unsafe_put_user(restorer, &frame->pretcode, Efault); | |
| 343 | 328 | |
| 344 | 329 | /* |
| 345 | 330 | * This is popl %eax ; movl $__NR_sigreturn, %eax ; int $0x80 |
| @@ -348,10 +333,8 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set, · 2 unmodified lines | ||
| 348 | 333 | * reasons and because gdb uses it as a signature to notice |
| 349 | 334 | * signal handler stack frames. |
| 350 | 335 | */ |
| 351 | − err |= __put_user(*((u64 *)&retcode), (u64 *)frame->retcode); | |
| 352 | − | |
| 353 | − if (err) | |
| 354 | − return -EFAULT; | |
| 336 | + unsafe_put_user(*((u64 *)&retcode), (u64 *)frame->retcode, Efault); | |
| 337 | + user_access_end(); | |
| 355 | 338 | |
| 356 | 339 | /* Set up registers for signal handler */ |
| 357 | 340 | regs->sp = (unsigned long)frame; |
| @@ -366,6 +349,10 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set, · 8 unmodified lines | ||
| 366 | 349 | regs->cs = __USER_CS; |
| 367 | 350 | |
| 368 | 351 | return 0; |
| 352 | + | |
| 353 | +Efault: | |
| 354 | + user_access_end(); | |
| 355 | + return -EFAULT; | |
| 369 | 356 | } |
| 370 | 357 | |
| 371 | 358 | static int __setup_rt_frame(int sig, struct ksignal *ksig, |
| @@ -373,50 +360,45 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, · 1 unmodified line | ||
| 373 | 360 | { |
| 374 | 361 | struct rt_sigframe __user *frame; |
| 375 | 362 | void __user *restorer; |
| 376 | − int err = 0; | |
| 377 | − void __user *fpstate = NULL; | |
| 363 | + void __user *fp = NULL; | |
| 378 | 364 | |
| 379 | − frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate); | |
| 365 | + frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp); | |
| 380 | 366 | |
| 381 | − if (!access_ok(frame, sizeof(*frame))) | |
| 367 | + if (!user_access_begin(frame, sizeof(*frame))) | |
| 382 | 368 | return -EFAULT; |
| 383 | 369 | |
| 384 | − put_user_try { | |
| 385 | − put_user_ex(sig, &frame->sig); | |
| 386 | − put_user_ex(&frame->info, &frame->pinfo); | |
| 387 | − put_user_ex(&frame->uc, &frame->puc); | |
| 370 | + unsafe_put_user(sig, &frame->sig, Efault); | |
| 371 | + unsafe_put_user(&frame->info, &frame->pinfo, Efault); | |
| 372 | + unsafe_put_user(&frame->uc, &frame->puc, Efault); | |
| 388 | 373 | |
| 389 | − /* Create the ucontext. */ | |
| 390 | − if (static_cpu_has(X86_FEATURE_XSAVE)) | |
| 391 | − put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags); | |
| 392 | − else | |
| 393 | − put_user_ex(0, &frame->uc.uc_flags); | |
| 394 | − put_user_ex(0, &frame->uc.uc_link); | |
| 395 | − save_altstack_ex(&frame->uc.uc_stack, regs->sp); | |
| 374 | + /* Create the ucontext. */ | |
| 375 | + if (static_cpu_has(X86_FEATURE_XSAVE)) | |
| 376 | + unsafe_put_user(UC_FP_XSTATE, &frame->uc.uc_flags, Efault); | |
| 377 | + else | |
| 378 | + unsafe_put_user(0, &frame->uc.uc_flags, Efault); | |
| 379 | + unsafe_put_user(0, &frame->uc.uc_link, Efault); | |
| 380 | + unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); | |
| 396 | 381 | |
| 397 | − /* Set up to return from userspace. */ | |
| 398 | − restorer = current->mm->context.vdso + | |
| 399 | − vdso_image_32.sym___kernel_rt_sigreturn; | |
| 400 | − if (ksig->ka.sa.sa_flags & SA_RESTORER) | |
| 401 | − restorer = ksig->ka.sa.sa_restorer; | |
| 402 | − put_user_ex(restorer, &frame->pretcode); | |
| 382 | + /* Set up to return from userspace. */ | |
| 383 | + restorer = current->mm->context.vdso + | |
| 384 | + vdso_image_32.sym___kernel_rt_sigreturn; | |
| 385 | + if (ksig->ka.sa.sa_flags & SA_RESTORER) | |
| 386 | + restorer = ksig->ka.sa.sa_restorer; | |
| 387 | + unsafe_put_user(restorer, &frame->pretcode, Efault); | |
| 403 | 388 | |
| 404 | − /* | |
| 405 | − * This is movl $__NR_rt_sigreturn, %ax ; int $0x80 | |
| 406 | − * | |
| 407 | − * WE DO NOT USE IT ANY MORE! It's only left here for historical | |
| 408 | − * reasons and because gdb uses it as a signature to notice | |
| 409 | − * signal handler stack frames. | |
| 410 | − */ | |
| 411 | − put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode); | |
| 412 | − } put_user_catch(err); | |
| 389 | + /* | |
| 390 | + * This is movl $__NR_rt_sigreturn, %ax ; int $0x80 | |
| 391 | + * | |
| 392 | + * WE DO NOT USE IT ANY MORE! It's only left here for historical | |
| 393 | + * reasons and because gdb uses it as a signature to notice | |
| 394 | + * signal handler stack frames. | |
| 395 | + */ | |
| 396 | + unsafe_put_user(*((u64 *)&rt_retcode), (u64 *)frame->retcode, Efault); | |
| 397 | + unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); | |
| 398 | + unsafe_put_sigmask(set, frame, Efault); | |
| 399 | + user_access_end(); | |
| 413 | 400 | |
| 414 | − err |= copy_siginfo_to_user(&frame->info, &ksig->info); | |
| 415 | − err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate, | |
| 416 | − regs, set->sig[0]); | |
| 417 | − err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | |
| 418 | − | |
| 419 | − if (err) | |
| 401 | + if (copy_siginfo_to_user(&frame->info, &ksig->info)) | |
| 420 | 402 | return -EFAULT; |
| 421 | 403 | |
| 422 | 404 | /* Set up registers for signal handler */ |
| @@ -432,6 +414,9 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, · 9 unmodified lines | ||
| 432 | 414 | regs->cs = __USER_CS; |
| 433 | 415 | |
| 434 | 416 | return 0; |
| 417 | +Efault: | |
| 418 | + user_access_end(); | |
| 419 | + return -EFAULT; | |
| 435 | 420 | } |
| 436 | 421 | #else /* !CONFIG_X86_32 */ |
| 437 | 422 | static unsigned long frame_uc_flags(struct pt_regs *regs) |
| @@ -455,43 +440,34 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, · 17 unmodified lines | ||
| 455 | 440 | struct rt_sigframe __user *frame; |
| 456 | 441 | void __user *fp = NULL; |
| 457 | 442 | unsigned long uc_flags; |
| 458 | − int err = 0; | |
| 443 | + | |
| 444 | + /* x86-64 should always use SA_RESTORER. */ | |
| 445 | + if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) | |
| 446 | + return -EFAULT; | |
| 459 | 447 | |
| 460 | 448 | frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp); |
| 449 | + uc_flags = frame_uc_flags(regs); | |
| 461 | 450 | |
| 462 | − if (!access_ok(frame, sizeof(*frame))) | |
| 451 | + if (!user_access_begin(frame, sizeof(*frame))) | |
| 463 | 452 | return -EFAULT; |
| 464 | 453 | |
| 454 | + /* Create the ucontext. */ | |
| 455 | + unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault); | |
| 456 | + unsafe_put_user(0, &frame->uc.uc_link, Efault); | |
| 457 | + unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); | |
| 458 | + | |
| 459 | + /* Set up to return from userspace. If provided, use a stub | |
| 460 | + already in userspace. */ | |
| 461 | + unsafe_put_user(ksig->ka.sa.sa_restorer, &frame->pretcode, Efault); | |
| 462 | + unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); | |
| 463 | + unsafe_put_sigmask(set, frame, Efault); | |
| 464 | + user_access_end(); | |
| 465 | + | |
| 465 | 466 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) { |
| 466 | 467 | if (copy_siginfo_to_user(&frame->info, &ksig->info)) |
| 467 | 468 | return -EFAULT; |
| 468 | 469 | } |
| 469 | 470 | |
| 470 | − uc_flags = frame_uc_flags(regs); | |
| 471 | − | |
| 472 | − put_user_try { | |
| 473 | − /* Create the ucontext. */ | |
| 474 | − put_user_ex(uc_flags, &frame->uc.uc_flags); | |
| 475 | − put_user_ex(0, &frame->uc.uc_link); | |
| 476 | − save_altstack_ex(&frame->uc.uc_stack, regs->sp); | |
| 477 | − | |
| 478 | − /* Set up to return from userspace. If provided, use a stub | |
| 479 | − already in userspace. */ | |
| 480 | − /* x86-64 should always use SA_RESTORER. */ | |
| 481 | − if (ksig->ka.sa.sa_flags & SA_RESTORER) { | |
| 482 | − put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode); | |
| 483 | − } else { | |
| 484 | − /* could use a vstub here */ | |
| 485 | − err |= -EFAULT; | |
| 486 | − } | |
| 487 | − } put_user_catch(err); | |
| 488 | − | |
| 489 | − err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]); | |
| 490 | − err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | |
| 491 | − | |
| 492 | − if (err) | |
| 493 | − return -EFAULT; | |
| 494 | − | |
| 495 | 471 | /* Set up registers for signal handler */ |
| 496 | 472 | regs->di = sig; |
| 497 | 473 | /* In case the signal handler was declared without prototypes */ |
| @@ -528,6 +504,10 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, · 30 unmodified lines | ||
| 528 | 504 | force_valid_ss(regs); |
| 529 | 505 | |
| 530 | 506 | return 0; |
| 507 | + | |
| 508 | +Efault: | |
| 509 | + user_access_end(); | |
| 510 | + return -EFAULT; | |
| 531 | 511 | } |
| 532 | 512 | #endif /* CONFIG_X86_32 */ |
| 533 | 513 | |
| @@ -539,44 +519,33 @@ static int x32_setup_rt_frame(struct ksignal *ksig, · 5 unmodified lines | ||
| 539 | 519 | struct rt_sigframe_x32 __user *frame; |
| 540 | 520 | unsigned long uc_flags; |
| 541 | 521 | void __user *restorer; |
| 542 | − int err = 0; | |
| 543 | − void __user *fpstate = NULL; | |
| 544 | − | |
| 545 | − frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate); | |
| 522 | + void __user *fp = NULL; | |
| 546 | 523 | |
| 547 | − if (!access_ok(frame, sizeof(*frame))) | |
| 524 | + if (!(ksig->ka.sa.sa_flags & SA_RESTORER)) | |
| 548 | 525 | return -EFAULT; |
| 549 | 526 | |
| 550 | − if (ksig->ka.sa.sa_flags & SA_SIGINFO) { | |
| 551 | − if (__copy_siginfo_to_user32(&frame->info, &ksig->info, true)) | |
| 552 | − return -EFAULT; | |
| 553 | − } | |
| 527 | + frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp); | |
| 554 | 528 | |
| 555 | 529 | uc_flags = frame_uc_flags(regs); |
| 556 | 530 | |
| 557 | − put_user_try { | |
| 558 | − /* Create the ucontext. */ | |
| 559 | − put_user_ex(uc_flags, &frame->uc.uc_flags); | |
| 560 | − put_user_ex(0, &frame->uc.uc_link); | |
| 561 | − compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); | |
| 562 | − put_user_ex(0, &frame->uc.uc__pad0); | |
| 563 | − | |
| 564 | − if (ksig->ka.sa.sa_flags & SA_RESTORER) { | |
| 565 | − restorer = ksig->ka.sa.sa_restorer; | |
| 566 | − } else { | |
| 567 | − /* could use a vstub here */ | |
| 568 | − restorer = NULL; | |
| 569 | − err |= -EFAULT; | |
| 570 | − } | |
| 571 | − put_user_ex(restorer, (unsigned long __user *)&frame->pretcode); | |
| 572 | − } put_user_catch(err); | |
| 531 | + if (!user_access_begin(frame, sizeof(*frame))) | |
| 532 | + return -EFAULT; | |
| 573 | 533 | |
| 574 | − err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate, | |
| 575 | − regs, set->sig[0]); | |
| 576 | − err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | |
| 534 | + /* Create the ucontext. */ | |
| 535 | + unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault); | |
| 536 | + unsafe_put_user(0, &frame->uc.uc_link, Efault); | |
| 537 | + unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->sp, Efault); | |
| 538 | + unsafe_put_user(0, &frame->uc.uc__pad0, Efault); | |
| 539 | + restorer = ksig->ka.sa.sa_restorer; | |
| 540 | + unsafe_put_user(restorer, (unsigned long __user *)&frame->pretcode, Efault); | |
| 541 | + unsafe_put_sigcontext(&frame->uc.uc_mcontext, fp, regs, set, Efault); | |
| 542 | + unsafe_put_sigmask(set, frame, Efault); | |
| 543 | + user_access_end(); | |
| 577 | 544 | |
| 578 | − if (err) | |
| 579 | − return -EFAULT; | |
| 545 | + if (ksig->ka.sa.sa_flags & SA_SIGINFO) { | |
| 546 | + if (__copy_siginfo_to_user32(&frame->info, &ksig->info, true)) | |
| 547 | + return -EFAULT; | |
| 548 | + } | |
| 580 | 549 | |
| 581 | 550 | /* Set up registers for signal handler */ |
| 582 | 551 | regs->sp = (unsigned long) frame; |
| @@ -595,6 +564,11 @@ static int x32_setup_rt_frame(struct ksignal *ksig, · 12 unmodified lines | ||
| 595 | 564 | #endif /* CONFIG_X86_X32_ABI */ |
| 596 | 565 | |
| 597 | 566 | return 0; |
| 567 | +#ifdef CONFIG_X86_X32_ABI | |
| 568 | +Efault: | |
| 569 | + user_access_end(); | |
| 570 | + return -EFAULT; | |
| 571 | +#endif | |
| 598 | 572 | } |
| 599 | 573 | |
| 600 | 574 | /* |
| @@ -611,9 +585,8 @@ SYSCALL_DEFINE0(sigreturn) · 10 unmodified lines | ||
| 611 | 585 | |
| 612 | 586 | if (!access_ok(frame, sizeof(*frame))) |
| 613 | 587 | goto badframe; |
| 614 | − if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1 | |
| 615 | − && __copy_from_user(&set.sig[1], &frame->extramask, | |
| 616 | − sizeof(frame->extramask)))) | |
| 588 | + if (__get_user(set.sig[0], &frame->sc.oldmask) || | |
| 589 | + __get_user(set.sig[1], &frame->extramask[0])) | |
| 617 | 590 | goto badframe; |
| 618 | 591 | |
| 619 | 592 | set_current_blocked(&set); |
| @@ -643,7 +616,7 @@ SYSCALL_DEFINE0(rt_sigreturn) · 23 unmodified lines | ||
| 643 | 616 | frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long)); |
| 644 | 617 | if (!access_ok(frame, sizeof(*frame))) |
| 645 | 618 | goto badframe; |
| 646 | − if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | |
| 619 | + if (__get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask)) | |
| 647 | 620 | goto badframe; |
| 648 | 621 | if (__get_user(uc_flags, &frame->uc.uc_flags)) |
| 649 | 622 | goto badframe; |
| @@ -868,7 +841,7 @@ COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn) · 218 unmodified lines | ||
| 868 | 841 | |
| 869 | 842 | if (!access_ok(frame, sizeof(*frame))) |
| 870 | 843 | goto badframe; |
| 871 | − if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | |
| 844 | + if (__get_user(set.sig[0], (__u64 __user *)&frame->uc.uc_sigmask)) | |
| 872 | 845 | goto badframe; |
| 873 | 846 | if (__get_user(uc_flags, &frame->uc.uc_flags)) |
| 874 | 847 | goto badframe; |
| @@ -1438,7 +1438,7 @@ early_param("possible_cpus", _setup_possible_cpus); · 1437 unmodified lines | ||
| 1438 | 1438 | /* |
| 1439 | 1439 | * cpu_possible_mask should be static, it cannot change as cpu's |
| 1440 | 1440 | * are onlined, or offlined. The reason is per-cpu data-structures |
| 1441 | − * are allocated by some modules at init time, and dont expect to | |
| 1441 | + * are allocated by some modules at init time, and don't expect to | |
| 1442 | 1442 | * do this dynamically on cpu arrival/departure. |
| 1443 | 1443 | * cpu_present_mask on the other hand can change dynamically. |
| 1444 | 1444 | * In case when cpu_hotplug is not compiled, then we resort to current |
| @@ -96,7 +96,8 @@ struct stack_frame_user { · 95 unmodified lines | ||
| 96 | 96 | }; |
| 97 | 97 | |
| 98 | 98 | static int |
| 99 | −copy_stack_frame(const void __user *fp, struct stack_frame_user *frame) | |
| 99 | +copy_stack_frame(const struct stack_frame_user __user *fp, | |
| 100 | + struct stack_frame_user *frame) | |
| 100 | 101 | { |
| 101 | 102 | int ret; |
| 102 | 103 | |
| @@ -105,7 +106,8 @@ copy_stack_frame(const void __user *fp, struct stack_frame_user *frame) · 2 unmodified lines | ||
| 105 | 106 | |
| 106 | 107 | ret = 1; |
| 107 | 108 | pagefault_disable(); |
| 108 | − if (__copy_from_user_inatomic(frame, fp, sizeof(*frame))) | |
| 109 | + if (__get_user(frame->next_fp, &fp->next_fp) || | |
| 110 | + __get_user(frame->ret_addr, &fp->ret_addr)) | |
| 109 | 111 | ret = 0; |
| 110 | 112 | pagefault_enable(); |
| 111 | 113 | |
| @@ -62,19 +62,16 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) · 61 unmodified lines | ||
| 62 | 62 | return IRQ_HANDLED; |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | −static struct irqaction irq0 = { | |
| 66 | − .handler = timer_interrupt, | |
| 67 | − .flags = IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, | |
| 68 | − .name = "timer" | |
| 69 | −}; | |
| 70 | − | |
| 71 | 65 | static void __init setup_default_timer_irq(void) |
| 72 | 66 | { |
| 67 | + unsigned long flags = IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER; | |
| 68 | + | |
| 73 | 69 | /* |
| 74 | − * Unconditionally register the legacy timer; even without legacy | |
| 75 | − * PIC/PIT we need this for the HPET0 in legacy replacement mode. | |
| 70 | + * Unconditionally register the legacy timer interrupt; even | |
| 71 | + * without legacy PIC/PIT we need this for the HPET0 in legacy | |
| 72 | + * replacement mode. | |
| 76 | 73 | */ |
| 77 | − if (setup_irq(0, &irq0)) | |
| 74 | + if (request_irq(0, timer_interrupt, flags, "timer", NULL)) | |
| 78 | 75 | pr_info("Failed to register legacy timer interrupt\n"); |
| 79 | 76 | } |
| 80 | 77 | |
| @@ -477,7 +477,7 @@ static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin) · 476 unmodified lines | ||
| 477 | 477 | * transition from one expected value to another with a fairly |
| 478 | 478 | * high accuracy, and we didn't miss any events. We can thus |
| 479 | 479 | * use the TSC value at the transitions to calculate a pretty |
| 480 | − * good value for the TSC frequencty. | |
| 480 | + * good value for the TSC frequency. | |
| 481 | 481 | */ |
| 482 | 482 | static inline int pit_verify_msb(unsigned char val) |
| 483 | 483 | { |
| @@ -295,7 +295,7 @@ static cycles_t check_tsc_warp(unsigned int timeout) · 294 unmodified lines | ||
| 295 | 295 | * But as the TSC is per-logical CPU and can potentially be modified wrongly |
| 296 | 296 | * by the bios, TSC sync test for smaller duration should be able |
| 297 | 297 | * to catch such errors. Also this will catch the condition where all the |
| 298 | − * cores in the socket doesn't get reset at the same time. | |
| 298 | + * cores in the socket don't get reset at the same time. | |
| 299 | 299 | */ |
| 300 | 300 | static inline unsigned int loop_timeout(int cpu) |
| 301 | 301 | { |
| @@ -98,7 +98,6 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval) · 97 unmodified lines | ||
| 98 | 98 | struct task_struct *tsk = current; |
| 99 | 99 | struct vm86plus_struct __user *user; |
| 100 | 100 | struct vm86 *vm86 = current->thread.vm86; |
| 101 | − long err = 0; | |
| 102 | 101 | |
| 103 | 102 | /* |
| 104 | 103 | * This gets called from entry.S with interrupts disabled, but |
| @@ -114,37 +113,30 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval) · 9 unmodified lines | ||
| 114 | 113 | set_flags(regs->pt.flags, VEFLAGS, X86_EFLAGS_VIF | vm86->veflags_mask); |
| 115 | 114 | user = vm86->user_vm86; |
| 116 | 115 | |
| 117 | − if (!access_ok(user, vm86->vm86plus.is_vm86pus ? | |
| 116 | + if (!user_access_begin(user, vm86->vm86plus.is_vm86pus ? | |
| 118 | 117 | sizeof(struct vm86plus_struct) : |
| 119 | − sizeof(struct vm86_struct))) { | |
| 120 | − pr_alert("could not access userspace vm86 info\n"); | |
| 121 | − do_exit(SIGSEGV); | |
| 122 | − } | |
| 123 | − | |
| 124 | − put_user_try { | |
| 125 | − put_user_ex(regs->pt.bx, &user->regs.ebx); | |
| 126 | − put_user_ex(regs->pt.cx, &user->regs.ecx); | |
| 127 | − put_user_ex(regs->pt.dx, &user->regs.edx); | |
| 128 | − put_user_ex(regs->pt.si, &user->regs.esi); | |
| 129 | − put_user_ex(regs->pt.di, &user->regs.edi); | |
| 130 | − put_user_ex(regs->pt.bp, &user->regs.ebp); | |
| 131 | − put_user_ex(regs->pt.ax, &user->regs.eax); | |
| 132 | − put_user_ex(regs->pt.ip, &user->regs.eip); | |
| 133 | − put_user_ex(regs->pt.cs, &user->regs.cs); | |
| 134 | − put_user_ex(regs->pt.flags, &user->regs.eflags); | |
| 135 | − put_user_ex(regs->pt.sp, &user->regs.esp); | |
| 136 | − put_user_ex(regs->pt.ss, &user->regs.ss); | |
| 137 | − put_user_ex(regs->es, &user->regs.es); | |
| 138 | − put_user_ex(regs->ds, &user->regs.ds); | |
| 139 | − put_user_ex(regs->fs, &user->regs.fs); | |
| 140 | − put_user_ex(regs->gs, &user->regs.gs); | |
| 141 | − | |
| 142 | − put_user_ex(vm86->screen_bitmap, &user->screen_bitmap); | |
| 143 | − } put_user_catch(err); | |
| 144 | − if (err) { | |
| 145 | − pr_alert("could not access userspace vm86 info\n"); | |
| 146 | − do_exit(SIGSEGV); | |
| 147 | − } | |
| 118 | + sizeof(struct vm86_struct))) | |
| 119 | + goto Efault; | |
| 120 | + | |
| 121 | + unsafe_put_user(regs->pt.bx, &user->regs.ebx, Efault_end); | |
| 122 | + unsafe_put_user(regs->pt.cx, &user->regs.ecx, Efault_end); | |
| 123 | + unsafe_put_user(regs->pt.dx, &user->regs.edx, Efault_end); | |
| 124 | + unsafe_put_user(regs->pt.si, &user->regs.esi, Efault_end); | |
| 125 | + unsafe_put_user(regs->pt.di, &user->regs.edi, Efault_end); | |
| 126 | + unsafe_put_user(regs->pt.bp, &user->regs.ebp, Efault_end); | |
| 127 | + unsafe_put_user(regs->pt.ax, &user->regs.eax, Efault_end); | |
| 128 | + unsafe_put_user(regs->pt.ip, &user->regs.eip, Efault_end); | |
| 129 | + unsafe_put_user(regs->pt.cs, &user->regs.cs, Efault_end); | |
| 130 | + unsafe_put_user(regs->pt.flags, &user->regs.eflags, Efault_end); | |
| 131 | + unsafe_put_user(regs->pt.sp, &user->regs.esp, Efault_end); | |
| 132 | + unsafe_put_user(regs->pt.ss, &user->regs.ss, Efault_end); | |
| 133 | + unsafe_put_user(regs->es, &user->regs.es, Efault_end); | |
| 134 | + unsafe_put_user(regs->ds, &user->regs.ds, Efault_end); | |
| 135 | + unsafe_put_user(regs->fs, &user->regs.fs, Efault_end); | |
| 136 | + unsafe_put_user(regs->gs, &user->regs.gs, Efault_end); | |
| 137 | + unsafe_put_user(vm86->screen_bitmap, &user->screen_bitmap, Efault_end); | |
| 138 | + | |
| 139 | + user_access_end(); | |
| 148 | 140 | |
| 149 | 141 | preempt_disable(); |
| 150 | 142 | tsk->thread.sp0 = vm86->saved_sp0; |
| @@ -159,6 +151,13 @@ void save_v86_state(struct kernel_vm86_regs *regs, int retval) · 8 unmodified lines | ||
| 159 | 151 | lazy_load_gs(vm86->regs32.gs); |
| 160 | 152 | |
| 161 | 153 | regs->pt.ax = retval; |
| 154 | + return; | |
| 155 | + | |
| 156 | +Efault_end: | |
| 157 | + user_access_end(); | |
| 158 | +Efault: | |
| 159 | + pr_alert("could not access userspace vm86 info\n"); | |
| 160 | + do_exit(SIGSEGV); | |
| 162 | 161 | } |
| 163 | 162 | |
| 164 | 163 | static void mark_screen_rdonly(struct mm_struct *mm) |
| @@ -243,6 +242,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) · 78 unmodified lines | ||
| 243 | 242 | struct kernel_vm86_regs vm86regs; |
| 244 | 243 | struct pt_regs *regs = current_pt_regs(); |
| 245 | 244 | unsigned long err = 0; |
| 245 | + struct vm86_struct v; | |
| 246 | 246 | |
| 247 | 247 | err = security_mmap_addr(0); |
| 248 | 248 | if (err) { |
| @@ -278,39 +278,32 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) · 29 unmodified lines | ||
| 278 | 278 | if (vm86->saved_sp0) |
| 279 | 279 | return -EPERM; |
| 280 | 280 | |
| 281 | − if (!access_ok(user_vm86, plus ? | |
| 282 | − sizeof(struct vm86_struct) : | |
| 283 | − sizeof(struct vm86plus_struct))) | |
| 281 | + if (copy_from_user(&v, user_vm86, | |
| 282 | + offsetof(struct vm86_struct, int_revectored))) | |
| 284 | 283 | return -EFAULT; |
| 285 | 284 | |
| 286 | 285 | memset(&vm86regs, 0, sizeof(vm86regs)); |
| 287 | − get_user_try { | |
| 288 | − unsigned short seg; | |
| 289 | − get_user_ex(vm86regs.pt.bx, &user_vm86->regs.ebx); | |
| 290 | − get_user_ex(vm86regs.pt.cx, &user_vm86->regs.ecx); | |
| 291 | − get_user_ex(vm86regs.pt.dx, &user_vm86->regs.edx); | |
| 292 | − get_user_ex(vm86regs.pt.si, &user_vm86->regs.esi); | |
| 293 | − get_user_ex(vm86regs.pt.di, &user_vm86->regs.edi); | |
| 294 | − get_user_ex(vm86regs.pt.bp, &user_vm86->regs.ebp); | |
| 295 | − get_user_ex(vm86regs.pt.ax, &user_vm86->regs.eax); | |
| 296 | − get_user_ex(vm86regs.pt.ip, &user_vm86->regs.eip); | |
| 297 | − get_user_ex(seg, &user_vm86->regs.cs); | |
| 298 | − vm86regs.pt.cs = seg; | |
| 299 | − get_user_ex(vm86regs.pt.flags, &user_vm86->regs.eflags); | |
| 300 | − get_user_ex(vm86regs.pt.sp, &user_vm86->regs.esp); | |
| 301 | − get_user_ex(seg, &user_vm86->regs.ss); | |
| 302 | − vm86regs.pt.ss = seg; | |
| 303 | − get_user_ex(vm86regs.es, &user_vm86->regs.es); | |
| 304 | − get_user_ex(vm86regs.ds, &user_vm86->regs.ds); | |
| 305 | − get_user_ex(vm86regs.fs, &user_vm86->regs.fs); | |
| 306 | − get_user_ex(vm86regs.gs, &user_vm86->regs.gs); | |
| 307 | − | |
| 308 | − get_user_ex(vm86->flags, &user_vm86->flags); | |
| 309 | − get_user_ex(vm86->screen_bitmap, &user_vm86->screen_bitmap); | |
| 310 | − get_user_ex(vm86->cpu_type, &user_vm86->cpu_type); | |
| 311 | − } get_user_catch(err); | |
| 312 | − if (err) | |
| 313 | − return err; | |
| 286 | + | |
| 287 | + vm86regs.pt.bx = v.regs.ebx; | |
| 288 | + vm86regs.pt.cx = v.regs.ecx; | |
| 289 | + vm86regs.pt.dx = v.regs.edx; | |
| 290 | + vm86regs.pt.si = v.regs.esi; | |
| 291 | + vm86regs.pt.di = v.regs.edi; | |
| 292 | + vm86regs.pt.bp = v.regs.ebp; | |
| 293 | + vm86regs.pt.ax = v.regs.eax; | |
| 294 | + vm86regs.pt.ip = v.regs.eip; | |
| 295 | + vm86regs.pt.cs = v.regs.cs; | |
| 296 | + vm86regs.pt.flags = v.regs.eflags; | |
| 297 | + vm86regs.pt.sp = v.regs.esp; | |
| 298 | + vm86regs.pt.ss = v.regs.ss; | |
| 299 | + vm86regs.es = v.regs.es; | |
| 300 | + vm86regs.ds = v.regs.ds; | |
| 301 | + vm86regs.fs = v.regs.fs; | |
| 302 | + vm86regs.gs = v.regs.gs; | |
| 303 | + | |
| 304 | + vm86->flags = v.flags; | |
| 305 | + vm86->screen_bitmap = v.screen_bitmap; | |
| 306 | + vm86->cpu_type = v.cpu_type; | |
| 314 | 307 | |
| 315 | 308 | if (copy_from_user(&vm86->int_revectored, |
| 316 | 309 | &user_vm86->int_revectored, |
| @@ -400,7 +400,7 @@ retry_walk: · 399 unmodified lines | ||
| 400 | 400 | goto error; |
| 401 | 401 | |
| 402 | 402 | ptep_user = (pt_element_t __user *)((void *)host_addr + offset); |
| 403 | − if (unlikely(__copy_from_user(&pte, ptep_user, sizeof(pte)))) | |
| 403 | + if (unlikely(__get_user(pte, ptep_user))) | |
| 404 | 404 | goto error; |
| 405 | 405 | walker->ptep_user[walker->level - 1] = ptep_user; |
| 406 | 406 | |
| @@ -42,6 +42,7 @@ · 41 unmodified lines | ||
| 42 | 42 | #include <asm/mce.h> |
| 43 | 43 | #include <asm/mmu_context.h> |
| 44 | 44 | #include <asm/mshyperv.h> |
| 45 | +#include <asm/mwait.h> | |
| 45 | 46 | #include <asm/spec-ctrl.h> |
| 46 | 47 | #include <asm/virtext.h> |
| 47 | 48 | #include <asm/vmx.h> |
| @@ -14,8 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | extern const u32 vmx_msr_index[]; |
| 15 | 15 | extern u64 host_efer; |
| 16 | 16 | |
| 17 | −extern u32 get_umwait_control_msr(void); | |
| 18 | − | |
| 19 | 17 | #define MSR_TYPE_R 1 |
| 20 | 18 | #define MSR_TYPE_W 2 |
| 21 | 19 | #define MSR_TYPE_RW 3 |
| @@ -80,18 +80,6 @@ __visible bool ex_handler_uaccess(const struct exception_table_entry *fixup, · 79 unmodified lines | ||
| 80 | 80 | } |
| 81 | 81 | EXPORT_SYMBOL(ex_handler_uaccess); |
| 82 | 82 | |
| 83 | −__visible bool ex_handler_ext(const struct exception_table_entry *fixup, | |
| 84 | − struct pt_regs *regs, int trapnr, | |
| 85 | − unsigned long error_code, | |
| 86 | − unsigned long fault_addr) | |
| 87 | −{ | |
| 88 | − /* Special hack for uaccess_err */ | |
| 89 | − current->thread.uaccess_err = 1; | |
| 90 | − regs->ip = ex_fixup_addr(fixup); | |
| 91 | − return true; | |
| 92 | −} | |
| 93 | −EXPORT_SYMBOL(ex_handler_ext); | |
| 94 | − | |
| 95 | 83 | __visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup, |
| 96 | 84 | struct pt_regs *regs, int trapnr, |
| 97 | 85 | unsigned long error_code, |
| @@ -324,7 +324,7 @@ static int __init split_nodes_size_interleave(struct numa_meminfo *ei, · 323 unmodified lines | ||
| 324 | 324 | 0, NULL, NUMA_NO_NODE); |
| 325 | 325 | } |
| 326 | 326 | |
| 327 | −int __init setup_emu2phys_nid(int *dfl_phys_nid) | |
| 327 | +static int __init setup_emu2phys_nid(int *dfl_phys_nid) | |
| 328 | 328 | { |
| 329 | 329 | int i, max_emu_nid = 0; |
| 330 | 330 | |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/gfp.h> |
| 16 | 16 | #include <linux/pci.h> |
| 17 | 17 | #include <linux/vmalloc.h> |
| 18 | +#include <linux/libnvdimm.h> | |
| 18 | 19 | |
| 19 | 20 | #include <asm/e820/api.h> |
| 20 | 21 | #include <asm/processor.h> |
| @@ -304,11 +305,13 @@ void clflush_cache_range(void *vaddr, unsigned int size) · 283 unmodified lines | ||
| 304 | 305 | } |
| 305 | 306 | EXPORT_SYMBOL_GPL(clflush_cache_range); |
| 306 | 307 | |
| 308 | +#ifdef CONFIG_ARCH_HAS_PMEM_API | |
| 307 | 309 | void arch_invalidate_pmem(void *addr, size_t size) |
| 308 | 310 | { |
| 309 | 311 | clflush_cache_range(addr, size); |
| 310 | 312 | } |
| 311 | 313 | EXPORT_SYMBOL_GPL(arch_invalidate_pmem); |
| 314 | +#endif | |
| 312 | 315 | |
| 313 | 316 | static void __cpa_flush_all(void *arg) |
| 314 | 317 | { |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | #include <asm/tlbflush.h> |
| 40 | 40 | #include <asm/desc.h> |
| 41 | 41 | #include <asm/sections.h> |
| 42 | +#include <asm/set_memory.h> | |
| 42 | 43 | |
| 43 | 44 | #undef pr_fmt |
| 44 | 45 | #define pr_fmt(fmt) "Kernel/User page tables isolation: " fmt |
| @@ -554,13 +555,6 @@ static inline bool pti_kernel_image_global_ok(void) · 509 unmodified lines | ||
| 554 | 555 | return true; |
| 555 | 556 | } |
| 556 | 557 | |
| 557 | −/* | |
| 558 | − * This is the only user for these and it is not arch-generic | |
| 559 | − * like the other set_memory.h functions. Just extern them. | |
| 560 | − */ | |
| 561 | −extern int set_memory_nonglobal(unsigned long addr, int numpages); | |
| 562 | −extern int set_memory_global(unsigned long addr, int numpages); | |
| 563 | − | |
| 564 | 558 | /* |
| 565 | 559 | * For some configurations, map all of kernel text into the user page |
| 566 | 560 | * tables. This reduces TLB misses, especially on non-PCID systems. |
| @@ -454,12 +454,13 @@ extern void __user *compat_alloc_user_space(unsigned long len); · 453 unmodified lines | ||
| 454 | 454 | |
| 455 | 455 | int compat_restore_altstack(const compat_stack_t __user *uss); |
| 456 | 456 | int __compat_save_altstack(compat_stack_t __user *, unsigned long); |
| 457 | −#define compat_save_altstack_ex(uss, sp) do { \ | |
| 457 | +#define unsafe_compat_save_altstack(uss, sp, label) do { \ | |
| 458 | 458 | compat_stack_t __user *__uss = uss; \ |
| 459 | 459 | struct task_struct *t = current; \ |
| 460 | − put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \ | |
| 461 | − put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \ | |
| 462 | − put_user_ex(t->sas_ss_size, &__uss->ss_size); \ | |
| 460 | + unsafe_put_user(ptr_to_compat((void __user *)t->sas_ss_sp), \ | |
| 461 | + &__uss->ss_sp, label); \ | |
| 462 | + unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \ | |
| 463 | + unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \ | |
| 463 | 464 | if (t->sas_ss_flags & SS_AUTODISARM) \ |
| 464 | 465 | sas_ss_reset(t); \ |
| 465 | 466 | } while (0); |
| @@ -1243,4 +1243,6 @@ struct linux_efi_memreserve { · 1242 unmodified lines | ||
| 1243 | 1243 | #define EFI_MEMRESERVE_COUNT(size) (((size) - sizeof(struct linux_efi_memreserve)) \ |
| 1244 | 1244 | / sizeof(((struct linux_efi_memreserve *)0)->entry[0])) |
| 1245 | 1245 | |
| 1246 | +void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size); | |
| 1247 | + | |
| 1246 | 1248 | #endif /* _LINUX_EFI_H */ |
| @@ -444,12 +444,12 @@ void signals_init(void); · 443 unmodified lines | ||
| 444 | 444 | int restore_altstack(const stack_t __user *); |
| 445 | 445 | int __save_altstack(stack_t __user *, unsigned long); |
| 446 | 446 | |
| 447 | −#define save_altstack_ex(uss, sp) do { \ | |
| 447 | +#define unsafe_save_altstack(uss, sp, label) do { \ | |
| 448 | 448 | stack_t __user *__uss = uss; \ |
| 449 | 449 | struct task_struct *t = current; \ |
| 450 | − put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \ | |
| 451 | − put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \ | |
| 452 | − put_user_ex(t->sas_ss_size, &__uss->ss_size); \ | |
| 450 | + unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \ | |
| 451 | + unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \ | |
| 452 | + unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \ | |
| 453 | 453 | if (t->sas_ss_flags & SS_AUTODISARM) \ |
| 454 | 454 | sas_ss_reset(t); \ |
| 455 | 455 | } while (0); |