0001
0002 #ifndef _ASM_POWERPC_PARAVIRT_H
0003 #define _ASM_POWERPC_PARAVIRT_H
0004
0005 #include <linux/jump_label.h>
0006 #include <asm/smp.h>
0007 #ifdef CONFIG_PPC64
0008 #include <asm/paca.h>
0009 #include <asm/hvcall.h>
0010 #endif
0011
0012 #ifdef CONFIG_PPC_SPLPAR
0013 #include <linux/smp.h>
0014 #include <asm/kvm_guest.h>
0015 #include <asm/cputhreads.h>
0016
0017 DECLARE_STATIC_KEY_FALSE(shared_processor);
0018
0019 static inline bool is_shared_processor(void)
0020 {
0021 return static_branch_unlikely(&shared_processor);
0022 }
0023
0024
0025 static inline u32 yield_count_of(int cpu)
0026 {
0027 __be32 yield_count = READ_ONCE(lppaca_of(cpu).yield_count);
0028 return be32_to_cpu(yield_count);
0029 }
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 static inline void yield_to_preempted(int cpu, u32 yield_count)
0048 {
0049 plpar_hcall_norets_notrace(H_CONFER, get_hard_smp_processor_id(cpu), yield_count);
0050 }
0051
0052 static inline void prod_cpu(int cpu)
0053 {
0054 plpar_hcall_norets_notrace(H_PROD, get_hard_smp_processor_id(cpu));
0055 }
0056
0057 static inline void yield_to_any(void)
0058 {
0059 plpar_hcall_norets_notrace(H_CONFER, -1, 0);
0060 }
0061 #else
0062 static inline bool is_shared_processor(void)
0063 {
0064 return false;
0065 }
0066
0067 static inline u32 yield_count_of(int cpu)
0068 {
0069 return 0;
0070 }
0071
0072 extern void ___bad_yield_to_preempted(void);
0073 static inline void yield_to_preempted(int cpu, u32 yield_count)
0074 {
0075 ___bad_yield_to_preempted();
0076 }
0077
0078 extern void ___bad_yield_to_any(void);
0079 static inline void yield_to_any(void)
0080 {
0081 ___bad_yield_to_any();
0082 }
0083
0084 extern void ___bad_prod_cpu(void);
0085 static inline void prod_cpu(int cpu)
0086 {
0087 ___bad_prod_cpu();
0088 }
0089
0090 #endif
0091
0092 #define vcpu_is_preempted vcpu_is_preempted
0093 static inline bool vcpu_is_preempted(int cpu)
0094 {
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 if (!is_shared_processor())
0109 return false;
0110
0111 #ifdef CONFIG_PPC_SPLPAR
0112 if (!is_kvm_guest()) {
0113 int first_cpu;
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 first_cpu = cpu_first_thread_sibling(raw_smp_processor_id());
0130
0131
0132
0133
0134
0135
0136
0137 if (cpu_first_thread_sibling(cpu) == first_cpu)
0138 return false;
0139 }
0140 #endif
0141
0142 if (yield_count_of(cpu) & 1)
0143 return true;
0144 return false;
0145 }
0146
0147 static inline bool pv_is_native_spin_unlock(void)
0148 {
0149 return !is_shared_processor();
0150 }
0151
0152 #endif