Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'x86/process' into x86/mm, to create new base for further patches

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+258 -88
+2 -2
arch/um/include/shared/os.h
··· 302 302 extern void maybe_sigio_broken(int fd, int read); 303 303 extern void sigio_broken(int fd, int read); 304 304 305 - /* sys-x86_64/prctl.c */ 306 - extern int os_arch_prctl(int pid, int code, unsigned long *addr); 305 + /* prctl.c */ 306 + extern int os_arch_prctl(int pid, int option, unsigned long *arg2); 307 307 308 308 /* tty.c */ 309 309 extern int get_pty(void);
+1
arch/x86/entry/syscalls/syscall_32.tbl
··· 390 390 381 i386 pkey_alloc sys_pkey_alloc 391 391 382 i386 pkey_free sys_pkey_free 392 392 383 i386 statx sys_statx 393 + 384 i386 arch_prctl sys_arch_prctl compat_sys_arch_prctl
+1
arch/x86/include/asm/cpufeatures.h
··· 187 187 * Reuse free bits when adding new feature flags! 188 188 */ 189 189 #define X86_FEATURE_RING3MWAIT ( 7*32+ 0) /* Ring 3 MONITOR/MWAIT */ 190 + #define X86_FEATURE_CPUID_FAULT ( 7*32+ 1) /* Intel CPUID faulting */ 190 191 #define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ 191 192 #define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ 192 193 #define X86_FEATURE_CAT_L3 ( 7*32+ 4) /* Cache Allocation Technology L3 */
+8 -3
arch/x86/include/asm/msr-index.h
··· 45 45 #define MSR_IA32_PERFCTR1 0x000000c2 46 46 #define MSR_FSB_FREQ 0x000000cd 47 47 #define MSR_PLATFORM_INFO 0x000000ce 48 + #define MSR_PLATFORM_INFO_CPUID_FAULT_BIT 31 49 + #define MSR_PLATFORM_INFO_CPUID_FAULT BIT_ULL(MSR_PLATFORM_INFO_CPUID_FAULT_BIT) 48 50 49 51 #define MSR_PKG_CST_CONFIG_CONTROL 0x000000e2 50 52 #define NHM_C3_AUTO_DEMOTE (1UL << 25) ··· 129 127 130 128 /* DEBUGCTLMSR bits (others vary by model): */ 131 129 #define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ 130 + #define DEBUGCTLMSR_BTF_SHIFT 1 132 131 #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ 133 132 #define DEBUGCTLMSR_TR (1UL << 6) 134 133 #define DEBUGCTLMSR_BTS (1UL << 7) ··· 555 552 #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT 39 556 553 #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT) 557 554 558 - /* MISC_FEATURE_ENABLES non-architectural features */ 559 - #define MSR_MISC_FEATURE_ENABLES 0x00000140 555 + /* MISC_FEATURES_ENABLES non-architectural features */ 556 + #define MSR_MISC_FEATURES_ENABLES 0x00000140 560 557 561 - #define MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT 1 558 + #define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT 0 559 + #define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT BIT_ULL(MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT) 560 + #define MSR_MISC_FEATURES_ENABLES_RING3MWAIT_BIT 1 562 561 563 562 #define MSR_IA32_TSC_DEADLINE 0x000006E0 564 563
+2
arch/x86/include/asm/processor.h
··· 888 888 extern int get_tsc_mode(unsigned long adr); 889 889 extern int set_tsc_mode(unsigned int val); 890 890 891 + DECLARE_PER_CPU(u64, msr_misc_features_shadow); 892 + 891 893 /* Register/unregister a process' MPX related resource */ 892 894 #define MPX_ENABLE_MANAGEMENT() mpx_enable_management() 893 895 #define MPX_DISABLE_MANAGEMENT() mpx_disable_management()
+3 -1
arch/x86/include/asm/proto.h
··· 9 9 10 10 #ifdef CONFIG_X86_64 11 11 void entry_SYSCALL_64(void); 12 + long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2); 12 13 #endif 13 14 14 15 #ifdef CONFIG_X86_32 ··· 31 30 32 31 extern int reboot_force; 33 32 34 - long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); 33 + long do_arch_prctl_common(struct task_struct *task, int option, 34 + unsigned long cpuid_enabled); 35 35 36 36 #endif /* _ASM_X86_PROTO_H */
+5 -1
arch/x86/include/asm/thread_info.h
··· 87 87 #define TIF_SECCOMP 8 /* secure computing */ 88 88 #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ 89 89 #define TIF_UPROBE 12 /* breakpointed or singlestepping */ 90 + #define TIF_NOCPUID 15 /* CPUID is not accessible in userland */ 90 91 #define TIF_NOTSC 16 /* TSC is not accessible in userland */ 91 92 #define TIF_IA32 17 /* IA32 compatibility process */ 92 93 #define TIF_NOHZ 19 /* in adaptive nohz mode */ ··· 111 110 #define _TIF_SECCOMP (1 << TIF_SECCOMP) 112 111 #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) 113 112 #define _TIF_UPROBE (1 << TIF_UPROBE) 113 + #define _TIF_NOCPUID (1 << TIF_NOCPUID) 114 114 #define _TIF_NOTSC (1 << TIF_NOTSC) 115 115 #define _TIF_IA32 (1 << TIF_IA32) 116 116 #define _TIF_NOHZ (1 << TIF_NOHZ) ··· 140 138 141 139 /* flags to check in __switch_to() */ 142 140 #define _TIF_WORK_CTXSW \ 143 - (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP) 141 + (_TIF_IO_BITMAP|_TIF_NOCPUID|_TIF_NOTSC|_TIF_BLOCKSTEP) 144 142 145 143 #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) 146 144 #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) ··· 241 239 extern void arch_task_cache_init(void); 242 240 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); 243 241 extern void arch_release_task_struct(struct task_struct *tsk); 242 + extern void arch_setup_new_exec(void); 243 + #define arch_setup_new_exec arch_setup_new_exec 244 244 #endif /* !__ASSEMBLY__ */ 245 245 246 246 #endif /* _ASM_X86_THREAD_INFO_H */
+10
arch/x86/include/asm/tlbflush.h
··· 110 110 } 111 111 } 112 112 113 + static inline void cr4_toggle_bits(unsigned long mask) 114 + { 115 + unsigned long cr4; 116 + 117 + cr4 = this_cpu_read(cpu_tlbstate.cr4); 118 + cr4 ^= mask; 119 + this_cpu_write(cpu_tlbstate.cr4, cr4); 120 + __write_cr4(cr4); 121 + } 122 + 113 123 /* Read the CR4 shadow. */ 114 124 static inline unsigned long cr4_read_shadow(void) 115 125 {
+7 -4
arch/x86/include/uapi/asm/prctl.h
··· 1 1 #ifndef _ASM_X86_PRCTL_H 2 2 #define _ASM_X86_PRCTL_H 3 3 4 - #define ARCH_SET_GS 0x1001 5 - #define ARCH_SET_FS 0x1002 6 - #define ARCH_GET_FS 0x1003 7 - #define ARCH_GET_GS 0x1004 4 + #define ARCH_SET_GS 0x1001 5 + #define ARCH_SET_FS 0x1002 6 + #define ARCH_GET_FS 0x1003 7 + #define ARCH_GET_GS 0x1004 8 + 9 + #define ARCH_GET_CPUID 0x1011 10 + #define ARCH_SET_CPUID 0x1012 8 11 9 12 #define ARCH_MAP_VDSO_X32 0x2001 10 13 #define ARCH_MAP_VDSO_32 0x2002
+32 -8
arch/x86/kernel/cpu/intel.c
··· 90 90 return; 91 91 } 92 92 93 - if (ring3mwait_disabled) { 94 - msr_clear_bit(MSR_MISC_FEATURE_ENABLES, 95 - MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT); 93 + if (ring3mwait_disabled) 96 94 return; 97 - } 98 - 99 - msr_set_bit(MSR_MISC_FEATURE_ENABLES, 100 - MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT); 101 95 102 96 set_cpu_cap(c, X86_FEATURE_RING3MWAIT); 97 + this_cpu_or(msr_misc_features_shadow, 98 + 1UL << MSR_MISC_FEATURES_ENABLES_RING3MWAIT_BIT); 103 99 104 100 if (c == &boot_cpu_data) 105 101 ELF_HWCAP2 |= HWCAP2_RING3MWAIT; ··· 484 488 init_intel_energy_perf(c); 485 489 } 486 490 491 + static void init_cpuid_fault(struct cpuinfo_x86 *c) 492 + { 493 + u64 msr; 494 + 495 + if (!rdmsrl_safe(MSR_PLATFORM_INFO, &msr)) { 496 + if (msr & MSR_PLATFORM_INFO_CPUID_FAULT) 497 + set_cpu_cap(c, X86_FEATURE_CPUID_FAULT); 498 + } 499 + } 500 + 501 + static void init_intel_misc_features(struct cpuinfo_x86 *c) 502 + { 503 + u64 msr; 504 + 505 + if (rdmsrl_safe(MSR_MISC_FEATURES_ENABLES, &msr)) 506 + return; 507 + 508 + /* Clear all MISC features */ 509 + this_cpu_write(msr_misc_features_shadow, 0); 510 + 511 + /* Check features and update capabilities and shadow control bits */ 512 + init_cpuid_fault(c); 513 + probe_xeon_phi_r3mwait(c); 514 + 515 + msr = this_cpu_read(msr_misc_features_shadow); 516 + wrmsrl(MSR_MISC_FEATURES_ENABLES, msr); 517 + } 518 + 487 519 static void init_intel(struct cpuinfo_x86 *c) 488 520 { 489 521 unsigned int l2 = 0; ··· 626 602 627 603 init_intel_energy_perf(c); 628 604 629 - probe_xeon_phi_r3mwait(c); 605 + init_intel_misc_features(c); 630 606 } 631 607 632 608 #ifdef CONFIG_X86_32
+115 -36
arch/x86/kernel/process.c
··· 37 37 #include <asm/vm86.h> 38 38 #include <asm/switch_to.h> 39 39 #include <asm/desc.h> 40 + #include <asm/prctl.h> 40 41 41 42 /* 42 43 * per-CPU TSS segments. Threads are completely 'soft' on Linux, ··· 125 124 fpu__clear(&tsk->thread.fpu); 126 125 } 127 126 128 - static void hard_disable_TSC(void) 129 - { 130 - cr4_set_bits(X86_CR4_TSD); 131 - } 132 - 133 127 void disable_TSC(void) 134 128 { 135 129 preempt_disable(); ··· 133 137 * Must flip the CPU state synchronously with 134 138 * TIF_NOTSC in the current running context. 135 139 */ 136 - hard_disable_TSC(); 140 + cr4_set_bits(X86_CR4_TSD); 137 141 preempt_enable(); 138 - } 139 - 140 - static void hard_enable_TSC(void) 141 - { 142 - cr4_clear_bits(X86_CR4_TSD); 143 142 } 144 143 145 144 static void enable_TSC(void) ··· 145 154 * Must flip the CPU state synchronously with 146 155 * TIF_NOTSC in the current running context. 147 156 */ 148 - hard_enable_TSC(); 157 + cr4_clear_bits(X86_CR4_TSD); 149 158 preempt_enable(); 150 159 } 151 160 ··· 173 182 return 0; 174 183 } 175 184 176 - void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, 177 - struct tss_struct *tss) 185 + DEFINE_PER_CPU(u64, msr_misc_features_shadow); 186 + 187 + static void set_cpuid_faulting(bool on) 178 188 { 179 - struct thread_struct *prev, *next; 189 + u64 msrval; 180 190 181 - prev = &prev_p->thread; 182 - next = &next_p->thread; 191 + msrval = this_cpu_read(msr_misc_features_shadow); 192 + msrval &= ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT; 193 + msrval |= (on << MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT); 194 + this_cpu_write(msr_misc_features_shadow, msrval); 195 + wrmsrl(MSR_MISC_FEATURES_ENABLES, msrval); 196 + } 183 197 184 - if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^ 185 - test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) { 186 - unsigned long debugctl = get_debugctlmsr(); 187 - 188 - debugctl &= ~DEBUGCTLMSR_BTF; 189 - if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) 190 - debugctl |= DEBUGCTLMSR_BTF; 191 - 192 - update_debugctlmsr(debugctl); 198 + static void disable_cpuid(void) 199 + { 200 + preempt_disable(); 201 + if (!test_and_set_thread_flag(TIF_NOCPUID)) { 202 + /* 203 + * Must flip the CPU state synchronously with 204 + * TIF_NOCPUID in the current running context. 205 + */ 206 + set_cpuid_faulting(true); 193 207 } 208 + preempt_enable(); 209 + } 194 210 195 - if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ 196 - test_tsk_thread_flag(next_p, TIF_NOTSC)) { 197 - /* prev and next are different */ 198 - if (test_tsk_thread_flag(next_p, TIF_NOTSC)) 199 - hard_disable_TSC(); 200 - else 201 - hard_enable_TSC(); 211 + static void enable_cpuid(void) 212 + { 213 + preempt_disable(); 214 + if (test_and_clear_thread_flag(TIF_NOCPUID)) { 215 + /* 216 + * Must flip the CPU state synchronously with 217 + * TIF_NOCPUID in the current running context. 218 + */ 219 + set_cpuid_faulting(false); 202 220 } 221 + preempt_enable(); 222 + } 203 223 204 - if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { 224 + static int get_cpuid_mode(void) 225 + { 226 + return !test_thread_flag(TIF_NOCPUID); 227 + } 228 + 229 + static int set_cpuid_mode(struct task_struct *task, unsigned long cpuid_enabled) 230 + { 231 + if (!static_cpu_has(X86_FEATURE_CPUID_FAULT)) 232 + return -ENODEV; 233 + 234 + if (cpuid_enabled) 235 + enable_cpuid(); 236 + else 237 + disable_cpuid(); 238 + 239 + return 0; 240 + } 241 + 242 + /* 243 + * Called immediately after a successful exec. 244 + */ 245 + void arch_setup_new_exec(void) 246 + { 247 + /* If cpuid was previously disabled for this task, re-enable it. */ 248 + if (test_thread_flag(TIF_NOCPUID)) 249 + enable_cpuid(); 250 + } 251 + 252 + static inline void switch_to_bitmap(struct tss_struct *tss, 253 + struct thread_struct *prev, 254 + struct thread_struct *next, 255 + unsigned long tifp, unsigned long tifn) 256 + { 257 + if (tifn & _TIF_IO_BITMAP) { 205 258 /* 206 259 * Copy the relevant range of the IO bitmap. 207 260 * Normally this is 128 bytes or less: 208 261 */ 209 262 memcpy(tss->io_bitmap, next->io_bitmap_ptr, 210 263 max(prev->io_bitmap_max, next->io_bitmap_max)); 211 - 212 264 /* 213 265 * Make sure that the TSS limit is correct for the CPU 214 266 * to notice the IO bitmap. 215 267 */ 216 268 refresh_tss_limit(); 217 - } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { 269 + } else if (tifp & _TIF_IO_BITMAP) { 218 270 /* 219 271 * Clear any possible leftover bits: 220 272 */ 221 273 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); 222 274 } 275 + } 276 + 277 + void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, 278 + struct tss_struct *tss) 279 + { 280 + struct thread_struct *prev, *next; 281 + unsigned long tifp, tifn; 282 + 283 + prev = &prev_p->thread; 284 + next = &next_p->thread; 285 + 286 + tifn = READ_ONCE(task_thread_info(next_p)->flags); 287 + tifp = READ_ONCE(task_thread_info(prev_p)->flags); 288 + switch_to_bitmap(tss, prev, next, tifp, tifn); 289 + 223 290 propagate_user_return_notify(prev_p, next_p); 291 + 292 + if ((tifp & _TIF_BLOCKSTEP || tifn & _TIF_BLOCKSTEP) && 293 + arch_has_block_step()) { 294 + unsigned long debugctl, msk; 295 + 296 + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); 297 + debugctl &= ~DEBUGCTLMSR_BTF; 298 + msk = tifn & _TIF_BLOCKSTEP; 299 + debugctl |= (msk >> TIF_BLOCKSTEP) << DEBUGCTLMSR_BTF_SHIFT; 300 + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); 301 + } 302 + 303 + if ((tifp ^ tifn) & _TIF_NOTSC) 304 + cr4_toggle_bits(X86_CR4_TSD); 305 + 306 + if ((tifp ^ tifn) & _TIF_NOCPUID) 307 + set_cpuid_faulting(!!(tifn & _TIF_NOCPUID)); 224 308 } 225 309 226 310 /* ··· 615 549 out: 616 550 put_task_stack(p); 617 551 return ret; 552 + } 553 + 554 + long do_arch_prctl_common(struct task_struct *task, int option, 555 + unsigned long cpuid_enabled) 556 + { 557 + switch (option) { 558 + case ARCH_GET_CPUID: 559 + return get_cpuid_mode(); 560 + case ARCH_SET_CPUID: 561 + return set_cpuid_mode(task, cpuid_enabled); 562 + } 563 + 564 + return -EINVAL; 618 565 }
+7
arch/x86/kernel/process_32.c
··· 37 37 #include <linux/uaccess.h> 38 38 #include <linux/io.h> 39 39 #include <linux/kdebug.h> 40 + #include <linux/syscalls.h> 40 41 41 42 #include <asm/pgtable.h> 42 43 #include <asm/ldt.h> ··· 57 56 #include <asm/switch_to.h> 58 57 #include <asm/vm86.h> 59 58 #include <asm/intel_rdt.h> 59 + #include <asm/proto.h> 60 60 61 61 void __show_regs(struct pt_regs *regs, int all) 62 62 { ··· 305 303 intel_rdt_sched_in(); 306 304 307 305 return prev_p; 306 + } 307 + 308 + SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) 309 + { 310 + return do_arch_prctl_common(current, option, arg2); 308 311 }
+32 -16
arch/x86/kernel/process_64.c
··· 37 37 #include <linux/uaccess.h> 38 38 #include <linux/io.h> 39 39 #include <linux/ftrace.h> 40 + #include <linux/syscalls.h> 40 41 41 42 #include <asm/pgtable.h> 42 43 #include <asm/processor.h> ··· 205 204 (struct user_desc __user *)tls, 0); 206 205 else 207 206 #endif 208 - err = do_arch_prctl(p, ARCH_SET_FS, tls); 207 + err = do_arch_prctl_64(p, ARCH_SET_FS, tls); 209 208 if (err) 210 209 goto out; 211 210 } ··· 548 547 } 549 548 #endif 550 549 551 - long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) 550 + long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2) 552 551 { 553 552 int ret = 0; 554 553 int doit = task == current; 555 554 int cpu; 556 555 557 - switch (code) { 556 + switch (option) { 558 557 case ARCH_SET_GS: 559 - if (addr >= TASK_SIZE_MAX) 558 + if (arg2 >= TASK_SIZE_MAX) 560 559 return -EPERM; 561 560 cpu = get_cpu(); 562 561 task->thread.gsindex = 0; 563 - task->thread.gsbase = addr; 562 + task->thread.gsbase = arg2; 564 563 if (doit) { 565 564 load_gs_index(0); 566 - ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr); 565 + ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, arg2); 567 566 } 568 567 put_cpu(); 569 568 break; 570 569 case ARCH_SET_FS: 571 570 /* Not strictly needed for fs, but do it for symmetry 572 571 with gs */ 573 - if (addr >= TASK_SIZE_MAX) 572 + if (arg2 >= TASK_SIZE_MAX) 574 573 return -EPERM; 575 574 cpu = get_cpu(); 576 575 task->thread.fsindex = 0; 577 - task->thread.fsbase = addr; 576 + task->thread.fsbase = arg2; 578 577 if (doit) { 579 578 /* set the selector to 0 to not confuse __switch_to */ 580 579 loadsegment(fs, 0); 581 - ret = wrmsrl_safe(MSR_FS_BASE, addr); 580 + ret = wrmsrl_safe(MSR_FS_BASE, arg2); 582 581 } 583 582 put_cpu(); 584 583 break; 585 584 case ARCH_GET_FS: { 586 585 unsigned long base; 586 + 587 587 if (doit) 588 588 rdmsrl(MSR_FS_BASE, base); 589 589 else 590 590 base = task->thread.fsbase; 591 - ret = put_user(base, (unsigned long __user *)addr); 591 + ret = put_user(base, (unsigned long __user *)arg2); 592 592 break; 593 593 } 594 594 case ARCH_GET_GS: { 595 595 unsigned long base; 596 + 596 597 if (doit) 597 598 rdmsrl(MSR_KERNEL_GS_BASE, base); 598 599 else 599 600 base = task->thread.gsbase; 600 - ret = put_user(base, (unsigned long __user *)addr); 601 + ret = put_user(base, (unsigned long __user *)arg2); 601 602 break; 602 603 } 603 604 604 605 #ifdef CONFIG_CHECKPOINT_RESTORE 605 606 # ifdef CONFIG_X86_X32_ABI 606 607 case ARCH_MAP_VDSO_X32: 607 - return prctl_map_vdso(&vdso_image_x32, addr); 608 + return prctl_map_vdso(&vdso_image_x32, arg2); 608 609 # endif 609 610 # if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION 610 611 case ARCH_MAP_VDSO_32: 611 - return prctl_map_vdso(&vdso_image_32, addr); 612 + return prctl_map_vdso(&vdso_image_32, arg2); 612 613 # endif 613 614 case ARCH_MAP_VDSO_64: 614 - return prctl_map_vdso(&vdso_image_64, addr); 615 + return prctl_map_vdso(&vdso_image_64, arg2); 615 616 #endif 616 617 617 618 default: ··· 624 621 return ret; 625 622 } 626 623 627 - long sys_arch_prctl(int code, unsigned long addr) 624 + SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) 628 625 { 629 - return do_arch_prctl(current, code, addr); 626 + long ret; 627 + 628 + ret = do_arch_prctl_64(current, option, arg2); 629 + if (ret == -EINVAL) 630 + ret = do_arch_prctl_common(current, option, arg2); 631 + 632 + return ret; 630 633 } 634 + 635 + #ifdef CONFIG_IA32_EMULATION 636 + COMPAT_SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) 637 + { 638 + return do_arch_prctl_common(current, option, arg2); 639 + } 640 + #endif 631 641 632 642 unsigned long KSTK_ESP(struct task_struct *task) 633 643 {
+4 -4
arch/x86/kernel/ptrace.c
··· 396 396 if (value >= TASK_SIZE_MAX) 397 397 return -EIO; 398 398 /* 399 - * When changing the segment base, use do_arch_prctl 399 + * When changing the segment base, use do_arch_prctl_64 400 400 * to set either thread.fs or thread.fsindex and the 401 401 * corresponding GDT slot. 402 402 */ 403 403 if (child->thread.fsbase != value) 404 - return do_arch_prctl(child, ARCH_SET_FS, value); 404 + return do_arch_prctl_64(child, ARCH_SET_FS, value); 405 405 return 0; 406 406 case offsetof(struct user_regs_struct,gs_base): 407 407 /* ··· 410 410 if (value >= TASK_SIZE_MAX) 411 411 return -EIO; 412 412 if (child->thread.gsbase != value) 413 - return do_arch_prctl(child, ARCH_SET_GS, value); 413 + return do_arch_prctl_64(child, ARCH_SET_GS, value); 414 414 return 0; 415 415 #endif 416 416 } ··· 869 869 Works just like arch_prctl, except that the arguments 870 870 are reversed. */ 871 871 case PTRACE_ARCH_PRCTL: 872 - ret = do_arch_prctl(child, data, addr); 872 + ret = do_arch_prctl_64(child, data, addr); 873 873 break; 874 874 #endif 875 875
+1 -1
arch/x86/um/Makefile
··· 16 16 17 17 ifeq ($(CONFIG_X86_32),y) 18 18 19 - obj-y += checksum_32.o 19 + obj-y += checksum_32.o syscalls_32.o 20 20 obj-$(CONFIG_ELF_CORE) += elfcore.o 21 21 22 22 subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o
+1 -1
arch/x86/um/asm/ptrace.h
··· 78 78 return -ENOSYS; 79 79 } 80 80 81 - extern long arch_prctl(struct task_struct *task, int code, 81 + extern long arch_prctl(struct task_struct *task, int option, 82 82 unsigned long __user *addr); 83 83 84 84 #endif
+2 -2
arch/x86/um/os-Linux/prctl.c
··· 6 6 #include <sys/ptrace.h> 7 7 #include <asm/ptrace.h> 8 8 9 - int os_arch_prctl(int pid, int code, unsigned long *addr) 9 + int os_arch_prctl(int pid, int option, unsigned long *arg2) 10 10 { 11 - return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code); 11 + return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, option); 12 12 }
+7
arch/x86/um/syscalls_32.c
··· 1 + #include <linux/syscalls.h> 2 + #include <os.h> 3 + 4 + SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) 5 + { 6 + return -EINVAL; 7 + }
+11 -9
arch/x86/um/syscalls_64.c
··· 7 7 8 8 #include <linux/sched.h> 9 9 #include <linux/sched/mm.h> 10 + #include <linux/syscalls.h> 10 11 #include <linux/uaccess.h> 11 12 #include <asm/prctl.h> /* XXX This should get the constants from libc */ 12 13 #include <os.h> 13 14 14 - long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) 15 + long arch_prctl(struct task_struct *task, int option, 16 + unsigned long __user *arg2) 15 17 { 16 - unsigned long *ptr = addr, tmp; 18 + unsigned long *ptr = arg2, tmp; 17 19 long ret; 18 20 int pid = task->mm->context.id.u.pid; 19 21 ··· 32 30 * arch_prctl is run on the host, then the registers are read 33 31 * back. 34 32 */ 35 - switch (code) { 33 + switch (option) { 36 34 case ARCH_SET_FS: 37 35 case ARCH_SET_GS: 38 36 ret = restore_registers(pid, &current->thread.regs.regs); ··· 52 50 ptr = &tmp; 53 51 } 54 52 55 - ret = os_arch_prctl(pid, code, ptr); 53 + ret = os_arch_prctl(pid, option, ptr); 56 54 if (ret) 57 55 return ret; 58 56 59 - switch (code) { 57 + switch (option) { 60 58 case ARCH_SET_FS: 61 59 current->thread.arch.fs = (unsigned long) ptr; 62 60 ret = save_registers(pid, &current->thread.regs.regs); ··· 65 63 ret = save_registers(pid, &current->thread.regs.regs); 66 64 break; 67 65 case ARCH_GET_FS: 68 - ret = put_user(tmp, addr); 66 + ret = put_user(tmp, arg2); 69 67 break; 70 68 case ARCH_GET_GS: 71 - ret = put_user(tmp, addr); 69 + ret = put_user(tmp, arg2); 72 70 break; 73 71 } 74 72 75 73 return ret; 76 74 } 77 75 78 - long sys_arch_prctl(int code, unsigned long addr) 76 + SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) 79 77 { 80 - return arch_prctl(current, code, (unsigned long __user *) addr); 78 + return arch_prctl(current, option, (unsigned long __user *) arg2); 81 79 } 82 80 83 81 void arch_switch_to(struct task_struct *to)
+1
fs/exec.c
··· 1320 1320 else 1321 1321 set_dumpable(current->mm, suid_dumpable); 1322 1322 1323 + arch_setup_new_exec(); 1323 1324 perf_event_exec(); 1324 1325 __set_task_comm(current, kbasename(bprm->filename), true); 1325 1326
+2
include/linux/compat.h
··· 723 723 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, 724 724 int, const char __user *); 725 725 726 + asmlinkage long compat_sys_arch_prctl(int option, unsigned long arg2); 727 + 726 728 /* 727 729 * For most but not all architectures, "am I in a compat syscall?" and 728 730 * "am I a compat task?" are the same question. For architectures on which
+4
include/linux/thread_info.h
··· 101 101 { } 102 102 #endif /* CONFIG_HARDENED_USERCOPY */ 103 103 104 + #ifndef arch_setup_new_exec 105 + static inline void arch_setup_new_exec(void) { } 106 + #endif 107 + 104 108 #endif /* __KERNEL__ */ 105 109 106 110 #endif /* _LINUX_THREAD_INFO_H */