Merge branches 'x86/acpi', 'x86/apic', 'x86/cpudetect', 'x86/headers', 'x86/paravirt...
authorIngo Molnar <mingo@elte.hu>
Tue, 17 Feb 2009 11:07:00 +0000 (12:07 +0100)
committerIngo Molnar <mingo@elte.hu>
Tue, 17 Feb 2009 11:07:00 +0000 (12:07 +0100)
1  2  3  4  5  6  7 
Makefile
arch/x86/kernel/apic.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/traps.c

diff --combined Makefile
+++ b/Makefile
@@@@@@@@ -1,7 -1,7 -1,7 -1,7 -1,7 -1,7 -1,7 +1,7 @@@@@@@@
       VERSION = 2
       PATCHLEVEL = 6
       SUBLEVEL = 29
-  -- -EXTRAVERSION = -rc4
  -    EXTRAVERSION = -rc1
     - EXTRAVERSION = -rc3
+ +++++EXTRAVERSION = -rc5
       NAME = Erotic Pickled Herring
       
       # *DOCUMENTATION*
       # Where to locate arch specific headers
       hdr-arch  := $(SRCARCH)
       
  +    ifeq ($(ARCH),m68knommu)
  +           hdr-arch  := m68k
  +    endif
  +    
       KCONFIG_CONFIG   ?= .config
       
       # SHELL used by kbuild
@@@@@@@@ -532,8 -532,8 -528,8 -532,9 -532,9 -532,8 -532,9 +532,9 @@@@@@@@ KBUILD_CFLAGS += $(call cc-option,-Wfra
       endif
       
       # Force gcc to behave correct even for buggy distributions
---  - # Arch Makefiles may override this setting
+++  + ifndef CONFIG_CC_STACKPROTECTOR
       KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+++  + endif
       
       ifdef CONFIG_FRAME_POINTER
       KBUILD_CFLAGS    += -fno-omit-frame-pointer -fno-optimize-sibling-calls
@@@@@@@@ -610,20 -610,20 -606,25 -611,20 -611,20 -610,20 -611,20 +611,20 @@@@@@@@ export        INSTALL_PATH ?= /boo
       MODLIB   = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
       export MODLIB
       
  -    strip-symbols := $(srctree)/scripts/strip-symbols \
  -              $(wildcard $(srctree)/arch/$(ARCH)/scripts/strip-symbols)
  -    
       #
  -    # INSTALL_MOD_STRIP, if defined, will cause modules to be stripped while
  -    # they get installed.  If INSTALL_MOD_STRIP is '1', then the default
  -    # options (see below) will be used.  Otherwise, INSTALL_MOD_STRIP will
  -    # be used as the option(s) to the objcopy command.
  +    #  INSTALL_MOD_STRIP, if defined, will cause modules to be
  +    #  stripped after they are installed.  If INSTALL_MOD_STRIP is '1', then
  +    #  the default option --strip-debug will be used.  Otherwise,
  +    #  INSTALL_MOD_STRIP will used as the options to the strip command.
  +    
       ifdef INSTALL_MOD_STRIP
       ifeq ($(INSTALL_MOD_STRIP),1)
  -    mod_strip_cmd = $(OBJCOPY) --strip-debug
  -    ifeq ($(CONFIG_KALLSYMS_ALL),$(CONFIG_KALLSYMS_STRIP_GENERATED))
  -    mod_strip_cmd += --wildcard $(addprefix --strip-symbols ,$(strip-symbols))
  -    endif
  +    mod_strip_cmd = $(STRIP) --strip-debug
       else
  -    mod_strip_cmd = $(OBJCOPY) $(INSTALL_MOD_STRIP)
  +    mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
       endif # INSTALL_MOD_STRIP=1
       else
  -    mod_strip_cmd = false
  +    mod_strip_cmd = true
       endif # INSTALL_MOD_STRIP
       export mod_strip_cmd
       
@@@@@@@@ -753,6 -753,6 -754,7 -754,6 -754,6 -753,6 -754,6 +754,6 @@@@@@@@ last_kallsyms := 
       endif
       
       kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
  -    kallsyms.h := $(wildcard include/config/kallsyms/*.h) $(wildcard include/config/kallsyms/*/*.h)
       
       define verify_kallsyms
        $(Q)$(if $($(quiet)cmd_sysmap),                                      \
       
       # Generate .S file with all kernel symbols
       quiet_cmd_kallsyms = KSYM    $@
  -          cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } \
  -                  | $(KALLSYMS) $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) >$@
  +          cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
  +                         $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
       
  -    quiet_cmd_kstrip = STRIP   $@
  -          cmd_kstrip = $(OBJCOPY) --wildcard $(addprefix --strip$(if $(CONFIG_RELOCATABLE),-unneeded)-symbols ,$(filter %/scripts/strip-symbols,$^)) $< $@
  -    
  -    $(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): KBUILD_AFLAGS += -Wa,--strip-local-absolute
  -    $(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): %.o: %.S scripts FORCE
  +    .tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
        $(call if_changed_dep,as_o_S)
       
  -    ifeq ($(CONFIG_KALLSYMS_STRIP_GENERATED),y)
  -    strip-ext := .stripped
  -    endif
  -    
  -    .tmp_kallsyms%.S: .tmp_vmlinux%$(strip-ext) $(KALLSYMS) $(kallsyms.h)
  +    .tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
        $(call cmd,kallsyms)
       
  -    # make -jN seems to have problems with intermediate files, see bug #3330.
  -    .SECONDARY: $(foreach n,1 2 3,.tmp_vmlinux$(n).stripped)
  -    .tmp_vmlinux%.stripped: .tmp_vmlinux% $(strip-symbols) $(kallsyms.h)
  -     $(call cmd,kstrip)
  -    
  -    ifneq ($(CONFIG_DEBUG_INFO),y)
  -    .tmp_vmlinux%: LDFLAGS_vmlinux += -S
  -    endif
       # .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
  -    .tmp_vmlinux%: $(vmlinux-lds) $(vmlinux-all) FORCE
  -     $(if $(filter 1,$*),$(call if_changed_rule,ksym_ld),$(call if_changed,vmlinux__))
  +    .tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
  +     $(call if_changed_rule,ksym_ld)
       
  -    .tmp_vmlinux0$(strip-ext):
  -     $(Q)echo "placeholder" >$@
  +    .tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
  +     $(call if_changed,vmlinux__)
       
  -    .tmp_vmlinux1: .tmp_kallsyms0.o
  -    .tmp_vmlinux2: .tmp_kallsyms1.o
  -    .tmp_vmlinux3: .tmp_kallsyms2.o
  +    .tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
  +     $(call if_changed,vmlinux__)
       
       # Needs to visit scripts/ before $(KALLSYMS) can be used.
       $(KALLSYMS): scripts ;
