···11+#ifndef _ASM_X86_BARRIER_H22+#define _ASM_X86_BARRIER_H33+44+#include <asm/alternative.h>55+#include <asm/nops.h>66+77+/*88+ * Force strict CPU ordering.99+ * And yes, this is required on UP too when we're talking1010+ * to devices.1111+ */1212+1313+#ifdef CONFIG_X86_321414+/*1515+ * Some non-Intel clones support out of order store. wmb() ceases to be a1616+ * nop for these.1717+ */1818+#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)1919+#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)2020+#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)2121+#else2222+#define mb() asm volatile("mfence":::"memory")2323+#define rmb() asm volatile("lfence":::"memory")2424+#define wmb() asm volatile("sfence" ::: "memory")2525+#endif2626+2727+/**2828+ * read_barrier_depends - Flush all pending reads that subsequents reads2929+ * depend on.3030+ *3131+ * No data-dependent reads from memory-like regions are ever reordered3232+ * over this barrier. All reads preceding this primitive are guaranteed3333+ * to access memory (but not necessarily other CPUs' caches) before any3434+ * reads following this primitive that depend on the data return by3535+ * any of the preceding reads. This primitive is much lighter weight than3636+ * rmb() on most CPUs, and is never heavier weight than is3737+ * rmb().3838+ *3939+ * These ordering constraints are respected by both the local CPU4040+ * and the compiler.4141+ *4242+ * Ordering is not guaranteed by anything other than these primitives,4343+ * not even by data dependencies. See the documentation for4444+ * memory_barrier() for examples and URLs to more information.4545+ *4646+ * For example, the following code would force ordering (the initial4747+ * value of "a" is zero, "b" is one, and "p" is "&a"):4848+ *4949+ * <programlisting>5050+ * CPU 0 CPU 15151+ *5252+ * b = 2;5353+ * memory_barrier();5454+ * p = &b; q = p;5555+ * read_barrier_depends();5656+ * d = *q;5757+ * </programlisting>5858+ *5959+ * because the read of "*q" depends on the read of "p" and these6060+ * two reads are separated by a read_barrier_depends(). However,6161+ * the following code, with the same initial values for "a" and "b":6262+ *6363+ * <programlisting>6464+ * CPU 0 CPU 16565+ *6666+ * a = 2;6767+ * memory_barrier();6868+ * b = 3; y = b;6969+ * read_barrier_depends();7070+ * x = a;7171+ * </programlisting>7272+ *7373+ * does not enforce ordering, since there is no data dependency between7474+ * the read of "a" and the read of "b". Therefore, on some CPUs, such7575+ * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()7676+ * in cases like this where there are no data dependencies.7777+ **/7878+7979+#define read_barrier_depends() do { } while (0)8080+8181+#ifdef CONFIG_SMP8282+#define smp_mb() mb()8383+#ifdef CONFIG_X86_PPRO_FENCE8484+# define smp_rmb() rmb()8585+#else8686+# define smp_rmb() barrier()8787+#endif8888+#ifdef CONFIG_X86_OOSTORE8989+# define smp_wmb() wmb()9090+#else9191+# define smp_wmb() barrier()9292+#endif9393+#define smp_read_barrier_depends() read_barrier_depends()9494+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)9595+#else9696+#define smp_mb() barrier()9797+#define smp_rmb() barrier()9898+#define smp_wmb() barrier()9999+#define smp_read_barrier_depends() do { } while (0)100100+#define set_mb(var, value) do { var = value; barrier(); } while (0)101101+#endif102102+103103+/*104104+ * Stop RDTSC speculation. This is needed when you need to use RDTSC105105+ * (or get_cycles or vread that possibly accesses the TSC) in a defined106106+ * code region.107107+ *108108+ * (Could use an alternative three way for this if there was one.)109109+ */110110+static __always_inline void rdtsc_barrier(void)111111+{112112+ alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);113113+ alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);114114+}115115+116116+#endif /* _ASM_X86_BARRIER_H */
···1414#include <asm/sigcontext.h>1515#include <asm/current.h>1616#include <asm/cpufeature.h>1717-#include <asm/system.h>1817#include <asm/page.h>1918#include <asm/pgtable_types.h>2019#include <asm/percpu.h>2120#include <asm/msr.h>2221#include <asm/desc_defs.h>2322#include <asm/nops.h>2323+#include <asm/special_insns.h>24242525#include <linux/personality.h>2626#include <linux/cpumask.h>···2929#include <linux/math64.h>3030#include <linux/init.h>3131#include <linux/err.h>3232+#include <linux/irqflags.h>3333+3434+/*3535+ * We handle most unaligned accesses in hardware. On the other hand3636+ * unaligned DMA can be quite expensive on some Nehalem processors.3737+ *3838+ * Based on this we disable the IP header alignment in network drivers.3939+ */4040+#define NET_IP_ALIGN 032413342#define HBP_NUM 43443/*···10301021#else10311022#define cpu_has_amd_erratum(x) (false)10321023#endif /* CONFIG_CPU_SUP_AMD */10241024+10251025+#ifdef CONFIG_X86_3210261026+/*10271027+ * disable hlt during certain critical i/o operations10281028+ */10291029+#define HAVE_DISABLE_HLT10301030+#endif10311031+10321032+void disable_hlt(void);10331033+void enable_hlt(void);10341034+10351035+void cpu_idle_wait(void);10361036+10371037+extern unsigned long arch_align_stack(unsigned long sp);10381038+extern void free_init_pages(char *what, unsigned long begin, unsigned long end);10391039+10401040+void default_idle(void);10411041+bool set_pm_idle_to_default(void);10421042+10431043+void stop_this_cpu(void *dummy);1033104410341045#endif /* _ASM_X86_PROCESSOR_H */
+56-2
arch/x86/include/asm/segment.h
···212212#ifdef __KERNEL__213213#ifndef __ASSEMBLY__214214extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10];215215-#endif216216-#endif215215+216216+/*217217+ * Load a segment. Fall back on loading the zero218218+ * segment if something goes wrong..219219+ */220220+#define loadsegment(seg, value) \221221+do { \222222+ unsigned short __val = (value); \223223+ \224224+ asm volatile(" \n" \225225+ "1: movl %k0,%%" #seg " \n" \226226+ \227227+ ".section .fixup,\"ax\" \n" \228228+ "2: xorl %k0,%k0 \n" \229229+ " jmp 1b \n" \230230+ ".previous \n" \231231+ \232232+ _ASM_EXTABLE(1b, 2b) \233233+ \234234+ : "+r" (__val) : : "memory"); \235235+} while (0)236236+237237+/*238238+ * Save a segment register away239239+ */240240+#define savesegment(seg, value) \241241+ asm("mov %%" #seg ",%0":"=r" (value) : : "memory")242242+243243+/*244244+ * x86_32 user gs accessors.245245+ */246246+#ifdef CONFIG_X86_32247247+#ifdef CONFIG_X86_32_LAZY_GS248248+#define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;})249249+#define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v))250250+#define task_user_gs(tsk) ((tsk)->thread.gs)251251+#define lazy_save_gs(v) savesegment(gs, (v))252252+#define lazy_load_gs(v) loadsegment(gs, (v))253253+#else /* X86_32_LAZY_GS */254254+#define get_user_gs(regs) (u16)((regs)->gs)255255+#define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0)256256+#define task_user_gs(tsk) (task_pt_regs(tsk)->gs)257257+#define lazy_save_gs(v) do { } while (0)258258+#define lazy_load_gs(v) do { } while (0)259259+#endif /* X86_32_LAZY_GS */260260+#endif /* X86_32 */261261+262262+static inline unsigned long get_limit(unsigned long segment)263263+{264264+ unsigned long __limit;265265+ asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));266266+ return __limit + 1;267267+}268268+269269+#endif /* !__ASSEMBLY__ */270270+#endif /* __KERNEL__ */217271218272#endif /* _ASM_X86_SEGMENT_H */
+199
arch/x86/include/asm/special_insns.h
···11+#ifndef _ASM_X86_SPECIAL_INSNS_H22+#define _ASM_X86_SPECIAL_INSNS_H33+44+55+#ifdef __KERNEL__66+77+static inline void native_clts(void)88+{99+ asm volatile("clts");1010+}1111+1212+/*1313+ * Volatile isn't enough to prevent the compiler from reordering the1414+ * read/write functions for the control registers and messing everything up.1515+ * A memory clobber would solve the problem, but would prevent reordering of1616+ * all loads stores around it, which can hurt performance. Solution is to1717+ * use a variable and mimic reads and writes to it to enforce serialization1818+ */1919+static unsigned long __force_order;2020+2121+static inline unsigned long native_read_cr0(void)2222+{2323+ unsigned long val;2424+ asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));2525+ return val;2626+}2727+2828+static inline void native_write_cr0(unsigned long val)2929+{3030+ asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));3131+}3232+3333+static inline unsigned long native_read_cr2(void)3434+{3535+ unsigned long val;3636+ asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));3737+ return val;3838+}3939+4040+static inline void native_write_cr2(unsigned long val)4141+{4242+ asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order));4343+}4444+4545+static inline unsigned long native_read_cr3(void)4646+{4747+ unsigned long val;4848+ asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));4949+ return val;5050+}5151+5252+static inline void native_write_cr3(unsigned long val)5353+{5454+ asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order));5555+}5656+5757+static inline unsigned long native_read_cr4(void)5858+{5959+ unsigned long val;6060+ asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));6161+ return val;6262+}6363+6464+static inline unsigned long native_read_cr4_safe(void)6565+{6666+ unsigned long val;6767+ /* This could fault if %cr4 does not exist. In x86_64, a cr4 always6868+ * exists, so it will never fail. */6969+#ifdef CONFIG_X86_327070+ asm volatile("1: mov %%cr4, %0\n"7171+ "2:\n"7272+ _ASM_EXTABLE(1b, 2b)7373+ : "=r" (val), "=m" (__force_order) : "0" (0));7474+#else7575+ val = native_read_cr4();7676+#endif7777+ return val;7878+}7979+8080+static inline void native_write_cr4(unsigned long val)8181+{8282+ asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order));8383+}8484+8585+#ifdef CONFIG_X86_648686+static inline unsigned long native_read_cr8(void)8787+{8888+ unsigned long cr8;8989+ asm volatile("movq %%cr8,%0" : "=r" (cr8));9090+ return cr8;9191+}9292+9393+static inline void native_write_cr8(unsigned long val)9494+{9595+ asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");9696+}9797+#endif9898+9999+static inline void native_wbinvd(void)100100+{101101+ asm volatile("wbinvd": : :"memory");102102+}103103+104104+extern void native_load_gs_index(unsigned);105105+106106+#ifdef CONFIG_PARAVIRT107107+#include <asm/paravirt.h>108108+#else109109+110110+static inline unsigned long read_cr0(void)111111+{112112+ return native_read_cr0();113113+}114114+115115+static inline void write_cr0(unsigned long x)116116+{117117+ native_write_cr0(x);118118+}119119+120120+static inline unsigned long read_cr2(void)121121+{122122+ return native_read_cr2();123123+}124124+125125+static inline void write_cr2(unsigned long x)126126+{127127+ native_write_cr2(x);128128+}129129+130130+static inline unsigned long read_cr3(void)131131+{132132+ return native_read_cr3();133133+}134134+135135+static inline void write_cr3(unsigned long x)136136+{137137+ native_write_cr3(x);138138+}139139+140140+static inline unsigned long read_cr4(void)141141+{142142+ return native_read_cr4();143143+}144144+145145+static inline unsigned long read_cr4_safe(void)146146+{147147+ return native_read_cr4_safe();148148+}149149+150150+static inline void write_cr4(unsigned long x)151151+{152152+ native_write_cr4(x);153153+}154154+155155+static inline void wbinvd(void)156156+{157157+ native_wbinvd();158158+}159159+160160+#ifdef CONFIG_X86_64161161+162162+static inline unsigned long read_cr8(void)163163+{164164+ return native_read_cr8();165165+}166166+167167+static inline void write_cr8(unsigned long x)168168+{169169+ native_write_cr8(x);170170+}171171+172172+static inline void load_gs_index(unsigned selector)173173+{174174+ native_load_gs_index(selector);175175+}176176+177177+#endif178178+179179+/* Clear the 'TS' bit */180180+static inline void clts(void)181181+{182182+ native_clts();183183+}184184+185185+#endif/* CONFIG_PARAVIRT */186186+187187+#define stts() write_cr0(read_cr0() | X86_CR0_TS)188188+189189+static inline void clflush(volatile void *__p)190190+{191191+ asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));192192+}193193+194194+#define nop() asm volatile ("nop")195195+196196+197197+#endif /* __KERNEL__ */198198+199199+#endif /* _ASM_X86_SPECIAL_INSNS_H */
···11+#ifndef _ASM_X86_SWITCH_TO_H22+#define _ASM_X86_SWITCH_TO_H33+44+struct task_struct; /* one of the stranger aspects of C forward declarations */55+struct task_struct *__switch_to(struct task_struct *prev,66+ struct task_struct *next);77+struct tss_struct;88+void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,99+ struct tss_struct *tss);1010+1111+#ifdef CONFIG_X86_321212+1313+#ifdef CONFIG_CC_STACKPROTECTOR1414+#define __switch_canary \1515+ "movl %P[task_canary](%[next]), %%ebx\n\t" \1616+ "movl %%ebx, "__percpu_arg([stack_canary])"\n\t"1717+#define __switch_canary_oparam \1818+ , [stack_canary] "=m" (stack_canary.canary)1919+#define __switch_canary_iparam \2020+ , [task_canary] "i" (offsetof(struct task_struct, stack_canary))2121+#else /* CC_STACKPROTECTOR */2222+#define __switch_canary2323+#define __switch_canary_oparam2424+#define __switch_canary_iparam2525+#endif /* CC_STACKPROTECTOR */2626+2727+/*2828+ * Saving eflags is important. It switches not only IOPL between tasks,2929+ * it also protects other tasks from NT leaking through sysenter etc.3030+ */3131+#define switch_to(prev, next, last) \3232+do { \3333+ /* \3434+ * Context-switching clobbers all registers, so we clobber \3535+ * them explicitly, via unused output variables. \3636+ * (EAX and EBP is not listed because EBP is saved/restored \3737+ * explicitly for wchan access and EAX is the return value of \3838+ * __switch_to()) \3939+ */ \4040+ unsigned long ebx, ecx, edx, esi, edi; \4141+ \4242+ asm volatile("pushfl\n\t" /* save flags */ \4343+ "pushl %%ebp\n\t" /* save EBP */ \4444+ "movl %%esp,%[prev_sp]\n\t" /* save ESP */ \4545+ "movl %[next_sp],%%esp\n\t" /* restore ESP */ \4646+ "movl $1f,%[prev_ip]\n\t" /* save EIP */ \4747+ "pushl %[next_ip]\n\t" /* restore EIP */ \4848+ __switch_canary \4949+ "jmp __switch_to\n" /* regparm call */ \5050+ "1:\t" \5151+ "popl %%ebp\n\t" /* restore EBP */ \5252+ "popfl\n" /* restore flags */ \5353+ \5454+ /* output parameters */ \5555+ : [prev_sp] "=m" (prev->thread.sp), \5656+ [prev_ip] "=m" (prev->thread.ip), \5757+ "=a" (last), \5858+ \5959+ /* clobbered output registers: */ \6060+ "=b" (ebx), "=c" (ecx), "=d" (edx), \6161+ "=S" (esi), "=D" (edi) \6262+ \6363+ __switch_canary_oparam \6464+ \6565+ /* input parameters: */ \6666+ : [next_sp] "m" (next->thread.sp), \6767+ [next_ip] "m" (next->thread.ip), \6868+ \6969+ /* regparm parameters for __switch_to(): */ \7070+ [prev] "a" (prev), \7171+ [next] "d" (next) \7272+ \7373+ __switch_canary_iparam \7474+ \7575+ : /* reloaded segment registers */ \7676+ "memory"); \7777+} while (0)7878+7979+#else /* CONFIG_X86_32 */8080+8181+/* frame pointer must be last for get_wchan */8282+#define SAVE_CONTEXT "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"8383+#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t"8484+8585+#define __EXTRA_CLOBBER \8686+ , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \8787+ "r12", "r13", "r14", "r15"8888+8989+#ifdef CONFIG_CC_STACKPROTECTOR9090+#define __switch_canary \9191+ "movq %P[task_canary](%%rsi),%%r8\n\t" \9292+ "movq %%r8,"__percpu_arg([gs_canary])"\n\t"9393+#define __switch_canary_oparam \9494+ , [gs_canary] "=m" (irq_stack_union.stack_canary)9595+#define __switch_canary_iparam \9696+ , [task_canary] "i" (offsetof(struct task_struct, stack_canary))9797+#else /* CC_STACKPROTECTOR */9898+#define __switch_canary9999+#define __switch_canary_oparam100100+#define __switch_canary_iparam101101+#endif /* CC_STACKPROTECTOR */102102+103103+/* Save restore flags to clear handle leaking NT */104104+#define switch_to(prev, next, last) \105105+ asm volatile(SAVE_CONTEXT \106106+ "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \107107+ "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \108108+ "call __switch_to\n\t" \109109+ "movq "__percpu_arg([current_task])",%%rsi\n\t" \110110+ __switch_canary \111111+ "movq %P[thread_info](%%rsi),%%r8\n\t" \112112+ "movq %%rax,%%rdi\n\t" \113113+ "testl %[_tif_fork],%P[ti_flags](%%r8)\n\t" \114114+ "jnz ret_from_fork\n\t" \115115+ RESTORE_CONTEXT \116116+ : "=a" (last) \117117+ __switch_canary_oparam \118118+ : [next] "S" (next), [prev] "D" (prev), \119119+ [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \120120+ [ti_flags] "i" (offsetof(struct thread_info, flags)), \121121+ [_tif_fork] "i" (_TIF_FORK), \122122+ [thread_info] "i" (offsetof(struct task_struct, stack)), \123123+ [current_task] "m" (current_task) \124124+ __switch_canary_iparam \125125+ : "memory", "cc" __EXTRA_CLOBBER)126126+127127+#endif /* CONFIG_X86_32 */128128+129129+#endif /* _ASM_X86_SWITCH_TO_H */
+5-522
arch/x86/include/asm/system.h
···11-#ifndef _ASM_X86_SYSTEM_H22-#define _ASM_X86_SYSTEM_H33-44-#include <asm/asm.h>55-#include <asm/segment.h>66-#include <asm/cpufeature.h>11+/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */22+#include <asm/barrier.h>73#include <asm/cmpxchg.h>88-#include <asm/nops.h>99-1010-#include <linux/kernel.h>1111-#include <linux/irqflags.h>1212-1313-/* entries in ARCH_DLINFO: */1414-#if defined(CONFIG_IA32_EMULATION) || !defined(CONFIG_X86_64)1515-# define AT_VECTOR_SIZE_ARCH 21616-#else /* else it's non-compat x86-64 */1717-# define AT_VECTOR_SIZE_ARCH 11818-#endif1919-2020-struct task_struct; /* one of the stranger aspects of C forward declarations */2121-struct task_struct *__switch_to(struct task_struct *prev,2222- struct task_struct *next);2323-struct tss_struct;2424-void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,2525- struct tss_struct *tss);2626-extern void show_regs_common(void);2727-2828-#ifdef CONFIG_X86_322929-3030-#ifdef CONFIG_CC_STACKPROTECTOR3131-#define __switch_canary \3232- "movl %P[task_canary](%[next]), %%ebx\n\t" \3333- "movl %%ebx, "__percpu_arg([stack_canary])"\n\t"3434-#define __switch_canary_oparam \3535- , [stack_canary] "=m" (stack_canary.canary)3636-#define __switch_canary_iparam \3737- , [task_canary] "i" (offsetof(struct task_struct, stack_canary))3838-#else /* CC_STACKPROTECTOR */3939-#define __switch_canary4040-#define __switch_canary_oparam4141-#define __switch_canary_iparam4242-#endif /* CC_STACKPROTECTOR */4343-4444-/*4545- * Saving eflags is important. It switches not only IOPL between tasks,4646- * it also protects other tasks from NT leaking through sysenter etc.4747- */4848-#define switch_to(prev, next, last) \4949-do { \5050- /* \5151- * Context-switching clobbers all registers, so we clobber \5252- * them explicitly, via unused output variables. \5353- * (EAX and EBP is not listed because EBP is saved/restored \5454- * explicitly for wchan access and EAX is the return value of \5555- * __switch_to()) \5656- */ \5757- unsigned long ebx, ecx, edx, esi, edi; \5858- \5959- asm volatile("pushfl\n\t" /* save flags */ \6060- "pushl %%ebp\n\t" /* save EBP */ \6161- "movl %%esp,%[prev_sp]\n\t" /* save ESP */ \6262- "movl %[next_sp],%%esp\n\t" /* restore ESP */ \6363- "movl $1f,%[prev_ip]\n\t" /* save EIP */ \6464- "pushl %[next_ip]\n\t" /* restore EIP */ \6565- __switch_canary \6666- "jmp __switch_to\n" /* regparm call */ \6767- "1:\t" \6868- "popl %%ebp\n\t" /* restore EBP */ \6969- "popfl\n" /* restore flags */ \7070- \7171- /* output parameters */ \7272- : [prev_sp] "=m" (prev->thread.sp), \7373- [prev_ip] "=m" (prev->thread.ip), \7474- "=a" (last), \7575- \7676- /* clobbered output registers: */ \7777- "=b" (ebx), "=c" (ecx), "=d" (edx), \7878- "=S" (esi), "=D" (edi) \7979- \8080- __switch_canary_oparam \8181- \8282- /* input parameters: */ \8383- : [next_sp] "m" (next->thread.sp), \8484- [next_ip] "m" (next->thread.ip), \8585- \8686- /* regparm parameters for __switch_to(): */ \8787- [prev] "a" (prev), \8888- [next] "d" (next) \8989- \9090- __switch_canary_iparam \9191- \9292- : /* reloaded segment registers */ \9393- "memory"); \9494-} while (0)9595-9696-/*9797- * disable hlt during certain critical i/o operations9898- */9999-#define HAVE_DISABLE_HLT100100-#else101101-102102-/* frame pointer must be last for get_wchan */103103-#define SAVE_CONTEXT "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"104104-#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t"105105-106106-#define __EXTRA_CLOBBER \107107- , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \108108- "r12", "r13", "r14", "r15"109109-110110-#ifdef CONFIG_CC_STACKPROTECTOR111111-#define __switch_canary \112112- "movq %P[task_canary](%%rsi),%%r8\n\t" \113113- "movq %%r8,"__percpu_arg([gs_canary])"\n\t"114114-#define __switch_canary_oparam \115115- , [gs_canary] "=m" (irq_stack_union.stack_canary)116116-#define __switch_canary_iparam \117117- , [task_canary] "i" (offsetof(struct task_struct, stack_canary))118118-#else /* CC_STACKPROTECTOR */119119-#define __switch_canary120120-#define __switch_canary_oparam121121-#define __switch_canary_iparam122122-#endif /* CC_STACKPROTECTOR */123123-124124-/* Save restore flags to clear handle leaking NT */125125-#define switch_to(prev, next, last) \126126- asm volatile(SAVE_CONTEXT \127127- "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \128128- "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \129129- "call __switch_to\n\t" \130130- "movq "__percpu_arg([current_task])",%%rsi\n\t" \131131- __switch_canary \132132- "movq %P[thread_info](%%rsi),%%r8\n\t" \133133- "movq %%rax,%%rdi\n\t" \134134- "testl %[_tif_fork],%P[ti_flags](%%r8)\n\t" \135135- "jnz ret_from_fork\n\t" \136136- RESTORE_CONTEXT \137137- : "=a" (last) \138138- __switch_canary_oparam \139139- : [next] "S" (next), [prev] "D" (prev), \140140- [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \141141- [ti_flags] "i" (offsetof(struct thread_info, flags)), \142142- [_tif_fork] "i" (_TIF_FORK), \143143- [thread_info] "i" (offsetof(struct task_struct, stack)), \144144- [current_task] "m" (current_task) \145145- __switch_canary_iparam \146146- : "memory", "cc" __EXTRA_CLOBBER)147147-#endif148148-149149-#ifdef __KERNEL__150150-151151-extern void native_load_gs_index(unsigned);152152-153153-/*154154- * Load a segment. Fall back on loading the zero155155- * segment if something goes wrong..156156- */157157-#define loadsegment(seg, value) \158158-do { \159159- unsigned short __val = (value); \160160- \161161- asm volatile(" \n" \162162- "1: movl %k0,%%" #seg " \n" \163163- \164164- ".section .fixup,\"ax\" \n" \165165- "2: xorl %k0,%k0 \n" \166166- " jmp 1b \n" \167167- ".previous \n" \168168- \169169- _ASM_EXTABLE(1b, 2b) \170170- \171171- : "+r" (__val) : : "memory"); \172172-} while (0)173173-174174-/*175175- * Save a segment register away176176- */177177-#define savesegment(seg, value) \178178- asm("mov %%" #seg ",%0":"=r" (value) : : "memory")179179-180180-/*181181- * x86_32 user gs accessors.182182- */183183-#ifdef CONFIG_X86_32184184-#ifdef CONFIG_X86_32_LAZY_GS185185-#define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;})186186-#define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v))187187-#define task_user_gs(tsk) ((tsk)->thread.gs)188188-#define lazy_save_gs(v) savesegment(gs, (v))189189-#define lazy_load_gs(v) loadsegment(gs, (v))190190-#else /* X86_32_LAZY_GS */191191-#define get_user_gs(regs) (u16)((regs)->gs)192192-#define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0)193193-#define task_user_gs(tsk) (task_pt_regs(tsk)->gs)194194-#define lazy_save_gs(v) do { } while (0)195195-#define lazy_load_gs(v) do { } while (0)196196-#endif /* X86_32_LAZY_GS */197197-#endif /* X86_32 */198198-199199-static inline unsigned long get_limit(unsigned long segment)200200-{201201- unsigned long __limit;202202- asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));203203- return __limit + 1;204204-}205205-206206-static inline void native_clts(void)207207-{208208- asm volatile("clts");209209-}210210-211211-/*212212- * Volatile isn't enough to prevent the compiler from reordering the213213- * read/write functions for the control registers and messing everything up.214214- * A memory clobber would solve the problem, but would prevent reordering of215215- * all loads stores around it, which can hurt performance. Solution is to216216- * use a variable and mimic reads and writes to it to enforce serialization217217- */218218-static unsigned long __force_order;219219-220220-static inline unsigned long native_read_cr0(void)221221-{222222- unsigned long val;223223- asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));224224- return val;225225-}226226-227227-static inline void native_write_cr0(unsigned long val)228228-{229229- asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));230230-}231231-232232-static inline unsigned long native_read_cr2(void)233233-{234234- unsigned long val;235235- asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));236236- return val;237237-}238238-239239-static inline void native_write_cr2(unsigned long val)240240-{241241- asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order));242242-}243243-244244-static inline unsigned long native_read_cr3(void)245245-{246246- unsigned long val;247247- asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));248248- return val;249249-}250250-251251-static inline void native_write_cr3(unsigned long val)252252-{253253- asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order));254254-}255255-256256-static inline unsigned long native_read_cr4(void)257257-{258258- unsigned long val;259259- asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));260260- return val;261261-}262262-263263-static inline unsigned long native_read_cr4_safe(void)264264-{265265- unsigned long val;266266- /* This could fault if %cr4 does not exist. In x86_64, a cr4 always267267- * exists, so it will never fail. */268268-#ifdef CONFIG_X86_32269269- asm volatile("1: mov %%cr4, %0\n"270270- "2:\n"271271- _ASM_EXTABLE(1b, 2b)272272- : "=r" (val), "=m" (__force_order) : "0" (0));273273-#else274274- val = native_read_cr4();275275-#endif276276- return val;277277-}278278-279279-static inline void native_write_cr4(unsigned long val)280280-{281281- asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order));282282-}283283-284284-#ifdef CONFIG_X86_64285285-static inline unsigned long native_read_cr8(void)286286-{287287- unsigned long cr8;288288- asm volatile("movq %%cr8,%0" : "=r" (cr8));289289- return cr8;290290-}291291-292292-static inline void native_write_cr8(unsigned long val)293293-{294294- asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");295295-}296296-#endif297297-298298-static inline void native_wbinvd(void)299299-{300300- asm volatile("wbinvd": : :"memory");301301-}302302-303303-#ifdef CONFIG_PARAVIRT304304-#include <asm/paravirt.h>305305-#else306306-307307-static inline unsigned long read_cr0(void)308308-{309309- return native_read_cr0();310310-}311311-312312-static inline void write_cr0(unsigned long x)313313-{314314- native_write_cr0(x);315315-}316316-317317-static inline unsigned long read_cr2(void)318318-{319319- return native_read_cr2();320320-}321321-322322-static inline void write_cr2(unsigned long x)323323-{324324- native_write_cr2(x);325325-}326326-327327-static inline unsigned long read_cr3(void)328328-{329329- return native_read_cr3();330330-}331331-332332-static inline void write_cr3(unsigned long x)333333-{334334- native_write_cr3(x);335335-}336336-337337-static inline unsigned long read_cr4(void)338338-{339339- return native_read_cr4();340340-}341341-342342-static inline unsigned long read_cr4_safe(void)343343-{344344- return native_read_cr4_safe();345345-}346346-347347-static inline void write_cr4(unsigned long x)348348-{349349- native_write_cr4(x);350350-}351351-352352-static inline void wbinvd(void)353353-{354354- native_wbinvd();355355-}356356-357357-#ifdef CONFIG_X86_64358358-359359-static inline unsigned long read_cr8(void)360360-{361361- return native_read_cr8();362362-}363363-364364-static inline void write_cr8(unsigned long x)365365-{366366- native_write_cr8(x);367367-}368368-369369-static inline void load_gs_index(unsigned selector)370370-{371371- native_load_gs_index(selector);372372-}373373-374374-#endif375375-376376-/* Clear the 'TS' bit */377377-static inline void clts(void)378378-{379379- native_clts();380380-}381381-382382-#endif/* CONFIG_PARAVIRT */383383-384384-#define stts() write_cr0(read_cr0() | X86_CR0_TS)385385-386386-#endif /* __KERNEL__ */387387-388388-static inline void clflush(volatile void *__p)389389-{390390- asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));391391-}392392-393393-#define nop() asm volatile ("nop")394394-395395-void disable_hlt(void);396396-void enable_hlt(void);397397-398398-void cpu_idle_wait(void);399399-400400-extern unsigned long arch_align_stack(unsigned long sp);401401-extern void free_init_pages(char *what, unsigned long begin, unsigned long end);402402-403403-void default_idle(void);404404-bool set_pm_idle_to_default(void);405405-406406-void stop_this_cpu(void *dummy);407407-408408-/*409409- * Force strict CPU ordering.410410- * And yes, this is required on UP too when we're talking411411- * to devices.412412- */413413-#ifdef CONFIG_X86_32414414-/*415415- * Some non-Intel clones support out of order store. wmb() ceases to be a416416- * nop for these.417417- */418418-#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)419419-#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)420420-#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)421421-#else422422-#define mb() asm volatile("mfence":::"memory")423423-#define rmb() asm volatile("lfence":::"memory")424424-#define wmb() asm volatile("sfence" ::: "memory")425425-#endif426426-427427-/**428428- * read_barrier_depends - Flush all pending reads that subsequents reads429429- * depend on.430430- *431431- * No data-dependent reads from memory-like regions are ever reordered432432- * over this barrier. All reads preceding this primitive are guaranteed433433- * to access memory (but not necessarily other CPUs' caches) before any434434- * reads following this primitive that depend on the data return by435435- * any of the preceding reads. This primitive is much lighter weight than436436- * rmb() on most CPUs, and is never heavier weight than is437437- * rmb().438438- *439439- * These ordering constraints are respected by both the local CPU440440- * and the compiler.441441- *442442- * Ordering is not guaranteed by anything other than these primitives,443443- * not even by data dependencies. See the documentation for444444- * memory_barrier() for examples and URLs to more information.445445- *446446- * For example, the following code would force ordering (the initial447447- * value of "a" is zero, "b" is one, and "p" is "&a"):448448- *449449- * <programlisting>450450- * CPU 0 CPU 1451451- *452452- * b = 2;453453- * memory_barrier();454454- * p = &b; q = p;455455- * read_barrier_depends();456456- * d = *q;457457- * </programlisting>458458- *459459- * because the read of "*q" depends on the read of "p" and these460460- * two reads are separated by a read_barrier_depends(). However,461461- * the following code, with the same initial values for "a" and "b":462462- *463463- * <programlisting>464464- * CPU 0 CPU 1465465- *466466- * a = 2;467467- * memory_barrier();468468- * b = 3; y = b;469469- * read_barrier_depends();470470- * x = a;471471- * </programlisting>472472- *473473- * does not enforce ordering, since there is no data dependency between474474- * the read of "a" and the read of "b". Therefore, on some CPUs, such475475- * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()476476- * in cases like this where there are no data dependencies.477477- **/478478-479479-#define read_barrier_depends() do { } while (0)480480-481481-#ifdef CONFIG_SMP482482-#define smp_mb() mb()483483-#ifdef CONFIG_X86_PPRO_FENCE484484-# define smp_rmb() rmb()485485-#else486486-# define smp_rmb() barrier()487487-#endif488488-#ifdef CONFIG_X86_OOSTORE489489-# define smp_wmb() wmb()490490-#else491491-# define smp_wmb() barrier()492492-#endif493493-#define smp_read_barrier_depends() read_barrier_depends()494494-#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)495495-#else496496-#define smp_mb() barrier()497497-#define smp_rmb() barrier()498498-#define smp_wmb() barrier()499499-#define smp_read_barrier_depends() do { } while (0)500500-#define set_mb(var, value) do { var = value; barrier(); } while (0)501501-#endif502502-503503-/*504504- * Stop RDTSC speculation. This is needed when you need to use RDTSC505505- * (or get_cycles or vread that possibly accesses the TSC) in a defined506506- * code region.507507- *508508- * (Could use an alternative three way for this if there was one.)509509- */510510-static __always_inline void rdtsc_barrier(void)511511-{512512- alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);513513- alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);514514-}515515-516516-/*517517- * We handle most unaligned accesses in hardware. On the other hand518518- * unaligned DMA can be quite expensive on some Nehalem processors.519519- *520520- * Based on this we disable the IP header alignment in network drivers.521521- */522522-#define NET_IP_ALIGN 0523523-#endif /* _ASM_X86_SYSTEM_H */44+#include <asm/exec.h>55+#include <asm/special_insns.h>66+#include <asm/switch_to.h>
···1414#include <acpi/processor.h>1515#include <asm/acpi.h>1616#include <asm/mwait.h>1717+#include <asm/special_insns.h>17181819/*1920 * Initialize bm_flags based on the CPU cache properties
···3434#include <asm/tce.h>3535#include <asm/calgary.h>3636#include <asm/proto.h>3737+#include <asm/cacheflush.h>37383839/* flush a tce at 'tceaddr' to main memory */3940static inline void flush_tce(void* tceaddr)