summaryrefslogtreecommitdiff
path: root/arch/x86/hyperv
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2026-08-04 07:15:41 +0000
committerPeter Zijlstra <peterz@infradead.org>2026-08-07 17:58:09 +0200
commitfc6ad5eadcd1694d2f1ee2717c8024efd8152e20 (patch)
tree7ff7e6782eb3be4ef9488799c8fef40854b29b87 /arch/x86/hyperv
parent1c7efabfbaf796f11000a46094a69955a01ec6cc (diff)
downloadlinux-fc6ad5eadcd1694d2f1ee2717c8024efd8152e20.tar.gz
linux-fc6ad5eadcd1694d2f1ee2717c8024efd8152e20.zip
x86/paravirt: Use static_call() for the paravirt spinlock ops
queued_spin_lock_slowpath() and queued_spin_unlock() are dispatched through pv_ops_lock via the paravirt-ops ALTERNATIVE machinery, which picks the target (native inline store / hypervisor call) once at boot and cannot change at runtime. Convert both to static_call(). The site becomes a direct call patched in place (one byte smaller), and on native the unlock still collapses to the inline "movb $0, (%rdi)" store, so the fast path is unchanged. Unlike the ALTERNATIVE mechanism, a static_call() target can also be updated at runtime via static_call_update(). This is a prerequisite for the contended_release tracepoint, which has to swap in a traced unlock while the system is running. [ ilvokhin: commit message; fix PARAVIRT_SPINLOCKS=n build; teach __static_call_validate() about the inline unlock insn; make the slowpath site module-safe: static_call_mod() + EXPORT_STATIC_CALL_TRAMP(); pass @lock to the callee-save unlock, fixing a boot hang under CALL_DEPTH_TRACKING. Boot tested native + KVM PV guest. ] Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Co-developed-by: Dmitry Ilvokhin <d@ilvokhin.com> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Juergen Gross <jgross@suse.com> Link: https://lore.kernel.org/all/20260603120811.GW3493090@noisy.programming.kicks-ass.net/ Link: https://patch.msgid.link/9a32ae399eb804a02a31af04dcabe7e7ee4f3fdf.1785778551.git.d@ilvokhin.com
Diffstat (limited to 'arch/x86/hyperv')
-rw-r--r--arch/x86/hyperv/hv_spinlock.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/x86/hyperv/hv_spinlock.c b/arch/x86/hyperv/hv_spinlock.c
index 210b494e4de0..6b4bdea18218 100644
--- a/arch/x86/hyperv/hv_spinlock.c
+++ b/arch/x86/hyperv/hv_spinlock.c
@@ -78,8 +78,8 @@ void __init hv_init_spinlocks(void)
pr_info("PV spinlocks enabled\n");
__pv_init_lock_hash();
- pv_ops_lock.queued_spin_lock_slowpath = __pv_queued_spin_lock_slowpath;
- pv_ops_lock.queued_spin_unlock = PV_CALLEE_SAVE(__pv_queued_spin_unlock);
+ static_call_update(queued_spin_lock_slowpath, __pv_queued_spin_lock_slowpath);
+ static_call_update(queued_spin_unlock, __raw_callee_save___pv_queued_spin_unlock);
pv_ops_lock.wait = hv_qlock_wait;
pv_ops_lock.kick = hv_qlock_kick;
pv_ops_lock.vcpu_is_preempted = PV_CALLEE_SAVE(hv_vcpu_is_preempted);