Commit d9a73c00161f3eaa4c8c035c62f45afd1549e38a

Authored by Linus Torvalds

Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  um, x86: Cast to (u64 *) inside set_64bit()
  x86-32, asm: Directly access per-cpu GDT
  x86-64, asm: Directly access per-cpu IST
  x86, asm: Merge cmpxchg_486_u64() and cmpxchg8b_emu()
  x86, asm: Move cmpxchg emulation code to arch/x86/lib
  x86, asm: Clean up and simplify <asm/cmpxchg.h>
  x86, asm: Clean up and simplify set_64bit()
  x86: Add memory modify constraints to xchg() and cmpxchg()
  x86-64: Simplify loading initial_gs
  x86: Use symbolic MSR names
  x86: Remove redundant K6 MSRs

Showing 16 changed files Side-by-side Diff

arch/um/include/asm/pgtable-3level.h
... ... @@ -60,7 +60,7 @@
60 60 set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
61 61  
62 62 #ifdef CONFIG_64BIT
63   -#define set_pud(pudptr, pudval) set_64bit((phys_t *) (pudptr), pud_val(pudval))
  63 +#define set_pud(pudptr, pudval) set_64bit((u64 *) (pudptr), pud_val(pudval))
64 64 #else
65 65 #define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
66 66 #endif
... ... @@ -73,7 +73,7 @@
73 73 static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; }
74 74  
75 75 #ifdef CONFIG_64BIT
76   -#define set_pmd(pmdptr, pmdval) set_64bit((phys_t *) (pmdptr), pmd_val(pmdval))
  76 +#define set_pmd(pmdptr, pmdval) set_64bit((u64 *) (pmdptr), pmd_val(pmdval))
