18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_LOONGARCH_PARAVIRT_H 38c2ecf20Sopenharmony_ci#define _ASM_LOONGARCH_PARAVIRT_H 48c2ecf20Sopenharmony_ci#include <asm/kvm_para.h> 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifdef CONFIG_PARAVIRT 78c2ecf20Sopenharmony_cistatic inline bool kvm_para_available(void) 88c2ecf20Sopenharmony_ci{ 98c2ecf20Sopenharmony_ci return true; 108c2ecf20Sopenharmony_ci} 118c2ecf20Sopenharmony_cistruct static_key; 128c2ecf20Sopenharmony_ciextern struct static_key paravirt_steal_enabled; 138c2ecf20Sopenharmony_ciextern struct static_key paravirt_steal_rq_enabled; 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistruct pv_time_ops { 168c2ecf20Sopenharmony_ci unsigned long long (*steal_clock)(int cpu); 178c2ecf20Sopenharmony_ci}; 188c2ecf20Sopenharmony_cistruct kvm_steal_time { 198c2ecf20Sopenharmony_ci __u64 steal; 208c2ecf20Sopenharmony_ci __u32 version; 218c2ecf20Sopenharmony_ci __u32 flags; 228c2ecf20Sopenharmony_ci __u8 preempted; 238c2ecf20Sopenharmony_ci __u8 pad[47]; 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ciextern struct pv_time_ops pv_time_ops; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cibool pv_is_native_spin_unlock(void); 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic inline u64 paravirt_steal_clock(int cpu) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci return pv_time_ops.steal_clock(cpu); 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic inline bool pv_feature_support(int feature) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci return kvm_hypercall1(KVM_HC_FUNC_FEATURE, feature) == KVM_RET_SUC; 378c2ecf20Sopenharmony_ci} 388c2ecf20Sopenharmony_cistatic inline void pv_notify_host(int feature, unsigned long data) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci kvm_hypercall2(KVM_HC_FUNC_NOTIFY, feature, data); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) 448c2ecf20Sopenharmony_cistruct qspinlock; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistruct pv_lock_ops { 478c2ecf20Sopenharmony_ci void (*queued_spin_lock_slowpath)(struct qspinlock *lock, u32 val); 488c2ecf20Sopenharmony_ci void (*queued_spin_unlock)(struct qspinlock *lock); 498c2ecf20Sopenharmony_ci void (*wait)(u8 *ptr, u8 val); 508c2ecf20Sopenharmony_ci void (*kick)(int cpu); 518c2ecf20Sopenharmony_ci bool (*vcpu_is_preempted)(long cpu); 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ciextern struct pv_lock_ops pv_lock_ops; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_civoid __init kvm_spinlock_init(void); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic __always_inline void pv_queued_spin_lock_slowpath(struct qspinlock *lock, 598c2ecf20Sopenharmony_ci u32 val) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci pv_lock_ops.queued_spin_lock_slowpath(lock, val); 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic __always_inline void pv_queued_spin_unlock(struct qspinlock *lock) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci pv_lock_ops.queued_spin_unlock(lock); 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic __always_inline void pv_wait(u8 *ptr, u8 val) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci pv_lock_ops.wait(ptr, val); 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic __always_inline void pv_kick(int cpu) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci pv_lock_ops.kick(cpu); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic __always_inline bool pv_vcpu_is_preempted(long cpu) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci return pv_lock_ops.vcpu_is_preempted(cpu); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#endif /* SMP && PARAVIRT_SPINLOCKS */ 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciint __init pv_time_init(void); 878c2ecf20Sopenharmony_ciint __init pv_ipi_init(void); 888c2ecf20Sopenharmony_ci#else 898c2ecf20Sopenharmony_cistatic inline bool kvm_para_available(void) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci return false; 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci#define pv_time_init() do {} while (0) 958c2ecf20Sopenharmony_ci#define pv_ipi_init() do {} while (0) 968c2ecf20Sopenharmony_ci#endif 978c2ecf20Sopenharmony_ci#endif /* _ASM_LOONGARCH_PARAVIRT_H */ 98