diff options
-rw-r--r-- | include/asm-x86_64/pda.h | 85 |
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 | */ |
42 | extern void __bad_pda_field(void); | 42 | extern 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 | */ | ||
46 | extern struct x8664_pda _proxy_pda; | 48 | extern 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)) { \ |
54 | case 2: \ | 56 | case 2: \ |
55 | asm(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) : \ |
57 | case 4: \ | 59 | "ri" ((T__)val), \ |
58 | asm(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; \ |
60 | case 8: \ | 62 | case 4: \ |
61 | asm(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) : \ |
63 | default: __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)) { \ |
70 | case 2: \ | 82 | case 2: \ |
71 | asm(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__) : \ |
73 | case 4: \ | 85 | "i" (pda_offset(field)), \ |
74 | asm(op "l %%gs:%c1,%0":"=r" (ret__):\ | 86 | "m" (_proxy_pda.field)); \ |
75 | "i" (pda_offset(field)), "m" (_proxy_pda.field)); break;\ | 87 | break; \ |
76 | case 8: \ | 88 | case 4: \ |
77 | asm(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__): \ |
79 | default: __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) |