diff options
Diffstat (limited to 'include/asm-x86/paravirt.h')
-rw-r--r-- | include/asm-x86/paravirt.h | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 854c19364da3..0735a90f531b 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h | |||
@@ -1085,52 +1085,68 @@ struct paravirt_patch_site { | |||
1085 | extern struct paravirt_patch_site __parainstructions[], | 1085 | extern struct paravirt_patch_site __parainstructions[], |
1086 | __parainstructions_end[]; | 1086 | __parainstructions_end[]; |
1087 | 1087 | ||
1088 | #ifdef CONFIG_X86_32 | ||
1089 | #define PV_SAVE_REGS "pushl %%ecx; pushl %%edx;" | ||
1090 | #define PV_RESTORE_REGS "popl %%edx; popl %%ecx" | ||
1091 | #define PV_FLAGS_ARG "0" | ||
1092 | #define PV_EXTRA_CLOBBERS | ||
1093 | #define PV_VEXTRA_CLOBBERS | ||
1094 | #else | ||
1095 | /* We save some registers, but all of them, that's too much. We clobber all | ||
1096 | * caller saved registers but the argument parameter */ | ||
1097 | #define PV_SAVE_REGS "pushq %%rdi;" | ||
1098 | #define PV_RESTORE_REGS "popq %%rdi;" | ||
1099 | #define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx" | ||
1100 | #define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx" | ||
1101 | #define PV_FLAGS_ARG "D" | ||
1102 | #endif | ||
1103 | |||
1088 | static inline unsigned long __raw_local_save_flags(void) | 1104 | static inline unsigned long __raw_local_save_flags(void) |
1089 | { | 1105 | { |
1090 | unsigned long f; | 1106 | unsigned long f; |
1091 | 1107 | ||
1092 | asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" | 1108 | asm volatile(paravirt_alt(PV_SAVE_REGS |
1093 | PARAVIRT_CALL | 1109 | PARAVIRT_CALL |
1094 | "popl %%edx; popl %%ecx") | 1110 | PV_RESTORE_REGS) |
1095 | : "=a"(f) | 1111 | : "=a"(f) |
1096 | : paravirt_type(pv_irq_ops.save_fl), | 1112 | : paravirt_type(pv_irq_ops.save_fl), |
1097 | paravirt_clobber(CLBR_EAX) | 1113 | paravirt_clobber(CLBR_EAX) |
1098 | : "memory", "cc"); | 1114 | : "memory", "cc" PV_VEXTRA_CLOBBERS); |
1099 | return f; | 1115 | return f; |
1100 | } | 1116 | } |
1101 | 1117 | ||
1102 | static inline void raw_local_irq_restore(unsigned long f) | 1118 | static inline void raw_local_irq_restore(unsigned long f) |
1103 | { | 1119 | { |
1104 | asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" | 1120 | asm volatile(paravirt_alt(PV_SAVE_REGS |
1105 | PARAVIRT_CALL | 1121 | PARAVIRT_CALL |
1106 | "popl %%edx; popl %%ecx") | 1122 | PV_RESTORE_REGS) |
1107 | : "=a"(f) | 1123 | : "=a"(f) |
1108 | : "0"(f), | 1124 | : PV_FLAGS_ARG(f), |
1109 | paravirt_type(pv_irq_ops.restore_fl), | 1125 | paravirt_type(pv_irq_ops.restore_fl), |
1110 | paravirt_clobber(CLBR_EAX) | 1126 | paravirt_clobber(CLBR_EAX) |
1111 | : "memory", "cc"); | 1127 | : "memory", "cc" PV_EXTRA_CLOBBERS); |
1112 | } | 1128 | } |
1113 | 1129 | ||
1114 | static inline void raw_local_irq_disable(void) | 1130 | static inline void raw_local_irq_disable(void) |
1115 | { | 1131 | { |
1116 | asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" | 1132 | asm volatile(paravirt_alt(PV_SAVE_REGS |
1117 | PARAVIRT_CALL | 1133 | PARAVIRT_CALL |
1118 | "popl %%edx; popl %%ecx") | 1134 | PV_RESTORE_REGS) |
1119 | : | 1135 | : |
1120 | : paravirt_type(pv_irq_ops.irq_disable), | 1136 | : paravirt_type(pv_irq_ops.irq_disable), |
1121 | paravirt_clobber(CLBR_EAX) | 1137 | paravirt_clobber(CLBR_EAX) |
1122 | : "memory", "eax", "cc"); | 1138 | : "memory", "eax", "cc" PV_EXTRA_CLOBBERS); |
1123 | } | 1139 | } |
1124 | 1140 | ||
1125 | static inline void raw_local_irq_enable(void) | 1141 | static inline void raw_local_irq_enable(void) |
1126 | { | 1142 | { |
1127 | asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" | 1143 | asm volatile(paravirt_alt(PV_SAVE_REGS |
1128 | PARAVIRT_CALL | 1144 | PARAVIRT_CALL |
1129 | "popl %%edx; popl %%ecx") | 1145 | PV_RESTORE_REGS) |
1130 | : | 1146 | : |
1131 | : paravirt_type(pv_irq_ops.irq_enable), | 1147 | : paravirt_type(pv_irq_ops.irq_enable), |
1132 | paravirt_clobber(CLBR_EAX) | 1148 | paravirt_clobber(CLBR_EAX) |
1133 | : "memory", "eax", "cc"); | 1149 | : "memory", "eax", "cc" PV_EXTRA_CLOBBERS); |
1134 | } | 1150 | } |
1135 | 1151 | ||
1136 | static inline unsigned long __raw_local_irq_save(void) | 1152 | static inline unsigned long __raw_local_irq_save(void) |
@@ -1205,6 +1221,7 @@ static inline unsigned long __raw_local_irq_save(void) | |||
1205 | CLBR_NONE, \ | 1221 | CLBR_NONE, \ |
1206 | jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret) | 1222 | jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret) |
1207 | 1223 | ||
1224 | |||
1208 | #ifdef CONFIG_X86_32 | 1225 | #ifdef CONFIG_X86_32 |
1209 | #define GET_CR0_INTO_EAX \ | 1226 | #define GET_CR0_INTO_EAX \ |
1210 | push %ecx; push %edx; \ | 1227 | push %ecx; push %edx; \ |