linux/arch/x86/include/asm/special_insns.h
<<
>>
Prefs
   1#ifndef _ASM_X86_SPECIAL_INSNS_H
   2#define _ASM_X86_SPECIAL_INSNS_H
   3
   4
   5#ifdef __KERNEL__
   6
   7static inline void native_clts(void)
   8{
   9        asm volatile("clts");
  10}
  11
  12/*
  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
  18 */
  19static unsigned long __force_order;
  20
  21static inline unsigned long native_read_cr0(void)
  22{
  23        unsigned long val;
  24        asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
  25        return val;
  26}
  27
  28static inline void native_write_cr0(unsigned long val)
  29{
  30        asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));
  31}
  32
  33static inline unsigned long native_read_cr2(void)
  34{
  35        unsigned long val;
  36        asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));
  37        return val;
  38}
  39
  40static inline void native_write_cr2(unsigned long val)
  41{
  42        asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order));
  43}
  44
  45static inline unsigned long native_read_cr3(void)
  46{
  47        unsigned long val;
  48        asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
  49        return val;
  50}
  51
  52static inline void native_write_cr3(unsigned long val)
  53{
  54        asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order));
  55}
  56
  57static inline unsigned long native_read_cr4(void)
  58{
  59        unsigned long val;
  60        asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
  61        return val;
  62}
  63
  64static inline unsigned long native_read_cr4_safe(void)
  65{
  66        unsigned long val;
  67        /* This could fault if %cr4 does not exist. In x86_64, a cr4 always
  68         * exists, so it will never fail. */
  69#ifdef CONFIG_X86_32
  70        asm volatile("1: mov %%cr4, %0\n"
  71                     "2:\n"
  72                     _ASM_EXTABLE(1b, 2b)
  73                     : "=r" (val), "=m" (__force_order) : "0" (0));
  74#else
  75        val = native_read_cr4();
  76#endif
  77        return val;
  78}
  79
  80static inline void native_write_cr4(unsigned long val)
  81{
  82        asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order));
  83}
  84
  85#ifdef CONFIG_X86_64
  86static inline unsigned long native_read_cr8(void)
  87{
  88        unsigned long cr8;
  89        asm volatile("movq %%cr8,%0" : "=r" (cr8));
  90        return cr8;
  91}
  92
  93static inline void native_write_cr8(unsigned long val)
  94{
  95        asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
  96}
  97#endif
  98
  99static inline void native_wbinvd(void)
 100{
 101        asm volatile("wbinvd": : :"memory");
 102}
 103
 104extern void native_load_gs_index(unsigned);
 105
 106#ifdef CONFIG_PARAVIRT
 107#include <asm/paravirt.h>
 108#else
 109
 110static inline unsigned long read_cr0(void)
 111{
 112        return native_read_cr0();
 113}
 114
 115static inline void write_cr0(unsigned long x)
 116{
 117        native_write_cr0(x);
 118}
 119
 120static inline unsigned long read_cr2(void)
 121{
 122        return native_read_cr2();
 123}
 124
 125static inline void write_cr2(unsigned long x)
 126{
 127        native_write_cr2(x);
 128}
 129
 130static inline unsigned long read_cr3(void)
 131{
 132        return native_read_cr3();
 133}
 134
 135static inline void write_cr3(unsigned long x)
 136{
 137        native_write_cr3(x);
 138}
 139
 140static inline unsigned long read_cr4(void)
 141{
 142        return native_read_cr4();
 143}
 144
 145static inline unsigned long read_cr4_safe(void)
 146{
 147        return native_read_cr4_safe();
 148}
 149
 150static inline void write_cr4(unsigned long x)
 151{
 152        native_write_cr4(x);
 153}
 154
 155static inline void wbinvd(void)
 156{
 157        native_wbinvd();
 158}
 159
 160#ifdef CONFIG_X86_64
 161
 162static inline unsigned long read_cr8(void)
 163{
 164        return native_read_cr8();
 165}
 166
 167static inline void write_cr8(unsigned long x)
 168{
 169        native_write_cr8(x);
 170}
 171
 172static inline void load_gs_index(unsigned selector)
 173{
 174        native_load_gs_index(selector);
 175}
 176
 177#endif
 178
 179/* Clear the 'TS' bit */
 180static inline void clts(void)
 181{
 182        native_clts();
 183}
 184
 185#endif/* CONFIG_PARAVIRT */
 186
 187#define stts() write_cr0(read_cr0() | X86_CR0_TS)
 188
 189static inline void clflush(volatile void *__p)
 190{
 191        asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));
 192}
 193
 194#define nop() asm volatile ("nop")
 195
 196
 197#endif /* __KERNEL__ */
 198
 199#endif /* _ASM_X86_SPECIAL_INSNS_H */
 200