aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/cpu/common.c6
-rw-r--r--arch/x86/kernel/cpu/intel.c4
-rw-r--r--arch/x86/kernel/entry_32.S3
-rw-r--r--arch/x86/kernel/entry_64.S3
-rw-r--r--arch/x86/kernel/head_32.S3
-rw-r--r--arch/x86/kernel/head_64.S4
-rw-r--r--arch/x86/kernel/kprobes/core.c54
-rw-r--r--arch/x86/kernel/kprobes/opt.c2
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kernel/ptrace.c10
-rw-r--r--arch/x86/kernel/syscall_32.c16
-rw-r--r--arch/x86/kernel/traps.c21
13 files changed, 95 insertions, 34 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index cdb1b70ddad0..c887cd944f0c 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_X86_32) += i386_ksyms_32.o
32obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o 32obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
33obj-$(CONFIG_X86_64) += mcount_64.o 33obj-$(CONFIG_X86_64) += mcount_64.o
34obj-y += syscall_$(BITS).o vsyscall_gtod.o 34obj-y += syscall_$(BITS).o vsyscall_gtod.o
35obj-$(CONFIG_IA32_EMULATION) += syscall_32.o
35obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o 36obj-$(CONFIG_X86_VSYSCALL_EMULATION) += vsyscall_64.o vsyscall_emu_64.o
36obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o 37obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
37obj-$(CONFIG_SYSFS) += ksysfs.o 38obj-$(CONFIG_SYSFS) += ksysfs.o
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index b5c8ff5e9dfc..2346c95c6ab1 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1396,6 +1396,12 @@ void cpu_init(void)
1396 1396
1397 wait_for_master_cpu(cpu); 1397 wait_for_master_cpu(cpu);
1398 1398
1399 /*
1400 * Initialize the CR4 shadow before doing anything that could
1401 * try to read it.
1402 */
1403 cr4_init_shadow();
1404
1399 show_ucode_info_early(); 1405 show_ucode_info_early();
1400 1406
1401 printk(KERN_INFO "Initializing CPU#%d\n", cpu); 1407 printk(KERN_INFO "Initializing CPU#%d\n", cpu);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 94d7dcb12145..50163fa9034f 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -565,8 +565,8 @@ static const struct _tlb_table intel_tlb_table[] = {
565 { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, 565 { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" },
566 { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, 566 { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" },
567 { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, 567 { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" },
568 { 0xb5, TLB_INST_4K, 64, " TLB_INST 4 KByte pages, 8-way set ssociative" }, 568 { 0xb5, TLB_INST_4K, 64, " TLB_INST 4 KByte pages, 8-way set associative" },
569 { 0xb6, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 8-way set ssociative" }, 569 { 0xb6, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 8-way set associative" },
570 { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, 570 { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" },
571 { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, 571 { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" },
572 { 0xc1, STLB_4K_2M, 1024, " STLB 4 KByte and 2 MByte pages, 8-way associative" }, 572 { 0xc1, STLB_4K_2M, 1024, " STLB 4 KByte and 2 MByte pages, 8-way associative" },
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index b910577d1ff9..7e0323cc0b7d 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -976,6 +976,9 @@ ENTRY(xen_hypervisor_callback)
976ENTRY(xen_do_upcall) 976ENTRY(xen_do_upcall)
9771: mov %esp, %eax 9771: mov %esp, %eax
978 call xen_evtchn_do_upcall 978 call xen_evtchn_do_upcall
979#ifndef CONFIG_PREEMPT
980 call xen_maybe_preempt_hcall
981#endif
979 jmp ret_from_intr 982 jmp ret_from_intr
980 CFI_ENDPROC 983 CFI_ENDPROC
981ENDPROC(xen_hypervisor_callback) 984ENDPROC(xen_hypervisor_callback)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index db13655c3a2a..10074ad9ebf8 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1208,6 +1208,9 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
1208 popq %rsp 1208 popq %rsp
1209 CFI_DEF_CFA_REGISTER rsp 1209 CFI_DEF_CFA_REGISTER rsp
1210 decl PER_CPU_VAR(irq_count) 1210 decl PER_CPU_VAR(irq_count)
1211#ifndef CONFIG_PREEMPT
1212 call xen_maybe_preempt_hcall
1213#endif
1211 jmp error_exit 1214 jmp error_exit
1212 CFI_ENDPROC 1215 CFI_ENDPROC
1213END(xen_do_hypervisor_callback) 1216END(xen_do_hypervisor_callback)
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index f36bd42d6f0c..d031bad9e07e 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -22,6 +22,7 @@
22#include <asm/cpufeature.h> 22#include <asm/cpufeature.h>
23#include <asm/percpu.h> 23#include <asm/percpu.h>
24#include <asm/nops.h> 24#include <asm/nops.h>
25#include <asm/bootparam.h>
25 26
26/* Physical address */ 27/* Physical address */
27#define pa(X) ((X) - __PAGE_OFFSET) 28#define pa(X) ((X) - __PAGE_OFFSET)
@@ -90,7 +91,7 @@ ENTRY(startup_32)
90 91
91 /* test KEEP_SEGMENTS flag to see if the bootloader is asking 92 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
92 us to not reload segments */ 93 us to not reload segments */
93 testb $(1<<6), BP_loadflags(%esi) 94 testb $KEEP_SEGMENTS, BP_loadflags(%esi)
94 jnz 2f 95 jnz 2f
95 96
96/* 97/*
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 6fd514d9f69a..9a0919678f97 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/head.S -- start in 32bit and switch to 64bit 2 * linux/arch/x86/kernel/head_64.S -- start in 32bit and switch to 64bit
3 * 3 *
4 * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE 4 * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
5 * Copyright (C) 2000 Pavel Machek <pavel@suse.cz> 5 * Copyright (C) 2000 Pavel Machek <pavel@suse.cz>
@@ -56,7 +56,7 @@ startup_64:
56 * %rsi holds a physical pointer to real_mode_data. 56 * %rsi holds a physical pointer to real_mode_data.
57 * 57 *
58 * We come here either directly from a 64bit bootloader, or from 58 * We come here either directly from a 64bit bootloader, or from
59 * arch/x86_64/boot/compressed/head.S. 59 * arch/x86/boot/compressed/head_64.S.
60 * 60 *
61 * We only come here initially at boot nothing else comes here. 61 * We only come here initially at boot nothing else comes here.
62 * 62 *
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 6a1146ea4d4d..4e3d5a9621fe 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -223,27 +223,48 @@ static unsigned long
223__recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) 223__recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
224{ 224{
225 struct kprobe *kp; 225 struct kprobe *kp;
226 unsigned long faddr;
226 227
227 kp = get_kprobe((void *)addr); 228 kp = get_kprobe((void *)addr);
228 /* There is no probe, return original address */ 229 faddr = ftrace_location(addr);
229 if (!kp) 230 /*
231 * Addresses inside the ftrace location are refused by
232 * arch_check_ftrace_location(). Something went terribly wrong
233 * if such an address is checked here.
234 */
235 if (WARN_ON(faddr && faddr != addr))
236 return 0UL;
237 /*
238 * Use the current code if it is not modified by Kprobe
239 * and it cannot be modified by ftrace.
240 */
241 if (!kp && !faddr)
230 return addr; 242 return addr;
231 243
232 /* 244 /*
233 * Basically, kp->ainsn.insn has an original instruction. 245 * Basically, kp->ainsn.insn has an original instruction.
234 * However, RIP-relative instruction can not do single-stepping 246 * However, RIP-relative instruction can not do single-stepping
235 * at different place, __copy_instruction() tweaks the displacement of 247 * at different place, __copy_instruction() tweaks the displacement of
236 * that instruction. In that case, we can't recover the instruction 248 * that instruction. In that case, we can't recover the instruction
237 * from the kp->ainsn.insn. 249 * from the kp->ainsn.insn.
238 * 250 *
239 * On the other hand, kp->opcode has a copy of the first byte of 251 * On the other hand, in case on normal Kprobe, kp->opcode has a copy
240 * the probed instruction, which is overwritten by int3. And 252 * of the first byte of the probed instruction, which is overwritten
241 * the instruction at kp->addr is not modified by kprobes except 253 * by int3. And the instruction at kp->addr is not modified by kprobes
242 * for the first byte, we can recover the original instruction 254 * except for the first byte, we can recover the original instruction
243 * from it and kp->opcode. 255 * from it and kp->opcode.
256 *
257 * In case of Kprobes using ftrace, we do not have a copy of
258 * the original instruction. In fact, the ftrace location might
259 * be modified at anytime and even could be in an inconsistent state.
260 * Fortunately, we know that the original code is the ideal 5-byte
261 * long NOP.
244 */ 262 */
245 memcpy(buf, kp->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 263 memcpy(buf, (void *)addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
246 buf[0] = kp->opcode; 264 if (faddr)
265 memcpy(buf, ideal_nops[NOP_ATOMIC5], 5);
266 else
267 buf[0] = kp->opcode;
247 return (unsigned long)buf; 268 return (unsigned long)buf;
248} 269}
249 270
@@ -251,6 +272,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
251 * Recover the probed instruction at addr for further analysis. 272 * Recover the probed instruction at addr for further analysis.
252 * Caller must lock kprobes by kprobe_mutex, or disable preemption 273 * Caller must lock kprobes by kprobe_mutex, or disable preemption
253 * for preventing to release referencing kprobes. 274 * for preventing to release referencing kprobes.
275 * Returns zero if the instruction can not get recovered.
254 */ 276 */
255unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr) 277unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr)
256{ 278{
@@ -285,6 +307,8 @@ static int can_probe(unsigned long paddr)
285 * normally used, we just go through if there is no kprobe. 307 * normally used, we just go through if there is no kprobe.
286 */ 308 */
287 __addr = recover_probed_instruction(buf, addr); 309 __addr = recover_probed_instruction(buf, addr);
310 if (!__addr)
311 return 0;
288 kernel_insn_init(&insn, (void *)__addr, MAX_INSN_SIZE); 312 kernel_insn_init(&insn, (void *)__addr, MAX_INSN_SIZE);
289 insn_get_length(&insn); 313 insn_get_length(&insn);
290 314
@@ -333,6 +357,8 @@ int __copy_instruction(u8 *dest, u8 *src)
333 unsigned long recovered_insn = 357 unsigned long recovered_insn =
334 recover_probed_instruction(buf, (unsigned long)src); 358 recover_probed_instruction(buf, (unsigned long)src);
335 359
360 if (!recovered_insn)
361 return 0;
336 kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); 362 kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE);
337 insn_get_length(&insn); 363 insn_get_length(&insn);
338 /* Another subsystem puts a breakpoint, failed to recover */ 364 /* Another subsystem puts a breakpoint, failed to recover */
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
index 0dd8d089c315..7b3b9d15c47a 100644
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -259,6 +259,8 @@ static int can_optimize(unsigned long paddr)
259 */ 259 */
260 return 0; 260 return 0;
261 recovered_insn = recover_probed_instruction(buf, addr); 261 recovered_insn = recover_probed_instruction(buf, addr);
262 if (!recovered_insn)
263 return 0;
262 kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); 264 kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE);
263 insn_get_length(&insn); 265 insn_get_length(&insn);
264 /* Another subsystem puts a breakpoint */ 266 /* Another subsystem puts a breakpoint */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 67fcc43577d2..854b5981b327 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -207,7 +207,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
207 */ 207 */
208 if (clone_flags & CLONE_SETTLS) { 208 if (clone_flags & CLONE_SETTLS) {
209#ifdef CONFIG_IA32_EMULATION 209#ifdef CONFIG_IA32_EMULATION
210 if (test_thread_flag(TIF_IA32)) 210 if (is_ia32_task())
211 err = do_set_thread_area(p, -1, 211 err = do_set_thread_area(p, -1,
212 (struct user_desc __user *)childregs->si, 0); 212 (struct user_desc __user *)childregs->si, 0);
213 else 213 else
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index e510618b2e91..1e125817cf9f 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -364,18 +364,12 @@ static int set_segment_reg(struct task_struct *task,
364 case offsetof(struct user_regs_struct,cs): 364 case offsetof(struct user_regs_struct,cs):
365 if (unlikely(value == 0)) 365 if (unlikely(value == 0))
366 return -EIO; 366 return -EIO;
367#ifdef CONFIG_IA32_EMULATION 367 task_pt_regs(task)->cs = value;
368 if (test_tsk_thread_flag(task, TIF_IA32))
369 task_pt_regs(task)->cs = value;
370#endif
371 break; 368 break;
372 case offsetof(struct user_regs_struct,ss): 369 case offsetof(struct user_regs_struct,ss):
373 if (unlikely(value == 0)) 370 if (unlikely(value == 0))
374 return -EIO; 371 return -EIO;
375#ifdef CONFIG_IA32_EMULATION 372 task_pt_regs(task)->ss = value;
376 if (test_tsk_thread_flag(task, TIF_IA32))
377 task_pt_regs(task)->ss = value;
378#endif
379 break; 373 break;
380 } 374 }
381 375
diff --git a/arch/x86/kernel/syscall_32.c b/arch/x86/kernel/syscall_32.c
index e9bcd57d8a9e..3777189c4a19 100644
--- a/arch/x86/kernel/syscall_32.c
+++ b/arch/x86/kernel/syscall_32.c
@@ -5,21 +5,29 @@
5#include <linux/cache.h> 5#include <linux/cache.h>
6#include <asm/asm-offsets.h> 6#include <asm/asm-offsets.h>
7 7
8#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ; 8#ifdef CONFIG_IA32_EMULATION
9#define SYM(sym, compat) compat
10#else
11#define SYM(sym, compat) sym
12#define ia32_sys_call_table sys_call_table
13#define __NR_ia32_syscall_max __NR_syscall_max
14#endif
15
16#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void SYM(sym, compat)(void) ;
9#include <asm/syscalls_32.h> 17#include <asm/syscalls_32.h>
10#undef __SYSCALL_I386 18#undef __SYSCALL_I386
11 19
12#define __SYSCALL_I386(nr, sym, compat) [nr] = sym, 20#define __SYSCALL_I386(nr, sym, compat) [nr] = SYM(sym, compat),
13 21
14typedef asmlinkage void (*sys_call_ptr_t)(void); 22typedef asmlinkage void (*sys_call_ptr_t)(void);
15 23
16extern asmlinkage void sys_ni_syscall(void); 24extern asmlinkage void sys_ni_syscall(void);
17 25
18__visible const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { 26__visible const sys_call_ptr_t ia32_sys_call_table[__NR_ia32_syscall_max+1] = {
19 /* 27 /*
20 * Smells like a compiler bug -- it doesn't work 28 * Smells like a compiler bug -- it doesn't work
21 * when the & below is removed. 29 * when the & below is removed.
22 */ 30 */
23 [0 ... __NR_syscall_max] = &sys_ni_syscall, 31 [0 ... __NR_ia32_syscall_max] = &sys_ni_syscall,
24#include <asm/syscalls_32.h> 32#include <asm/syscalls_32.h>
25}; 33};
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 9d2073e2ecc9..42819886be0c 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -925,9 +925,17 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
925/* Set of traps needed for early debugging. */ 925/* Set of traps needed for early debugging. */
926void __init early_trap_init(void) 926void __init early_trap_init(void)
927{ 927{
928 set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK); 928 /*
929 * Don't set ist to DEBUG_STACK as it doesn't work until TSS is
930 * ready in cpu_init() <-- trap_init(). Before trap_init(), CPU
931 * runs at ring 0 so it is impossible to hit an invalid stack.
932 * Using the original stack works well enough at this early
933 * stage. DEBUG_STACK will be equipped after cpu_init() in
934 * trap_init().
935 */
936 set_intr_gate_ist(X86_TRAP_DB, &debug, 0);
929 /* int3 can be called from all */ 937 /* int3 can be called from all */
930 set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK); 938 set_system_intr_gate_ist(X86_TRAP_BP, &int3, 0);
931#ifdef CONFIG_X86_32 939#ifdef CONFIG_X86_32
932 set_intr_gate(X86_TRAP_PF, page_fault); 940 set_intr_gate(X86_TRAP_PF, page_fault);
933#endif 941#endif
@@ -1005,6 +1013,15 @@ void __init trap_init(void)
1005 */ 1013 */
1006 cpu_init(); 1014 cpu_init();
1007 1015
1016 /*
1017 * X86_TRAP_DB and X86_TRAP_BP have been set
1018 * in early_trap_init(). However, DEBUG_STACK works only after
1019 * cpu_init() loads TSS. See comments in early_trap_init().
1020 */
1021 set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK);
1022 /* int3 can be called from all */
1023 set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK);
1024
1008 x86_init.irqs.trap_init(); 1025 x86_init.irqs.trap_init();
1009 1026
1010#ifdef CONFIG_X86_64 1027#ifdef CONFIG_X86_64