Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: Fix kprobes build with non-gawk awk
x86: Split swiotlb initialization into two stages
x86: Regex support and known-movable symbols for relocs, fix _end
x86, msr: Remove incorrect, duplicated code in the MSR driver
x86: Merge kernel_thread()
x86: Sync 32/64-bit kernel_thread
x86, 32-bit: Use same regs as 64-bit for kernel_thread_helper
x86, 64-bit: Use user_mode() to determine new stack pointer in copy_thread()
x86, 64-bit: Move kernel_thread to C
x86-64, paravirt: Call set_iopl_mask() on 64 bits
x86-32: Avoid pipeline serialization in PTREGSCALL1 and 2
x86: Merge sys_clone
x86, 32-bit: Convert sys_vm86 & sys_vm86old
x86: Merge sys_sigaltstack
x86: Merge sys_execve
x86: Merge sys_iopl
x86-32: Add new pt_regs stubs
cpumask: Use modern cpumask style in arch/x86/kernel/cpu/mcheck/mce-inject.c

+245 -294
+60 -29
arch/x86/boot/compressed/relocs.c
··· 9 9 #include <byteswap.h> 10 10 #define USE_BSD 11 11 #include <endian.h> 12 + #include <regex.h> 13 + 14 + static void die(char *fmt, ...); 12 15 13 16 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 14 17 static Elf32_Ehdr ehdr; ··· 33 30 * the address for which it has been compiled. Don't warn user about 34 31 * absolute relocations present w.r.t these symbols. 35 32 */ 36 - static const char* safe_abs_relocs[] = { 37 - "xen_irq_disable_direct_reloc", 38 - "xen_save_fl_direct_reloc", 39 - }; 40 - 41 - static int is_safe_abs_reloc(const char* sym_name) 33 + static const char abs_sym_regex[] = 34 + "^(xen_irq_disable_direct_reloc$|" 35 + "xen_save_fl_direct_reloc$|" 36 + "VDSO|" 37 + "__crc_)"; 38 + static regex_t abs_sym_regex_c; 39 + static int is_abs_reloc(const char *sym_name) 42 40 { 43 - int i; 41 + return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); 42 + } 44 43 45 - for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { 46 - if (!strcmp(sym_name, safe_abs_relocs[i])) 47 - /* Match found */ 48 - return 1; 49 - } 50 - if (strncmp(sym_name, "VDSO", 4) == 0) 51 - return 1; 52 - if (strncmp(sym_name, "__crc_", 6) == 0) 53 - return 1; 54 - return 0; 44 + /* 45 + * These symbols are known to be relative, even if the linker marks them 46 + * as absolute (typically defined outside any section in the linker script.) 47 + */ 48 + static const char rel_sym_regex[] = 49 + "^_end$"; 50 + static regex_t rel_sym_regex_c; 51 + static int is_rel_reloc(const char *sym_name) 52 + { 53 + return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); 54 + } 55 + 56 + static void regex_init(void) 57 + { 58 + char errbuf[128]; 59 + int err; 60 + 61 + err = regcomp(&abs_sym_regex_c, abs_sym_regex, 62 + REG_EXTENDED|REG_NOSUB); 63 + if (err) { 64 + regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); 65 + die("%s", errbuf); 66 + } 67 + 68 + err = regcomp(&rel_sym_regex_c, rel_sym_regex, 69 + REG_EXTENDED|REG_NOSUB); 70 + if (err) { 71 + regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); 72 + die("%s", errbuf); 73 + } 55 74 } 56 75 57 76 static void die(char *fmt, ...) ··· 156 131 #undef REL_TYPE 157 132 }; 158 133 const char *name = "unknown type rel type name"; 159 - if (type < ARRAY_SIZE(type_name)) { 134 + if (type < ARRAY_SIZE(type_name) && type_name[type]) { 160 135 name = type_name[type]; 161 136 } 162 137 return name; ··· 473 448 * Before warning check if this absolute symbol 474 449 * relocation is harmless. 475 450 */ 476 - if (is_safe_abs_reloc(name)) 451 + if (is_abs_reloc(name) || is_rel_reloc(name)) 477 452 continue; 478 453 479 454 if (!printed) { ··· 526 501 sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; 527 502 r_type = ELF32_R_TYPE(rel->r_info); 528 503 /* Don't visit relocations to absolute symbols */ 529 - if (sym->st_shndx == SHN_ABS) { 504 + if (sym->st_shndx == SHN_ABS && 505 + !is_rel_reloc(sym_name(sym_strtab, sym))) { 530 506 continue; 531 507 } 532 - if (r_type == R_386_NONE || r_type == R_386_PC32) { 508 + switch (r_type) { 509 + case R_386_NONE: 510 + case R_386_PC32: 533 511 /* 534 512 * NONE can be ignored and and PC relative 535 513 * relocations don't need to be adjusted. 536 514 */ 537 - } 538 - else if (r_type == R_386_32) { 515 + break; 516 + case R_386_32: 539 517 /* Visit relocations that need to be adjusted */ 540 518 visit(rel, sym); 541 - } 542 - else { 543 - die("Unsupported relocation type: %d\n", r_type); 519 + break; 520 + default: 521 + die("Unsupported relocation type: %s (%d)\n", 522 + rel_type(r_type), r_type); 523 + break; 544 524 } 545 525 } 546 526 } ··· 601 571 } 602 572 else { 603 573 unsigned char buf[4]; 604 - buf[0] = buf[1] = buf[2] = buf[3] = 0; 605 574 /* Print a stop */ 606 - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); 575 + fwrite("\0\0\0\0", 4, 1, stdout); 607 576 /* Now print each relocation */ 608 577 for (i = 0; i < reloc_count; i++) { 609 578 buf[0] = (relocs[i] >> 0) & 0xff; 610 579 buf[1] = (relocs[i] >> 8) & 0xff; 611 580 buf[2] = (relocs[i] >> 16) & 0xff; 612 581 buf[3] = (relocs[i] >> 24) & 0xff; 613 - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); 582 + fwrite(buf, 4, 1, stdout); 614 583 } 615 584 } 616 585 } ··· 626 597 const char *fname; 627 598 FILE *fp; 628 599 int i; 600 + 601 + regex_init(); 629 602 630 603 show_absolute_syms = 0; 631 604 show_absolute_relocs = 0;
+6 -2
arch/x86/include/asm/swiotlb.h
··· 5 5 6 6 #ifdef CONFIG_SWIOTLB 7 7 extern int swiotlb; 8 - extern int pci_swiotlb_init(void); 8 + extern int __init pci_swiotlb_detect(void); 9 + extern void __init pci_swiotlb_init(void); 9 10 #else 10 11 #define swiotlb 0 11 - static inline int pci_swiotlb_init(void) 12 + static inline int pci_swiotlb_detect(void) 12 13 { 13 14 return 0; 15 + } 16 + static inline void pci_swiotlb_init(void) 17 + { 14 18 } 15 19 #endif 16 20
+10 -22
arch/x86/include/asm/syscalls.h
··· 18 18 /* Common in X86_32 and X86_64 */ 19 19 /* kernel/ioport.c */ 20 20 asmlinkage long sys_ioperm(unsigned long, unsigned long, int); 21 + long sys_iopl(unsigned int, struct pt_regs *); 21 22 22 23 /* kernel/process.c */ 23 24 int sys_fork(struct pt_regs *); 24 25 int sys_vfork(struct pt_regs *); 26 + long sys_execve(char __user *, char __user * __user *, 27 + char __user * __user *, struct pt_regs *); 28 + long sys_clone(unsigned long, unsigned long, void __user *, 29 + void __user *, struct pt_regs *); 25 30 26 31 /* kernel/ldt.c */ 27 32 asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); 28 33 29 34 /* kernel/signal.c */ 30 35 long sys_rt_sigreturn(struct pt_regs *); 36 + long sys_sigaltstack(const stack_t __user *, stack_t __user *, 37 + struct pt_regs *); 38 + 31 39 32 40 /* kernel/tls.c */ 33 41 asmlinkage int sys_set_thread_area(struct user_desc __user *); ··· 43 35 44 36 /* X86_32 only */ 45 37 #ifdef CONFIG_X86_32 46 - /* kernel/ioport.c */ 47 - long sys_iopl(struct pt_regs *); 48 - 49 - /* kernel/process_32.c */ 50 - int sys_clone(struct pt_regs *); 51 - int sys_execve(struct pt_regs *); 52 38 53 39 /* kernel/signal.c */ 54 40 asmlinkage int sys_sigsuspend(int, int, old_sigset_t); 55 41 asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, 56 42 struct old_sigaction __user *); 57 - int sys_sigaltstack(struct pt_regs *); 58 43 unsigned long sys_sigreturn(struct pt_regs *); 59 44 60 45 /* kernel/sys_i386_32.c */ ··· 63 62 asmlinkage int sys_olduname(struct oldold_utsname __user *); 64 63 65 64 /* kernel/vm86_32.c */ 66 - int sys_vm86old(struct pt_regs *); 67 - int sys_vm86(struct pt_regs *); 65 + int sys_vm86old(struct vm86_struct __user *, struct pt_regs *); 66 + int sys_vm86(unsigned long, unsigned long, struct pt_regs *); 68 67 69 68 #else /* CONFIG_X86_32 */ 70 69 71 70 /* X86_64 only */ 72 - /* kernel/ioport.c */ 73 - asmlinkage long sys_iopl(unsigned int, struct pt_regs *); 74 - 75 71 /* kernel/process_64.c */ 76 - asmlinkage long sys_clone(unsigned long, unsigned long, 77 - void __user *, void __user *, 78 - struct pt_regs *); 79 - asmlinkage long sys_execve(char __user *, char __user * __user *, 80 - char __user * __user *, 81 - struct pt_regs *); 82 72 long sys_arch_prctl(int, unsigned long); 83 - 84 - /* kernel/signal.c */ 85 - asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *, 86 - struct pt_regs *); 87 73 88 74 /* kernel/sys_x86_64.c */ 89 75 struct new_utsname;
+12 -10
arch/x86/kernel/cpu/mcheck/mce-inject.c
··· 74 74 m->finished = 0; 75 75 } 76 76 77 - static cpumask_t mce_inject_cpumask; 77 + static cpumask_var_t mce_inject_cpumask; 78 78 79 79 static int mce_raise_notify(struct notifier_block *self, 80 80 unsigned long val, void *data) ··· 82 82 struct die_args *args = (struct die_args *)data; 83 83 int cpu = smp_processor_id(); 84 84 struct mce *m = &__get_cpu_var(injectm); 85 - if (val != DIE_NMI_IPI || !cpu_isset(cpu, mce_inject_cpumask)) 85 + if (val != DIE_NMI_IPI || !cpumask_test_cpu(cpu, mce_inject_cpumask)) 86 86 return NOTIFY_DONE; 87 - cpu_clear(cpu, mce_inject_cpumask); 87 + cpumask_clear_cpu(cpu, mce_inject_cpumask); 88 88 if (m->inject_flags & MCJ_EXCEPTION) 89 89 raise_exception(m, args->regs); 90 90 else if (m->status) ··· 148 148 unsigned long start; 149 149 int cpu; 150 150 get_online_cpus(); 151 - mce_inject_cpumask = cpu_online_map; 152 - cpu_clear(get_cpu(), mce_inject_cpumask); 151 + cpumask_copy(mce_inject_cpumask, cpu_online_mask); 152 + cpumask_clear_cpu(get_cpu(), mce_inject_cpumask); 153 153 for_each_online_cpu(cpu) { 154 154 struct mce *mcpu = &per_cpu(injectm, cpu); 155 155 if (!mcpu->finished || 156 156 MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM) 157 - cpu_clear(cpu, mce_inject_cpumask); 157 + cpumask_clear_cpu(cpu, mce_inject_cpumask); 158 158 } 159 - if (!cpus_empty(mce_inject_cpumask)) 160 - apic->send_IPI_mask(&mce_inject_cpumask, NMI_VECTOR); 159 + if (!cpumask_empty(mce_inject_cpumask)) 160 + apic->send_IPI_mask(mce_inject_cpumask, NMI_VECTOR); 161 161 start = jiffies; 162 - while (!cpus_empty(mce_inject_cpumask)) { 162 + while (!cpumask_empty(mce_inject_cpumask)) { 163 163 if (!time_before(jiffies, start + 2*HZ)) { 164 164 printk(KERN_ERR 165 165 "Timeout waiting for mce inject NMI %lx\n", 166 - *cpus_addr(mce_inject_cpumask)); 166 + *cpumask_bits(mce_inject_cpumask)); 167 167 break; 168 168 } 169 169 cpu_relax(); ··· 210 210 211 211 static int inject_init(void) 212 212 { 213 + if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) 214 + return -ENOMEM; 213 215 printk(KERN_INFO "Machine check injector initialized\n"); 214 216 mce_chrdev_ops.write = mce_write; 215 217 register_die_notifier(&mce_raise_nb);
+52 -17
arch/x86/kernel/entry_32.S
··· 725 725 /* 726 726 * System calls that need a pt_regs pointer. 727 727 */ 728 - #define PTREGSCALL(name) \ 728 + #define PTREGSCALL0(name) \ 729 729 ALIGN; \ 730 730 ptregs_##name: \ 731 731 leal 4(%esp),%eax; \ 732 732 jmp sys_##name; 733 733 734 - PTREGSCALL(iopl) 735 - PTREGSCALL(fork) 736 - PTREGSCALL(clone) 737 - PTREGSCALL(vfork) 738 - PTREGSCALL(execve) 739 - PTREGSCALL(sigaltstack) 740 - PTREGSCALL(sigreturn) 741 - PTREGSCALL(rt_sigreturn) 742 - PTREGSCALL(vm86) 743 - PTREGSCALL(vm86old) 734 + #define PTREGSCALL1(name) \ 735 + ALIGN; \ 736 + ptregs_##name: \ 737 + leal 4(%esp),%edx; \ 738 + movl (PT_EBX+4)(%esp),%eax; \ 739 + jmp sys_##name; 740 + 741 + #define PTREGSCALL2(name) \ 742 + ALIGN; \ 743 + ptregs_##name: \ 744 + leal 4(%esp),%ecx; \ 745 + movl (PT_ECX+4)(%esp),%edx; \ 746 + movl (PT_EBX+4)(%esp),%eax; \ 747 + jmp sys_##name; 748 + 749 + #define PTREGSCALL3(name) \ 750 + ALIGN; \ 751 + ptregs_##name: \ 752 + leal 4(%esp),%eax; \ 753 + pushl %eax; \ 754 + movl PT_EDX(%eax),%ecx; \ 755 + movl PT_ECX(%eax),%edx; \ 756 + movl PT_EBX(%eax),%eax; \ 757 + call sys_##name; \ 758 + addl $4,%esp; \ 759 + ret 760 + 761 + PTREGSCALL1(iopl) 762 + PTREGSCALL0(fork) 763 + PTREGSCALL0(vfork) 764 + PTREGSCALL3(execve) 765 + PTREGSCALL2(sigaltstack) 766 + PTREGSCALL0(sigreturn) 767 + PTREGSCALL0(rt_sigreturn) 768 + PTREGSCALL2(vm86) 769 + PTREGSCALL1(vm86old) 770 + 771 + /* Clone is an oddball. The 4th arg is in %edi */ 772 + ALIGN; 773 + ptregs_clone: 774 + leal 4(%esp),%eax 775 + pushl %eax 776 + pushl PT_EDI(%eax) 777 + movl PT_EDX(%eax),%ecx 778 + movl PT_ECX(%eax),%edx 779 + movl PT_EBX(%eax),%eax 780 + call sys_clone 781 + addl $8,%esp 782 + ret 744 783 745 784 .macro FIXUP_ESPFIX_STACK 746 785 /* ··· 1047 1008 ENTRY(kernel_thread_helper) 1048 1009 pushl $0 # fake return address for unwinder 1049 1010 CFI_STARTPROC 1050 - movl %edx,%eax 1051 - push %edx 1052 - CFI_ADJUST_CFA_OFFSET 4 1053 - call *%ebx 1054 - push %eax 1055 - CFI_ADJUST_CFA_OFFSET 4 1011 + movl %edi,%eax 1012 + call *%esi 1056 1013 call do_exit 1057 1014 ud2 # padding for call trace 1058 1015 CFI_ENDPROC
+3 -46
arch/x86/kernel/entry_64.S
··· 1166 1166 jmp 2b 1167 1167 .previous 1168 1168 1169 - /* 1170 - * Create a kernel thread. 1171 - * 1172 - * C extern interface: 1173 - * extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 1174 - * 1175 - * asm input arguments: 1176 - * rdi: fn, rsi: arg, rdx: flags 1177 - */ 1178 - ENTRY(kernel_thread) 1179 - CFI_STARTPROC 1180 - FAKE_STACK_FRAME $child_rip 1181 - SAVE_ALL 1182 - 1183 - # rdi: flags, rsi: usp, rdx: will be &pt_regs 1184 - movq %rdx,%rdi 1185 - orq kernel_thread_flags(%rip),%rdi 1186 - movq $-1, %rsi 1187 - movq %rsp, %rdx 1188 - 1189 - xorl %r8d,%r8d 1190 - xorl %r9d,%r9d 1191 - 1192 - # clone now 1193 - call do_fork 1194 - movq %rax,RAX(%rsp) 1195 - xorl %edi,%edi 1196 - 1197 - /* 1198 - * It isn't worth to check for reschedule here, 1199 - * so internally to the x86_64 port you can rely on kernel_thread() 1200 - * not to reschedule the child before returning, this avoids the need 1201 - * of hacks for example to fork off the per-CPU idle tasks. 1202 - * [Hopefully no generic code relies on the reschedule -AK] 1203 - */ 1204 - RESTORE_ALL 1205 - UNFAKE_STACK_FRAME 1206 - ret 1207 - CFI_ENDPROC 1208 - END(kernel_thread) 1209 - 1210 - ENTRY(child_rip) 1169 + ENTRY(kernel_thread_helper) 1211 1170 pushq $0 # fake return address 1212 1171 CFI_STARTPROC 1213 1172 /* 1214 1173 * Here we are in the child and the registers are set as they were 1215 1174 * at kernel_thread() invocation in the parent. 1216 1175 */ 1217 - movq %rdi, %rax 1218 - movq %rsi, %rdi 1219 - call *%rax 1176 + call *%rsi 1220 1177 # exit 1221 1178 mov %eax, %edi 1222 1179 call do_exit 1223 1180 ud2 # padding for call trace 1224 1181 CFI_ENDPROC 1225 - END(child_rip) 1182 + END(kernel_thread_helper) 1226 1183 1227 1184 /* 1228 1185 * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
+4 -24
arch/x86/kernel/ioport.c
··· 103 103 * on system-call entry - see also fork() and the signal handling 104 104 * code. 105 105 */ 106 - static int do_iopl(unsigned int level, struct pt_regs *regs) 106 + long sys_iopl(unsigned int level, struct pt_regs *regs) 107 107 { 108 108 unsigned int old = (regs->flags >> 12) & 3; 109 + struct thread_struct *t = &current->thread; 109 110 110 111 if (level > 3) 111 112 return -EINVAL; ··· 116 115 return -EPERM; 117 116 } 118 117 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); 118 + t->iopl = level << 12; 119 + set_iopl_mask(t->iopl); 119 120 120 121 return 0; 121 122 } 122 - 123 - #ifdef CONFIG_X86_32 124 - long sys_iopl(struct pt_regs *regs) 125 - { 126 - unsigned int level = regs->bx; 127 - struct thread_struct *t = &current->thread; 128 - int rc; 129 - 130 - rc = do_iopl(level, regs); 131 - if (rc < 0) 132 - goto out; 133 - 134 - t->iopl = level << 12; 135 - set_iopl_mask(t->iopl); 136 - out: 137 - return rc; 138 - } 139 - #else 140 - asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs) 141 - { 142 - return do_iopl(level, regs); 143 - } 144 - #endif
+2 -3
arch/x86/kernel/msr.c
··· 172 172 173 173 static int msr_open(struct inode *inode, struct file *file) 174 174 { 175 - unsigned int cpu = iminor(file->f_path.dentry->d_inode); 176 - struct cpuinfo_x86 *c = &cpu_data(cpu); 175 + unsigned int cpu; 176 + struct cpuinfo_x86 *c; 177 177 178 178 cpu = iminor(file->f_path.dentry->d_inode); 179 - 180 179 if (cpu >= nr_cpu_ids || !cpu_online(cpu)) 181 180 return -ENXIO; /* No such CPU */ 182 181
+4 -5
arch/x86/kernel/pci-dma.c
··· 120 120 121 121 void __init pci_iommu_alloc(void) 122 122 { 123 - int use_swiotlb; 124 - 125 - use_swiotlb = pci_swiotlb_init(); 126 123 #ifdef CONFIG_X86_64 127 124 /* free the range so iommu could get some range less than 4G */ 128 125 dma32_free_bootmem(); 129 126 #endif 130 - if (use_swiotlb) 131 - return; 127 + if (pci_swiotlb_detect()) 128 + goto out; 132 129 133 130 gart_iommu_hole_init(); 134 131 ··· 135 138 136 139 /* needs to be called after gart_iommu_hole_init */ 137 140 amd_iommu_detect(); 141 + out: 142 + pci_swiotlb_init(); 138 143 } 139 144 140 145 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
+7 -4
arch/x86/kernel/pci-swiotlb.c
··· 43 43 }; 44 44 45 45 /* 46 - * pci_swiotlb_init - initialize swiotlb if necessary 46 + * pci_swiotlb_detect - set swiotlb to 1 if necessary 47 47 * 48 48 * This returns non-zero if we are forced to use swiotlb (by the boot 49 49 * option). 50 50 */ 51 - int __init pci_swiotlb_init(void) 51 + int __init pci_swiotlb_detect(void) 52 52 { 53 53 int use_swiotlb = swiotlb | swiotlb_force; 54 54 ··· 60 60 if (swiotlb_force) 61 61 swiotlb = 1; 62 62 63 + return use_swiotlb; 64 + } 65 + 66 + void __init pci_swiotlb_init(void) 67 + { 63 68 if (swiotlb) { 64 69 swiotlb_init(0); 65 70 dma_ops = &swiotlb_dma_ops; 66 71 } 67 - 68 - return use_swiotlb; 69 72 }
+70
arch/x86/kernel/process.c
··· 255 255 NULL, NULL); 256 256 } 257 257 258 + long 259 + sys_clone(unsigned long clone_flags, unsigned long newsp, 260 + void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) 261 + { 262 + if (!newsp) 263 + newsp = regs->sp; 264 + return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); 265 + } 266 + 267 + /* 268 + * This gets run with %si containing the 269 + * function to call, and %di containing 270 + * the "args". 271 + */ 272 + extern void kernel_thread_helper(void); 273 + 274 + /* 275 + * Create a kernel thread 276 + */ 277 + int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) 278 + { 279 + struct pt_regs regs; 280 + 281 + memset(&regs, 0, sizeof(regs)); 282 + 283 + regs.si = (unsigned long) fn; 284 + regs.di = (unsigned long) arg; 285 + 286 + #ifdef CONFIG_X86_32 287 + regs.ds = __USER_DS; 288 + regs.es = __USER_DS; 289 + regs.fs = __KERNEL_PERCPU; 290 + regs.gs = __KERNEL_STACK_CANARY; 291 + #endif 292 + 293 + regs.orig_ax = -1; 294 + regs.ip = (unsigned long) kernel_thread_helper; 295 + regs.cs = __KERNEL_CS | get_kernel_rpl(); 296 + regs.flags = X86_EFLAGS_IF | 0x2; 297 + 298 + /* Ok, create the new process.. */ 299 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 300 + } 301 + EXPORT_SYMBOL(kernel_thread); 302 + 303 + /* 304 + * sys_execve() executes a new program. 305 + */ 306 + long sys_execve(char __user *name, char __user * __user *argv, 307 + char __user * __user *envp, struct pt_regs *regs) 308 + { 309 + long error; 310 + char *filename; 311 + 312 + filename = getname(name); 313 + error = PTR_ERR(filename); 314 + if (IS_ERR(filename)) 315 + return error; 316 + error = do_execve(filename, argv, envp, regs); 317 + 318 + #ifdef CONFIG_X86_32 319 + if (error == 0) { 320 + /* Make sure we don't return using sysenter.. */ 321 + set_thread_flag(TIF_IRET); 322 + } 323 + #endif 324 + 325 + putname(filename); 326 + return error; 327 + } 258 328 259 329 /* 260 330 * Idle related variables and functions
-73
arch/x86/kernel/process_32.c
··· 180 180 show_trace(NULL, regs, &regs->sp, regs->bp); 181 181 } 182 182 183 - /* 184 - * This gets run with %bx containing the 185 - * function to call, and %dx containing 186 - * the "args". 187 - */ 188 - extern void kernel_thread_helper(void); 189 - 190 - /* 191 - * Create a kernel thread 192 - */ 193 - int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) 194 - { 195 - struct pt_regs regs; 196 - 197 - memset(&regs, 0, sizeof(regs)); 198 - 199 - regs.bx = (unsigned long) fn; 200 - regs.dx = (unsigned long) arg; 201 - 202 - regs.ds = __USER_DS; 203 - regs.es = __USER_DS; 204 - regs.fs = __KERNEL_PERCPU; 205 - regs.gs = __KERNEL_STACK_CANARY; 206 - regs.orig_ax = -1; 207 - regs.ip = (unsigned long) kernel_thread_helper; 208 - regs.cs = __KERNEL_CS | get_kernel_rpl(); 209 - regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; 210 - 211 - /* Ok, create the new process.. */ 212 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 213 - } 214 - EXPORT_SYMBOL(kernel_thread); 215 - 216 183 void release_thread(struct task_struct *dead_task) 217 184 { 218 185 BUG_ON(dead_task->mm); ··· 389 422 percpu_write(current_task, next_p); 390 423 391 424 return prev_p; 392 - } 393 - 394 - int sys_clone(struct pt_regs *regs) 395 - { 396 - unsigned long clone_flags; 397 - unsigned long newsp; 398 - int __user *parent_tidptr, *child_tidptr; 399 - 400 - clone_flags = regs->bx; 401 - newsp = regs->cx; 402 - parent_tidptr = (int __user *)regs->dx; 403 - child_tidptr = (int __user *)regs->di; 404 - if (!newsp) 405 - newsp = regs->sp; 406 - return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); 407 - } 408 - 409 - /* 410 - * sys_execve() executes a new program. 411 - */ 412 - int sys_execve(struct pt_regs *regs) 413 - { 414 - int error; 415 - char *filename; 416 - 417 - filename = getname((char __user *) regs->bx); 418 - error = PTR_ERR(filename); 419 - if (IS_ERR(filename)) 420 - goto out; 421 - error = do_execve(filename, 422 - (char __user * __user *) regs->cx, 423 - (char __user * __user *) regs->dx, 424 - regs); 425 - if (error == 0) { 426 - /* Make sure we don't return using sysenter.. */ 427 - set_thread_flag(TIF_IRET); 428 - } 429 - putname(filename); 430 - out: 431 - return error; 432 425 } 433 426 434 427 #define top_esp (THREAD_SIZE - sizeof(unsigned long))
+3 -32
arch/x86/kernel/process_64.c
··· 57 57 DEFINE_PER_CPU(unsigned long, old_rsp); 58 58 static DEFINE_PER_CPU(unsigned char, is_idle); 59 59 60 - unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; 61 - 62 60 static ATOMIC_NOTIFIER_HEAD(idle_notifier); 63 61 64 62 void idle_notifier_register(struct notifier_block *n) ··· 271 273 *childregs = *regs; 272 274 273 275 childregs->ax = 0; 274 - childregs->sp = sp; 275 - if (sp == ~0UL) 276 + if (user_mode(regs)) 277 + childregs->sp = sp; 278 + else 276 279 childregs->sp = (unsigned long)childregs; 277 280 278 281 p->thread.sp = (unsigned long) childregs; ··· 507 508 return prev_p; 508 509 } 509 510 510 - /* 511 - * sys_execve() executes a new program. 512 - */ 513 - asmlinkage 514 - long sys_execve(char __user *name, char __user * __user *argv, 515 - char __user * __user *envp, struct pt_regs *regs) 516 - { 517 - long error; 518 - char *filename; 519 - 520 - filename = getname(name); 521 - error = PTR_ERR(filename); 522 - if (IS_ERR(filename)) 523 - return error; 524 - error = do_execve(filename, argv, envp, regs); 525 - putname(filename); 526 - return error; 527 - } 528 - 529 511 void set_personality_64bit(void) 530 512 { 531 513 /* inherit personality from parent */ ··· 519 539 so it's not too bad. The main problem is just that 520 540 32bit childs are affected again. */ 521 541 current->personality &= ~READ_IMPLIES_EXEC; 522 - } 523 - 524 - asmlinkage long 525 - sys_clone(unsigned long clone_flags, unsigned long newsp, 526 - void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) 527 - { 528 - if (!newsp) 529 - newsp = regs->sp; 530 - return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); 531 542 } 532 543 533 544 unsigned long get_wchan(struct task_struct *p)
+1 -11
arch/x86/kernel/signal.c
··· 545 545 } 546 546 #endif /* CONFIG_X86_32 */ 547 547 548 - #ifdef CONFIG_X86_32 549 - int sys_sigaltstack(struct pt_regs *regs) 550 - { 551 - const stack_t __user *uss = (const stack_t __user *)regs->bx; 552 - stack_t __user *uoss = (stack_t __user *)regs->cx; 553 - 554 - return do_sigaltstack(uss, uoss, regs->sp); 555 - } 556 - #else /* !CONFIG_X86_32 */ 557 - asmlinkage long 548 + long 558 549 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 559 550 struct pt_regs *regs) 560 551 { 561 552 return do_sigaltstack(uss, uoss, regs->sp); 562 553 } 563 - #endif /* CONFIG_X86_32 */ 564 554 565 555 /* 566 556 * Do a signal return; undo the signal stack.
+5 -6
arch/x86/kernel/vm86_32.c
··· 197 197 static int do_vm86_irq_handling(int subfunction, int irqnumber); 198 198 static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk); 199 199 200 - int sys_vm86old(struct pt_regs *regs) 200 + int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs) 201 201 { 202 - struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx; 203 202 struct kernel_vm86_struct info; /* declare this _on top_, 204 203 * this avoids wasting of stack space. 205 204 * This remains on the stack until we ··· 226 227 } 227 228 228 229 229 - int sys_vm86(struct pt_regs *regs) 230 + int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs) 230 231 { 231 232 struct kernel_vm86_struct info; /* declare this _on top_, 232 233 * this avoids wasting of stack space. ··· 238 239 struct vm86plus_struct __user *v86; 239 240 240 241 tsk = current; 241 - switch (regs->bx) { 242 + switch (cmd) { 242 243 case VM86_REQUEST_IRQ: 243 244 case VM86_FREE_IRQ: 244 245 case VM86_GET_IRQ_BITS: 245 246 case VM86_GET_AND_RESET_IRQ: 246 - ret = do_vm86_irq_handling(regs->bx, (int)regs->cx); 247 + ret = do_vm86_irq_handling(cmd, (int)arg); 247 248 goto out; 248 249 case VM86_PLUS_INSTALL_CHECK: 249 250 /* ··· 260 261 ret = -EPERM; 261 262 if (tsk->thread.saved_sp0) 262 263 goto out; 263 - v86 = (struct vm86plus_struct __user *)regs->cx; 264 + v86 = (struct vm86plus_struct __user *)arg; 264 265 tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, 265 266 offsetof(struct kernel_vm86_struct, regs32) - 266 267 sizeof(info.regs));
+1 -3
arch/x86/kernel/vmlinux.lds.S
··· 319 319 __brk_limit = .; 320 320 } 321 321 322 - .end : AT(ADDR(.end) - LOAD_OFFSET) { 323 - _end = .; 324 - } 322 + _end = .; 325 323 326 324 STABS_DEBUG 327 325 DWARF_DEBUG
-2
arch/x86/kernel/x8664_ksyms_64.c
··· 17 17 EXPORT_SYMBOL(mcount); 18 18 #endif 19 19 20 - EXPORT_SYMBOL(kernel_thread); 21 - 22 20 EXPORT_SYMBOL(__get_user_1); 23 21 EXPORT_SYMBOL(__get_user_2); 24 22 EXPORT_SYMBOL(__get_user_4);
+5 -5
arch/x86/tools/gen-insn-attr-x86.awk
··· 226 226 } 227 227 228 228 # convert operands to flags. 229 - function convert_operands(opnd, i,imm,mod) 229 + function convert_operands(count,opnd, i,j,imm,mod) 230 230 { 231 231 imm = null 232 232 mod = null 233 - for (i in opnd) { 234 - i = opnd[i] 233 + for (j = 1; j <= count; j++) { 234 + i = opnd[j] 235 235 if (match(i, imm_expr) == 1) { 236 236 if (!imm_flag[i]) 237 237 semantic_error("Unknown imm opnd: " i) ··· 282 282 # parse one opcode 283 283 if (match($i, opnd_expr)) { 284 284 opnd = $i 285 - split($(i++), opnds, ",") 286 - flags = convert_operands(opnds) 285 + count = split($(i++), opnds, ",") 286 + flags = convert_operands(count, opnds) 287 287 } 288 288 if (match($i, ext_expr)) 289 289 ext = $(i++)