77 77 #else
78 78 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
79 79 #endif
arch/x86/include/asm/cmpxchg_32.h
... ... @@ -11,38 +11,42 @@
11 11 extern void __xchg_wrong_size(void);
12 12  
13 13 /*
14   - * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
15   - * Note 2: xchg has side effect, so that attribute volatile is necessary,
16   - * but generally the primitive is invalid, *ptr is output argument. --ANK
  14 + * Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
  15 + * Since this is generally used to protect other memory information, we
  16 + * use "asm volatile" and "memory" clobbers to prevent gcc from moving
  17 + * information around.
17 18 */
18   -
19   -struct __xchg_dummy {
20   - unsigned long a[100];
21   -};
22   -#define __xg(x) ((struct __xchg_dummy *)(x))
23   -
24 19 #define __xchg(x, ptr, size) \
25 20 ({ \
26 21 __typeof(*(ptr)) __x = (x); \
27 22 switch (size) { \
28 23 case 1: \
29   - asm volatile("xchgb %b0,%1" \
30   - : "=q" (__x) \
31   - : "m" (*__xg(ptr)), "0" (__x) \
  24 + { \
  25 + volatile u8 *__ptr = (volatile u8 *)(ptr); \
  26 + asm volatile("xchgb %0,%1" \
  27 + : "=q" (__x), "+m" (*__ptr) \
  28 + : "0" (__x) \
32 29 : "memory"); \
33 30 break; \
  31 + } \
34 32 case 2: \
35   - asm volatile("xchgw %w0,%1" \
36   - : "=r" (__x) \
37   - : "m" (*__xg(ptr)), "0" (__x) \
  33 + { \
  34 + volatile u16 *__ptr = (volatile u16 *)(ptr); \
  35 + asm volatile("xchgw %0,%1" \
  36 + : "=r" (__x), "+m" (*__ptr) \
  37 + : "0" (__x) \
38 38 : "memory"); \
39 39 break; \
  40 + } \
40 41 case 4: \
  42 + { \
  43 + volatile u32 *__ptr = (volatile u32 *)(ptr); \
41 44 asm volatile("xchgl %0,%1" \
42   - : "=r" (__x) \
43   - : "m" (*__xg(ptr)), "0" (__x) \
  45 + : "=r" (__x), "+m" (*__ptr) \
  46 + : "0" (__x) \
44 47 : "memory"); \
45 48 break; \
  49 + } \
46 50 default: \
47 51 __xchg_wrong_size(); \
48 52 } \
49 53  
50 54  
51 55  
52 56  
53 57  
54 58  
... ... @@ -53,60 +57,33 @@
53 57 __xchg((v), (ptr), sizeof(*ptr))
54 58  
55 59 /*
56   - * The semantics of XCHGCMP8B are a bit strange, this is why
57   - * there is a loop and the loading of %%eax and %%edx has to
58   - * be inside. This inlines well in most cases, the cached
59   - * cost is around ~38 cycles. (in the future we might want
60   - * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
61   - * might have an implicit FPU-save as a cost, so it's not
62   - * clear which path to go.)
  60 + * CMPXCHG8B only writes to the target if we had the previous
  61 + * value in registers, otherwise it acts as a read and gives us the
  62 + * "new previous" value. That is why there is a loop. Preloading
  63 + * EDX:EAX is a performance optimization: in the common case it means
  64 + * we need only one locked operation.
63 65 *
64   - * cmpxchg8b must be used with the lock prefix here to allow
65   - * the instruction to be executed atomically, see page 3-102
66   - * of the instruction set reference 24319102.pdf. We need
67   - * the reader side to see the coherent 64bit value.
  66 + * A SIMD/3DNOW!/MMX/FPU 64-bit store here would require at the very
  67 + * least an FPU save and/or %cr0.ts manipulation.
  68 + *
  69 + * cmpxchg8b must be used with the lock prefix here to allow the
  70 + * instruction to be executed atomically. We need to have the reader
  71 + * side to see the coherent 64bit value.
68 72 */
69   -static inline void __set_64bit(unsigned long long *ptr,
70   - unsigned int low, unsigned int high)
  73 +static inline void set_64bit(volatile u64 *ptr, u64 value)
71 74 {
  75 + u32 low = value;
  76 + u32 high = value >> 32;
  77 + u64 prev = *ptr;
  78 +
72 79 asm volatile("\n1:\t"
73   - "movl (%0), %%eax\n\t"
74   - "movl 4(%0), %%edx\n\t"
75   - LOCK_PREFIX "cmpxchg8b (%0)\n\t"
  80 + LOCK_PREFIX "cmpxchg8b %0\n\t"
76 81 "jnz 1b"
77   - : /* no outputs */
78   - : "D"(ptr),
79   - "b"(low),
80   - "c"(high)
81   - : "ax", "dx", "memory");
  82 + : "=m" (*ptr), "+A" (prev)
  83 + : "b" (low), "c" (high)
  84 + : "memory");
82 85 }
83 86  
84   -static inline void __set_64bit_constant(unsigned long long *ptr,
85   - unsigned long long value)
86   -{
87   - __set_64bit(ptr, (unsigned int)value, (unsigned int)(value >> 32));
88   -}
89   -
90   -#define ll_low(x) *(((unsigned int *)&(x)) + 0)
91   -#define ll_high(x) *(((unsigned int *)&(x)) + 1)
92   -
93   -static inline void __set_64bit_var(unsigned long long *ptr,
94   - unsigned long long value)
95   -{
96   - __set_64bit(ptr, ll_low(value), ll_high(value));
97   -}
98   -
99   -#define set_64bit(ptr, value) \
100   - (__builtin_constant_p((value)) \
101   - ? __set_64bit_constant((ptr), (value)) \
102   - : __set_64bit_var((ptr), (value)))
103   -
104   -#define _set_64bit(ptr, value) \
105   - (__builtin_constant_p(value) \
106   - ? __set_64bit(ptr, (unsigned int)(value), \
107   - (unsigned int)((value) >> 32)) \
108   - : __set_64bit(ptr, ll_low((value)), ll_high((value))))
109   -
110 87 extern void __cmpxchg_wrong_size(void);
111 88  
112 89 /*
113 90  
114 91  
115 92  
116 93  
117 94  
... ... @@ -121,23 +98,32 @@
121 98 __typeof__(*(ptr)) __new = (new); \
122 99 switch (size) { \
123 100 case 1: \
124   - asm volatile(lock "cmpxchgb %b1,%2" \
125   - : "=a"(__ret) \
126   - : "q"(__new), "m"(*__xg(ptr)), "0"(__old) \
  101 + { \
  102 + volatile u8 *__ptr = (volatile u8 *)(ptr); \
  103 + asm volatile(lock "cmpxchgb %2,%1" \
  104 + : "=a" (__ret), "+m" (*__ptr) \
  105 + : "q" (__new), "0" (__old) \
127 106 : "memory"); \
128 107 break; \
  108 + } \
129 109 case 2: \
130   - asm volatile(lock "cmpxchgw %w1,%2" \
131   - : "=a"(__ret) \
132   - : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
  110 + { \
  111 + volatile u16 *__ptr = (volatile u16 *)(ptr); \
  112 + asm volatile(lock "cmpxchgw %2,%1" \
  113 + : "=a" (__ret), "+m" (*__ptr) \
  114 + : "r" (__new), "0" (__old) \
133 115 : "memory"); \
134 116 break; \
  117 + } \
135 118 case 4: \
136   - asm volatile(lock "cmpxchgl %1,%2" \
137   - : "=a"(__ret) \
138   - : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
  119 + { \
  120 + volatile u32 *__ptr = (volatile u32 *)(ptr); \
  121 + asm volatile(lock "cmpxchgl %2,%1" \
  122 + : "=a" (__ret), "+m" (*__ptr) \
  123 + : "r" (__new), "0" (__old) \
139 124 : "memory"); \
140 125 break; \
  126 + } \
141 127 default: \
142 128 __cmpxchg_wrong_size(); \
143 129 } \
144 130  
145 131  
146 132  
... ... @@ -175,32 +161,28 @@
175 161 (unsigned long long)(n)))
176 162 #endif
177 163  
178   -static inline unsigned long long __cmpxchg64(volatile void *ptr,
179   - unsigned long long old,
180   - unsigned long long new)
  164 +static inline u64 __cmpxchg64(volatile u64 *ptr, u64 old, u64 new)
181 165 {
182   - unsigned long long prev;
183   - asm volatile(LOCK_PREFIX "cmpxchg8b %3"
184   - : "=A"(prev)
185   - : "b"((unsigned long)new),
186   - "c"((unsigned long)(new >> 32)),
187   - "m"(*__xg(ptr)),
188   - "0"(old)
  166 + u64 prev;
  167 + asm volatile(LOCK_PREFIX "cmpxchg8b %1"
  168 + : "=A" (prev),
  169 + "+m" (*ptr)
  170 + : "b" ((u32)new),
  171 + "c" ((u32)(new >> 32)),
  172 + "0" (old)
189 173 : "memory");
190 174 return prev;
191 175 }
192 176  
193   -static inline unsigned long long __cmpxchg64_local(volatile void *ptr,
194   - unsigned long long old,
195   - unsigned long long new)
  177 +static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
196 178 {
197   - unsigned long long prev;
198   - asm volatile("cmpxchg8b %3"
199   - : "=A"(prev)
200   - : "b"((unsigned long)new),
201   - "c"((unsigned long)(new >> 32)),
202   - "m"(*__xg(ptr)),
203   - "0"(old)
  179 + u64 prev;
  180 + asm volatile("cmpxchg8b %1"
  181 + : "=A" (prev),
  182 + "+m" (*ptr)
  183 + : "b" ((u32)new),
  184 + "c" ((u32)(new >> 32)),
  185 + "0" (old)
204 186 : "memory");
205 187 return prev;
206 188 }
... ... @@ -264,8 +246,6 @@
264 246 * to simulate the cmpxchg8b on the 80386 and 80486 CPU.
265 247 */
266 248  
267   -extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
268   -
269 249 #define cmpxchg64(ptr, o, n) \
270 250 ({ \
271 251 __typeof__(*(ptr)) __ret; \
... ... @@ -283,20 +263,20 @@
283 263 __ret; })
284 264  
285 265  
286   -
287   -#define cmpxchg64_local(ptr, o, n) \
288   -({ \
289   - __typeof__(*(ptr)) __ret; \
290   - if (likely(boot_cpu_data.x86 > 4)) \
291   - __ret = (__typeof__(*(ptr)))__cmpxchg64_local((ptr), \
292   - (unsigned long long)(o), \
293   - (unsigned long long)(n)); \
294   - else \
295   - __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \
296   - (unsigned long long)(o), \
297   - (unsigned long long)(n)); \
298   - __ret; \
299   -})
  266 +#define cmpxchg64_local(ptr, o, n) \
  267 +({ \
  268 + __typeof__(*(ptr)) __ret; \
  269 + __typeof__(*(ptr)) __old = (o); \
  270 + __typeof__(*(ptr)) __new = (n); \
  271 + alternative_io("call cmpxchg8b_emu", \
  272 + "cmpxchg8b (%%esi)" , \
  273 + X86_FEATURE_CX8, \
  274 + "=A" (__ret), \
  275 + "S" ((ptr)), "0" (__old), \
  276 + "b" ((unsigned int)__new), \
  277 + "c" ((unsigned int)(__new>>32)) \
  278 + : "memory"); \
  279 + __ret; })
300 280  
301 281 #endif
302 282  
arch/x86/include/asm/cmpxchg_64.h
... ... @@ -3,51 +3,60 @@
3 3  
4 4 #include <asm/alternative.h> /* Provides LOCK_PREFIX */
5 5  
6   -#define __xg(x) ((volatile long *)(x))
7   -
8   -static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
  6 +static inline void set_64bit(volatile u64 *ptr, u64 val)
9 7 {
10 8 *ptr = val;
11 9 }
12 10  
13   -#define _set_64bit set_64bit
14   -
15 11 extern void __xchg_wrong_size(void);
16 12 extern void __cmpxchg_wrong_size(void);
17 13  
18 14 /*
19   - * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
20   - * Note 2: xchg has side effect, so that attribute volatile is necessary,
21   - * but generally the primitive is invalid, *ptr is output argument. --ANK
  15 + * Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
  16 + * Since this is generally used to protect other memory information, we
  17 + * use "asm volatile" and "memory" clobbers to prevent gcc from moving
  18 + * information around.
22 19 */
23 20 #define __xchg(x, ptr, size) \
24 21 ({ \
25 22 __typeof(*(ptr)) __x = (x); \
26 23 switch (size) { \
27 24 case 1: \
28   - asm volatile("xchgb %b0,%1" \
29   - : "=q" (__x) \
30   - : "m" (*__xg(ptr)), "0" (__x) \
  25 + { \
  26 + volatile u8 *__ptr = (volatile u8 *)(ptr); \
  27 + asm volatile("xchgb %0,%1" \
  28 + : "=q" (__x), "+m" (*__ptr) \
  29 + : "0" (__x) \
31 30 : "memory"); \
32 31 break; \
  32 + } \
33 33 case 2: \
34   - asm volatile("xchgw %w0,%1" \
35   - : "=r" (__x) \
36   - : "m" (*__xg(ptr)), "0" (__x) \
  34 + { \
  35 + volatile u16 *__ptr = (volatile u16 *)(ptr); \
  36 + asm volatile("xchgw %0,%1" \
  37 + : "=r" (__x), "+m" (*__ptr) \
  38 + : "0" (__x) \
37 39 : "memory"); \
38 40 break; \
  41 + } \
39 42 case 4: \
40   - asm volatile("xchgl %k0,%1" \
41   - : "=r" (__x) \
42   - : "m" (*__xg(ptr)), "0" (__x) \
  43 + { \
  44 + volatile u32 *__ptr = (volatile u32 *)(ptr); \
  45 + asm volatile("xchgl %0,%1" \
  46 + : "=r" (__x), "+m" (*__ptr) \
  47 + : "0" (__x) \
43 48 : "memory"); \
44 49 break; \
  50 + } \
45 51 case 8: \
  52 + { \
  53 + volatile u64 *__ptr = (volatile u64 *)(ptr); \
46 54 asm volatile("xchgq %0,%1" \
47   - : "=r" (__x) \
48   - : "m" (*__xg(ptr)), "0" (__x) \
  55 + : "=r" (__x), "+m" (*__ptr) \
  56 + : "0" (__x) \
49 57 : "memory"); \
50 58 break; \
  59 + } \
51 60 default: \
52 61 __xchg_wrong_size(); \
53 62 } \
54 63  
55 64  
56 65  
57 66  
58 67  
59 68  
60 69  
... ... @@ -71,29 +80,41 @@
71 80 __typeof__(*(ptr)) __new = (new); \
72 81 switch (size) { \
73 82 case 1: \
74   - asm volatile(lock "cmpxchgb %b1,%2" \
75   - : "=a"(__ret) \
76   - : "q"(__new), "m"(*__xg(ptr)), "0"(__old) \
  83 + { \
  84 + volatile u8 *__ptr = (volatile u8 *)(ptr); \
  85 + asm volatile(lock "cmpxchgb %2,%1" \
  86 + : "=a" (__ret), "+m" (*__ptr) \
  87 + : "q" (__new), "0" (__old) \
77 88 : "memory"); \
78 89 break; \
  90 + } \
79 91 case 2: \
80   - asm volatile(lock "cmpxchgw %w1,%2" \
81   - : "=a"(__ret) \
82   - : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
  92 + { \
  93 + volatile u16 *__ptr = (volatile u16 *)(ptr); \
  94 + asm volatile(lock "cmpxchgw %2,%1" \
  95 + : "=a" (__ret), "+m" (*__ptr) \
  96 + : "r" (__new), "0" (__old) \
83 97 : "memory"); \
84 98 break; \
  99 + } \
85 100 case 4: \
86   - asm volatile(lock "cmpxchgl %k1,%2" \
87   - : "=a"(__ret) \
88   - : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
  101 + { \
  102 + volatile u32 *__ptr = (volatile u32 *)(ptr); \
  103 + asm volatile(lock "cmpxchgl %2,%1" \
  104 + : "=a" (__ret), "+m" (*__ptr) \
  105 + : "r" (__new), "0" (__old) \
89 106 : "memory"); \
90 107 break; \
  108 + } \
91 109 case 8: \
92   - asm volatile(lock "cmpxchgq %1,%2" \
93   - : "=a"(__ret) \
94   - : "r"(__new), "m"(*__xg(ptr)), "0"(__old) \
  110 + { \
  111 + volatile u64 *__ptr = (volatile u64 *)(ptr); \
  112 + asm volatile(lock "cmpxchgq %2,%1" \
  113 + : "=a" (__ret), "+m" (*__ptr) \
  114 + : "r" (__new), "0" (__old) \
95 115 : "memory"); \
96 116 break; \
  117 + } \
97 118 default: \
98 119 __cmpxchg_wrong_size(); \
99 120 } \
arch/x86/include/asm/msr-index.h
... ... @@ -161,8 +161,6 @@
161 161 #define MSR_K7_FID_VID_STATUS 0xc0010042
162 162  
163 163 /* K6 MSRs */
164   -#define MSR_K6_EFER 0xc0000080
165   -#define MSR_K6_STAR 0xc0000081
166 164 #define MSR_K6_WHCR 0xc0000082
167 165 #define MSR_K6_UWCCR 0xc0000085
168 166 #define MSR_K6_EPMR 0xc0000086
arch/x86/kernel/acpi/realmode/wakeup.S
... ... @@ -104,7 +104,7 @@
104 104 movl %eax, %ecx
105 105 orl %edx, %ecx
106 106 jz 1f
107   - movl $0xc0000080, %ecx
  107 + movl $MSR_EFER, %ecx
108 108 wrmsr
109 109 1:
110 110  
arch/x86/kernel/cpu/Makefile
... ... @@ -16,7 +16,7 @@
16 16 obj-y += proc.o capflags.o powerflags.o common.o
17 17 obj-y += vmware.o hypervisor.o sched.o mshyperv.o
18 18  
19   -obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o
  19 +obj-$(CONFIG_X86_32) += bugs.o
20 20 obj-$(CONFIG_X86_64) += bugs_64.o
21 21  
22 22 obj-$(CONFIG_CPU_SUP_INTEL) += intel.o
arch/x86/kernel/cpu/cmpxchg.c
1   -/*
2   - * cmpxchg*() fallbacks for CPU not supporting these instructions
3   - */
4   -
5   -#include <linux/kernel.h>
6   -#include <linux/smp.h>
7   -#include <linux/module.h>
8   -
9   -#ifndef CONFIG_X86_CMPXCHG
10   -unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
11   -{
12   - u8 prev;
13   - unsigned long flags;
14   -
15   - /* Poor man's cmpxchg for 386. Unsuitable for SMP */
16   - local_irq_save(flags);
17   - prev = *(u8 *)ptr;
18   - if (prev == old)
19   - *(u8 *)ptr = new;
20   - local_irq_restore(flags);
21   - return prev;
22   -}
23   -EXPORT_SYMBOL(cmpxchg_386_u8);
24   -
25   -unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
26   -{
27   - u16 prev;
28   - unsigned long flags;
29   -
30   - /* Poor man's cmpxchg for 386. Unsuitable for SMP */
31   - local_irq_save(flags);
32   - prev = *(u16 *)ptr;
33   - if (prev == old)
34   - *(u16 *)ptr = new;
35   - local_irq_restore(flags);
36   - return prev;
37   -}
38   -EXPORT_SYMBOL(cmpxchg_386_u16);
39   -
40   -unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
41   -{
42   - u32 prev;
43   - unsigned long flags;
44   -
45   - /* Poor man's cmpxchg for 386. Unsuitable for SMP */
46   - local_irq_save(flags);
47   - prev = *(u32 *)ptr;
48   - if (prev == old)
49   - *(u32 *)ptr = new;
50   - local_irq_restore(flags);
51   - return prev;
52   -}
53   -EXPORT_SYMBOL(cmpxchg_386_u32);
54   -#endif
55   -
56   -#ifndef CONFIG_X86_CMPXCHG64
57   -unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new)
58   -{
59   - u64 prev;
60   - unsigned long flags;
61   -
62   - /* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */
63   - local_irq_save(flags);
64   - prev = *(u64 *)ptr;
65   - if (prev == old)
66   - *(u64 *)ptr = new;
67   - local_irq_restore(flags);
68   - return prev;
69   -}
70   -EXPORT_SYMBOL(cmpxchg_486_u64);
71   -#endif
arch/x86/kernel/entry_32.S
... ... @@ -611,14 +611,14 @@
611 611 * compensating for the offset by changing to the ESPFIX segment with
612 612 * a base address that matches for the difference.
613 613 */
  614 +#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
614 615 mov %esp, %edx /* load kernel esp */
615 616 mov PT_OLDESP(%esp), %eax /* load userspace esp */
616 617 mov %dx, %ax /* eax: new kernel esp */
617 618 sub %eax, %edx /* offset (low word is 0) */
618   - PER_CPU(gdt_page, %ebx)
619 619 shr $16, %edx
620   - mov %dl, GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx) /* bits 16..23 */
621   - mov %dh, GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx) /* bits 24..31 */
  620 + mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
  621 + mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
622 622 pushl $__ESPFIX_SS
623 623 CFI_ADJUST_CFA_OFFSET 4
624 624 push %eax /* new kernel esp */
... ... @@ -791,9 +791,8 @@
791 791 * normal stack and adjusts ESP with the matching offset.
792 792 */
793 793 /* fixup the stack */
794   - PER_CPU(gdt_page, %ebx)
795   - mov GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx), %al /* bits 16..23 */
796   - mov GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx), %ah /* bits 24..31 */
  794 + mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
  795 + mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
797 796 shl $16, %eax
798 797 addl %esp, %eax /* the adjusted stack pointer */
799 798 pushl $__KERNEL_DS
arch/x86/kernel/entry_64.S
... ... @@ -1065,6 +1065,7 @@
1065 1065 END(\sym)
1066 1066 .endm
1067 1067  
  1068 +#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
1068 1069 .macro paranoidzeroentry_ist sym do_sym ist
1069 1070 ENTRY(\sym)
1070 1071 INTR_FRAME
1071 1072  
... ... @@ -1076,10 +1077,9 @@
1076 1077 TRACE_IRQS_OFF
1077 1078 movq %rsp,%rdi /* pt_regs pointer */
1078 1079 xorl %esi,%esi /* no error code */
1079   - PER_CPU(init_tss, %r12)
1080   - subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
  1080 + subq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
1081 1081 call \do_sym
1082   - addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
  1082 + addq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
1083 1083 jmp paranoid_exit /* %ebx: no swapgs flag */
1084 1084 CFI_ENDPROC
1085 1085 END(\sym)
arch/x86/kernel/head_64.S
... ... @@ -234,9 +234,8 @@
234 234 * init data section till per cpu areas are set up.
235 235 */
236 236 movl $MSR_GS_BASE,%ecx
237   - movq initial_gs(%rip),%rax
238   - movq %rax,%rdx
239   - shrq $32,%rdx
  237 + movl initial_gs(%rip),%eax
  238 + movl initial_gs+4(%rip),%edx
240 239 wrmsr
241 240  
242 241 /* esi is pointer to real mode structure with interesting info.
arch/x86/kernel/verify_cpu_64.S
... ... @@ -31,6 +31,7 @@
31 31 */
32 32  
33 33 #include <asm/cpufeature.h>
  34 +#include <asm/msr-index.h>
34 35  
35 36 verify_cpu:
36 37 pushfl # Save caller passed flags
... ... @@ -88,7 +89,7 @@
88 89 je verify_cpu_sse_ok
89 90 test %di,%di
90 91 jz verify_cpu_no_longmode # only try to force SSE on AMD
91   - movl $0xc0010015,%ecx # HWCR
  92 + movl $MSR_K7_HWCR,%ecx
92 93 rdmsr
93 94 btr $15,%eax # enable SSE
94 95 wrmsr
... ... @@ -131,7 +131,7 @@
131 131 u32 index; /* Index of the MSR */
132 132 bool always; /* True if intercept is always on */
133 133 } direct_access_msrs[] = {
134   - { .index = MSR_K6_STAR, .always = true },
  134 + { .index = MSR_STAR, .always = true },
135 135 { .index = MSR_IA32_SYSENTER_CS, .always = true },
136 136 #ifdef CONFIG_X86_64
137 137 { .index = MSR_GS_BASE, .always = true },
... ... @@ -2432,7 +2432,7 @@
2432 2432 *data = tsc_offset + native_read_tsc();
2433 2433 break;
2434 2434 }
2435   - case MSR_K6_STAR:
  2435 + case MSR_STAR:
2436 2436 *data = svm->vmcb->save.star;
2437 2437 break;
2438 2438 #ifdef CONFIG_X86_64
... ... @@ -2556,7 +2556,7 @@
2556 2556  
2557 2557 break;
2558 2558 }
2559   - case MSR_K6_STAR:
  2559 + case MSR_STAR:
2560 2560 svm->vmcb->save.star = data;
2561 2561 break;
2562 2562 #ifdef CONFIG_X86_64
... ... @@ -240,14 +240,14 @@
240 240 static void ept_save_pdptrs(struct kvm_vcpu *vcpu);
241 241  
242 242 /*
243   - * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it
  243 + * Keep MSR_STAR at the end, as setup_msrs() will try to optimize it
244 244 * away by decrementing the array size.
245 245 */
246 246 static const u32 vmx_msr_index[] = {
247 247 #ifdef CONFIG_X86_64
248 248 MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR,
249 249 #endif
250   - MSR_EFER, MSR_TSC_AUX, MSR_K6_STAR,
  250 + MSR_EFER, MSR_TSC_AUX, MSR_STAR,
251 251 };
252 252 #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
253 253  
254 254  
... ... @@ -1117,10 +1117,10 @@
1117 1117 if (index >= 0 && vmx->rdtscp_enabled)
1118 1118 move_msr_up(vmx, index, save_nmsrs++);
1119 1119 /*
1120   - * MSR_K6_STAR is only needed on long mode guests, and only
  1120 + * MSR_STAR is only needed on long mode guests, and only
1121 1121 * if efer.sce is enabled.
1122 1122 */
1123   - index = __find_msr_index(vmx, MSR_K6_STAR);
  1123 + index = __find_msr_index(vmx, MSR_STAR);
1124 1124 if ((index >= 0) && (vmx->vcpu.arch.efer & EFER_SCE))
1125 1125 move_msr_up(vmx, index, save_nmsrs++);
1126 1126 }
... ... @@ -733,7 +733,7 @@
733 733 HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
734 734 HV_X64_MSR_APIC_ASSIST_PAGE,
735 735 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
736   - MSR_K6_STAR,
  736 + MSR_STAR,
737 737 #ifdef CONFIG_X86_64
738 738 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
739 739 #endif
arch/x86/lib/Makefile
... ... @@ -30,6 +30,7 @@
30 30 lib-y += checksum_32.o
31 31 lib-y += strstr_32.o
32 32 lib-y += semaphore_32.o string_32.o
  33 + lib-y += cmpxchg.o
33 34 ifneq ($(CONFIG_X86_CMPXCHG64),y)
34 35 lib-y += cmpxchg8b_emu.o atomic64_386_32.o
35 36 endif
arch/x86/lib/cmpxchg.c
  1 +/*
  2 + * cmpxchg*() fallbacks for CPU not supporting these instructions
  3 + */
  4 +
  5 +#include <linux/kernel.h>
  6 +#include <linux/smp.h>
  7 +#include <linux/module.h>
  8 +
  9 +#ifndef CONFIG_X86_CMPXCHG
  10 +unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
  11 +{
  12 + u8 prev;
  13 + unsigned long flags;
  14 +
  15 + /* Poor man's cmpxchg for 386. Unsuitable for SMP */
  16 + local_irq_save(flags);
  17 + prev = *(u8 *)ptr;
  18 + if (prev == old)
  19 + *(u8 *)ptr = new;
  20 + local_irq_restore(flags);
  21 + return prev;
  22 +}
  23 +EXPORT_SYMBOL(cmpxchg_386_u8);
  24 +
  25 +unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
  26 +{
  27 + u16 prev;
  28 + unsigned long flags;
  29 +
  30 + /* Poor man's cmpxchg for 386. Unsuitable for SMP */
  31 + local_irq_save(flags);
  32 + prev = *(u16 *)ptr;
  33 + if (prev == old)
  34 + *(u16 *)ptr = new;
  35 + local_irq_restore(flags);
  36 + return prev;
  37 +}
  38 +EXPORT_SYMBOL(cmpxchg_386_u16);
  39 +
  40 +unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
  41 +{
  42 + u32 prev;
  43 + unsigned long flags;
  44 +
  45 + /* Poor man's cmpxchg for 386. Unsuitable for SMP */
  46 + local_irq_save(flags);
  47 + prev = *(u32 *)ptr;
  48 + if (prev == old)
  49 + *(u32 *)ptr = new;
  50 + local_irq_restore(flags);
  51 + return prev;
  52 +}
  53 +EXPORT_SYMBOL(cmpxchg_386_u32);
  54 +#endif