diff --combined arch/x86/kernel/apic.c
@@@@@@@@ -1,7 -1,7 -1,7 -1,7 -1,7 -1,7 -1,7 +1,7 @@@@@@@@
       /*
        *       Local APIC handling, local APIC timers
        *
- -  -  *       (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
+ +  +  *       (c) 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com>
        *
        *       Fixes
        *       Maciej W. Rozycki       :       Bits for genuine 82489DX APICs;
        *       Mikael Pettersson       :       PM converted to driver model.
        */
       
- -  - #include <linux/init.h>
- -  - 
- -  - #include <linux/mm.h>
- -  - #include <linux/delay.h>
- -  - #include <linux/bootmem.h>
- -  - #include <linux/interrupt.h>
- -  - #include <linux/mc146818rtc.h>
       #include <linux/kernel_stat.h>
- -  - #include <linux/sysdev.h>
- -  - #include <linux/ioport.h>
- -  - #include <linux/cpu.h>
- -  - #include <linux/clockchips.h>
+ +  + #include <linux/mc146818rtc.h>
       #include <linux/acpi_pmtmr.h>
+ +  + #include <linux/clockchips.h>
+ +  + #include <linux/interrupt.h>
+ +  + #include <linux/bootmem.h>
+ +  + #include <linux/ftrace.h>
+ +  + #include <linux/ioport.h>
       #include <linux/module.h>
- -  - #include <linux/dmi.h>
+ +  + #include <linux/sysdev.h>
+ +  + #include <linux/delay.h>
+ +  + #include <linux/timex.h>
       #include <linux/dmar.h>
- -  - #include <linux/ftrace.h>
- -  - #include <linux/smp.h>
+ +  + #include <linux/init.h>
+ +  + #include <linux/cpu.h>
+ +  + #include <linux/dmi.h>
       #include <linux/nmi.h>
- -  - #include <linux/timex.h>
+ +  + #include <linux/smp.h>
+ +  + #include <linux/mm.h>
       
- -  - #include <asm/atomic.h>
- -  - #include <asm/mtrr.h>
- -  - #include <asm/mpspec.h>
- -  - #include <asm/desc.h>
       #include <asm/arch_hooks.h>
- -  - #include <asm/hpet.h>
       #include <asm/pgalloc.h>
+ +  + #include <asm/genapic.h>
+ +  + #include <asm/atomic.h>
+ +  + #include <asm/mpspec.h>
       #include <asm/i8253.h>
- -  - #include <asm/idle.h>
+ +  + #include <asm/i8259.h>
       #include <asm/proto.h>
       #include <asm/apic.h>
- -  - #include <asm/i8259.h>
+ +  + #include <asm/desc.h>
+ +  + #include <asm/hpet.h>
+ +  + #include <asm/idle.h>
+ +  + #include <asm/mtrr.h>
       #include <asm/smp.h>
       
- -  - #include <mach_apic.h>
- -  - #include <mach_apicdef.h>
- -  - #include <mach_ipi.h>
+ +  + unsigned int num_processors;
+ +  + 
+ +  + unsigned disabled_cpus __cpuinitdata;
+ +  + 
+ +  + /* Processor that is doing the boot up */
+ +  + unsigned int boot_cpu_physical_apicid = -1U;
       
       /*
- -  -  * Sanity check
+ +  +  * The highest APIC ID seen during enumeration.
+ +  +  *
+ +  +  * This determines the messaging protocol we can use: if all APIC IDs
+ +  +  * are in the 0 ... 7 range, then we can use logical addressing which
+ +  +  * has some performance advantages (better broadcasting).
+ +  +  *
+ +  +  * If there's an APIC ID above 8, we use physical addressing.
        */
