1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _ASM_LOONGARCH_PARAVIRT_H 3#define _ASM_LOONGARCH_PARAVIRT_H 4#include <asm/kvm_para.h> 5 6#ifdef CONFIG_PARAVIRT 7static inline bool kvm_para_available(void) 8{ 9 return true; 10} 11struct static_key; 12extern struct static_key paravirt_steal_enabled; 13extern struct static_key paravirt_steal_rq_enabled; 14 15struct pv_time_ops { 16 unsigned long long (*steal_clock)(int cpu); 17}; 18struct kvm_steal_time { 19 __u64 steal; 20 __u32 version; 21 __u32 flags; 22 __u8 preempted; 23 __u8 pad[47]; 24}; 25extern struct pv_time_ops pv_time_ops; 26 27bool pv_is_native_spin_unlock(void); 28 29static inline u64 paravirt_steal_clock(int cpu) 30{ 31 return pv_time_ops.steal_clock(cpu); 32} 33 34static inline bool pv_feature_support(int feature) 35{ 36 return kvm_hypercall1(KVM_HC_FUNC_FEATURE, feature) == KVM_RET_SUC; 37} 38static inline void pv_notify_host(int feature, unsigned long data) 39{ 40 kvm_hypercall2(KVM_HC_FUNC_NOTIFY, feature, data); 41} 42 43#if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) 44struct qspinlock; 45 46struct pv_lock_ops { 47 void (*queued_spin_lock_slowpath)(struct qspinlock *lock, u32 val); 48 void (*queued_spin_unlock)(struct qspinlock *lock); 49 void (*wait)(u8 *ptr, u8 val); 50 void (*kick)(int cpu); 51 bool (*vcpu_is_preempted)(long cpu); 52}; 53 54extern struct pv_lock_ops pv_lock_ops; 55 56void __init kvm_spinlock_init(void); 57 58static __always_inline void pv_queued_spin_lock_slowpath(struct qspinlock *lock, 59 u32 val) 60{ 61 pv_lock_ops.queued_spin_lock_slowpath(lock, val); 62} 63 64static __always_inline void pv_queued_spin_unlock(struct qspinlock *lock) 65{ 66 pv_lock_ops.queued_spin_unlock(lock); 67} 68 69static __always_inline void pv_wait(u8 *ptr, u8 val) 70{ 71 pv_lock_ops.wait(ptr, val); 72} 73 74static __always_inline void pv_kick(int cpu) 75{ 76 pv_lock_ops.kick(cpu); 77} 78 79static __always_inline bool pv_vcpu_is_preempted(long cpu) 80{ 81 return pv_lock_ops.vcpu_is_preempted(cpu); 82} 83 84#endif /* SMP && PARAVIRT_SPINLOCKS */ 85 86int __init pv_time_init(void); 87int __init pv_ipi_init(void); 88#else 89static inline bool kvm_para_available(void) 90{ 91 return false; 92} 93 94#define pv_time_init() do {} while (0) 95#define pv_ipi_init() do {} while (0) 96#endif 97#endif /* _ASM_LOONGARCH_PARAVIRT_H */ 98