1 #ifndef _ASM_X86_SPECIAL_INSNS_H
2 #define _ASM_X86_SPECIAL_INSNS_H
7 static inline void native_clts(void)
13 * Volatile isn't enough to prevent the compiler from reordering the
14 * read/write functions for the control registers and messing everything up.
15 * A memory clobber would solve the problem, but would prevent reordering of
16 * all loads stores around it, which can hurt performance. Solution is to
17 * use a variable and mimic reads and writes to it to enforce serialization
19 extern unsigned long __force_order
;
21 static inline unsigned long native_read_cr0(void)
24 asm volatile("mov %%cr0,%0\n\t" : "=r" (val
), "=m" (__force_order
));
28 static inline void native_write_cr0(unsigned long val
)
30 asm volatile("mov %0,%%cr0": : "r" (val
), "m" (__force_order
));
33 static inline unsigned long native_read_cr2(void)
36 asm volatile("mov %%cr2,%0\n\t" : "=r" (val
), "=m" (__force_order
));
40 static inline void native_write_cr2(unsigned long val
)
42 asm volatile("mov %0,%%cr2": : "r" (val
), "m" (__force_order
));
45 static inline unsigned long native_read_cr3(void)
48 asm volatile("mov %%cr3,%0\n\t" : "=r" (val
), "=m" (__force_order
));
52 static inline void native_write_cr3(unsigned long val
)
54 asm volatile("mov %0,%%cr3": : "r" (val
), "m" (__force_order
));
57 static inline unsigned long native_read_cr4(void)
60 asm volatile("mov %%cr4,%0\n\t" : "=r" (val
), "=m" (__force_order
));
64 static inline unsigned long native_read_cr4_safe(void)
67 /* This could fault if %cr4 does not exist. In x86_64, a cr4 always
68 * exists, so it will never fail. */
70 asm volatile("1: mov %%cr4, %0\n"
73 : "=r" (val
), "=m" (__force_order
) : "0" (0));
75 val
= native_read_cr4();
80 static inline void native_write_cr4(unsigned long val
)
82 asm volatile("mov %0,%%cr4": : "r" (val
), "m" (__force_order
));
86 static inline unsigned long native_read_cr8(void)
89 asm volatile("movq %%cr8,%0" : "=r" (cr8
));
93 static inline void native_write_cr8(unsigned long val
)
95 asm volatile("movq %0,%%cr8" :: "r" (val
) : "memory");
99 static inline void native_wbinvd(void)
101 asm volatile("wbinvd": : :"memory");
104 extern void native_load_gs_index(unsigned);
106 #ifdef CONFIG_PARAVIRT
107 #include <asm/paravirt.h>
110 static inline unsigned long read_cr0(void)
112 return native_read_cr0();
115 static inline void write_cr0(unsigned long x
)
120 static inline unsigned long read_cr2(void)
122 return native_read_cr2();
125 static inline void write_cr2(unsigned long x
)
130 static inline unsigned long read_cr3(void)
132 return native_read_cr3();
135 static inline void write_cr3(unsigned long x
)
140 static inline unsigned long read_cr4(void)
142 return native_read_cr4();
145 static inline unsigned long read_cr4_safe(void)
147 return native_read_cr4_safe();
150 static inline void write_cr4(unsigned long x
)
155 static inline void wbinvd(void)
162 static inline unsigned long read_cr8(void)
164 return native_read_cr8();
167 static inline void write_cr8(unsigned long x
)
172 static inline void load_gs_index(unsigned selector
)
174 native_load_gs_index(selector
);
179 /* Clear the 'TS' bit */
180 static inline void clts(void)
185 #endif/* CONFIG_PARAVIRT */
187 #define stts() write_cr0(read_cr0() | X86_CR0_TS)
189 static inline void clflush(volatile void *__p
)
191 asm volatile("clflush %0" : "+m" (*(volatile char __force
*)__p
));
194 #define nop() asm volatile ("nop")
197 #endif /* __KERNEL__ */
199 #endif /* _ASM_X86_SPECIAL_INSNS_H */