Make the paravirt callee-save infrastructure more generic by allowing
arbitrary register interfaces via prologue and epilogue helper macros.

Signed-off-by: Juergen Gross <[email protected]>
---
V3:
- carved out from patch 5 of V1
---
 arch/x86/include/asm/paravirt_types.h     | 43 ++++++++++++++---------
 arch/x86/include/asm/qspinlock_paravirt.h |  4 +--
 2 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/paravirt_types.h 
b/arch/x86/include/asm/paravirt_types.h
index 1e7188247c1f..999a5abe54ed 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -457,27 +457,38 @@ extern struct paravirt_patch_template pv_ops;
 #define PV_SAVE_ALL_CALLER_REGS                "pushl %ecx;"
 #define PV_RESTORE_ALL_CALLER_REGS     "popl  %ecx;"
 #else
+/* Save and restore caller-save registers, except %rax, %rcx and %rdx. */
+#define PV_SAVE_COMMON_CALLER_REGS     \
+       "push %rsi;"                    \
+       "push %rdi;"                    \
+       "push %r8;"                     \
+       "push %r9;"                     \
+       "push %r10;"                    \
+       "push %r11;"
+
+#define PV_RESTORE_COMMON_CALLER_REGS  \
+       "pop %r11;"                     \
+       "pop %r10;"                     \
+       "pop %r9;"                      \
+       "pop %r8;"                      \
+       "pop %rdi;"                     \
+       "pop %rsi;"
+
 /* save and restore all caller-save registers, except return value */
 #define PV_SAVE_ALL_CALLER_REGS                                                
\
        "push %rcx;"                                                    \
        "push %rdx;"                                                    \
-       "push %rsi;"                                                    \
-       "push %rdi;"                                                    \
-       "push %r8;"                                                     \
-       "push %r9;"                                                     \
-       "push %r10;"                                                    \
-       "push %r11;"
+       PV_SAVE_COMMON_CALLER_REGS
+
 #define PV_RESTORE_ALL_CALLER_REGS                                     \
-       "pop %r11;"                                                     \
-       "pop %r10;"                                                     \
-       "pop %r9;"                                                      \
-       "pop %r8;"                                                      \
-       "pop %rdi;"                                                     \
-       "pop %rsi;"                                                     \
+       PV_RESTORE_COMMON_CALLER_REGS                                   \
        "pop %rdx;"                                                     \
        "pop %rcx;"
 #endif
 
+#define PV_PROLOGUE_ALL(func)  PV_SAVE_ALL_CALLER_REGS
+#define PV_EPILOGUE_ALL(func)  PV_RESTORE_ALL_CALLER_REGS
+
 /*
  * Generate a thunk around a function which saves all caller-save
  * registers except for the return value.  This allows C functions to
@@ -491,7 +502,7 @@ extern struct paravirt_patch_template pv_ops;
  * functions.
  */
 #define PV_THUNK_NAME(func) "__raw_callee_save_" #func
-#define __PV_CALLEE_SAVE_REGS_THUNK(func, section)                     \
+#define __PV_CALLEE_SAVE_REGS_THUNK(func, section, helper)             \
        extern typeof(func) __raw_callee_save_##func;                   \
                                                                        \
        asm(".pushsection " section ", \"ax\";"                         \
@@ -501,16 +512,16 @@ extern struct paravirt_patch_template pv_ops;
            PV_THUNK_NAME(func) ":"                                     \
            ASM_ENDBR                                                   \
            FRAME_BEGIN                                                 \
-           PV_SAVE_ALL_CALLER_REGS                                     \
+           PV_PROLOGUE_##helper(func)                                  \
            "call " #func ";"                                           \
-           PV_RESTORE_ALL_CALLER_REGS                                  \
+           PV_EPILOGUE_##helper(func)                                  \
            FRAME_END                                                   \
            ASM_RET                                                     \
            ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";" \
            ".popsection")
 
 #define PV_CALLEE_SAVE_REGS_THUNK(func)                        \
-       __PV_CALLEE_SAVE_REGS_THUNK(func, ".text")
+       __PV_CALLEE_SAVE_REGS_THUNK(func, ".text", ALL)
 
 /* Get a reference to a callee-save function */
 #define PV_CALLEE_SAVE(func)                                           \
diff --git a/arch/x86/include/asm/qspinlock_paravirt.h 
b/arch/x86/include/asm/qspinlock_paravirt.h
index 0a985784be9b..002b17f0735e 100644
--- a/arch/x86/include/asm/qspinlock_paravirt.h
+++ b/arch/x86/include/asm/qspinlock_paravirt.h
@@ -14,7 +14,7 @@ void __lockfunc __pv_queued_spin_unlock_slowpath(struct 
qspinlock *lock, u8 lock
  */
 #ifdef CONFIG_64BIT
 
-__PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath, 
".spinlock.text");
+__PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath, 
".spinlock.text", ALL);
 #define __pv_queued_spin_unlock        __pv_queued_spin_unlock
 
 /*
@@ -61,7 +61,7 @@ DEFINE_ASM_FUNC(__raw_callee_save___pv_queued_spin_unlock,
 #else /* CONFIG_64BIT */
 
 extern void __lockfunc __pv_queued_spin_unlock(struct qspinlock *lock);
-__PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock, ".spinlock.text");
+__PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock, ".spinlock.text", ALL);
 
 #endif /* CONFIG_64BIT */
 #endif
-- 
2.53.0


Reply via email to