Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Sep 2009 14:57:32 +0000 (07:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Sep 2009 14:57:32 +0000 (07:57 -0700)
* 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (22 commits)
  x86: Fix code patching for paravirt-alternatives on 486
  x86, msr: change msr-reg.o to obj-y, and export its symbols
  x86: Use hard_smp_processor_id() to get apic id for AMD K8 cpus
  x86, sched: Workaround broken sched domain creation for AMD Magny-Cours
  x86, mcheck: Use correct cpumask for shared bank4
  x86, cacheinfo: Fixup L3 cache information for AMD multi-node processors
  x86: Fix CPU llc_shared_map information for AMD Magny-Cours
  x86, msr: Fix msr-reg.S compilation with gas 2.16.1, on 32-bit too
  x86: Move kernel_fpu_using to irq_fpu_usable in asm/i387.h
  x86, msr: fix msr-reg.S compilation with gas 2.16.1
  x86, msr: Export the register-setting MSR functions via /dev/*/msr
  x86, msr: Create _on_cpu helpers for {rw,wr}msr_safe_regs()
  x86, msr: Have the _safe MSR functions return -EIO, not -EFAULT
  x86, msr: CFI annotations, cleanups for msr-reg.S
  x86, asm: Make _ASM_EXTABLE() usable from assembly code
  x86, asm: Add 32-bit versions of the combined CFI macros
  x86, AMD: Disable wrongly set X86_FEATURE_LAHF_LM CPUID bit
  x86, msr: Rewrite AMD rd/wrmsr variants
  x86, msr: Add rd/wrmsr interfaces with preset registers
  x86: add specific support for Intel Atom architecture
  ...

1  2 
arch/x86/Makefile
arch/x86/crypto/aesni-intel_glue.c
arch/x86/include/asm/module.h
arch/x86/include/asm/processor.h
arch/x86/kernel/alternative.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/proc.c
arch/x86/xen/enlighten.c

diff --combined arch/x86/Makefile
index 5e7db44d709e5fd58e689afcb09cc750bcd6406c,8a4c24c96d085864c5b806f34299f2a6c239cffc..5128b178529f39fc24c2f1a2aad82371c7a4b484
@@@ -55,6 -55,8 +55,8 @@@ els
  
          cflags-$(CONFIG_MCORE2) += \
                  $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
+       cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \
+               $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
          cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
          KBUILD_CFLAGS += $(cflags-y)
  
@@@ -72,7 -74,7 +74,7 @@@ endi
  
  ifdef CONFIG_CC_STACKPROTECTOR
        cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
 -        ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC)),y)
 +        ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y)
                  stackp-y := -fstack-protector
                  stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all
                  KBUILD_CFLAGS += $(stackp-y)
index d3ec8d588d4b12b1d2b5085b88d1cd5a496bf543,7667235ade19543f0357dcdf2ee48c9d657b849d..585edebe12cffa97d0b6c7381b66f6b38b81bc80
@@@ -59,13 -59,6 +59,6 @@@ asmlinkage void aesni_cbc_enc(struct cr
  asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
                              const u8 *in, unsigned int len, u8 *iv);
  
- static inline int kernel_fpu_using(void)
- {
-       if (in_interrupt() && !(read_cr0() & X86_CR0_TS))
-               return 1;
-       return 0;
- }
  static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx)
  {
        unsigned long addr = (unsigned long)raw_ctx;
@@@ -89,7 -82,7 +82,7 @@@ static int aes_set_key_common(struct cr
                return -EINVAL;
        }
  
-       if (kernel_fpu_using())
+       if (irq_fpu_usable())
                err = crypto_aes_expand_key(ctx, in_key, key_len);
        else {
                kernel_fpu_begin();
@@@ -110,7 -103,7 +103,7 @@@ static void aes_encrypt(struct crypto_t
  {
        struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
  
-       if (kernel_fpu_using())
+       if (irq_fpu_usable())
                crypto_aes_encrypt_x86(ctx, dst, src);
        else {
                kernel_fpu_begin();
@@@ -123,7 -116,7 +116,7 @@@ static void aes_decrypt(struct crypto_t
  {
        struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
  
-       if (kernel_fpu_using())
+       if (irq_fpu_usable())
                crypto_aes_decrypt_x86(ctx, dst, src);
        else {
                kernel_fpu_begin();
@@@ -349,7 -342,7 +342,7 @@@ static int ablk_encrypt(struct ablkciph
        struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
        struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  
-       if (kernel_fpu_using()) {
+       if (irq_fpu_usable()) {
                struct ablkcipher_request *cryptd_req =
                        ablkcipher_request_ctx(req);
                memcpy(cryptd_req, req, sizeof(*req));
@@@ -370,7 -363,7 +363,7 @@@ static int ablk_decrypt(struct ablkciph
        struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
        struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  
-       if (kernel_fpu_using()) {
+       if (irq_fpu_usable()) {
                struct ablkcipher_request *cryptd_req =
                        ablkcipher_request_ctx(req);
                memcpy(cryptd_req, req, sizeof(*req));
@@@ -636,7 -629,7 +629,7 @@@ static int __init aesni_init(void
        int err;
  
        if (!cpu_has_aes) {
 -              printk(KERN_ERR "Intel AES-NI instructions are not detected.\n");
 +              printk(KERN_INFO "Intel AES-NI instructions are not detected.\n");
                return -ENODEV;
        }
        if ((err = crypto_register_alg(&aesni_alg)))
index 555bc12bdcd68bb83f1b5102ee08a47026b05488,e959c4afab59958b4607c9127a93b781e5398908..3e2ce58a31a37f4ef65c67762f1b0dd75eb8ae33
@@@ -1,7 -1,18 +1,7 @@@
  #ifndef _ASM_X86_MODULE_H
  #define _ASM_X86_MODULE_H
  
 -/* x86_32/64 are simple */
 -struct mod_arch_specific {};
 -
 -#ifdef CONFIG_X86_32
 -# define Elf_Shdr Elf32_Shdr
 -# define Elf_Sym Elf32_Sym
 -# define Elf_Ehdr Elf32_Ehdr
 -#else
 -# define Elf_Shdr Elf64_Shdr
 -# define Elf_Sym Elf64_Sym
 -# define Elf_Ehdr Elf64_Ehdr
 -#endif
 +#include <asm-generic/module.h>
  
  #ifdef CONFIG_X86_64
  /* X86_64 does not define MODULE_PROC_FAMILY */
@@@ -17,6 -28,8 +17,8 @@@
  #define MODULE_PROC_FAMILY "586MMX "
  #elif defined CONFIG_MCORE2
  #define MODULE_PROC_FAMILY "CORE2 "
+ #elif defined CONFIG_MATOM
+ #define MODULE_PROC_FAMILY "ATOM "
  #elif defined CONFIG_M686
  #define MODULE_PROC_FAMILY "686 "
  #elif defined CONFIG_MPENTIUMII
index ac7e79654f3af5b898c023c78ea35ef123594cf5,2db56c57a2812952345ef97fff5f4222e5a45602..e08ea043e085c7a35882cf382dc218d17a97b00c
@@@ -403,17 -403,7 +403,17 @@@ extern unsigned long kernel_eflags
  extern asmlinkage void ignore_sysret(void);
  #else /* X86_64 */
  #ifdef CONFIG_CC_STACKPROTECTOR
 -DECLARE_PER_CPU(unsigned long, stack_canary);
 +/*
 + * Make sure stack canary segment base is cached-aligned:
 + *   "For Intel Atom processors, avoid non zero segment base address
 + *    that is not aligned to cache line boundary at all cost."
 + * (Optim Ref Manual Assembly/Compiler Coding Rule 15.)
 + */
 +struct stack_canary {
 +      char __pad[20];         /* canary at %gs:20 */
 +      unsigned long canary;
 +};
 +DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
  #endif
  #endif        /* X86_64 */
  
@@@ -713,13 -703,23 +713,23 @@@ static inline void cpu_relax(void
        rep_nop();
  }
  
- /* Stop speculative execution: */
+ /* Stop speculative execution and prefetching of modified code. */
  static inline void sync_core(void)
  {
        int tmp;
  
-       asm volatile("cpuid" : "=a" (tmp) : "0" (1)
-                    : "ebx", "ecx", "edx", "memory");
+ #if defined(CONFIG_M386) || defined(CONFIG_M486)
+       if (boot_cpu_data.x86 < 5)
+               /* There is no speculative execution.
+                * jmp is a barrier to prefetching. */
+               asm volatile("jmp 1f\n1:\n" ::: "memory");
+       else
+ #endif
+               /* cpuid is a barrier to speculative execution.
+                * Prefetched instructions are automatically
+                * invalidated when modified. */
+               asm volatile("cpuid" : "=a" (tmp) : "0" (1)
+                            : "ebx", "ecx", "edx", "memory");
  }
  
  static inline void __monitor(const void *eax, unsigned long ecx,
index 486935143e026190c9c187350072c3425fa69469,b8ebd0b689b16b08367136ed5b30cd911d1c28bf..de7353c0ce9ca5bbb029e513bd55773a6c2396d5
@@@ -2,7 -2,6 +2,7 @@@
  #include <linux/sched.h>
  #include <linux/mutex.h>
  #include <linux/list.h>
 +#include <linux/stringify.h>
  #include <linux/kprobes.h>
  #include <linux/mm.h>
  #include <linux/vmalloc.h>
@@@ -33,7 -32,7 +33,7 @@@ __setup("smp-alt-boot", bootonly)
  #define smp_alt_once 1
  #endif
  
 -static int debug_alternative;
 +static int __initdata_or_module debug_alternative;
  
  static int __init debug_alt(char *str)
  {
@@@ -52,7 -51,7 +52,7 @@@ static int __init setup_noreplace_smp(c
  __setup("noreplace-smp", setup_noreplace_smp);
  
  #ifdef CONFIG_PARAVIRT
 -static int noreplace_paravirt = 0;
 +static int __initdata_or_module noreplace_paravirt = 0;
  
  static int __init setup_noreplace_paravirt(char *str)
  {
@@@ -65,17 -64,16 +65,17 @@@ __setup("noreplace-paravirt", setup_nor
  #define DPRINTK(fmt, args...) if (debug_alternative) \
        printk(KERN_DEBUG fmt, args)
  
 -#ifdef GENERIC_NOP1
 +#if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64)
  /* Use inline assembly to define this because the nops are defined
     as inline assembly strings in the include files and we cannot
     get them easily into strings. */
 -asm("\t.section .rodata, \"a\"\nintelnops: "
 +asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nintelnops: "
        GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
        GENERIC_NOP7 GENERIC_NOP8
      "\t.previous");
  extern const unsigned char intelnops[];
 -static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
 +static const unsigned char *const __initconst_or_module
 +intel_nops[ASM_NOP_MAX+1] = {
        NULL,
        intelnops,
        intelnops + 1,
  #endif
  
  #ifdef K8_NOP1
 -asm("\t.section .rodata, \"a\"\nk8nops: "
 +asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: "
        K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
        K8_NOP7 K8_NOP8
      "\t.previous");
  extern const unsigned char k8nops[];
 -static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
 +static const unsigned char *const __initconst_or_module
 +k8_nops[ASM_NOP_MAX+1] = {
        NULL,
        k8nops,
        k8nops + 1,
  };
  #endif
  
 -#ifdef K7_NOP1
 -asm("\t.section .rodata, \"a\"\nk7nops: "
 +#if defined(K7_NOP1) && !defined(CONFIG_X86_64)
 +asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: "
        K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
        K7_NOP7 K7_NOP8
      "\t.previous");
  extern const unsigned char k7nops[];
 -static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
 +static const unsigned char *const __initconst_or_module
 +k7_nops[ASM_NOP_MAX+1] = {
        NULL,
        k7nops,
        k7nops + 1,
  #endif
  
  #ifdef P6_NOP1
 -asm("\t.section .rodata, \"a\"\np6nops: "
 +asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: "
        P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
        P6_NOP7 P6_NOP8
      "\t.previous");
  extern const unsigned char p6nops[];
 -static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
 +static const unsigned char *const __initconst_or_module
 +p6_nops[ASM_NOP_MAX+1] = {
        NULL,
        p6nops,
        p6nops + 1,
  #ifdef CONFIG_X86_64
  
  extern char __vsyscall_0;
 -const unsigned char *const *find_nop_table(void)
 +static const unsigned char *const *__init_or_module find_nop_table(void)
  {
        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
            boot_cpu_has(X86_FEATURE_NOPL))
  
  #else /* CONFIG_X86_64 */
  
 -const unsigned char *const *find_nop_table(void)
 +static const unsigned char *const *__init_or_module find_nop_table(void)
  {
        if (boot_cpu_has(X86_FEATURE_K8))
                return k8_nops;
  #endif /* CONFIG_X86_64 */
  
  /* Use this to add nops to a buffer, then text_poke the whole buffer. */
 -void add_nops(void *insns, unsigned int len)
 +static void __init_or_module add_nops(void *insns, unsigned int len)
  {
        const unsigned char *const *noptable = find_nop_table();
  
                len -= noplen;
        }
  }
 -EXPORT_SYMBOL_GPL(add_nops);
  
  extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
  extern u8 *__smp_locks[], *__smp_locks_end[];
 +static void *text_poke_early(void *addr, const void *opcode, size_t len);
  
  /* Replace instructions with better alternatives for this CPU type.
     This runs before SMP is initialized to avoid SMP problems with
     APs have less capabilities than the boot processor are not handled.
     Tough. Make sure you disable such features by hand. */
  
 -void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
 +void __init_or_module apply_alternatives(struct alt_instr *start,
 +                                       struct alt_instr *end)
  {
        struct alt_instr *a;
        char insnbuf[MAX_PATCH_LEN];
@@@ -285,10 -279,9 +285,10 @@@ static LIST_HEAD(smp_alt_modules)
  static DEFINE_MUTEX(smp_alt);
  static int smp_mode = 1;      /* protected by smp_alt */
  
 -void alternatives_smp_module_add(struct module *mod, char *name,
 -                               void *locks, void *locks_end,
 -                               void *text,  void *text_end)
 +void __init_or_module alternatives_smp_module_add(struct module *mod,
 +                                                char *name,
 +                                                void *locks, void *locks_end,
 +                                                void *text,  void *text_end)
  {
        struct smp_alt_module *smp;
  
        mutex_unlock(&smp_alt);
  }
  
 -void alternatives_smp_module_del(struct module *mod)
 +void __init_or_module alternatives_smp_module_del(struct module *mod)
  {
        struct smp_alt_module *item;
  
@@@ -393,8 -386,8 +393,8 @@@ void alternatives_smp_switch(int smp
  #endif
  
  #ifdef CONFIG_PARAVIRT
 -void apply_paravirt(struct paravirt_patch_site *start,
 -                  struct paravirt_patch_site *end)
 +void __init_or_module apply_paravirt(struct paravirt_patch_site *start,
 +                                   struct paravirt_patch_site *end)
  {
        struct paravirt_patch_site *p;
        char insnbuf[MAX_PATCH_LEN];
@@@ -492,14 -485,13 +492,14 @@@ void __init alternative_instructions(vo
   * instructions. And on the local CPU you need to be protected again NMI or MCE
   * handlers seeing an inconsistent instruction while you patch.
   */
 -void *text_poke_early(void *addr, const void *opcode, size_t len)
 +static void *__init_or_module text_poke_early(void *addr, const void *opcode,
 +                                            size_t len)
  {
        unsigned long flags;
        local_irq_save(flags);
        memcpy(addr, opcode, len);
-       local_irq_restore(flags);
        sync_core();
+       local_irq_restore(flags);
        /* Could also do a CLFLUSH here to speed up CPU recovery; but
           that causes hangs on some VIA CPUs. */
        return addr;
index 83b217c7225fb2d02d83941a514884539daae0e5,e1600c775e1d2f4665fe37b5079c2574597bcc82..22a47c82f3c022d3de0fb0b08397fc9ea0ba422c
@@@ -2,7 -2,7 +2,7 @@@
  #include <linux/bitops.h>
  #include <linux/mm.h>
  
 -#include <asm/io.h>
 +#include <linux/io.h>
  #include <asm/processor.h>
  #include <asm/apic.h>
  #include <asm/cpu.h>
@@@ -45,8 -45,8 +45,8 @@@ static void __cpuinit init_amd_k5(struc
  #define CBAR_ENB      (0x80000000)
  #define CBAR_KEY      (0X000000CB)
        if (c->x86_model == 9 || c->x86_model == 10) {
 -              if (inl (CBAR) & CBAR_ENB)
 -                      outl (0 | CBAR_KEY, CBAR);
 +              if (inl(CBAR) & CBAR_ENB)
 +                      outl(0 | CBAR_KEY, CBAR);
        }
  }
  
@@@ -87,10 -87,9 +87,10 @@@ static void __cpuinit init_amd_k6(struc
                d = d2-d;
  
                if (d > 20*K6_BUG_LOOP)
 -                      printk("system stability may be impaired when more than 32 MB are used.\n");
 +                      printk(KERN_CONT
 +                              "system stability may be impaired when more than 32 MB are used.\n");
                else
 -                      printk("probably OK (after B9730xxxx).\n");
 +                      printk(KERN_CONT "probably OK (after B9730xxxx).\n");
                printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n");
        }
  
@@@ -220,9 -219,8 +220,9 @@@ static void __cpuinit init_amd_k7(struc
        if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
                rdmsr(MSR_K7_CLK_CTL, l, h);
                if ((l & 0xfff00000) != 0x20000000) {
 -                      printk ("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", l,
 -                              ((l & 0x000fffff)|0x20000000));
 +                      printk(KERN_INFO
 +                          "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
 +                                      l, ((l & 0x000fffff)|0x20000000));
                        wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
                }
        }
@@@ -252,6 -250,64 +252,64 @@@ static int __cpuinit nearby_node(int ap
  }
  #endif
  
+ /*
+  * Fixup core topology information for AMD multi-node processors.
+  * Assumption 1: Number of cores in each internal node is the same.
+  * Assumption 2: Mixed systems with both single-node and dual-node
+  *               processors are not supported.
+  */
+ #ifdef CONFIG_X86_HT
+ static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
+ {
+ #ifdef CONFIG_PCI
+       u32 t, cpn;
+       u8 n, n_id;
+       int cpu = smp_processor_id();
+       /* fixup topology information only once for a core */
+       if (cpu_has(c, X86_FEATURE_AMD_DCM))
+               return;
+       /* check for multi-node processor on boot cpu */
+       t = read_pci_config(0, 24, 3, 0xe8);
+       if (!(t & (1 << 29)))
+               return;
+       set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+       /* cores per node: each internal node has half the number of cores */
+       cpn = c->x86_max_cores >> 1;
+       /* even-numbered NB_id of this dual-node processor */
+       n = c->phys_proc_id << 1;
+       /*
+        * determine internal node id and assign cores fifty-fifty to
+        * each node of the dual-node processor
+        */
+       t = read_pci_config(0, 24 + n, 3, 0xe8);
+       n = (t>>30) & 0x3;
+       if (n == 0) {
+               if (c->cpu_core_id < cpn)
+                       n_id = 0;
+               else
+                       n_id = 1;
+       } else {
+               if (c->cpu_core_id < cpn)
+                       n_id = 1;
+               else
+                       n_id = 0;
+       }
+       /* compute entire NodeID, use llc_shared_map to store sibling info */
+       per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;
+       /* fixup core id to be in range from 0 to cpn */
+       c->cpu_core_id = c->cpu_core_id % cpn;
+ #endif
+ }
+ #endif
  /*
   * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
   * Assumes number of cores is a power of two.
@@@ -269,6 -325,9 +327,9 @@@ static void __cpuinit amd_detect_cmp(st
        c->phys_proc_id = c->initial_apicid >> bits;
        /* use socket ID also for last level cache */
        per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+       /* fixup topology information on multi-node processors */
+       if ((c->x86 == 0x10) && (c->x86_model == 9))
+               amd_fixup_dcm(c);
  #endif
  }
  
@@@ -277,9 -336,10 +338,10 @@@ static void __cpuinit srat_detect_node(
  #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
        int cpu = smp_processor_id();
        int node;
-       unsigned apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid;
+       unsigned apicid = c->apicid;
+       node = per_cpu(cpu_llc_id, cpu);
  
-       node = c->phys_proc_id;
        if (apicid_to_node[apicid] != NUMA_NO_NODE)
                node = apicid_to_node[apicid];
        if (!node_online(node)) {
@@@ -400,18 -460,30 +462,30 @@@ static void __cpuinit init_amd(struct c
                u32 level;
  
                level = cpuid_eax(1);
 -              if((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
 +              if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
                        set_cpu_cap(c, X86_FEATURE_REP_GOOD);
  
                /*
                 * Some BIOSes incorrectly force this feature, but only K8
                 * revision D (model = 0x14) and later actually support it.
+                * (AMD Erratum #110, docId: 25759).
                 */
-               if (c->x86_model < 0x14)
+               if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) {
+                       u64 val;
                        clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
+                       if (!rdmsrl_amd_safe(0xc001100d, &val)) {
+                               val &= ~(1ULL << 32);
+                               wrmsrl_amd_safe(0xc001100d, val);
+                       }
+               }
        }
        if (c->x86 == 0x10 || c->x86 == 0x11)
                set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+       /* get apicid instead of initial apic id from cpuid */
+       c->apicid = hard_smp_processor_id();
  #else
  
        /*
                 * benefit in doing so.
                 */
                if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
 -                  printk(KERN_DEBUG "tseg: %010llx\n", tseg);
 -                  if ((tseg>>PMD_SHIFT) <
 +                      printk(KERN_DEBUG "tseg: %010llx\n", tseg);
 +                      if ((tseg>>PMD_SHIFT) <
                                (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) ||
 -                      ((tseg>>PMD_SHIFT) <
 +                              ((tseg>>PMD_SHIFT) <
                                (max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) &&
 -                       (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT))))
 -                      set_memory_4k((unsigned long)__va(tseg), 1);
 +                              (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT))))
 +                              set_memory_4k((unsigned long)__va(tseg), 1);
                }
        }
  #endif
  }
  
  #ifdef CONFIG_X86_32
 -static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 +static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,
 +                                                      unsigned int size)
  {
        /* AMD errata T13 (order #21922) */
        if ((c->x86 == 6)) {
 -              if (c->x86_model == 3 && c->x86_mask == 0)      /* Duron Rev A0 */
 +              /* Duron Rev A0 */
 +              if (c->x86_model == 3 && c->x86_mask == 0)
                        size = 64;
 +              /* Tbird rev A1/A2 */
                if (c->x86_model == 4 &&
 -                  (c->x86_mask == 0 || c->x86_mask == 1))     /* Tbird rev A1/A2 */
 +                      (c->x86_mask == 0 || c->x86_mask == 1))
                        size = 256;
        }
        return size;
index 306bf0dca0616f342498ff3d402a74f2541d450f,cb98a73e516730fcfe0b13e15bdd1ab481324e84..804c40e2bc3e1fd588f08f50db90dc83e02ae1b4
@@@ -3,7 -3,7 +3,7 @@@
   *
   *    Changes:
   *    Venkatesh Pallipadi     : Adding cache identification through cpuid(4)
 - *            Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
 + *    Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
   *    Andi Kleen / Andreas Herrmann   : CPUID4 emulation on AMD.
   */
  
@@@ -16,7 -16,7 +16,7 @@@
  #include <linux/pci.h>
  
  #include <asm/processor.h>
 -#include <asm/smp.h>
 +#include <linux/smp.h>
  #include <asm/k8.h>
  
  #define LVL_1_INST    1
  #define LVL_3         4
  #define LVL_TRACE     5
  
 -struct _cache_table
 -{
 +struct _cache_table {
        unsigned char descriptor;
        char cache_type;
        short size;
  };
  
 -/* all the cache descriptor types we care about (no TLB or trace cache entries) */
 +/* All the cache descriptor types we care about (no TLB or
 +   trace cache entries) */
 +
  static const struct _cache_table __cpuinitconst cache_table[] =
  {
        { 0x06, LVL_1_INST, 8 },        /* 4-way set assoc, 32 byte line size */
  };
  
  
 -enum _cache_type
 -{
 +enum _cache_type {
        CACHE_TYPE_NULL = 0,
        CACHE_TYPE_DATA = 1,
        CACHE_TYPE_INST = 2,
@@@ -170,31 -170,31 +170,31 @@@ unsigned short                  num_cache_leaves
     Maybe later */
  union l1_cache {
        struct {
 -              unsigned line_size : 8;
 -              unsigned lines_per_tag : 8;
 -              unsigned assoc : 8;
 -              unsigned size_in_kb : 8;
 +              unsigned line_size:8;
 +              unsigned lines_per_tag:8;
 +              unsigned assoc:8;
 +              unsigned size_in_kb:8;
        };
        unsigned val;
  };
  
  union l2_cache {
        struct {
 -              unsigned line_size : 8;
 -              unsigned lines_per_tag : 4;
 -              unsigned assoc : 4;
 -              unsigned size_in_kb : 16;
 +              unsigned line_size:8;
 +              unsigned lines_per_tag:4;
 +              unsigned assoc:4;
 +              unsigned size_in_kb:16;
        };
        unsigned val;
  };
  
  union l3_cache {
        struct {
 -              unsigned line_size : 8;
 -              unsigned lines_per_tag : 4;
 -              unsigned assoc : 4;
 -              unsigned res : 2;
 -              unsigned size_encoded : 14;
 +              unsigned line_size:8;
 +              unsigned lines_per_tag:4;
 +              unsigned assoc:4;
 +              unsigned res:2;
 +              unsigned size_encoded:14;
        };
        unsigned val;
  };
@@@ -241,7 -241,7 +241,7 @@@ amd_cpuid4(int leaf, union _cpuid4_leaf
        case 0:
                if (!l1->val)
                        return;
-               assoc = l1->assoc;
+               assoc = assocs[l1->assoc];
                line_size = l1->line_size;
                lines_per_tag = l1->lines_per_tag;
                size_in_kb = l1->size_in_kb;
        case 2:
                if (!l2.val)
                        return;
-               assoc = l2.assoc;
+               assoc = assocs[l2.assoc];
                line_size = l2.line_size;
                lines_per_tag = l2.lines_per_tag;
                /* cpu_data has errata corrections for K7 applied */
        case 3:
                if (!l3.val)
                        return;
-               assoc = l3.assoc;
+               assoc = assocs[l3.assoc];
                line_size = l3.line_size;
                lines_per_tag = l3.lines_per_tag;
                size_in_kb = l3.size_encoded * 512;
+               if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
+                       size_in_kb = size_in_kb >> 1;
+                       assoc = assoc >> 1;
+               }
                break;
        default:
                return;
        eax->split.is_self_initializing = 1;
        eax->split.type = types[leaf];
        eax->split.level = levels[leaf];
-       if (leaf == 3)
-               eax->split.num_threads_sharing =
-                       current_cpu_data.x86_max_cores - 1;
-       else
-               eax->split.num_threads_sharing = 0;
+       eax->split.num_threads_sharing = 0;
        eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
  
  
-       if (assoc == 0xf)
+       if (assoc == 0xffff)
                eax->split.is_fully_associative = 1;
        ebx->split.coherency_line_size = line_size - 1;
-       ebx->split.ways_of_associativity = assocs[assoc] - 1;
+       ebx->split.ways_of_associativity = assoc - 1;
        ebx->split.physical_line_partition = lines_per_tag - 1;
        ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
                (ebx->split.ways_of_associativity + 1) - 1;
@@@ -350,8 -350,7 +350,8 @@@ static int __cpuinit find_num_cache_lea
  
  unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
  {
 -      unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
 +      /* Cache sizes */
 +      unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
        unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
        unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
        unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
  
                        retval = cpuid4_cache_lookup_regs(i, &this_leaf);
                        if (retval >= 0) {
 -                              switch(this_leaf.eax.split.level) {
 -                                  case 1:
 +                              switch (this_leaf.eax.split.level) {
 +                              case 1:
                                        if (this_leaf.eax.split.type ==
                                                        CACHE_TYPE_DATA)
                                                new_l1d = this_leaf.size/1024;
                                                        CACHE_TYPE_INST)
                                                new_l1i = this_leaf.size/1024;
                                        break;
 -                                  case 2:
 +                              case 2:
                                        new_l2 = this_leaf.size/1024;
                                        num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
                                        index_msb = get_count_order(num_threads_sharing);
                                        l2_id = c->apicid >> index_msb;
                                        break;
 -                                  case 3:
 +                              case 3:
                                        new_l3 = this_leaf.size/1024;
                                        num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
 -                                      index_msb = get_count_order(num_threads_sharing);
 +                                      index_msb = get_count_order(
 +                                                      num_threads_sharing);
                                        l3_id = c->apicid >> index_msb;
                                        break;
 -                                  default:
 +                              default:
                                        break;
                                }
                        }
                /* Number of times to iterate */
                n = cpuid_eax(2) & 0xFF;
  
 -              for ( i = 0 ; i < n ; i++ ) {
 +              for (i = 0 ; i < n ; i++) {
                        cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
  
                        /* If bit 31 is set, this is an unknown format */
 -                      for ( j = 0 ; j < 3 ; j++ ) {
 -                              if (regs[j] & (1 << 31)) regs[j] = 0;
 -                      }
 +                      for (j = 0 ; j < 3 ; j++)
 +                              if (regs[j] & (1 << 31))
 +                                      regs[j] = 0;
  
                        /* Byte 0 is level count, not a descriptor */
 -                      for ( j = 1 ; j < 16 ; j++ ) {
 +                      for (j = 1 ; j < 16 ; j++) {
                                unsigned char des = dp[j];
                                unsigned char k = 0;
  
                                /* look up this descriptor in the table */
 -                              while (cache_table[k].descriptor != 0)
 -                              {
 +                              while (cache_table[k].descriptor != 0) {
                                        if (cache_table[k].descriptor == des) {
                                                if (only_trace && cache_table[k].cache_type != LVL_TRACE)
                                                        break;
        }
  
        if (trace)
 -              printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
 -      else if ( l1i )
 -              printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
 +              printk(KERN_INFO "CPU: Trace cache: %dK uops", trace);
 +      else if (l1i)
 +              printk(KERN_INFO "CPU: L1 I cache: %dK", l1i);
  
        if (l1d)
 -              printk(", L1 D cache: %dK\n", l1d);
 +              printk(KERN_CONT ", L1 D cache: %dK\n", l1d);
        else
 -              printk("\n");
 +              printk(KERN_CONT "\n");
  
        if (l2)
                printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
@@@ -523,6 -522,18 +523,18 @@@ static void __cpuinit cache_shared_cpu_
        int index_msb, i;
        struct cpuinfo_x86 *c = &cpu_data(cpu);
  
+       if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
+               struct cpuinfo_x86 *d;
+               for_each_online_cpu(i) {
+                       if (!per_cpu(cpuid4_info, i))
+                               continue;
+                       d = &cpu_data(i);
+                       this_leaf = CPUID4_INFO_IDX(i, index);
+                       cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
+                                    d->llc_shared_map);
+               }
+               return;
+       }
        this_leaf = CPUID4_INFO_IDX(cpu, index);
        num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
  
@@@ -559,13 -570,8 +571,13 @@@ static void __cpuinit cache_remove_shar
        }
  }
  #else
 -static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
 -static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
 +static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 +{
 +}
 +
 +static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
 +{
 +}
  #endif
  
  static void __cpuinit free_cache_attributes(unsigned int cpu)
@@@ -651,7 -657,7 +663,7 @@@ static DEFINE_PER_CPU(struct _index_kob
  static ssize_t show_##file_name                                               \
                        (struct _cpuid4_info *this_leaf, char *buf)     \
  {                                                                     \
 -      return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
 +      return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
  }
  
  show_one_plus(level, eax.split.level, 0);
@@@ -662,7 -668,7 +674,7 @@@ show_one_plus(number_of_sets, ecx.split
  
  static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
  {
 -      return sprintf (buf, "%luK\n", this_leaf->size / 1024);
 +      return sprintf(buf, "%luK\n", this_leaf->size / 1024);
  }
  
  static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
                const struct cpumask *mask;
  
                mask = to_cpumask(this_leaf->shared_cpu_map);
 -              n = type?
 +              n = type ?
                        cpulist_scnprintf(buf, len-2, mask) :
                        cpumask_scnprintf(buf, len-2, mask);
                buf[n++] = '\n';
@@@ -806,7 -812,7 +818,7 @@@ static struct _cache_attr cache_disable
  static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
                show_cache_disable_1, store_cache_disable_1);
  
 -static struct attribute * default_attrs[] = {
 +static struct attribute *default_attrs[] = {
        &type.attr,
        &level.attr,
        &coherency_line_size.attr,
        NULL
  };
  
 -static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
 +static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
  {
        struct _cache_attr *fattr = to_attr(attr);
        struct _index_kobject *this_leaf = to_object(kobj);
        return ret;
  }
  
 -static ssize_t store(struct kobject * kobj, struct attribute * attr,
 -                   const char * buf, size_t count)
 +static ssize_t store(struct kobject *kobj, struct attribute *attr,
 +                   const char *buf, size_t count)
  {
        struct _cache_attr *fattr = to_attr(attr);
        struct _index_kobject *this_leaf = to_object(kobj);
@@@ -889,7 -895,7 +901,7 @@@ static int __cpuinit cpuid4_cache_sysfs
                goto err_out;
  
        per_cpu(index_kobject, cpu) = kzalloc(
 -          sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
 +          sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
        if (unlikely(per_cpu(index_kobject, cpu) == NULL))
                goto err_out;
  
@@@ -923,7 -929,7 +935,7 @@@ static int __cpuinit cache_add_dev(stru
        }
  
        for (i = 0; i < num_cache_leaves; i++) {
 -              this_object = INDEX_KOBJECT_PTR(cpu,i);
 +              this_object = INDEX_KOBJECT_PTR(cpu, i);
                this_object->cpu = cpu;
                this_object->index = i;
                retval = kobject_init_and_add(&(this_object->kobj),
                                              per_cpu(cache_kobject, cpu),
                                              "index%1lu", i);
                if (unlikely(retval)) {
 -                      for (j = 0; j < i; j++) {
 -                              kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
 -                      }
 +                      for (j = 0; j < i; j++)
 +                              kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
                        kobject_put(per_cpu(cache_kobject, cpu));
                        cpuid4_cache_sysfs_exit(cpu);
                        return retval;
@@@ -957,7 -964,7 +969,7 @@@ static void __cpuinit cache_remove_dev(
        cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
  
        for (i = 0; i < num_cache_leaves; i++)
 -              kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
 +              kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
        kobject_put(per_cpu(cache_kobject, cpu));
        cpuid4_cache_sysfs_exit(cpu);
  }
@@@ -982,7 -989,8 +994,7 @@@ static int __cpuinit cacheinfo_cpu_call
        return NOTIFY_OK;
  }
  
 -static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
 -{
 +static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
        .notifier_call = cacheinfo_cpu_callback,
  };
  
index 1e904346bbf4b98bceb1a38813b9e41ded7ef31a,f82706a3901dfcdfeb1d09e8e745894c3b6eab00..62ac8cb6ba277218eec7cae7c7ef6d474d6406bc
@@@ -116,11 -116,9 +116,9 @@@ static int show_cpuinfo(struct seq_fil
                seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
  #endif
        seq_printf(m, "clflush size\t: %u\n", c->x86_clflush_size);
- #ifdef CONFIG_X86_64
        seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
        seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n",
                   c->x86_phys_bits, c->x86_virt_bits);
- #endif
  
        seq_printf(m, "power management:");
        for (i = 0; i < 32; i++) {
                        if (i < ARRAY_SIZE(x86_power_flags) &&
                            x86_power_flags[i])
                                seq_printf(m, "%s%s",
 -                                         x86_power_flags[i][0]?" ":"",
 +                                         x86_power_flags[i][0] ? " " : "",
                                           x86_power_flags[i]);
                        else
                                seq_printf(m, " [%d]", i);
diff --combined arch/x86/xen/enlighten.c
index eb33aaa8415de0d7b4e13d7dd18c826829a59466,a8432d816903a8fe4b8d2d9b071b80f35de06366..b62ccb840cfb1a6a3a64735781249f2ef412d179
@@@ -215,7 -215,6 +215,7 @@@ static __init void xen_init_cpuid_mask(
                          (1 << X86_FEATURE_ACPI));  /* disable ACPI */
  
        ax = 1;
 +      cx = 0;
        xen_cpuid(&ax, &bx, &cx, &dx);
  
        /* cpuid claims we support xsave; try enabling it to see what happens */
@@@ -714,7 -713,7 +714,7 @@@ static int xen_write_msr_safe(unsigned 
        set:
                base = ((u64)high << 32) | low;
                if (HYPERVISOR_set_segment_base(which, base) != 0)
-                       ret = -EFAULT;
+                       ret = -EIO;
                break;
  #endif
  
@@@ -975,6 -974,10 +975,6 @@@ asmlinkage void __init xen_start_kernel
  
        xen_domain_type = XEN_PV_DOMAIN;
  
 -      BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0);
 -
 -      xen_setup_features();
 -
        /* Install Xen paravirt ops */
        pv_info = xen_info;
        pv_init_ops = xen_init_ops;
        pv_apic_ops = xen_apic_ops;
        pv_mmu_ops = xen_mmu_ops;
  
 -      xen_init_irq_ops();
 +#ifdef CONFIG_X86_64
 +      /*
 +       * Setup percpu state.  We only need to do this for 64-bit
 +       * because 32-bit already has %fs set properly.
 +       */
 +      load_percpu_segment(0);
 +#endif
  
 +      xen_init_irq_ops();
        xen_init_cpuid_mask();
  
  #ifdef CONFIG_X86_LOCAL_APIC
        set_xen_basic_apic_ops();
  #endif
  
 +      xen_setup_features();
 +
        if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
                pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
                pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
  
        machine_ops = xen_machine_ops;
  
 -#ifdef CONFIG_X86_64
 -      /*
 -       * Setup percpu state.  We only need to do this for 64-bit
 -       * because 32-bit already has %fs set properly.
 -       */
 -      load_percpu_segment(0);
 -#endif
        /*
         * The only reliable way to retain the initial address of the
         * percpu gdt_page is to remember it here, so we can go and
        /* set up basic CPUID stuff */
        cpu_detect(&new_cpu_data);
        new_cpu_data.hard_math = 1;
 +      new_cpu_data.wp_works_ok = 1;
        new_cpu_data.x86_capability[0] = cpuid_edx(1);
  #endif