1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 #ifndef _ASM_POWERPC_PARAVIRT_H 3 #define _ASM_POWERPC_PARAVIRT_H 4 5 #include <linux/jump_label.h> 6 #include <asm/smp.h> 7 #ifdef CONFIG_PPC64 8 #include <asm/paca.h> 9 #include <asm/hvcall.h> 10 #endif 11 12 #ifdef CONFIG_PPC_SPLPAR 13 DECLARE_STATIC_KEY_FALSE(shared_processor); 14 15 static inline bool is_shared_processor(void) 16 { 17 return static_branch_unlikely(&shared_processor); 18 } 19 20 /* If bit 0 is set, the cpu has been preempted */ 21 static inline u32 yield_count_of(int cpu) 22 { 23 __be32 yield_count = READ_ONCE(lppaca_of(cpu).yield_count); 24 return be32_to_cpu(yield_count); 25 } 26 27 static inline void yield_to_preempted(int cpu, u32 yield_count) 28 { 29 plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(cpu), yield_count); 30 } 31 32 static inline void prod_cpu(int cpu) 33 { 34 plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu)); 35 } 36 37 static inline void yield_to_any(void) 38 { 39 plpar_hcall_norets(H_CONFER, -1, 0); 40 } 41 #else 42 static inline bool is_shared_processor(void) 43 { 44 return false; 45 } 46 47 static inline u32 yield_count_of(int cpu) 48 { 49 return 0; 50 } 51 52 extern void ___bad_yield_to_preempted(void); 53 static inline void yield_to_preempted(int cpu, u32 yield_count) 54 { 55 ___bad_yield_to_preempted(); /* This would be a bug */ 56 } 57 58 extern void ___bad_yield_to_any(void); 59 static inline void yield_to_any(void) 60 { 61 ___bad_yield_to_any(); /* This would be a bug */ 62 } 63 64 extern void ___bad_prod_cpu(void); 65 static inline void prod_cpu(int cpu) 66 { 67 ___bad_prod_cpu(); /* This would be a bug */ 68 } 69 70 #endif 71 72 #define vcpu_is_preempted vcpu_is_preempted 73 static inline bool vcpu_is_preempted(int cpu) 74 { 75 if (!is_shared_processor()) 76 return false; 77 if (yield_count_of(cpu) & 1) 78 return true; 79 return false; 80 } 81 82 static inline bool pv_is_native_spin_unlock(void) 83 { 84 return !is_shared_processor(); 85 } 86 87 #endif /* _ASM_POWERPC_PARAVIRT_H */ 88