Merge branch 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-flexiantxendom0-3.2.10.git] / arch / x86 / include / asm / processor.h
index 5bec21a..f302ef6 100644 (file)
@@ -14,13 +14,13 @@ struct mm_struct;
 #include <asm/sigcontext.h>
 #include <asm/current.h>
 #include <asm/cpufeature.h>
-#include <asm/system.h>
 #include <asm/page.h>
 #include <asm/pgtable_types.h>
 #include <asm/percpu.h>
 #include <asm/msr.h>
 #include <asm/desc_defs.h>
 #include <asm/nops.h>
+#include <asm/special_insns.h>
 
 #include <linux/personality.h>
 #include <linux/cpumask.h>
@@ -29,6 +29,15 @@ struct mm_struct;
 #include <linux/math64.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/irqflags.h>
+
+/*
+ * We handle most unaligned accesses in hardware.  On the other hand
+ * unaligned DMA can be quite expensive on some Nehalem processors.
+ *
+ * Based on this we disable the IP header alignment in network drivers.
+ */
+#define NET_IP_ALIGN   0
 
 #define HBP_NUM 4
 /*
@@ -94,26 +103,22 @@ struct cpuinfo_x86 {
        int                     x86_cache_alignment;    /* In bytes */
        int                     x86_power;
        unsigned long           loops_per_jiffy;
-#ifdef CONFIG_SMP
-       /* cpus sharing the last level cache: */
-       cpumask_var_t           llc_shared_map;
-#endif
        /* cpuid returned max cores value: */
        u16                      x86_max_cores;
        u16                     apicid;
        u16                     initial_apicid;
        u16                     x86_clflush_size;
-#ifdef CONFIG_SMP
        /* number of cores as seen by the OS: */
        u16                     booted_cores;
        /* Physical processor id: */
        u16                     phys_proc_id;
        /* Core id: */
        u16                     cpu_core_id;
+       /* Compute unit id */
+       u8                      compute_unit_id;
        /* Index into per_cpu list: */
        u16                     cpu_index;
-#endif
-       unsigned int            x86_hyper_vendor;
+       u32                     microcode;
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 #define X86_VENDOR_INTEL       0
@@ -127,9 +132,6 @@ struct cpuinfo_x86 {
 
 #define X86_VENDOR_UNKNOWN     0xff
 
-#define X86_HYPER_VENDOR_NONE  0
-#define X86_HYPER_VENDOR_VMWARE 1
-
 /*
  * capabilities of CPUs
  */
@@ -143,10 +145,9 @@ extern __u32                       cpu_caps_set[NCAPINTS];
 #ifdef CONFIG_SMP
 DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
 #define cpu_data(cpu)          per_cpu(cpu_info, cpu)
-#define current_cpu_data       __get_cpu_var(cpu_info)
 #else
+#define cpu_info               boot_cpu_data
 #define cpu_data(cpu)          boot_cpu_data
-#define current_cpu_data       boot_cpu_data
 #endif
 
 extern const struct seq_operations cpuinfo_op;
@@ -170,6 +171,7 @@ extern void early_cpu_init(void);
 extern void identify_boot_cpu(void);
 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+void print_cpu_msr(struct cpuinfo_x86 *);
 extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
@@ -186,7 +188,8 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
              "=b" (*ebx),
              "=c" (*ecx),
              "=d" (*edx)
-           : "0" (*eax), "2" (*ecx));
+           : "0" (*eax), "2" (*ecx)
+           : "memory");
 }
 
 static inline void load_cr3(pgd_t *pgdir)
@@ -380,6 +383,12 @@ union thread_xstate {
        struct xsave_struct             xsave;
 };
 
+struct fpu {
+       unsigned int last_cpu;
+       unsigned int has_fpu;
+       union thread_xstate *state;
+};
+
 #ifdef CONFIG_X86_64
 DECLARE_PER_CPU(struct orig_ist, orig_ist);
 
