aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/paravirt.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-x86/paravirt.h')
-rw-r--r--include/asm-x86/paravirt.h43
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 {
1085extern struct paravirt_patch_site __parainstructions[], 1085extern 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
1088static inline unsigned long __raw_local_save_flags(void) 1104static 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
1102static inline void raw_local_irq_restore(unsigned long f) 1118static 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
1114static inline void raw_local_irq_disable(void) 1130static 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
1125static inline void raw_local_irq_enable(void) 1141static 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
1136static inline unsigned long __raw_local_irq_save(void) 1152static 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; \