cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

smp.h (7096B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/* 
      3 * smp.h: PowerPC-specific SMP code.
      4 *
      5 * Original was a copy of sparc smp.h.  Now heavily modified
      6 * for PPC.
      7 *
      8 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
      9 * Copyright (C) 1996-2001 Cort Dougan <cort@fsmlabs.com>
     10 */
     11
     12#ifndef _ASM_POWERPC_SMP_H
     13#define _ASM_POWERPC_SMP_H
     14#ifdef __KERNEL__
     15
     16#include <linux/threads.h>
     17#include <linux/cpumask.h>
     18#include <linux/kernel.h>
     19#include <linux/irqreturn.h>
     20
     21#ifndef __ASSEMBLY__
     22
     23#ifdef CONFIG_PPC64
     24#include <asm/paca.h>
     25#endif
     26#include <asm/percpu.h>
     27
     28extern int boot_cpuid;
     29extern int spinning_secondaries;
     30extern u32 *cpu_to_phys_id;
     31extern bool coregroup_enabled;
     32
     33extern int cpu_to_chip_id(int cpu);
     34extern int *chip_id_lookup_table;
     35
     36DECLARE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map);
     37DECLARE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map);
     38DECLARE_PER_CPU(cpumask_var_t, thread_group_l3_cache_map);
     39
     40#ifdef CONFIG_SMP
     41
     42struct smp_ops_t {
     43	void  (*message_pass)(int cpu, int msg);
     44#ifdef CONFIG_PPC_SMP_MUXED_IPI
     45	void  (*cause_ipi)(int cpu);
     46#endif
     47	int   (*cause_nmi_ipi)(int cpu);
     48	void  (*probe)(void);
     49	int   (*kick_cpu)(int nr);
     50	int   (*prepare_cpu)(int nr);
     51	void  (*setup_cpu)(int nr);
     52	void  (*bringup_done)(void);
     53	void  (*take_timebase)(void);
     54	void  (*give_timebase)(void);
     55	int   (*cpu_disable)(void);
     56	void  (*cpu_die)(unsigned int nr);
     57	int   (*cpu_bootable)(unsigned int nr);
     58#ifdef CONFIG_HOTPLUG_CPU
     59	void  (*cpu_offline_self)(void);
     60#endif
     61};
     62
     63extern struct task_struct *secondary_current;
     64
     65void start_secondary(void *unused);
     66extern int smp_send_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us);
     67extern int smp_send_safe_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us);
     68extern void smp_send_debugger_break(void);
     69extern void start_secondary_resume(void);
     70extern void smp_generic_give_timebase(void);
     71extern void smp_generic_take_timebase(void);
     72
     73DECLARE_PER_CPU(unsigned int, cpu_pvr);
     74
     75#ifdef CONFIG_HOTPLUG_CPU
     76int generic_cpu_disable(void);
     77void generic_cpu_die(unsigned int cpu);
     78void generic_set_cpu_dead(unsigned int cpu);
     79void generic_set_cpu_up(unsigned int cpu);
     80int generic_check_cpu_restart(unsigned int cpu);
     81int is_cpu_dead(unsigned int cpu);
     82#else
     83#define generic_set_cpu_up(i)	do { } while (0)
     84#endif
     85
     86#ifdef CONFIG_PPC64
     87#define raw_smp_processor_id()	(local_paca->paca_index)
     88#define hard_smp_processor_id() (get_paca()->hw_cpu_id)
     89#else
     90/* 32-bit */
     91extern int smp_hw_index[];
     92
     93#define raw_smp_processor_id()		(current_thread_info()->cpu)
     94#define hard_smp_processor_id() 	(smp_hw_index[smp_processor_id()])
     95
     96static inline int get_hard_smp_processor_id(int cpu)
     97{
     98	return smp_hw_index[cpu];
     99}
    100
    101static inline void set_hard_smp_processor_id(int cpu, int phys)
    102{
    103	smp_hw_index[cpu] = phys;
    104}
    105#endif
    106
    107DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
    108DECLARE_PER_CPU(cpumask_var_t, cpu_l2_cache_map);
    109DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
    110DECLARE_PER_CPU(cpumask_var_t, cpu_smallcore_map);
    111
    112static inline struct cpumask *cpu_sibling_mask(int cpu)
    113{
    114	return per_cpu(cpu_sibling_map, cpu);
    115}
    116
    117static inline struct cpumask *cpu_core_mask(int cpu)
    118{
    119	return per_cpu(cpu_core_map, cpu);
    120}
    121
    122static inline struct cpumask *cpu_l2_cache_mask(int cpu)
    123{
    124	return per_cpu(cpu_l2_cache_map, cpu);
    125}
    126
    127static inline struct cpumask *cpu_smallcore_mask(int cpu)
    128{
    129	return per_cpu(cpu_smallcore_map, cpu);
    130}
    131
    132extern int cpu_to_core_id(int cpu);
    133
    134extern bool has_big_cores;
    135extern bool thread_group_shares_l2;
    136extern bool thread_group_shares_l3;
    137
    138#define cpu_smt_mask cpu_smt_mask
    139#ifdef CONFIG_SCHED_SMT
    140static inline const struct cpumask *cpu_smt_mask(int cpu)
    141{
    142	if (has_big_cores)
    143		return per_cpu(cpu_smallcore_map, cpu);
    144
    145	return per_cpu(cpu_sibling_map, cpu);
    146}
    147#endif /* CONFIG_SCHED_SMT */
    148
    149/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
    150 *
    151 * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
    152 * in /proc/interrupts will be wrong!!! --Troy */
    153#define PPC_MSG_CALL_FUNCTION	0
    154#define PPC_MSG_RESCHEDULE	1
    155#define PPC_MSG_TICK_BROADCAST	2
    156#define PPC_MSG_NMI_IPI		3
    157
    158/* This is only used by the powernv kernel */
    159#define PPC_MSG_RM_HOST_ACTION	4
    160
    161#define NMI_IPI_ALL_OTHERS		-2
    162
    163#ifdef CONFIG_NMI_IPI
    164extern int smp_handle_nmi_ipi(struct pt_regs *regs);
    165#else
    166static inline int smp_handle_nmi_ipi(struct pt_regs *regs) { return 0; }
    167#endif
    168
    169/* for irq controllers that have dedicated ipis per message (4) */
    170extern int smp_request_message_ipi(int virq, int message);
    171extern const char *smp_ipi_name[];
    172
    173/* for irq controllers with only a single ipi */
    174extern void smp_muxed_ipi_message_pass(int cpu, int msg);
    175extern void smp_muxed_ipi_set_message(int cpu, int msg);
    176extern irqreturn_t smp_ipi_demux(void);
    177extern irqreturn_t smp_ipi_demux_relaxed(void);
    178
    179void smp_init_pSeries(void);
    180void smp_init_cell(void);
    181void smp_setup_cpu_maps(void);
    182
    183extern int __cpu_disable(void);
    184extern void __cpu_die(unsigned int cpu);
    185
    186#else
    187/* for UP */
    188#define hard_smp_processor_id()		get_hard_smp_processor_id(0)
    189#define smp_setup_cpu_maps()
    190#define thread_group_shares_l2  0
    191#define thread_group_shares_l3	0
    192static inline const struct cpumask *cpu_sibling_mask(int cpu)
    193{
    194	return cpumask_of(cpu);
    195}
    196
    197static inline const struct cpumask *cpu_smallcore_mask(int cpu)
    198{
    199	return cpumask_of(cpu);
    200}
    201
    202static inline const struct cpumask *cpu_l2_cache_mask(int cpu)
    203{
    204	return cpumask_of(cpu);
    205}
    206#endif /* CONFIG_SMP */
    207
    208#ifdef CONFIG_PPC64
    209static inline int get_hard_smp_processor_id(int cpu)
    210{
    211	return paca_ptrs[cpu]->hw_cpu_id;
    212}
    213
    214static inline void set_hard_smp_processor_id(int cpu, int phys)
    215{
    216	paca_ptrs[cpu]->hw_cpu_id = phys;
    217}
    218#else
    219/* 32-bit */
    220#ifndef CONFIG_SMP
    221extern int boot_cpuid_phys;
    222static inline int get_hard_smp_processor_id(int cpu)
    223{
    224	return boot_cpuid_phys;
    225}
    226
    227static inline void set_hard_smp_processor_id(int cpu, int phys)
    228{
    229	boot_cpuid_phys = phys;
    230}
    231#endif /* !CONFIG_SMP */
    232#endif /* !CONFIG_PPC64 */
    233
    234#if defined(CONFIG_PPC64) && (defined(CONFIG_SMP) || defined(CONFIG_KEXEC_CORE))
    235extern void smp_release_cpus(void);
    236#else
    237static inline void smp_release_cpus(void) { }
    238#endif
    239
    240extern int smt_enabled_at_boot;
    241
    242extern void smp_mpic_probe(void);
    243extern void smp_mpic_setup_cpu(int cpu);
    244extern int smp_generic_kick_cpu(int nr);
    245extern int smp_generic_cpu_bootable(unsigned int nr);
    246
    247
    248extern void smp_generic_give_timebase(void);
    249extern void smp_generic_take_timebase(void);
    250
    251extern struct smp_ops_t *smp_ops;
    252
    253extern void arch_send_call_function_single_ipi(int cpu);
    254extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
    255
    256/* Definitions relative to the secondary CPU spin loop
    257 * and entry point. Not all of them exist on both 32 and
    258 * 64-bit but defining them all here doesn't harm
    259 */
    260extern void generic_secondary_smp_init(void);
    261extern unsigned long __secondary_hold_spinloop;
    262extern unsigned long __secondary_hold_acknowledge;
    263extern char __secondary_hold;
    264extern unsigned int booting_thread_hwid;
    265
    266extern void __early_start(void);
    267#endif /* __ASSEMBLY__ */
    268
    269#endif /* __KERNEL__ */
    270#endif /* _ASM_POWERPC_SMP_H) */