@@ -457,7 +466,7 @@ struct thread_struct {
        unsigned long           trap_no;
        unsigned long           error_code;
        /* floating point and extended processor state */
-       union thread_xstate     *xstate;
+       struct fpu              fpu;
 #ifdef CONFIG_X86_32
        /* Virtual 86 mode info */
        struct vm86_struct __user *vm86_info;
@@ -475,61 +484,6 @@ struct thread_struct {
        unsigned                io_bitmap_max;
 };
 
-static inline unsigned long native_get_debugreg(int regno)
-{
-       unsigned long val = 0;  /* Damn you, gcc! */
-
-       switch (regno) {
-       case 0:
-               asm("mov %%db0, %0" :"=r" (val));
-               break;
-       case 1:
-               asm("mov %%db1, %0" :"=r" (val));
-               break;
-       case 2:
-               asm("mov %%db2, %0" :"=r" (val));
-               break;
-       case 3:
-               asm("mov %%db3, %0" :"=r" (val));
-               break;
-       case 6:
-               asm("mov %%db6, %0" :"=r" (val));
-               break;
-       case 7:
-               asm("mov %%db7, %0" :"=r" (val));
-               break;
-       default:
-               BUG();
-       }
-       return val;
-}
-
-static inline void native_set_debugreg(int regno, unsigned long value)
-{
-       switch (regno) {
-       case 0:
-               asm("mov %0, %%db0"     ::"r" (value));
-               break;
-       case 1:
-               asm("mov %0, %%db1"     ::"r" (value));
-               break;
-       case 2:
-               asm("mov %0, %%db2"     ::"r" (value));
-               break;
-       case 3:
-               asm("mov %0, %%db3"     ::"r" (value));
-               break;
-       case 6:
-               asm("mov %0, %%db6"     ::"r" (value));
-               break;
-       case 7:
-               asm("mov %0, %%db7"     ::"r" (value));
-               break;
-       default:
-               BUG();
-       }
-}
-
 /*
  * Set IOPL bits in EFLAGS from given mask
  */
@@ -575,14 +529,6 @@ static inline void native_swapgs(void)
 #define __cpuid                        native_cpuid
 #define paravirt_enabled()     0
 
-/*
- * These special macros can be used to get or set a debugging register
- */
-#define get_debugreg(var, register)                            \
-       (var) = native_get_debugreg(register)
-#define set_debugreg(value, register)                          \
-       native_set_debugreg(register, value)
-
 static inline void load_sp0(struct tss_struct *tss,
                            struct thread_struct *thread)
 {
@@ -602,7 +548,7 @@ extern unsigned long                mmu_cr4_features;
 
 static inline void set_in_cr4(unsigned long mask)
 {
-       unsigned cr4;
+       unsigned long cr4;
 
        mmu_cr4_features |= mask;
        cr4 = read_cr4();
@@ -612,7 +558,7 @@ static inline void set_in_cr4(unsigned long mask)
 
 static inline void clear_in_cr4(unsigned long mask)
 {
-       unsigned cr4;
+       unsigned long cr4;
 
        mmu_cr4_features &= ~mask;
        cr4 = read_cr4();
@@ -754,41 +700,20 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
                     :: "a" (eax), "c" (ecx));
 }
 
-extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
-
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
-extern void init_c1e_mask(void);
+extern void init_amd_e400_c1e_mask(void);
 
 extern unsigned long           boot_option_idle_override;
-extern unsigned long           idle_halt;
-extern unsigned long           idle_nomwait;
+extern bool                    amd_e400_c1e_detected;
 
-/*
- * on systems with caches, caches must be flashed as the absolute
- * last instruction before going into a suspended halt.  Otherwise,
- * dirty data can linger in the cache and become stale on resume,
- * leading to strange errors.
- *
- * perform a variety of operations to guarantee that the compiler
- * will not reorder instructions.  wbinvd itself is serializing
- * so the processor will not reorder.
- *
- * Systems without cache can just go into halt.
- */
-static inline void wbinvd_halt(void)
-{
-       mb();
-       /* check for clflush to determine if wbinvd is legal */
-       if (cpu_has_clflush)
-               asm volatile("cli; wbinvd; 1: hlt; jmp 1b" : : : "memory");
-       else
-               while (1)
-                       halt();
-}
+enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
+                        IDLE_POLL, IDLE_FORCE_MWAIT};
 
 extern void enable_sep_cpu(void);
 extern int sysenter_setup(void);
 
+extern void early_trap_init(void);
+
 /* Defined in head.S */
 extern struct desc_ptr         early_gdt_descr;
 
@@ -799,7 +724,7 @@ extern void cpu_init(void);
 
 static inline unsigned long get_debugctlmsr(void)
 {
-    unsigned long debugctlmsr = 0;
+       unsigned long debugctlmsr = 0;
 
 #ifndef CONFIG_X86_DEBUGCTLMSR
        if (boot_cpu_data.x86 < 6)
@@ -807,7 +732,7 @@ static inline unsigned long get_debugctlmsr(void)
 #endif
        rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
 
-    return debugctlmsr;
+       return debugctlmsr;
 }
 
 static inline void update_debugctlmsr(unsigned long debugctlmsr)
@@ -920,7 +845,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
 /*
  * The below -8 is to reserve 8 bytes on top of the ring0 stack.
  * This is necessary to guarantee that the entire "struct pt_regs"
- * is accessable even if the CPU haven't stored the SS/ESP registers
+ * is accessible even if the CPU haven't stored the SS/ESP registers
  * on the stack (interrupt gate does not save these registers
  * when switching to the same priv ring).
  * Therefore beware: accessing the ss/esp fields of the
@@ -948,9 +873,9 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
 #define IA32_PAGE_OFFSET       ((current->personality & ADDR_LIMIT_3GB) ? \
                                        0xc0000000 : 0xFFFFe000)
 
-#define TASK_SIZE              (test_thread_flag(TIF_IA32) ? \
+#define TASK_SIZE              (test_thread_flag(TIF_ADDR32) ? \
                                        IA32_PAGE_OFFSET : TASK_SIZE_MAX)
-#define TASK_SIZE_OF(child)    ((test_tsk_thread_flag(child, TIF_IA32)) ? \
+#define TASK_SIZE_OF(child)    ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \
                                        IA32_PAGE_OFFSET : TASK_SIZE_MAX)
 
 #define STACK_TOP              TASK_SIZE
@@ -972,6 +897,12 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
 
 #define task_pt_regs(tsk)      ((struct pt_regs *)(tsk)->thread.sp0 - 1)
 extern unsigned long KSTK_ESP(struct task_struct *task);
+
+/*
+ * User space RSP while inside the SYSCALL fast path
+ */
+DECLARE_PER_CPU(unsigned long, old_rsp);
+
 #endif /* CONFIG_X86_64 */
 
 extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
@@ -1023,4 +954,44 @@ unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
        return ratio;
 }
 
