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