- -  - #if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F)
- -  - # error SPURIOUS_APIC_VECTOR definition error
- -  - #endif
+ +  + unsigned int max_physical_apicid;
+ +  + 
+ +  + /*
+ +  +  * Bitmask of physically existing CPUs:
+ +  +  */
+ +  + physid_mask_t phys_cpu_present_map;
+ +  + 
+ +  + /*
+ +  +  * Map cpu index to physical APIC ID
+ +  +  */
+ +  + DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID);
+ +  + DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID);
+ +  + EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+ +  + EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
       
       #ifdef CONFIG_X86_32
       /*
@@@@@@@@ -457,7 -477,7 -457,7 -477,7 -477,7 -457,7 -477,7 +477,7 @@@@@@@@ static void lapic_timer_setup(enum cloc
       static void lapic_timer_broadcast(const struct cpumask *mask)
       {
       #ifdef CONFIG_SMP
- -  -  send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
+ +  +  apic->send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
       #endif
       }
       
@@@@@@@@ -535,7 -555,7 -535,7 -555,8 -555,8 -535,7 -555,8 +555,8 @@@@@@@@ static void __init lapic_cal_handler(st
        }
       }
       
---  - static int __init calibrate_by_pmtimer(long deltapm, long *delta)
+++  + static int __init
+++  + calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
       {
        const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
        const long pm_thresh = pm_100ms / 100;
        return -1;
       #endif
       
---  -  apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
+++  +  apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm);
       
        /* Check, if the PM timer is available */
        if (!deltapm)
       
        if (deltapm > (pm_100ms - pm_thresh) &&
            deltapm < (pm_100ms + pm_thresh)) {
---  -          apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
---  -  } else {
---  -          res = (((u64)deltapm) *  mult) >> 22;
---  -          do_div(res, 1000000);
---  -          pr_warning("APIC calibration not consistent "
---  -                  "with PM Timer: %ldms instead of 100ms\n",
---  -                  (long)res);
---  -          /* Correct the lapic counter value */
---  -          res = (((u64)(*delta)) * pm_100ms);
+++  +          apic_printk(APIC_VERBOSE, "... PM-Timer result ok\n");
+++  +          return 0;
+++  +  }
+++  + 
+++  +  res = (((u64)deltapm) *  mult) >> 22;
+++  +  do_div(res, 1000000);
+++  +  pr_warning("APIC calibration not consistent "
+++  +             "with PM-Timer: %ldms instead of 100ms\n",(long)res);
+++  + 
+++  +  /* Correct the lapic counter value */
+++  +  res = (((u64)(*delta)) * pm_100ms);
+++  +  do_div(res, deltapm);
+++  +  pr_info("APIC delta adjusted to PM-Timer: "
+++  +          "%lu (%ld)\n", (unsigned long)res, *delta);
+++  +  *delta = (long)res;
+++  + 
+++  +  /* Correct the tsc counter value */
+++  +  if (cpu_has_tsc) {
+++  +          res = (((u64)(*deltatsc)) * pm_100ms);
                do_div(res, deltapm);
---  -          pr_info("APIC delta adjusted to PM-Timer: "
---  -                  "%lu (%ld)\n", (unsigned long)res, *delta);
---  -          *delta = (long)res;
+++  +          apic_printk(APIC_VERBOSE, "TSC delta adjusted to "
+++  +                                    "PM-Timer: %lu (%ld) \n",
+++  +                                  (unsigned long)res, *deltatsc);
+++  +          *deltatsc = (long)res;
        }
       
        return 0;
@@@@@@@@ -579,7 -599,7 -579,7 -611,7 -611,7 -579,7 -611,7 +611,7 @@@@@@@@ static int __init calibrate_APIC_clock(
        struct clock_event_device *levt = &__get_cpu_var(lapic_events);
        void (*real_handler)(struct clock_event_device *dev);
        unsigned long deltaj;
---  -  long delta;
+++  +  long delta, deltatsc;
        int pm_referenced = 0;
       
        local_irq_disable();
        delta = lapic_cal_t1 - lapic_cal_t2;
        apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
       
+++  +  deltatsc = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
+++  + 
        /* we trust the PM based calibration if possible */
        pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
---  -                                  &delta);
+++  +                                  &delta, &deltatsc);
       
        /* Calculate the scaled math multiplication factor */
        lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
                    calibration_result);
       
        if (cpu_has_tsc) {
---  -          delta = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
                apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
                            "%ld.%04ld MHz.\n",
---  -                      (delta / LAPIC_CAL_LOOPS) / (1000000 / HZ),
---  -                      (delta / LAPIC_CAL_LOOPS) % (1000000 / HZ));
+++  +                      (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ),
+++  +                      (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ));
        }
       
        apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