+/*
+ * AMD errata checking
+ */
+#ifdef CONFIG_CPU_SUP_AMD
+extern const int amd_erratum_383[];
+extern const int amd_erratum_400[];
+extern bool cpu_has_amd_erratum(const int *);
+
+#define AMD_LEGACY_ERRATUM(...)                { -1, __VA_ARGS__, 0 }
+#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 }
+#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
+       ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
+#define AMD_MODEL_RANGE_FAMILY(range)  (((range) >> 24) & 0xff)
+#define AMD_MODEL_RANGE_START(range)   (((range) >> 12) & 0xfff)
+#define AMD_MODEL_RANGE_END(range)     ((range) & 0xfff)
+
+#else
+#define cpu_has_amd_erratum(x) (false)
+#endif /* CONFIG_CPU_SUP_AMD */
+
+#ifdef CONFIG_X86_32
+/*
+ * disable hlt during certain critical i/o operations
+ */
+#define HAVE_DISABLE_HLT
+#endif
+
+void disable_hlt(void);
+void enable_hlt(void);
+
+void cpu_idle_wait(void);
+
+extern unsigned long arch_align_stack(unsigned long sp);
+extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
+
+void default_idle(void);
+bool set_pm_idle_to_default(void);
+
+void stop_this_cpu(void *dummy);
+
 #endif /* _ASM_X86_PROCESSOR_H */