x86/asm changes for v3.7
Subsystems (5)
Linus,
Please pull the latest x86-asm-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-asm-for-linus
HEAD: c416ddf5b909736f5b57d348f5de159693e699ad x86: Unspaghettize do_trap()
The one change that stands out is the alternatives patching change that prevents us from ever patching back instructions from SMP to UP: this simplifies things and speeds up CPU hotplug. Other than that it's smaller fixes, cleanups and improvements.
out-of-topic modifications in x86-asm-for-linus:
------------------------------------------------kernel/cpu.c # 816afe4: x86/smp: Don't ever patch back to
Thanks,
Ingo
------------------>
Frederic Weisbecker (1):
x86: Unspaghettize do_trap()
Ian Campbell (1):
x86: Drop unnecessary kernel_eflags variable on 64-bit
Jan Beulich (3):
x86/64: Adjust types of temporaries used by ffs()/fls()/fls64()
x86: Prefer TZCNT over BFS
x86: Use REP BSF unconditionally
Rusty Russell (1):
x86/smp: Don't ever patch back to UP if we unplug cpus
Tao Guo (1):
x86_64: Work around old GAS bug
Documentation/kernel-parameters.txt | 3 - arch/x86/include/asm/alternative.h | 4 +- arch/x86/include/asm/bitops.h | 14 ++--- arch/x86/include/asm/calling.h | 48 ++++++++-------- arch/x86/include/asm/processor.h | 1 - arch/x86/kernel/alternative.c | 107 +++++++++--------------------------- arch/x86/kernel/cpu/common.c | 4 -- arch/x86/kernel/entry_64.S | 22 ++++---- arch/x86/kernel/smpboot.c | 20 +------ arch/x86/kernel/traps.c | 60 ++++++++++---------- arch/x86/xen/smp.c | 6 +- kernel/cpu.c | 11 ---- 12 files changed, 101 insertions(+), 199 deletions(-)
Documentation/kernel-parameters.txt +0 -3
@@ -2638,9 +2638,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. smart2= [HW] Format: <io1>[,<io2>[,...,<io8>]] - smp-alt-once [X86-32,SMP] On a hotplug CPU system, only - attempt to substitute SMP alternatives once at boot. - smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port smsc-ircc2.ircc_sir= [HW] SIR base I/O port
arch/x86/include/asm/alternative.h +2 -2
@@ -60,7 +60,7 @@ extern void alternatives_smp_module_add(struct module *mod, char *name, void *locks, void *locks_end, void *text, void *text_end);extern void alternatives_smp_module_del (struct module *mod); -extern void alternatives_smp_switch (int smp); +extern void alternatives_enable_smp (void );extern int alternatives_text_reserved (void *start,void *end);extern bool skip_smp_alternatives;#else
@@ -68,7 +68,7 @@ static inline void alternatives_smp_module_add(struct module *mod, char *name, void *locks, void *locks_end, void *text, void *text_end) {} static inline void alternatives_smp_module_del(struct module *mod) {} -static inline void alternatives_smp_switch(int smp) {} +static inline void alternatives_enable_smp(void) {} static inline int alternatives_text_reserved(void *start, void *end) { return 0;
arch/x86/include/asm/bitops.h +6 -8
@@ -355,7 +355,7 @@ static int test_bit(int nr, const volatile unsigned long *addr);*/ static inline unsigned long __ffs (unsigned long word) { - asm("bsf %1,%0" + asm("rep; bsf %1,%0" :"=r" (word) :"rm" (word));return word;
@@ -369,7 +369,7 @@ static inline unsigned long __ffs(unsigned long word)*/ static inline unsigned long ffz (unsigned long word) { - asm("bsf %1,%0" + asm("rep; bsf %1,%0" :"=r" (word) :"r" (~word));return word;
@@ -417,10 +417,9 @@ static inline int ffs(int x)* We cannot do this on 32 bits because at the very least some * 486 CPUs did not behave this way. */ -long tmp =-1 ; asm("bsfl %1,%0" :"=r" (r) - :"rm" (x),"0" (tmp)); + :"rm" (x),"0" (-1 ));#elif defined(CONFIG_X86_CMOV ) asm("bsfl %1,%0\n\t" "cmovzl %2,%0"
@@ -459,10 +458,9 @@ static inline int fls(int x)* We cannot do this on 32 bits because at the very least some * 486 CPUs did not behave this way. */ -long tmp =-1 ; asm("bsrl %1,%0" :"=r" (r) - :"rm" (x),"0" (tmp)); + :"rm" (x),"0" (-1 ));#elif defined(CONFIG_X86_CMOV ) asm("bsrl %1,%0\n\t" "cmovzl %2,%0"
@@ -490,13 +488,13 @@ static inline int fls(int x)#ifdef CONFIG_X86_64 static __always_inline int fls64(__u64 x) { -long bitpos =-1 ; +int bitpos =-1 ;/* * AMD64 says BSRQ won't clobber the dest reg if x==0; Intel64 says the * dest reg is undefined if x==0, but their CPU architect says its * value is written to set it to the same as before. */ - asm("bsrq %1,%0" + asm("bsrq %1,%q0" :"+r" (bitpos) :"rm" (x));return bitpos +1 ;
arch/x86/include/asm/calling.h +23 -25
61 lines not on this page · raw message
arch/x86/include/asm/processor.h +0 -1
@@ -423,7 +423,6 @@ DECLARE_INIT_PER_CPU(irq_stack_union); DECLARE_PER_CPU(char *, irq_stack_ptr); DECLARE_PER_CPU(unsigned int, irq_count); -extern unsigned long kernel_eflags; extern asmlinkage void ignore_sysret(void);#else /* X86_64 */ #ifdef CONFIG_CC_STACKPROTECTOR
arch/x86/kernel/alternative.c +26 -81
189 lines not on this page · raw message
arch/x86/kernel/cpu/common.c +0 -4
@@ -1116,8 +1116,6 @@ void syscall_init(void) X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL); } -unsigned long kernel_eflags; -/* * Copies of the original ist values from the tss are only accessed during * debugging, no special alignment required.
@@ -1299,8 +1297,6 @@ void __cpuinit cpu_init(void)fpu_init ();xsave_init (); -raw_local_save_flags (kernel_eflags); -if (is_uv_system ())uv_cpu_init (); }
arch/x86/kernel/entry_64.S +11 -11
@@ -342,15 +342,15 @@ ENDPROC(native_usergs_sysret64) .macro SAVE_ARGS_IRQ cld /* start from rbp in pt_regs and jump over */ - movq_cfi rdi, RDI-RBP - movq_cfi rsi, RSI-RBP - movq_cfi rdx, RDX-RBP - movq_cfi rcx, RCX-RBP - movq_cfi rax, RAX-RBP - movq_cfi r8, R8-RBP - movq_cfi r9, R9-RBP - movq_cfi r10, R10-RBP - movq_cfi r11, R11-RBP + movq_cfi rdi, (RDI-RBP) + movq_cfi rsi, (RSI-RBP) + movq_cfi rdx, (RDX-RBP) + movq_cfi rcx, (RCX-RBP) + movq_cfi rax, (RAX-RBP) + movq_cfi r8, (R8-RBP) + movq_cfi r9, (R9-RBP) + movq_cfi r10, (R10-RBP) + movq_cfi r11, (R11-RBP) /* Save rbp so that we can unwind from get_irq_regs() */ movq_cfi rbp, 0
@@ -384,7 +384,7 @@ ENDPROC(native_usergs_sysret64) .endm ENTRY(save_rest) - PARTIAL_FRAME 1 REST_SKIP+8 + PARTIAL_FRAME 1 (REST_SKIP+8) movq 5*8+16(%rsp), %r11 /* save return address */ movq_cfi rbx, RBX+16 movq_cfi rbp, RBP+16
@@ -440,7 +440,7 @@ ENTRY(ret_from_fork) LOCK ; btr $TIF_FORK,TI_flags(%r8) - pushq_cfi kernel_eflags(%rip) + pushq_cfi $0x0002 popfq_cfi # reset kernel eflags call schedule_tail # rdi: 'prev' task parameter
arch/x86/kernel/smpboot.c +2 -18
@@ -665,7 +665,8 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)unsigned long boot_error =0 ;int timeout; -alternatives_smp_switch (1 ); +/* Just in case we booted with a single CPU. */ +alternatives_enable_smp (); idle->thread.sp = (unsigned long ) (((struct pt_regs *) (THREAD_SIZE +task_stack_page (idle))) -1 );
@@ -1053,20 +1054,6 @@ out:preempt_enable (); } -void arch_disable_nonboot_cpus_begin (void ) -{ -/* -* Avoid the smp alternatives switch during the disable_nonboot_cpus(). -* In the suspend path, we will be back in the SMP mode shortly anyways. -*/ - skip_smp_alternatives = true; -} - -void arch_disable_nonboot_cpus_end (void ) -{ - skip_smp_alternatives = false; -} -void arch_enable_nonboot_cpus_begin (void ) {set_mtrr_aps_delayed_init ();
@@ -1256,9 +1243,6 @@ void native_cpu_die(unsigned int cpu)if (per_cpu (cpu_state, cpu) ==CPU_DEAD ) {if (system_state ==SYSTEM_RUNNING )pr_info ("CPU %u is now offline\n" , cpu); - -if (1 ==num_online_cpus ()) -alternatives_smp_switch (0 );return ; }msleep (100 );
arch/x86/kernel/traps.c +29 -31
82 lines not on this page · raw message
arch/x86/xen/smp.c +2 -4
@@ -377,7 +377,8 @@ static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle)return rc;if (num_online_cpus () ==1 ) -alternatives_smp_switch (1 ); +/* Just in case we booted with a single CPU. */ +alternatives_enable_smp (); rc =xen_smp_intr_init (cpu);if (rc)
@@ -424,9 +425,6 @@ static void xen_cpu_die(unsigned int cpu)unbind_from_irqhandler (per_cpu (xen_irq_work, cpu),NULL );xen_uninit_lock_cpu (cpu);xen_teardown_timer (cpu); - -if (num_online_cpus () ==1 ) -alternatives_smp_switch (0 ); }static void __cpuinit xen_play_dead (void )/* used only with HOTPLUG_CPU */
kernel/cpu.c +0 -11
@@ -439,14 +439,6 @@ EXPORT_SYMBOL_GPL(cpu_up);#ifdef CONFIG_PM_SLEEP_SMP static cpumask_var_t frozen_cpus; -void __weak arch_disable_nonboot_cpus_begin (void ) -{ -} - -void __weak arch_disable_nonboot_cpus_end (void ) -{ -} -int disable_nonboot_cpus (void ) {int cpu, first_cpu, error =0 ;
@@ -458,7 +450,6 @@ int disable_nonboot_cpus(void)* with the userspace trying to use the CPU hotplug at the same time */ cpumask_clear (frozen_cpus); -arch_disable_nonboot_cpus_begin ();printk ("Disabling non-boot CPUs ...\n" );for_each_online_cpu (cpu) {
@@ -474,8 +465,6 @@ int disable_nonboot_cpus(void) } } -arch_disable_nonboot_cpus_end (); -if (!error) {BUG_ON (num_online_cpus () >1 );/* Make sure the CPUs won't be enabled by someone else */