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

