File Index
Files and directories
Sign in
FILE

smp.h

File preview with syntax highlighting.

linux-6.19.14/arch/x86/include/asm/smp.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef _ASM_X86_SMP_H
  3#define _ASM_X86_SMP_H
  4#ifndef __ASSEMBLER__
  5#include <linux/cpumask.h>
  6#include <linux/thread_info.h>
  7
  8#include <asm/cpumask.h>
  9
 10DECLARE_PER_CPU_CACHE_HOT(int, cpu_number);
 11
 12DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
 13DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
 14DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
 15/* cpus sharing the last level cache: */
 16DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
 17DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map);
 18
 19DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_apicid);
 20DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid);
 21
 22struct task_struct;
 23
 24struct smp_ops {
 25	void (*smp_prepare_boot_cpu)(void);
 26	void (*smp_prepare_cpus)(unsigned max_cpus);
 27	void (*smp_cpus_done)(unsigned max_cpus);
 28
 29	void (*stop_other_cpus)(int wait);
 30	void (*crash_stop_other_cpus)(void);
 31	void (*smp_send_reschedule)(int cpu);
 32
 33	void (*cleanup_dead_cpu)(unsigned cpu);
 34	void (*poll_sync_state)(void);
 35	int (*kick_ap_alive)(unsigned cpu, struct task_struct *tidle);
 36	int (*cpu_disable)(void);
 37	void (*cpu_die)(unsigned int cpu);
 38	void (*play_dead)(void);
 39	void (*stop_this_cpu)(void);
 40
 41	void (*send_call_func_ipi)(const struct cpumask *mask);
 42	void (*send_call_func_single_ipi)(int cpu);
 43};
 44
 45/* Globals due to paravirt */
 46extern void set_cpu_sibling_map(int cpu);
 47
 48#ifdef CONFIG_SMP
 49extern struct smp_ops smp_ops;
 50
 51static inline void smp_send_stop(void)
 52{
 53	smp_ops.stop_other_cpus(0);
 54}
 55
 56static inline void stop_other_cpus(void)
 57{
 58	smp_ops.stop_other_cpus(1);
 59}
 60
 61static inline void smp_prepare_cpus(unsigned int max_cpus)
 62{
 63	smp_ops.smp_prepare_cpus(max_cpus);
 64}
 65
 66static inline void smp_cpus_done(unsigned int max_cpus)
 67{
 68	smp_ops.smp_cpus_done(max_cpus);
 69}
 70
 71static inline int __cpu_disable(void)
 72{
 73	return smp_ops.cpu_disable();
 74}
 75
 76static inline void __cpu_die(unsigned int cpu)
 77{
 78	if (smp_ops.cpu_die)
 79		smp_ops.cpu_die(cpu);
 80}
 81
 82static inline void __noreturn play_dead(void)
 83{
 84	smp_ops.play_dead();
 85	BUG();
 86}
 87
 88static inline void arch_smp_send_reschedule(int cpu)
 89{
 90	smp_ops.smp_send_reschedule(cpu);
 91}
 92
 93static inline void arch_send_call_function_single_ipi(int cpu)
 94{
 95	smp_ops.send_call_func_single_ipi(cpu);
 96}
 97
 98static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 99{
100	smp_ops.send_call_func_ipi(mask);
101}
102
103void cpu_disable_common(void);
104void native_smp_prepare_boot_cpu(void);
105void smp_prepare_cpus_common(void);
106void native_smp_prepare_cpus(unsigned int max_cpus);
107void native_smp_cpus_done(unsigned int max_cpus);
108int common_cpu_up(unsigned int cpunum, struct task_struct *tidle);
109int native_kick_ap(unsigned int cpu, struct task_struct *tidle);
110int native_cpu_disable(void);
111void __noreturn hlt_play_dead(void);
112void __noreturn native_play_dead(void);
113void play_dead_common(void);
114void wbinvd_on_cpu(int cpu);
115void wbinvd_on_all_cpus(void);
116void wbinvd_on_cpus_mask(struct cpumask *cpus);
117void wbnoinvd_on_all_cpus(void);
118void wbnoinvd_on_cpus_mask(struct cpumask *cpus);
119
120void smp_kick_mwait_play_dead(void);
121void __noreturn mwait_play_dead(unsigned int eax_hint);
122
123void native_smp_send_reschedule(int cpu);
124void native_send_call_func_ipi(const struct cpumask *mask);
125void native_send_call_func_single_ipi(int cpu);
126
127asmlinkage __visible void smp_reboot_interrupt(void);
128__visible void smp_reschedule_interrupt(struct pt_regs *regs);
129__visible void smp_call_function_interrupt(struct pt_regs *regs);
130__visible void smp_call_function_single_interrupt(struct pt_regs *r);
131
132#define cpu_physical_id(cpu)	per_cpu(x86_cpu_to_apicid, cpu)
133#define cpu_acpi_id(cpu)	per_cpu(x86_cpu_to_acpiid, cpu)
134
135/*
136 * This function is needed by all SMP systems. It must _always_ be valid
137 * from the initial startup.
138 */
139#define raw_smp_processor_id()  this_cpu_read(cpu_number)
140#define __smp_processor_id() __this_cpu_read(cpu_number)
141
142static inline struct cpumask *cpu_llc_shared_mask(int cpu)
143{
144	return per_cpu(cpu_llc_shared_map, cpu);
145}
146
147static inline struct cpumask *cpu_l2c_shared_mask(int cpu)
148{
149	return per_cpu(cpu_l2c_shared_map, cpu);
150}
151
152#else /* !CONFIG_SMP */
153#define wbinvd_on_cpu(cpu)     wbinvd()
154static inline void wbinvd_on_all_cpus(void)
155{
156	wbinvd();
157}
158
159static inline void wbinvd_on_cpus_mask(struct cpumask *cpus)
160{
161	wbinvd();
162}
163
164static inline void wbnoinvd_on_all_cpus(void)
165{
166	wbnoinvd();
167}
168
169static inline void wbnoinvd_on_cpus_mask(struct cpumask *cpus)
170{
171	wbnoinvd();
172}
173
174static inline struct cpumask *cpu_llc_shared_mask(int cpu)
175{
176	return (struct cpumask *)cpumask_of(0);
177}
178
179static inline void __noreturn mwait_play_dead(unsigned int eax_hint) { BUG(); }
180#endif /* CONFIG_SMP */
181
182#ifdef CONFIG_DEBUG_NMI_SELFTEST
183extern void nmi_selftest(void);
184#else
185#define nmi_selftest() do { } while (0)
186#endif
187
188extern unsigned int smpboot_control;
189extern unsigned long apic_mmio_base;
190
191#endif /* !__ASSEMBLER__ */
192
193/* Control bits for startup_64 */
194#define STARTUP_READ_APICID	0x80000000
195
196/* Top 8 bits are reserved for control */
197#define STARTUP_PARALLEL_MASK	0xFF000000
198
199#endif /* _ASM_X86_SMP_H */
~/ Read-only file preview.