@@@@@@@@ -895,10 -915,10 -895,6 -928,10 -928,10 -895,10 -928,10 +928,10 @@@@@@@@ void disable_local_APIC(void
       {
        unsigned int value;
       
  +     /* APIC hasn't been mapped yet */
  +     if (!apic_phys)
  +             return;
  +    
        clear_local_APIC();
       
        /*
@@@@@@@@ -991,11 -1011,11 -987,11 -1024,11 -1024,11 -991,11 -1024,11 +1024,11 @@@@@@@@ int __init verify_local_APIC(void
         */
        reg0 = apic_read(APIC_ID);
        apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
- -  -  apic_write(APIC_ID, reg0 ^ APIC_ID_MASK);
+ +  +  apic_write(APIC_ID, reg0 ^ apic->apic_id_mask);
        reg1 = apic_read(APIC_ID);
        apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
        apic_write(APIC_ID, reg0);
- -  -  if (reg1 != (reg0 ^ APIC_ID_MASK))
+ +  +  if (reg1 != (reg0 ^ apic->apic_id_mask))
                return 0;
       
        /*
@@@@@@@@ -1089,7 -1109,7 -1085,7 -1122,7 -1122,7 -1089,7 -1122,7 +1122,7 @@@@@@@@ static void __cpuinit lapic_setup_esr(v
                return;
        }
       
- -  -  if (esr_disable) {
+ +  +  if (apic->disable_esr) {
                /*
                 * Something untraceable is creating bad interrupts on
                 * secondary quads ... for the moment, just leave the
@@@@@@@@ -1130,9 -1150,14 -1126,9 -1163,14 -1163,14 -1130,9 -1163,14 +1163,14 @@@@@@@@ void __cpuinit setup_local_APIC(void
        unsigned int value;
        int i, j;
       
+ +  +  if (disable_apic) {
+ +  +          arch_disable_smp_support();
+ +  +          return;
+ +  +  }
+ +  + 
       #ifdef CONFIG_X86_32
        /* Pound the ESR really hard over the head with a big hammer - mbligh */
- -  -  if (lapic_is_integrated() && esr_disable) {
+ +  +  if (lapic_is_integrated() && apic->disable_esr) {
                apic_write(APIC_ESR, 0);
                apic_write(APIC_ESR, 0);
                apic_write(APIC_ESR, 0);
         * Double-check whether this APIC is really registered.
         * This is meaningless in clustered apic mode, so we skip it.
         */
- -  -  if (!apic_id_registered())
+ +  +  if (!apic->apic_id_registered())
                BUG();
       
        /*
         * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
         * document number 292116).  So here it goes...
         */
- -  -  init_apic_ldr();
+ +  +  apic->init_apic_ldr();
       
        /*
         * Set Task Priority to 'accept all'. We never change this
@@@@@@@@ -1436,7 -1461,7 -1432,7 -1474,7 -1474,7 -1436,7 -1474,7 +1474,7 @@@@@@@@ static int __init detect_init_APIC(void
        switch (boot_cpu_data.x86_vendor) {
        case X86_VENDOR_AMD:
                if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
  -                 (boot_cpu_data.x86 == 15))
  +                 (boot_cpu_data.x86 >= 15))
                        break;
                goto no_apic;
        case X86_VENDOR_INTEL:
@@@@@@@@ -1570,11 -1595,11 -1566,11 -1608,11 -1608,11 -1570,11 -1608,11 +1608,11 @@@@@@@@ int apic_version[MAX_APICS]
       
       int __init APIC_init_uniprocessor(void)
       {
- -  - #ifdef CONFIG_X86_64
        if (disable_apic) {
                pr_info("Apic disabled\n");
                return -1;
        }
+ +  + #ifdef CONFIG_X86_64
        if (!cpu_has_apic) {
                disable_apic = 1;
                pr_info("Apic disabled by BIOS\n");
        enable_IR_x2apic();
       #endif
       #ifdef CONFIG_X86_64
- -  -  setup_apic_routing();
+ +  +  default_setup_apic_routing();
       #endif
       
        verify_local_APIC();
        physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
        setup_local_APIC();
       
- -----#ifdef CONFIG_X86_64
+ +++++#ifdef CONFIG_X86_IO_APIC
        /*
         * Now enable IO-APICs, actually call clear_IO_APIC
- -----  * We need clear_IO_APIC before enabling vector on BP
+ +++++  * We need clear_IO_APIC before enabling error vector
         */
        if (!skip_ioapic_setup && nr_ioapics)
                enable_IO_APIC();
       #endif
       
- -----#ifdef CONFIG_X86_IO_APIC
- ----- if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
- -----#endif
- -----         localise_nmi_watchdog();
        end_local_APIC_setup();
       
       #ifdef CONFIG_X86_IO_APIC
        if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
                setup_IO_APIC();
- -----# ifdef CONFIG_X86_64
- ----- else
+ +++++ else {
                nr_ioapics = 0;
- -----# endif
+ +++++         localise_nmi_watchdog();
+ +++++ }
+ +++++#else
+ +++++ localise_nmi_watchdog();
       #endif
       
+ +++++ setup_boot_clock();
       #ifdef CONFIG_X86_64
- ----- setup_boot_APIC_clock();
        check_nmi_watchdog();
- -----#else
- ----- setup_boot_clock();
       #endif
       
        return 0;
@@@@@@@@ -1738,7 -1759,8 -1734,7 -1776,8 -1776,8 -1738,7 -1776,8 +1772,8 @@@@@@@@ void __init connect_bsp_APIC(void
                outb(0x01, 0x23);
        }
       #endif
- -  -  enable_apic_mode();
+ +  +  if (apic->enable_apic_mode)
+ +  +          apic->enable_apic_mode();
       }
       
       /**
@@@@@@@@ -1837,11 -1859,11 -1833,6 -1876,11 -1876,11 -1837,11 -1876,11 +1872,11 @@@@@@@@ void __cpuinit generic_processor_info(i
        num_processors++;
        cpu = cpumask_next_zero(-1, cpu_present_mask);
       
  +     if (version != apic_version[boot_cpu_physical_apicid])
  +             WARN_ONCE(1,
  +                     "ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n",
  +                     apic_version[boot_cpu_physical_apicid], cpu, version);
  +    
        physid_set(apicid, phys_cpu_present_map);
        if (apicid == boot_cpu_physical_apicid) {
                /*
        }
       #endif
       
- -  - #if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64)
- -  -  /* are we being called early in kernel startup? */
- -  -  if (early_per_cpu_ptr(x86_cpu_to_apicid)) {
- -  -          u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid);
- -  -          u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
- -  - 
- -  -          cpu_to_apicid[cpu] = apicid;
- -  -          bios_cpu_apicid[cpu] = apicid;
- -  -  } else {
- -  -          per_cpu(x86_cpu_to_apicid, cpu) = apicid;
- -  -          per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
- -  -  }
+ +  + #if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
+ +  +  early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
+ +  +  early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
       #endif
       
        set_cpu_possible(cpu, true);
        set_cpu_present(cpu, true);
       }
       
- -  - #ifdef CONFIG_X86_64
       int hard_smp_processor_id(void)
       {
        return read_apic_id();
       }
+ +  + 
+ +  + void default_init_apic_ldr(void)
+ +  + {
+ +  +  unsigned long val;
+ +  + 
+ +  +  apic_write(APIC_DFR, APIC_DFR_VALUE);
+ +  +  val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+ +  +  val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
+ +  +  apic_write(APIC_LDR, val);
+ +  + }
+ +  + 
+ +  + #ifdef CONFIG_X86_32
+ +  + int default_apicid_to_node(int logical_apicid)
+ +  + {
+ +  + #ifdef CONFIG_SMP
+ +  +  return apicid_2_node[hard_smp_processor_id()];
+ +  + #else
+ +  +  return 0;
+ +  + #endif
+ +  + }
       #endif
       
       /*
       #include <asm/asm.h>
       #include <asm/numa.h>
       #include <asm/smp.h>
+ +  + #include <asm/cpu.h>
+ +  + #include <asm/cpumask.h>
       #ifdef CONFIG_X86_LOCAL_APIC
       #include <asm/mpspec.h>
       #include <asm/apic.h>
- -  - #include <mach_apic.h>
       #include <asm/genapic.h>
+ +  + #include <asm/genapic.h>
+ +  + #include <asm/uv/uv.h>
       #endif
       
- -  - #include <asm/pda.h>
       #include <asm/pgtable.h>
       #include <asm/processor.h>
       #include <asm/desc.h>
       #include <asm/sections.h>
       #include <asm/setup.h>
       #include <asm/hypervisor.h>
+++  + #include <asm/stackprotector.h>
       
       #include "cpu.h"
       
@@@@@@@@ -50,6 -52,15 -50,6 -53,15 -53,15 -50,6 -53,15 +53,15 @@@@@@@@ cpumask_var_t cpu_initialized_mask
       /* representing cpus for which sibling maps can be computed */
       cpumask_var_t cpu_sibling_setup_mask;
       
+ +  + /* correctly size the local cpu masks */
+ +  + void __init setup_cpu_local_masks(void)
+ +  + {
+ +  +  alloc_bootmem_cpumask_var(&cpu_initialized_mask);
+ +  +  alloc_bootmem_cpumask_var(&cpu_callin_mask);
+ +  +  alloc_bootmem_cpumask_var(&cpu_callout_mask);
+ +  +  alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
+ +  + }
+ +  + 
       #else /* CONFIG_X86_32 */
       
       cpumask_t cpu_callin_map;
@@@@@@@@ -62,23 -73,23 -62,23 -74,23 -74,23 -62,23 -74,23 +74,23 @@@@@@@@ cpumask_t cpu_sibling_setup_map
       
       static struct cpu_dev *this_cpu __cpuinitdata;
       
+ +  + DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
       #ifdef CONFIG_X86_64
- -  - /* We need valid kernel segments for data and code in long mode too
- -  -  * IRET will check the segment types  kkeil 2000/10/28
- -  -  * Also sysret mandates a special GDT layout
- -  -  */
- -  - /* The TLS descriptors are currently at a different place compared to i386.
- -  -    Hopefully nobody expects them at a fixed place (Wine?) */
- -  - DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
+ +  +  /*
+ +  +   * We need valid kernel segments for data and code in long mode too
+ +  +   * IRET will check the segment types  kkeil 2000/10/28
+ +  +   * Also sysret mandates a special GDT layout
+ +  +   *
+ +  +   * The TLS descriptors are currently at a different place compared to i386.
+ +  +   * Hopefully nobody expects them at a fixed place (Wine?)
+ +  +   */
        [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
        [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
        [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
        [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
        [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
        [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
- -  - } };
       #else
- -  - DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
        [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
        [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
        [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
        [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
       
        [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
- -  -  [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
- -  - } };
+ +  +  [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } },
+++  +  GDT_STACK_CANARY_INIT
       #endif
+ +  + } };
       EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
       
       #ifdef CONFIG_X86_32
@@@@@@@@ -213,6 -224,49 -213,49 -226,49 -226,49 -213,6 -226,49 +226,49 @@@@@@@@ static inline void squash_the_stupid_se
       #endif
       
       /*
 - -- -             ((s32)df->feature < 0 ?
 - -- -              (u32)df->feature > (u32)c->extended_cpuid_level :
 - -- -              (s32)df->feature > (s32)c->cpuid_level)) {
+    +  * Some CPU features depend on higher CPUID levels, which may not always
+    +  * be available due to CPUID level capping or broken virtualization
+    +  * software.  Add those features to this table to auto-disable them.
+    +  */
+    + struct cpuid_dependent_feature {
+    +  u32 feature;
+    +  u32 level;
+    + };
+    + static const struct cpuid_dependent_feature __cpuinitconst
+    + cpuid_dependent_features[] = {
+    +  { X86_FEATURE_MWAIT,            0x00000005 },
+    +  { X86_FEATURE_DCA,              0x00000009 },
+    +  { X86_FEATURE_XSAVE,            0x0000000d },
+    +  { 0, 0 }
+    + };
+    + 
+    + static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
+    + {
+    +  const struct cpuid_dependent_feature *df;
+    +  for (df = cpuid_dependent_features; df->feature; df++) {
+    +          /*
+    +           * Note: cpuid_level is set to -1 if unavailable, but
+    +           * extended_extended_level is set to 0 if unavailable
+    +           * and the legitimate extended levels are all negative
+    +           * when signed; hence the weird messing around with
+    +           * signs here...
+    +           */
+    +          if (cpu_has(c, df->feature) &&
 - -- -}        
++ ++++             ((s32)df->level < 0 ?
++ ++++              (u32)df->level > (u32)c->extended_cpuid_level :
++ ++++              (s32)df->level > (s32)c->cpuid_level)) {
+    +                  clear_cpu_cap(c, df->feature);
+    +                  if (warn)
+    +                          printk(KERN_WARNING
+    +                                 "CPU: CPU feature %s disabled "
+    +                                 "due to lack of CPUID level 0x%x\n",
+    +                                 x86_cap_flags[df->feature],
+    +                                 df->level);
+    +          }
+    +  }
++ ++++}
+    + 
+    + /*
        * Naming convention should be: <Name> [(<Codename>)]
        * This table only is used unless init_<vendor>() below doesn't set it;
        * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used
@@@@@@@@ -242,18 -296,28 -285,18 -298,29 -298,29 -242,18 -298,29 +298,29 @@@@@@@@ static char __cpuinit *table_lookup_mod
       
       __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
       
+ +  + void load_percpu_segment(int cpu)
+ +  + {
+ +  + #ifdef CONFIG_X86_32
+ +  +  loadsegment(fs, __KERNEL_PERCPU);
+ +  + #else
+ +  +  loadsegment(gs, 0);
+ +  +  wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
+ +  + #endif
+++  +  load_stack_canary_segment();
+ +  + }
+ +  + 
       /* Current gdt points %fs at the "master" per-cpu area: after this,
        * it's on the real one. */
- -  - void switch_to_new_gdt(void)
+ +  + void switch_to_new_gdt(int cpu)
       {
        struct desc_ptr gdt_descr;
       
- -  -  gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
+ +  +  gdt_descr.address = (long)get_cpu_gdt_table(cpu);
        gdt_descr.size = GDT_SIZE - 1;
        load_gdt(&gdt_descr);
- -  - #ifdef CONFIG_X86_32
- -  -  asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
- -  - #endif
+ +  +  /* Reload the per-cpu base */
+ +  + 
+ +  +  load_percpu_segment(cpu);
       }
       
       static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};
@@@@@@@@ -383,11 -447,7 -426,11 -450,7 -450,7 -383,11 -450,7 +450,7 @@@@@@@@ void __cpuinit detect_ht(struct cpuinfo
                }
       
                index_msb = get_count_order(smp_num_siblings);
- -  - #ifdef CONFIG_X86_64
- -  -          c->phys_proc_id = phys_pkg_id(index_msb);
- -  - #else
- -  -          c->phys_proc_id = phys_pkg_id(c->initial_apicid, index_msb);
- -  - #endif
+ +  +          c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb);
       
                smp_num_siblings = smp_num_siblings / c->x86_max_cores;
       
       
                core_bits = get_count_order(c->x86_max_cores);
       
- -  - #ifdef CONFIG_X86_64
- -  -          c->cpu_core_id = phys_pkg_id(index_msb) &
  -                                            ((1 << core_bits) - 1);
  -    #else
  -             c->cpu_core_id = phys_pkg_id(c->initial_apicid, index_msb) &
+ +  +          c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, index_msb) &
                                               ((1 << core_bits) - 1);
-    - #else
-    -          c->cpu_core_id = phys_pkg_id(c->initial_apicid, index_msb) &
-    -                                         ((1 << core_bits) - 1);
- -  - #endif
        }
       
       out:
@@@@@@@@ -570,11 -625,10 -613,10 -628,10 -628,10 -570,11 -628,10 +628,10 @@@@@@@@ static void __init early_identify_cpu(s
        if (this_cpu->c_early_init)
                this_cpu->c_early_init(c);
       
       #ifdef CONFIG_SMP
        c->cpu_index = boot_cpu_id;
       #endif
+    +  filter_cpuid_features(c, false);
       }
       
       void __init early_cpu_init(void)
@@@@@@@@ -637,7 -691,7 -679,7 -694,7 -694,7 -637,7 -694,7 +694,7 @@@@@@@@ static void __cpuinit generic_identify(
                c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xFF;
       #ifdef CONFIG_X86_32
       # ifdef CONFIG_X86_HT
- -  -          c->apicid = phys_pkg_id(c->initial_apicid, 0);
+ +  +          c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
       # else
                c->apicid = c->initial_apicid;
       # endif
@@@@@@@@ -684,7 -738,7 -726,7 -741,7 -741,7 -684,7 -741,7 +741,7 @@@@@@@@ static void __cpuinit identify_cpu(stru
                this_cpu->c_identify(c);
       
       #ifdef CONFIG_X86_64
- -  -  c->apicid = phys_pkg_id(0);
+ +  +  c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
       #endif
       
        /*
         * we do "generic changes."
         */
       
+    +  /* Filter out anything that depends on CPUID levels we don't have */
+    +  filter_cpuid_features(c, true);
+    + 
        /* If the model name is still unset, do table lookup. */
        if (!c->x86_model_id[0]) {
                char *p;
@@@@@@@@ -877,54 -934,26 -922,54 -937,22 -937,22 -877,54 -937,22 +937,22 @@@@@@@@ static __init int setup_disablecpuid(ch
       __setup("clearcpuid=", setup_disablecpuid);
       
       #ifdef CONFIG_X86_64
- -  - struct x8664_pda **_cpu_pda __read_mostly;
- -  - EXPORT_SYMBOL(_cpu_pda);
- -  - 
       struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
       
- -  - static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
-    - 
-    - void __cpuinit pda_init(int cpu)
-    - {
-    -  struct x8664_pda *pda = cpu_pda(cpu);
+ +  + DEFINE_PER_CPU_FIRST(union irq_stack_union,
+ +  +               irq_stack_union) __aligned(PAGE_SIZE);
 -     #ifdef CONFIG_SMP
 -     DEFINE_PER_CPU(char *, irq_stack_ptr);   /* will be set during per cpu init */
 -     #else
+ +  + DEFINE_PER_CPU(char *, irq_stack_ptr) =
 -      per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
 -     #endif
+++  +  init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
       
-    -  /* Setup up data that may be needed in __get_free_pages early */
-    -  loadsegment(fs, 0);
-    -  loadsegment(gs, 0);
-    -  /* Memory clobbers used to order PDA accessed */
-    -  mb();
-    -  wrmsrl(MSR_GS_BASE, pda);
-    -  mb();
-    - 
-    -  pda->cpunumber = cpu;
-    -  pda->irqcount = -1;
-    -  pda->kernelstack = (unsigned long)stack_thread_info() -
-    -                           PDA_STACKOFFSET + THREAD_SIZE;
-    -  pda->active_mm = &init_mm;
-    -  pda->mmu_state = 0;
-    - 
-    -  if (cpu == 0) {
-    -          /* others are initialized in smpboot.c */
-    -          pda->pcurrent = &init_task;
-    -          pda->irqstackptr = boot_cpu_stack;
-    -          pda->irqstackptr += IRQSTACKSIZE - 64;
-    -  } else {
-    -          if (!pda->irqstackptr) {
-    -                  pda->irqstackptr = (char *)
-    -                          __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
-    -                  if (!pda->irqstackptr)
-    -                          panic("cannot allocate irqstack for cpu %d",
-    -                                cpu);
-    -                  pda->irqstackptr += IRQSTACKSIZE - 64;
-    -          }
  -    void __cpuinit pda_init(int cpu)
  -    {
  -     struct x8664_pda *pda = cpu_pda(cpu);
  -    
  -     /* Setup up data that may be needed in __get_free_pages early */
  -     loadsegment(fs, 0);
  -     loadsegment(gs, 0);
  -     /* Memory clobbers used to order PDA accessed */
  -     mb();
  -     wrmsrl(MSR_GS_BASE, pda);
  -     mb();
  -    
  -     pda->cpunumber = cpu;
  -     pda->irqcount = -1;
  -     pda->kernelstack = (unsigned long)stack_thread_info() -
  -                              PDA_STACKOFFSET + THREAD_SIZE;
  -     pda->active_mm = &init_mm;
  -     pda->mmu_state = 0;
  -    
  -     if (cpu == 0) {
  -             /* others are initialized in smpboot.c */
  -             pda->pcurrent = &init_task;
  -             pda->irqstackptr = boot_cpu_stack;
  -             pda->irqstackptr += IRQSTACKSIZE - 64;
  -     } else {
  -             if (!pda->irqstackptr) {
  -                     pda->irqstackptr = (char *)
  -                             __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
  -                     if (!pda->irqstackptr)
  -                             panic("cannot allocate irqstack for cpu %d",
  -                                   cpu);
  -                     pda->irqstackptr += IRQSTACKSIZE - 64;
  -             }
+ +  + DEFINE_PER_CPU(unsigned long, kernel_stack) =
+ +  +  (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;
+ +  + EXPORT_PER_CPU_SYMBOL(kernel_stack);
       
- -  -          if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE)
- -  -                  pda->nodenumber = cpu_to_node(cpu);
- -  -  }
- -  - }
+ +  + DEFINE_PER_CPU(unsigned int, irq_count) = -1;
       
- -  - static char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ +
- -  -                            DEBUG_STKSZ] __page_aligned_bss;
+ +  + static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
+ +  +  [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ])
+ +  +  __aligned(PAGE_SIZE);
       
       extern asmlinkage void ignore_sysret(void);
       
@@@@@@@@ -957,16 -986,16 -1002,16 -985,21 -985,21 -957,16 -985,21 +985,21 @@@@@@@@ unsigned long kernel_eflags
        */
       DEFINE_PER_CPU(struct orig_ist, orig_ist);
       
---  - #else
+++  + #else    /* x86_64 */
+    + 
 --    /* Make sure %fs is initialized properly in idle threads */
+++  + #ifdef CONFIG_CC_STACKPROTECTOR
+++  + DEFINE_PER_CPU(unsigned long, stack_canary);
+++  + #endif
 ++    
-    - /* Make sure %fs is initialized properly in idle threads */
+++  + /* Make sure %fs and %gs are initialized properly in idle threads */
       struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
       {
        memset(regs, 0, sizeof(struct pt_regs));
        regs->fs = __KERNEL_PERCPU;
+++  +  regs->gs = __KERNEL_STACK_CANARY;
        return regs;
       }
---  - #endif
+++  + #endif   /* x86_64 */
       
       /*
        * cpu_init() initializes state that is per-CPU. Some data is already
@@@@@@@@ -982,15 -1011,14 -1027,15 -1015,14 -1015,14 -982,15 -1015,14 +1015,14 @@@@@@@@ void __cpuinit cpu_init(void
        struct tss_struct *t = &per_cpu(init_tss, cpu);
        struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
        unsigned long v;
        struct task_struct *me;
        int i;
       
- -  -  /* CPU 0 is initialised in head64.c */
- -  -  if (cpu != 0)
- -  -          pda_init(cpu);
- -  -  else
- -  -          estacks = boot_exception_stacks;
+ +  + #ifdef CONFIG_NUMA
+ +  +  if (cpu != 0 && percpu_read(node_number) == 0 &&
+ +  +      cpu_to_node(cpu) != NUMA_NO_NODE)
+ +  +          percpu_write(node_number, cpu_to_node(cpu));
+ +  + #endif
       
        me = current;
       
         * and set up the GDT descriptor:
         */
       
- -  -  switch_to_new_gdt();
+ +  +  switch_to_new_gdt(cpu);
+ +  +  loadsegment(fs, 0);
+ +  + 
        load_idt((const struct desc_ptr *)&idt_descr);
       
        memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
         * set up and load the per-CPU TSS
         */
        if (!orig_ist->ist[0]) {
- -  -          static const unsigned int order[N_EXCEPTION_STACKS] = {
- -  -            [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
- -  -            [DEBUG_STACK - 1] = DEBUG_STACK_ORDER
+ +  +          static const unsigned int sizes[N_EXCEPTION_STACKS] = {
+ +  +            [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
+ +  +            [DEBUG_STACK - 1] = DEBUG_STKSZ
                };
+ +  +          char *estacks = per_cpu(exception_stacks, cpu);
                for (v = 0; v < N_EXCEPTION_STACKS; v++) {
- -  -                  if (cpu) {
- -  -                          estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
- -  -                          if (!estacks)
- -  -                                  panic("Cannot allocate exception "
- -  -                                        "stack %ld %d\n", v, cpu);
- -  -                  }
- -  -                  estacks += PAGE_SIZE << order[v];
+ +  +                  estacks += sizes[v];
                        orig_ist->ist[v] = t->x86_tss.ist[v] =
                                        (unsigned long)estacks;
                }
         */
        if (kgdb_connected && arch_kgdb_ops.correct_hw_break)
                arch_kgdb_ops.correct_hw_break();
- -  -  else {
+ +  +  else
       #endif
- -  -  /*
- -  -   * Clear all 6 debug registers:
- -  -   */
- -  - 
- -  -  set_debugreg(0UL, 0);
- -  -  set_debugreg(0UL, 1);
- -  -  set_debugreg(0UL, 2);
- -  -  set_debugreg(0UL, 3);
- -  -  set_debugreg(0UL, 6);
- -  -  set_debugreg(0UL, 7);
- -  - #ifdef CONFIG_KGDB
- -  -  /* If the kgdb is connected no debug regs should be altered. */
+ +  +  {
+ +  +          /*
+ +  +           * Clear all 6 debug registers:
+ +  +           */
+ +  +          set_debugreg(0UL, 0);
+ +  +          set_debugreg(0UL, 1);
+ +  +          set_debugreg(0UL, 2);
+ +  +          set_debugreg(0UL, 3);
+ +  +          set_debugreg(0UL, 6);
+ +  +          set_debugreg(0UL, 7);
        }
- -  - #endif
       
        fpu_init();
       
@@@@@@@@ -1114,7 -1136,7 -1159,7 -1140,7 -1140,7 -1114,7 -1140,7 +1140,7 @@@@@@@@ void __cpuinit cpu_init(void
                clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
       
        load_idt(&idt_descr);
- -  -  switch_to_new_gdt();
+ +  +  switch_to_new_gdt(cpu);
       
        /*
         * Set up and load the per-CPU TSS and LDT
        __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
       #endif
       
---  -  /* Clear %gs. */
---  -  asm volatile ("mov %0, %%gs" : : "r" (0));
---  - 
        /* Clear all 6 debug registers: */
        set_debugreg(0, 0);
        set_debugreg(0, 1);
diff --combined arch/x86/kernel/traps.c
       #include <asm/desc.h>
       #include <asm/i387.h>
       
- -  - #include <mach_traps.h>
+ +  + #include <asm/mach_traps.h>
       
       #ifdef CONFIG_X86_64
       #include <asm/pgalloc.h>
       #include <asm/proto.h>
- -  - #include <asm/pda.h>
       #else
       #include <asm/processor-flags.h>
       #include <asm/arch_hooks.h>
@@@@@@@@ -99,6 -98,6 -99,6 -98,6 -98,6 -99,12 -98,6 +98,12 @@@@@@@@ static inline void preempt_conditional_
                local_irq_enable();
       }
       
+++++ +static inline void conditional_cli(struct pt_regs *regs)
+++++ +{
+++++ + if (regs->flags & X86_EFLAGS_IF)
+++++ +         local_irq_disable();
+++++ +}
+++++ +
       static inline void preempt_conditional_cli(struct pt_regs *regs)
       {
        if (regs->flags & X86_EFLAGS_IF)
@@@@@@@@ -626,8 -625,8 -626,8 -625,8 -625,8 -632,10 -625,8 +631,10 @@@@@@@@ clear_dr7
       
       #ifdef CONFIG_X86_32
       debug_vm86:
+++++ + /* reenable preemption: handle_vm86_trap() might sleep */
+++++ + dec_preempt_count();
        handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
----- - preempt_conditional_cli(regs);
+++++ + conditional_cli(regs);
        return;
       #endif
       
@@@@@@@@ -896,7 -895,7 -896,7 -895,7 -895,7 -904,7 -895,7 +903,7 @@@@@@@@ asmlinkage void math_state_restore(void
       EXPORT_SYMBOL_GPL(math_state_restore);
       
       #ifndef CONFIG_MATH_EMULATION
- -    asmlinkage void math_emulate(long arg)
+ +    void math_emulate(struct math_emu_info *info)
       {
        printk(KERN_EMERG
                "math-emulation not enabled and no coprocessor found.\n");
       }
       #endif /* CONFIG_MATH_EMULATION */
       
 -   - dotraplinkage void __kprobes do_device_not_available(struct pt_regs regs)
 +   + dotraplinkage void __kprobes
- -    do_device_not_available(struct pt_regs *regs, long error)
+++  + do_device_not_available(struct pt_regs *regs, long error_code)
       {
       #ifdef CONFIG_X86_32
        if (read_cr0() & X86_CR0_EM) {
 -   -          conditional_sti(&regs);
+ +             struct math_emu_info info = { };
+ +    
- -             math_emulate(0);
 +   +          conditional_sti(regs);
 -   -          info.regs = &regs;
+ +    
+++  +          info.regs = regs;
+ +             math_emulate(&info);
        } else {
                math_state_restore(); /* interrupts still off */
 -   -          conditional_sti(&regs);
 +   +          conditional_sti(regs);
        }
       #else
        math_state_restore();