From 92bc2056855b3250bf6fd5849f05f88d85839efa Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 8 Feb 2008 12:09:56 -0800 Subject: x86: change most X86_32 pt_regs members to unsigned long Signed-off-by: Harvey Harrison Cc: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/process_32.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/x86/kernel/process_32.c') diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 43930e73f657..2cd89b8a7050 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -332,7 +332,7 @@ void __show_registers(struct pt_regs *regs, int all) init_utsname()->version); printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", - 0xffff & regs->cs, regs->ip, regs->flags, + (u16)regs->cs, regs->ip, regs->flags, smp_processor_id()); print_symbol("EIP is at %s\n", regs->ip); @@ -341,8 +341,7 @@ void __show_registers(struct pt_regs *regs, int all) printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", regs->si, regs->di, regs->bp, sp); printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", - regs->ds & 0xffff, regs->es & 0xffff, - regs->fs & 0xffff, gs, ss); + (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss); if (!all) return; -- cgit v1.2.3-59-g8ed1b From 513ad84bf60d96a6998bca10ed07c3d340449be8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 21 Feb 2008 05:18:40 +0100 Subject: x86: de-macro start_thread() Signed-off-by: Ingo Molnar --- arch/x86/kernel/process_32.c | 15 +++++++++++++++ arch/x86/kernel/process_64.c | 15 +++++++++++++++ include/asm-x86/processor.h | 29 +++-------------------------- 3 files changed, 33 insertions(+), 26 deletions(-) (limited to 'arch/x86/kernel/process_32.c') diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 2cd89b8a7050..9230ce060d09 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -512,6 +512,21 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, return err; } +void +start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) +{ + __asm__("movl %0, %%gs" :: "r"(0)); + regs->fs = 0; + set_fs(USER_DS); + regs->ds = __USER_DS; + regs->es = __USER_DS; + regs->ss = __USER_DS; + regs->cs = __USER_CS; + regs->ip = new_ip; + regs->sp = new_sp; +} +EXPORT_SYMBOL_GPL(start_thread); + #ifdef CONFIG_SECCOMP static void hard_disable_TSC(void) { diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 46c4c546b499..1ffce14cff6e 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -528,6 +528,21 @@ out: return err; } +void +start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) +{ + asm volatile("movl %0, %%fs; movl %0, %%es; movl %0, %%ds" :: "r"(0)); + load_gs_index(0); + regs->ip = new_ip; + regs->sp = new_sp; + write_pda(oldrsp, new_sp); + regs->cs = __USER_CS; + regs->ss = __USER_DS; + regs->flags = 0x200; + set_fs(USER_DS); +} +EXPORT_SYMBOL_GPL(start_thread); + /* * This special macro can be used to load a debugging register */ diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 43d2cc829a94..9054734589fe 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -817,20 +817,6 @@ static inline void spin_lock_prefetch(const void *x) .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, \ } -#define start_thread(regs, new_eip, new_esp) \ -do { \ - __asm__("movl %0,%%gs": :"r" (0)); \ - regs->fs = 0; \ - set_fs(USER_DS); \ - regs->ds = __USER_DS; \ - regs->es = __USER_DS; \ - regs->ss = __USER_DS; \ - regs->cs = __USER_CS; \ - regs->ip = new_eip; \ - regs->sp = new_esp; \ -} while (0) - - extern unsigned long thread_saved_pc(struct task_struct *tsk); #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) @@ -887,18 +873,6 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } -#define start_thread(regs, new_rip, new_rsp) do { \ - asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \ - load_gs_index(0); \ - (regs)->ip = (new_rip); \ - (regs)->sp = (new_rsp); \ - write_pda(oldrsp, (new_rsp)); \ - (regs)->cs = __USER_CS; \ - (regs)->ss = __USER_DS; \ - (regs)->flags = 0x200; \ - set_fs(USER_DS); \ -} while (0) - /* * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork. @@ -909,6 +883,9 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ #endif /* CONFIG_X86_64 */ +extern void start_thread(struct pt_regs *regs, unsigned long new_ip, + unsigned long new_sp); + /* * This decides where the kernel will search for a free chunk of vm * space during mmap's. -- cgit v1.2.3-59-g8ed1b From 5b0e508415a83989fe704b4718a1a214bc333ca7 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 10 Mar 2008 13:11:17 +0000 Subject: x86: prevent unconditional writes to DebugCtl MSR Otherwise, enabling (or better, subsequent disabling) of single stepping would cause a kernel oops on CPUs not having this MSR. The patch could have been added a conditional to the MSR write in user_disable_single_step(), but centralizing the updates seems safer and (looking forward) better manageable. Signed-off-by: Jan Beulich Cc: Markus Metzger Signed-off-by: Ingo Molnar --- arch/x86/kernel/kprobes.c | 4 ++-- arch/x86/kernel/process_32.c | 4 ++-- arch/x86/kernel/process_64.c | 4 ++-- arch/x86/kernel/step.c | 2 +- include/asm-x86/processor.h | 9 +++++++++ 5 files changed, 16 insertions(+), 7 deletions(-) (limited to 'arch/x86/kernel/process_32.c') diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 34a591283f5d..1e3de7db9ad5 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -410,13 +410,13 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, static void __kprobes clear_btf(void) { if (test_thread_flag(TIF_DEBUGCTLMSR)) - wrmsrl(MSR_IA32_DEBUGCTLMSR, 0); + update_debugctlmsr(0); } static void __kprobes restore_btf(void) { if (test_thread_flag(TIF_DEBUGCTLMSR)) - wrmsrl(MSR_IA32_DEBUGCTLMSR, current->thread.debugctlmsr); + update_debugctlmsr(current->thread.debugctlmsr); } static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 9230ce060d09..ec05fb750dfc 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -564,12 +564,12 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, /* we clear debugctl to make sure DS * is not in use when we change it */ debugctl = 0; - wrmsrl(MSR_IA32_DEBUGCTLMSR, 0); + update_debugctlmsr(0); wrmsr(MSR_IA32_DS_AREA, next->ds_area_msr, 0); } if (next->debugctlmsr != debugctl) - wrmsr(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr, 0); + update_debugctlmsr(next->debugctlmsr); if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { set_debugreg(next->debugreg0, 0); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 1ffce14cff6e..4f40272474dd 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -563,12 +563,12 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, /* we clear debugctl to make sure DS * is not in use when we change it */ debugctl = 0; - wrmsrl(MSR_IA32_DEBUGCTLMSR, 0); + update_debugctlmsr(0); wrmsrl(MSR_IA32_DS_AREA, next->ds_area_msr); } if (next->debugctlmsr != debugctl) - wrmsrl(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr); + update_debugctlmsr(next->debugctlmsr); if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { loaddebug(next, 0); diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index 071ff4798236..92c20fee6781 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -148,7 +148,7 @@ static void write_debugctlmsr(struct task_struct *child, unsigned long val) if (child != current) return; - wrmsrl(MSR_IA32_DEBUGCTLMSR, val); + update_debugctlmsr(val); } /* diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index cc0268395ea2..40227c9bf51b 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -741,6 +741,15 @@ extern void switch_to_new_gdt(void); extern void cpu_init(void); extern void init_gdt(int cpu); +static inline void update_debugctlmsr(unsigned long debugctlmsr) +{ +#ifndef CONFIG_X86_DEBUGCTLMSR + if (boot_cpu_data.x86 < 6) + return; +#endif + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr); +} + /* * from system description table in BIOS. Mostly for MCA use, but * others may find it useful: -- cgit v1.2.3-59-g8ed1b From 3b22ec7b13cb31e0d87fbc0aabe14caaaad309e8 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 19 Mar 2008 14:25:06 -0300 Subject: x86: always enable irqs when entering idle This matches x86_64 behaviour, which is a superior one IMHO Signed-off-by: Glauber Costa Signed-off-by: Ingo Molnar --- arch/x86/kernel/process_32.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/x86/kernel/process_32.c') diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index ec05fb750dfc..08c41ed5e805 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -127,6 +127,7 @@ void default_idle(void) local_irq_enable(); current_thread_info()->status |= TS_POLLING; } else { + local_irq_enable(); /* loop is done by the caller */ cpu_relax(); } @@ -142,6 +143,7 @@ EXPORT_SYMBOL(default_idle); */ static void poll_idle(void) { + local_irq_enable(); cpu_relax(); } @@ -248,8 +250,11 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx) __monitor((void *)¤t_thread_info()->flags, 0, 0); smp_mb(); if (!need_resched()) - __mwait(ax, cx); - } + __sti_mwait(ax, cx); + else + local_irq_enable(); + } else + local_irq_enable(); } /* Default MONITOR/MWAIT with no hints, used for default C1 state */ -- cgit v1.2.3-59-g8ed1b From 13af4836b3914b23946f6a8982934e2c828c183f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 2 Apr 2008 13:23:22 +0200 Subject: x86: improve default idle Signed-off-by: Ingo Molnar --- arch/x86/kernel/process_32.c | 8 -------- arch/x86/kernel/process_64.c | 8 -------- 2 files changed, 16 deletions(-) (limited to 'arch/x86/kernel/process_32.c') diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 08c41ed5e805..3903a8f2eb97 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -113,16 +113,8 @@ void default_idle(void) local_irq_disable(); if (!need_resched()) { - ktime_t t0, t1; - u64 t0n, t1n; - - t0 = ktime_get(); - t0n = ktime_to_ns(t0); safe_halt(); /* enables interrupts racelessly */ local_irq_disable(); - t1 = ktime_get(); - t1n = ktime_to_ns(t1); - sched_clock_idle_wakeup_event(t1n - t0n); } local_irq_enable(); current_thread_info()->status |= TS_POLLING; diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 4f40272474dd..e75ccc8a2b87 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -107,16 +107,8 @@ void default_idle(void) smp_mb(); local_irq_disable(); if (!need_resched()) { - ktime_t t0, t1; - u64 t0n, t1n; - - t0 = ktime_get(); - t0n = ktime_to_ns(t0); safe_halt(); /* enables interrupts racelessly */ local_irq_disable(); - t1 = ktime_get(); - t1n = ktime_to_ns(t1); - sched_clock_idle_wakeup_event(t1n - t0n); } local_irq_enable(); current_thread_info()->status |= TS_POLLING; -- cgit v1.2.3-59-g8ed1b