aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asm-x86_64/pda.h85
1 files changed, 53 insertions, 32 deletions
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
index 5dadb201f769..9e3aaf74475d 100644
--- a/include/asm-x86_64/pda.h
+++ b/include/asm-x86_64/pda.h
@@ -41,46 +41,67 @@ extern struct x8664_pda boot_cpu_pda[];
41 */ 41 */
42extern void __bad_pda_field(void); 42extern void __bad_pda_field(void);
43 43
44/* proxy_pda doesn't actually exist, but tell gcc it is accessed 44/*
45 for all PDA accesses so it gets read/write dependencies right. */ 45 * proxy_pda doesn't actually exist, but tell gcc it is accessed for
46 * all PDA accesses so it gets read/write dependencies right.
47 */
46extern struct x8664_pda _proxy_pda; 48extern struct x8664_pda _proxy_pda;
47 49
48#define pda_offset(field) offsetof(struct x8664_pda, field) 50#define pda_offset(field) offsetof(struct x8664_pda, field)
49 51
50#define pda_to_op(op,field,val) do { \ 52#define pda_to_op(op,field,val) do { \
51 typedef typeof(_proxy_pda.field) T__; \ 53 typedef typeof(_proxy_pda.field) T__; \
52 if (0) { T__ tmp__; tmp__ = (val); } \ 54 if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \
53 switch (sizeof(_proxy_pda.field)) { \ 55 switch (sizeof(_proxy_pda.field)) { \
54case 2: \ 56 case 2: \
55asm(op "w %1,%%gs:%c2" : "+m" (_proxy_pda.field) : \ 57 asm(op "w %1,%%gs:%c2" : \
56 "ri" ((T__)val),"i"(pda_offset(field))); break; \ 58 "+m" (_proxy_pda.field) : \
57case 4: \ 59 "ri" ((T__)val), \
58asm(op "l %1,%%gs:%c2" : "+m" (_proxy_pda.field) : \ 60 "i"(pda_offset(field))); \
59 "ri" ((T__)val),"i"(pda_offset(field))); break; \ 61 break; \
60case 8: \ 62 case 4: \
61asm(op "q %1,%%gs:%c2": "+m" (_proxy_pda.field) : \ 63 asm(op "l %1,%%gs:%c2" : \
62 "ri" ((T__)val),"i"(pda_offset(field))); break; \ 64 "+m" (_proxy_pda.field) : \
63default: __bad_pda_field(); \ 65 "ri" ((T__)val), \
64 } \ 66 "i" (pda_offset(field))); \
67 break; \
68 case 8: \
69 asm(op "q %1,%%gs:%c2": \
70 "+m" (_proxy_pda.field) : \
71 "ri" ((T__)val), \
72 "i"(pda_offset(field))); \
73 break; \
74 default: \
75 __bad_pda_field(); \
76 } \
65 } while (0) 77 } while (0)
66 78
67#define pda_from_op(op,field) ({ \ 79#define pda_from_op(op,field) ({ \
68 typeof(_proxy_pda.field) ret__; \ 80 typeof(_proxy_pda.field) ret__; \
69 switch (sizeof(_proxy_pda.field)) { \ 81 switch (sizeof(_proxy_pda.field)) { \
70case 2: \ 82 case 2: \
71asm(op "w %%gs:%c1,%0":"=r" (ret__):\ 83 asm(op "w %%gs:%c1,%0" : \
72 "i" (pda_offset(field)), "m" (_proxy_pda.field)); break;\ 84 "=r" (ret__) : \
73case 4: \ 85 "i" (pda_offset(field)), \
74asm(op "l %%gs:%c1,%0":"=r" (ret__):\ 86 "m" (_proxy_pda.field)); \
75 "i" (pda_offset(field)), "m" (_proxy_pda.field)); break;\ 87 break; \
76case 8: \ 88 case 4: \
77asm(op "q %%gs:%c1,%0":"=r" (ret__):\ 89 asm(op "l %%gs:%c1,%0": \
78 "i" (pda_offset(field)), "m" (_proxy_pda.field)); break;\ 90 "=r" (ret__): \
79default: __bad_pda_field(); \ 91 "i" (pda_offset(field)), \
80 } \ 92 "m" (_proxy_pda.field)); \
93 break; \
94 case 8: \
95 asm(op "q %%gs:%c1,%0": \
96 "=r" (ret__) : \
97 "i" (pda_offset(field)), \
98 "m" (_proxy_pda.field)); \
99 break; \
100 default: \
101 __bad_pda_field(); \
102 } \
81 ret__; }) 103 ret__; })
82 104
83
84#define read_pda(field) pda_from_op("mov",field) 105#define read_pda(field) pda_from_op("mov",field)
85#define write_pda(field,val) pda_to_op("mov",field,val) 106#define write_pda(field,val) pda_to_op("mov",field,val)
86#define add_pda(field,val) pda_to_op("add",field,val) 107#define add_pda(field,val) pda_to_op("add",field,val)