18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_PROCESSOR_H
38c2ecf20Sopenharmony_ci#define _ASM_X86_PROCESSOR_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <asm/processor-flags.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci/* Forward declaration, a strange C thing */
88c2ecf20Sopenharmony_cistruct task_struct;
98c2ecf20Sopenharmony_cistruct mm_struct;
108c2ecf20Sopenharmony_cistruct io_bitmap;
118c2ecf20Sopenharmony_cistruct vm86;
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <asm/math_emu.h>
148c2ecf20Sopenharmony_ci#include <asm/segment.h>
158c2ecf20Sopenharmony_ci#include <asm/types.h>
168c2ecf20Sopenharmony_ci#include <uapi/asm/sigcontext.h>
178c2ecf20Sopenharmony_ci#include <asm/current.h>
188c2ecf20Sopenharmony_ci#include <asm/cpufeatures.h>
198c2ecf20Sopenharmony_ci#include <asm/page.h>
208c2ecf20Sopenharmony_ci#include <asm/pgtable_types.h>
218c2ecf20Sopenharmony_ci#include <asm/percpu.h>
228c2ecf20Sopenharmony_ci#include <asm/msr.h>
238c2ecf20Sopenharmony_ci#include <asm/desc_defs.h>
248c2ecf20Sopenharmony_ci#include <asm/nops.h>
258c2ecf20Sopenharmony_ci#include <asm/special_insns.h>
268c2ecf20Sopenharmony_ci#include <asm/fpu/types.h>
278c2ecf20Sopenharmony_ci#include <asm/unwind_hints.h>
288c2ecf20Sopenharmony_ci#include <asm/vmxfeatures.h>
298c2ecf20Sopenharmony_ci#include <asm/vdso/processor.h>
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#include <linux/personality.h>
328c2ecf20Sopenharmony_ci#include <linux/cache.h>
338c2ecf20Sopenharmony_ci#include <linux/threads.h>
348c2ecf20Sopenharmony_ci#include <linux/math64.h>
358c2ecf20Sopenharmony_ci#include <linux/err.h>
368c2ecf20Sopenharmony_ci#include <linux/irqflags.h>
378c2ecf20Sopenharmony_ci#include <linux/mem_encrypt.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/*
408c2ecf20Sopenharmony_ci * We handle most unaligned accesses in hardware.  On the other hand
418c2ecf20Sopenharmony_ci * unaligned DMA can be quite expensive on some Nehalem processors.
428c2ecf20Sopenharmony_ci *
438c2ecf20Sopenharmony_ci * Based on this we disable the IP header alignment in network drivers.
448c2ecf20Sopenharmony_ci */
458c2ecf20Sopenharmony_ci#define NET_IP_ALIGN	0
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define HBP_NUM 4
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/*
508c2ecf20Sopenharmony_ci * These alignment constraints are for performance in the vSMP case,
518c2ecf20Sopenharmony_ci * but in the task_struct case we must also meet hardware imposed
528c2ecf20Sopenharmony_ci * alignment requirements of the FPU state:
538c2ecf20Sopenharmony_ci */
548c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_VSMP
558c2ecf20Sopenharmony_ci# define ARCH_MIN_TASKALIGN		(1 << INTERNODE_CACHE_SHIFT)
568c2ecf20Sopenharmony_ci# define ARCH_MIN_MMSTRUCT_ALIGN	(1 << INTERNODE_CACHE_SHIFT)
578c2ecf20Sopenharmony_ci#else
588c2ecf20Sopenharmony_ci# define ARCH_MIN_TASKALIGN		__alignof__(union fpregs_state)
598c2ecf20Sopenharmony_ci# define ARCH_MIN_MMSTRUCT_ALIGN	0
608c2ecf20Sopenharmony_ci#endif
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cienum tlb_infos {
638c2ecf20Sopenharmony_ci	ENTRIES,
648c2ecf20Sopenharmony_ci	NR_INFO
658c2ecf20Sopenharmony_ci};
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ciextern u16 __read_mostly tlb_lli_4k[NR_INFO];
688c2ecf20Sopenharmony_ciextern u16 __read_mostly tlb_lli_2m[NR_INFO];
698c2ecf20Sopenharmony_ciextern u16 __read_mostly tlb_lli_4m[NR_INFO];
708c2ecf20Sopenharmony_ciextern u16 __read_mostly tlb_lld_4k[NR_INFO];
718c2ecf20Sopenharmony_ciextern u16 __read_mostly tlb_lld_2m[NR_INFO];
728c2ecf20Sopenharmony_ciextern u16 __read_mostly tlb_lld_4m[NR_INFO];
738c2ecf20Sopenharmony_ciextern u16 __read_mostly tlb_lld_1g[NR_INFO];
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/*
768c2ecf20Sopenharmony_ci *  CPU type and hardware bug flags. Kept separately for each CPU.
778c2ecf20Sopenharmony_ci *  Members of this structure are referenced in head_32.S, so think twice
788c2ecf20Sopenharmony_ci *  before touching them. [mj]
798c2ecf20Sopenharmony_ci */
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistruct cpuinfo_x86 {
828c2ecf20Sopenharmony_ci	__u8			x86;		/* CPU family */
838c2ecf20Sopenharmony_ci	__u8			x86_vendor;	/* CPU vendor */
848c2ecf20Sopenharmony_ci	__u8			x86_model;
858c2ecf20Sopenharmony_ci	__u8			x86_stepping;
868c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
878c2ecf20Sopenharmony_ci	/* Number of 4K pages in DTLB/ITLB combined(in pages): */
888c2ecf20Sopenharmony_ci	int			x86_tlbsize;
898c2ecf20Sopenharmony_ci#endif
908c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_VMX_FEATURE_NAMES
918c2ecf20Sopenharmony_ci	__u32			vmx_capability[NVMXINTS];
928c2ecf20Sopenharmony_ci#endif
938c2ecf20Sopenharmony_ci	__u8			x86_virt_bits;
948c2ecf20Sopenharmony_ci	__u8			x86_phys_bits;
958c2ecf20Sopenharmony_ci	/* CPUID returned core id bits: */
968c2ecf20Sopenharmony_ci	__u8			x86_coreid_bits;
978c2ecf20Sopenharmony_ci	__u8			cu_id;
988c2ecf20Sopenharmony_ci	/* Max extended CPUID function supported: */
998c2ecf20Sopenharmony_ci	__u32			extended_cpuid_level;
1008c2ecf20Sopenharmony_ci	/* Maximum supported CPUID level, -1=no CPUID: */
1018c2ecf20Sopenharmony_ci	int			cpuid_level;
1028c2ecf20Sopenharmony_ci	/*
1038c2ecf20Sopenharmony_ci	 * Align to size of unsigned long because the x86_capability array
1048c2ecf20Sopenharmony_ci	 * is passed to bitops which require the alignment. Use unnamed
1058c2ecf20Sopenharmony_ci	 * union to enforce the array is aligned to size of unsigned long.
1068c2ecf20Sopenharmony_ci	 */
1078c2ecf20Sopenharmony_ci	union {
1088c2ecf20Sopenharmony_ci		__u32		x86_capability[NCAPINTS + NBUGINTS];
1098c2ecf20Sopenharmony_ci		unsigned long	x86_capability_alignment;
1108c2ecf20Sopenharmony_ci	};
1118c2ecf20Sopenharmony_ci	char			x86_vendor_id[16];
1128c2ecf20Sopenharmony_ci	char			x86_model_id[64];
1138c2ecf20Sopenharmony_ci	/* in KB - valid for CPUS which support this call: */
1148c2ecf20Sopenharmony_ci	unsigned int		x86_cache_size;
1158c2ecf20Sopenharmony_ci	int			x86_cache_alignment;	/* In bytes */
1168c2ecf20Sopenharmony_ci	/* Cache QoS architectural values, valid only on the BSP: */
1178c2ecf20Sopenharmony_ci	int			x86_cache_max_rmid;	/* max index */
1188c2ecf20Sopenharmony_ci	int			x86_cache_occ_scale;	/* scale to bytes */
1198c2ecf20Sopenharmony_ci	int			x86_cache_mbm_width_offset;
1208c2ecf20Sopenharmony_ci	int			x86_power;
1218c2ecf20Sopenharmony_ci	unsigned long		loops_per_jiffy;
1228c2ecf20Sopenharmony_ci	/* cpuid returned max cores value: */
1238c2ecf20Sopenharmony_ci	u16			x86_max_cores;
1248c2ecf20Sopenharmony_ci	u16			apicid;
1258c2ecf20Sopenharmony_ci	u16			initial_apicid;
1268c2ecf20Sopenharmony_ci	u16			x86_clflush_size;
1278c2ecf20Sopenharmony_ci	/* number of cores as seen by the OS: */
1288c2ecf20Sopenharmony_ci	u16			booted_cores;
1298c2ecf20Sopenharmony_ci	/* Physical processor id: */
1308c2ecf20Sopenharmony_ci	u16			phys_proc_id;
1318c2ecf20Sopenharmony_ci	/* Logical processor id: */
1328c2ecf20Sopenharmony_ci	u16			logical_proc_id;
1338c2ecf20Sopenharmony_ci	/* Core id: */
1348c2ecf20Sopenharmony_ci	u16			cpu_core_id;
1358c2ecf20Sopenharmony_ci	u16			cpu_die_id;
1368c2ecf20Sopenharmony_ci	u16			logical_die_id;
1378c2ecf20Sopenharmony_ci	/* Index into per_cpu list: */
1388c2ecf20Sopenharmony_ci	u16			cpu_index;
1398c2ecf20Sopenharmony_ci	u32			microcode;
1408c2ecf20Sopenharmony_ci	/* Address space bits used by the cache internally */
1418c2ecf20Sopenharmony_ci	u8			x86_cache_bits;
1428c2ecf20Sopenharmony_ci	unsigned		initialized : 1;
1438c2ecf20Sopenharmony_ci} __randomize_layout;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistruct cpuid_regs {
1468c2ecf20Sopenharmony_ci	u32 eax, ebx, ecx, edx;
1478c2ecf20Sopenharmony_ci};
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_cienum cpuid_regs_idx {
1508c2ecf20Sopenharmony_ci	CPUID_EAX = 0,
1518c2ecf20Sopenharmony_ci	CPUID_EBX,
1528c2ecf20Sopenharmony_ci	CPUID_ECX,
1538c2ecf20Sopenharmony_ci	CPUID_EDX,
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci#define X86_VENDOR_INTEL	0
1578c2ecf20Sopenharmony_ci#define X86_VENDOR_CYRIX	1
1588c2ecf20Sopenharmony_ci#define X86_VENDOR_AMD		2
1598c2ecf20Sopenharmony_ci#define X86_VENDOR_UMC		3
1608c2ecf20Sopenharmony_ci#define X86_VENDOR_CENTAUR	5
1618c2ecf20Sopenharmony_ci#define X86_VENDOR_TRANSMETA	7
1628c2ecf20Sopenharmony_ci#define X86_VENDOR_NSC		8
1638c2ecf20Sopenharmony_ci#define X86_VENDOR_HYGON	9
1648c2ecf20Sopenharmony_ci#define X86_VENDOR_ZHAOXIN	10
1658c2ecf20Sopenharmony_ci#define X86_VENDOR_NUM		11
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci#define X86_VENDOR_UNKNOWN	0xff
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci/*
1708c2ecf20Sopenharmony_ci * capabilities of CPUs
1718c2ecf20Sopenharmony_ci */
1728c2ecf20Sopenharmony_ciextern struct cpuinfo_x86	boot_cpu_data;
1738c2ecf20Sopenharmony_ciextern struct cpuinfo_x86	new_cpu_data;
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ciextern __u32			cpu_caps_cleared[NCAPINTS + NBUGINTS];
1768c2ecf20Sopenharmony_ciextern __u32			cpu_caps_set[NCAPINTS + NBUGINTS];
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP
1798c2ecf20Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
1808c2ecf20Sopenharmony_ci#define cpu_data(cpu)		per_cpu(cpu_info, cpu)
1818c2ecf20Sopenharmony_ci#else
1828c2ecf20Sopenharmony_ci#define cpu_info		boot_cpu_data
1838c2ecf20Sopenharmony_ci#define cpu_data(cpu)		boot_cpu_data
1848c2ecf20Sopenharmony_ci#endif
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ciextern const struct seq_operations cpuinfo_op;
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci#define cache_line_size()	(boot_cpu_data.x86_cache_alignment)
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ciextern void cpu_detect(struct cpuinfo_x86 *c);
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_cistatic inline unsigned long long l1tf_pfn_limit(void)
1938c2ecf20Sopenharmony_ci{
1948c2ecf20Sopenharmony_ci	return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
1958c2ecf20Sopenharmony_ci}
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ciextern void early_cpu_init(void);
1988c2ecf20Sopenharmony_ciextern void identify_boot_cpu(void);
1998c2ecf20Sopenharmony_ciextern void identify_secondary_cpu(struct cpuinfo_x86 *);
2008c2ecf20Sopenharmony_ciextern void print_cpu_info(struct cpuinfo_x86 *);
2018c2ecf20Sopenharmony_civoid print_cpu_msr(struct cpuinfo_x86 *);
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
2048c2ecf20Sopenharmony_ciextern int have_cpuid_p(void);
2058c2ecf20Sopenharmony_ci#else
2068c2ecf20Sopenharmony_cistatic inline int have_cpuid_p(void)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	return 1;
2098c2ecf20Sopenharmony_ci}
2108c2ecf20Sopenharmony_ci#endif
2118c2ecf20Sopenharmony_cistatic inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
2128c2ecf20Sopenharmony_ci				unsigned int *ecx, unsigned int *edx)
2138c2ecf20Sopenharmony_ci{
2148c2ecf20Sopenharmony_ci	/* ecx is often an input as well as an output. */
2158c2ecf20Sopenharmony_ci	asm volatile("cpuid"
2168c2ecf20Sopenharmony_ci	    : "=a" (*eax),
2178c2ecf20Sopenharmony_ci	      "=b" (*ebx),
2188c2ecf20Sopenharmony_ci	      "=c" (*ecx),
2198c2ecf20Sopenharmony_ci	      "=d" (*edx)
2208c2ecf20Sopenharmony_ci	    : "0" (*eax), "2" (*ecx)
2218c2ecf20Sopenharmony_ci	    : "memory");
2228c2ecf20Sopenharmony_ci}
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci#define native_cpuid_reg(reg)					\
2258c2ecf20Sopenharmony_cistatic inline unsigned int native_cpuid_##reg(unsigned int op)	\
2268c2ecf20Sopenharmony_ci{								\
2278c2ecf20Sopenharmony_ci	unsigned int eax = op, ebx, ecx = 0, edx;		\
2288c2ecf20Sopenharmony_ci								\
2298c2ecf20Sopenharmony_ci	native_cpuid(&eax, &ebx, &ecx, &edx);			\
2308c2ecf20Sopenharmony_ci								\
2318c2ecf20Sopenharmony_ci	return reg;						\
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci/*
2358c2ecf20Sopenharmony_ci * Native CPUID functions returning a single datum.
2368c2ecf20Sopenharmony_ci */
2378c2ecf20Sopenharmony_cinative_cpuid_reg(eax)
2388c2ecf20Sopenharmony_cinative_cpuid_reg(ebx)
2398c2ecf20Sopenharmony_cinative_cpuid_reg(ecx)
2408c2ecf20Sopenharmony_cinative_cpuid_reg(edx)
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci/*
2438c2ecf20Sopenharmony_ci * Friendlier CR3 helpers.
2448c2ecf20Sopenharmony_ci */
2458c2ecf20Sopenharmony_cistatic inline unsigned long read_cr3_pa(void)
2468c2ecf20Sopenharmony_ci{
2478c2ecf20Sopenharmony_ci	return __read_cr3() & CR3_ADDR_MASK;
2488c2ecf20Sopenharmony_ci}
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_cistatic inline unsigned long native_read_cr3_pa(void)
2518c2ecf20Sopenharmony_ci{
2528c2ecf20Sopenharmony_ci	return __native_read_cr3() & CR3_ADDR_MASK;
2538c2ecf20Sopenharmony_ci}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cistatic inline void load_cr3(pgd_t *pgdir)
2568c2ecf20Sopenharmony_ci{
2578c2ecf20Sopenharmony_ci	write_cr3(__sme_pa(pgdir));
2588c2ecf20Sopenharmony_ci}
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci/*
2618c2ecf20Sopenharmony_ci * Note that while the legacy 'TSS' name comes from 'Task State Segment',
2628c2ecf20Sopenharmony_ci * on modern x86 CPUs the TSS also holds information important to 64-bit mode,
2638c2ecf20Sopenharmony_ci * unrelated to the task-switch mechanism:
2648c2ecf20Sopenharmony_ci */
2658c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
2668c2ecf20Sopenharmony_ci/* This is the TSS defined by the hardware. */
2678c2ecf20Sopenharmony_cistruct x86_hw_tss {
2688c2ecf20Sopenharmony_ci	unsigned short		back_link, __blh;
2698c2ecf20Sopenharmony_ci	unsigned long		sp0;
2708c2ecf20Sopenharmony_ci	unsigned short		ss0, __ss0h;
2718c2ecf20Sopenharmony_ci	unsigned long		sp1;
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	/*
2748c2ecf20Sopenharmony_ci	 * We don't use ring 1, so ss1 is a convenient scratch space in
2758c2ecf20Sopenharmony_ci	 * the same cacheline as sp0.  We use ss1 to cache the value in
2768c2ecf20Sopenharmony_ci	 * MSR_IA32_SYSENTER_CS.  When we context switch
2778c2ecf20Sopenharmony_ci	 * MSR_IA32_SYSENTER_CS, we first check if the new value being
2788c2ecf20Sopenharmony_ci	 * written matches ss1, and, if it's not, then we wrmsr the new
2798c2ecf20Sopenharmony_ci	 * value and update ss1.
2808c2ecf20Sopenharmony_ci	 *
2818c2ecf20Sopenharmony_ci	 * The only reason we context switch MSR_IA32_SYSENTER_CS is
2828c2ecf20Sopenharmony_ci	 * that we set it to zero in vm86 tasks to avoid corrupting the
2838c2ecf20Sopenharmony_ci	 * stack if we were to go through the sysenter path from vm86
2848c2ecf20Sopenharmony_ci	 * mode.
2858c2ecf20Sopenharmony_ci	 */
2868c2ecf20Sopenharmony_ci	unsigned short		ss1;	/* MSR_IA32_SYSENTER_CS */
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci	unsigned short		__ss1h;
2898c2ecf20Sopenharmony_ci	unsigned long		sp2;
2908c2ecf20Sopenharmony_ci	unsigned short		ss2, __ss2h;
2918c2ecf20Sopenharmony_ci	unsigned long		__cr3;
2928c2ecf20Sopenharmony_ci	unsigned long		ip;
2938c2ecf20Sopenharmony_ci	unsigned long		flags;
2948c2ecf20Sopenharmony_ci	unsigned long		ax;
2958c2ecf20Sopenharmony_ci	unsigned long		cx;
2968c2ecf20Sopenharmony_ci	unsigned long		dx;
2978c2ecf20Sopenharmony_ci	unsigned long		bx;
2988c2ecf20Sopenharmony_ci	unsigned long		sp;
2998c2ecf20Sopenharmony_ci	unsigned long		bp;
3008c2ecf20Sopenharmony_ci	unsigned long		si;
3018c2ecf20Sopenharmony_ci	unsigned long		di;
3028c2ecf20Sopenharmony_ci	unsigned short		es, __esh;
3038c2ecf20Sopenharmony_ci	unsigned short		cs, __csh;
3048c2ecf20Sopenharmony_ci	unsigned short		ss, __ssh;
3058c2ecf20Sopenharmony_ci	unsigned short		ds, __dsh;
3068c2ecf20Sopenharmony_ci	unsigned short		fs, __fsh;
3078c2ecf20Sopenharmony_ci	unsigned short		gs, __gsh;
3088c2ecf20Sopenharmony_ci	unsigned short		ldt, __ldth;
3098c2ecf20Sopenharmony_ci	unsigned short		trace;
3108c2ecf20Sopenharmony_ci	unsigned short		io_bitmap_base;
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci} __attribute__((packed));
3138c2ecf20Sopenharmony_ci#else
3148c2ecf20Sopenharmony_cistruct x86_hw_tss {
3158c2ecf20Sopenharmony_ci	u32			reserved1;
3168c2ecf20Sopenharmony_ci	u64			sp0;
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	/*
3198c2ecf20Sopenharmony_ci	 * We store cpu_current_top_of_stack in sp1 so it's always accessible.
3208c2ecf20Sopenharmony_ci	 * Linux does not use ring 1, so sp1 is not otherwise needed.
3218c2ecf20Sopenharmony_ci	 */
3228c2ecf20Sopenharmony_ci	u64			sp1;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	/*
3258c2ecf20Sopenharmony_ci	 * Since Linux does not use ring 2, the 'sp2' slot is unused by
3268c2ecf20Sopenharmony_ci	 * hardware.  entry_SYSCALL_64 uses it as scratch space to stash
3278c2ecf20Sopenharmony_ci	 * the user RSP value.
3288c2ecf20Sopenharmony_ci	 */
3298c2ecf20Sopenharmony_ci	u64			sp2;
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	u64			reserved2;
3328c2ecf20Sopenharmony_ci	u64			ist[7];
3338c2ecf20Sopenharmony_ci	u32			reserved3;
3348c2ecf20Sopenharmony_ci	u32			reserved4;
3358c2ecf20Sopenharmony_ci	u16			reserved5;
3368c2ecf20Sopenharmony_ci	u16			io_bitmap_base;
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci} __attribute__((packed));
3398c2ecf20Sopenharmony_ci#endif
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci/*
3428c2ecf20Sopenharmony_ci * IO-bitmap sizes:
3438c2ecf20Sopenharmony_ci */
3448c2ecf20Sopenharmony_ci#define IO_BITMAP_BITS			65536
3458c2ecf20Sopenharmony_ci#define IO_BITMAP_BYTES			(IO_BITMAP_BITS / BITS_PER_BYTE)
3468c2ecf20Sopenharmony_ci#define IO_BITMAP_LONGS			(IO_BITMAP_BYTES / sizeof(long))
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci#define IO_BITMAP_OFFSET_VALID_MAP				\
3498c2ecf20Sopenharmony_ci	(offsetof(struct tss_struct, io_bitmap.bitmap) -	\
3508c2ecf20Sopenharmony_ci	 offsetof(struct tss_struct, x86_tss))
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci#define IO_BITMAP_OFFSET_VALID_ALL				\
3538c2ecf20Sopenharmony_ci	(offsetof(struct tss_struct, io_bitmap.mapall) -	\
3548c2ecf20Sopenharmony_ci	 offsetof(struct tss_struct, x86_tss))
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_IOPL_IOPERM
3578c2ecf20Sopenharmony_ci/*
3588c2ecf20Sopenharmony_ci * sizeof(unsigned long) coming from an extra "long" at the end of the
3598c2ecf20Sopenharmony_ci * iobitmap. The limit is inclusive, i.e. the last valid byte.
3608c2ecf20Sopenharmony_ci */
3618c2ecf20Sopenharmony_ci# define __KERNEL_TSS_LIMIT	\
3628c2ecf20Sopenharmony_ci	(IO_BITMAP_OFFSET_VALID_ALL + IO_BITMAP_BYTES + \
3638c2ecf20Sopenharmony_ci	 sizeof(unsigned long) - 1)
3648c2ecf20Sopenharmony_ci#else
3658c2ecf20Sopenharmony_ci# define __KERNEL_TSS_LIMIT	\
3668c2ecf20Sopenharmony_ci	(offsetof(struct tss_struct, x86_tss) + sizeof(struct x86_hw_tss) - 1)
3678c2ecf20Sopenharmony_ci#endif
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci/* Base offset outside of TSS_LIMIT so unpriviledged IO causes #GP */
3708c2ecf20Sopenharmony_ci#define IO_BITMAP_OFFSET_INVALID	(__KERNEL_TSS_LIMIT + 1)
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_cistruct entry_stack {
3738c2ecf20Sopenharmony_ci	char	stack[PAGE_SIZE];
3748c2ecf20Sopenharmony_ci};
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_cistruct entry_stack_page {
3778c2ecf20Sopenharmony_ci	struct entry_stack stack;
3788c2ecf20Sopenharmony_ci} __aligned(PAGE_SIZE);
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci/*
3818c2ecf20Sopenharmony_ci * All IO bitmap related data stored in the TSS:
3828c2ecf20Sopenharmony_ci */
3838c2ecf20Sopenharmony_cistruct x86_io_bitmap {
3848c2ecf20Sopenharmony_ci	/* The sequence number of the last active bitmap. */
3858c2ecf20Sopenharmony_ci	u64			prev_sequence;
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	/*
3888c2ecf20Sopenharmony_ci	 * Store the dirty size of the last io bitmap offender. The next
3898c2ecf20Sopenharmony_ci	 * one will have to do the cleanup as the switch out to a non io
3908c2ecf20Sopenharmony_ci	 * bitmap user will just set x86_tss.io_bitmap_base to a value
3918c2ecf20Sopenharmony_ci	 * outside of the TSS limit. So for sane tasks there is no need to
3928c2ecf20Sopenharmony_ci	 * actually touch the io_bitmap at all.
3938c2ecf20Sopenharmony_ci	 */
3948c2ecf20Sopenharmony_ci	unsigned int		prev_max;
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci	/*
3978c2ecf20Sopenharmony_ci	 * The extra 1 is there because the CPU will access an
3988c2ecf20Sopenharmony_ci	 * additional byte beyond the end of the IO permission
3998c2ecf20Sopenharmony_ci	 * bitmap. The extra byte must be all 1 bits, and must
4008c2ecf20Sopenharmony_ci	 * be within the limit.
4018c2ecf20Sopenharmony_ci	 */
4028c2ecf20Sopenharmony_ci	unsigned long		bitmap[IO_BITMAP_LONGS + 1];
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	/*
4058c2ecf20Sopenharmony_ci	 * Special I/O bitmap to emulate IOPL(3). All bytes zero,
4068c2ecf20Sopenharmony_ci	 * except the additional byte at the end.
4078c2ecf20Sopenharmony_ci	 */
4088c2ecf20Sopenharmony_ci	unsigned long		mapall[IO_BITMAP_LONGS + 1];
4098c2ecf20Sopenharmony_ci};
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_cistruct tss_struct {
4128c2ecf20Sopenharmony_ci	/*
4138c2ecf20Sopenharmony_ci	 * The fixed hardware portion.  This must not cross a page boundary
4148c2ecf20Sopenharmony_ci	 * at risk of violating the SDM's advice and potentially triggering
4158c2ecf20Sopenharmony_ci	 * errata.
4168c2ecf20Sopenharmony_ci	 */
4178c2ecf20Sopenharmony_ci	struct x86_hw_tss	x86_tss;
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci	struct x86_io_bitmap	io_bitmap;
4208c2ecf20Sopenharmony_ci} __aligned(PAGE_SIZE);
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ciDECLARE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw);
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci/* Per CPU interrupt stacks */
4258c2ecf20Sopenharmony_cistruct irq_stack {
4268c2ecf20Sopenharmony_ci	char		stack[IRQ_STACK_SIZE];
4278c2ecf20Sopenharmony_ci} __aligned(IRQ_STACK_SIZE);
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ciDECLARE_PER_CPU(struct irq_stack *, hardirq_stack_ptr);
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
4328c2ecf20Sopenharmony_ciDECLARE_PER_CPU(unsigned long, cpu_current_top_of_stack);
4338c2ecf20Sopenharmony_ci#else
4348c2ecf20Sopenharmony_ci/* The RO copy can't be accessed with this_cpu_xyz(), so use the RW copy. */
4358c2ecf20Sopenharmony_ci#define cpu_current_top_of_stack cpu_tss_rw.x86_tss.sp1
4368c2ecf20Sopenharmony_ci#endif
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
4398c2ecf20Sopenharmony_cistruct fixed_percpu_data {
4408c2ecf20Sopenharmony_ci	/*
4418c2ecf20Sopenharmony_ci	 * GCC hardcodes the stack canary as %gs:40.  Since the
4428c2ecf20Sopenharmony_ci	 * irq_stack is the object at %gs:0, we reserve the bottom
4438c2ecf20Sopenharmony_ci	 * 48 bytes of the irq stack for the canary.
4448c2ecf20Sopenharmony_ci	 */
4458c2ecf20Sopenharmony_ci	char		gs_base[40];
4468c2ecf20Sopenharmony_ci	unsigned long	stack_canary;
4478c2ecf20Sopenharmony_ci};
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ciDECLARE_PER_CPU_FIRST(struct fixed_percpu_data, fixed_percpu_data) __visible;
4508c2ecf20Sopenharmony_ciDECLARE_INIT_PER_CPU(fixed_percpu_data);
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_cistatic inline unsigned long cpu_kernelmode_gs_base(int cpu)
4538c2ecf20Sopenharmony_ci{
4548c2ecf20Sopenharmony_ci	return (unsigned long)per_cpu(fixed_percpu_data.gs_base, cpu);
4558c2ecf20Sopenharmony_ci}
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_ciDECLARE_PER_CPU(unsigned int, irq_count);
4588c2ecf20Sopenharmony_ciextern asmlinkage void ignore_sysret(void);
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci/* Save actual FS/GS selectors and bases to current->thread */
4618c2ecf20Sopenharmony_civoid current_save_fsgs(void);
4628c2ecf20Sopenharmony_ci#else	/* X86_64 */
4638c2ecf20Sopenharmony_ci#ifdef CONFIG_STACKPROTECTOR
4648c2ecf20Sopenharmony_ci/*
4658c2ecf20Sopenharmony_ci * Make sure stack canary segment base is cached-aligned:
4668c2ecf20Sopenharmony_ci *   "For Intel Atom processors, avoid non zero segment base address
4678c2ecf20Sopenharmony_ci *    that is not aligned to cache line boundary at all cost."
4688c2ecf20Sopenharmony_ci * (Optim Ref Manual Assembly/Compiler Coding Rule 15.)
4698c2ecf20Sopenharmony_ci */
4708c2ecf20Sopenharmony_cistruct stack_canary {
4718c2ecf20Sopenharmony_ci	char __pad[20];		/* canary at %gs:20 */
4728c2ecf20Sopenharmony_ci	unsigned long canary;
4738c2ecf20Sopenharmony_ci};
4748c2ecf20Sopenharmony_ciDECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
4758c2ecf20Sopenharmony_ci#endif
4768c2ecf20Sopenharmony_ci/* Per CPU softirq stack pointer */
4778c2ecf20Sopenharmony_ciDECLARE_PER_CPU(struct irq_stack *, softirq_stack_ptr);
4788c2ecf20Sopenharmony_ci#endif	/* X86_64 */
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ciextern unsigned int fpu_kernel_xstate_size;
4818c2ecf20Sopenharmony_ciextern unsigned int fpu_user_xstate_size;
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_cistruct perf_event;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_cistruct thread_struct {
4868c2ecf20Sopenharmony_ci	/* Cached TLS descriptors: */
4878c2ecf20Sopenharmony_ci	struct desc_struct	tls_array[GDT_ENTRY_TLS_ENTRIES];
4888c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
4898c2ecf20Sopenharmony_ci	unsigned long		sp0;
4908c2ecf20Sopenharmony_ci#endif
4918c2ecf20Sopenharmony_ci	unsigned long		sp;
4928c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
4938c2ecf20Sopenharmony_ci	unsigned long		sysenter_cs;
4948c2ecf20Sopenharmony_ci#else
4958c2ecf20Sopenharmony_ci	unsigned short		es;
4968c2ecf20Sopenharmony_ci	unsigned short		ds;
4978c2ecf20Sopenharmony_ci	unsigned short		fsindex;
4988c2ecf20Sopenharmony_ci	unsigned short		gsindex;
4998c2ecf20Sopenharmony_ci#endif
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
5028c2ecf20Sopenharmony_ci	unsigned long		fsbase;
5038c2ecf20Sopenharmony_ci	unsigned long		gsbase;
5048c2ecf20Sopenharmony_ci#else
5058c2ecf20Sopenharmony_ci	/*
5068c2ecf20Sopenharmony_ci	 * XXX: this could presumably be unsigned short.  Alternatively,
5078c2ecf20Sopenharmony_ci	 * 32-bit kernels could be taught to use fsindex instead.
5088c2ecf20Sopenharmony_ci	 */
5098c2ecf20Sopenharmony_ci	unsigned long fs;
5108c2ecf20Sopenharmony_ci	unsigned long gs;
5118c2ecf20Sopenharmony_ci#endif
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	/* Save middle states of ptrace breakpoints */
5148c2ecf20Sopenharmony_ci	struct perf_event	*ptrace_bps[HBP_NUM];
5158c2ecf20Sopenharmony_ci	/* Debug status used for traps, single steps, etc... */
5168c2ecf20Sopenharmony_ci	unsigned long           virtual_dr6;
5178c2ecf20Sopenharmony_ci	/* Keep track of the exact dr7 value set by the user */
5188c2ecf20Sopenharmony_ci	unsigned long           ptrace_dr7;
5198c2ecf20Sopenharmony_ci	/* Fault info: */
5208c2ecf20Sopenharmony_ci	unsigned long		cr2;
5218c2ecf20Sopenharmony_ci	unsigned long		trap_nr;
5228c2ecf20Sopenharmony_ci	unsigned long		error_code;
5238c2ecf20Sopenharmony_ci#ifdef CONFIG_VM86
5248c2ecf20Sopenharmony_ci	/* Virtual 86 mode info */
5258c2ecf20Sopenharmony_ci	struct vm86		*vm86;
5268c2ecf20Sopenharmony_ci#endif
5278c2ecf20Sopenharmony_ci	/* IO permissions: */
5288c2ecf20Sopenharmony_ci	struct io_bitmap	*io_bitmap;
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci	/*
5318c2ecf20Sopenharmony_ci	 * IOPL. Priviledge level dependent I/O permission which is
5328c2ecf20Sopenharmony_ci	 * emulated via the I/O bitmap to prevent user space from disabling
5338c2ecf20Sopenharmony_ci	 * interrupts.
5348c2ecf20Sopenharmony_ci	 */
5358c2ecf20Sopenharmony_ci	unsigned long		iopl_emul;
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci	unsigned int		iopl_warn:1;
5388c2ecf20Sopenharmony_ci	unsigned int		sig_on_uaccess_err:1;
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_ci	/* Floating point and extended processor state */
5418c2ecf20Sopenharmony_ci	struct fpu		fpu;
5428c2ecf20Sopenharmony_ci	/*
5438c2ecf20Sopenharmony_ci	 * WARNING: 'fpu' is dynamically-sized.  It *MUST* be at
5448c2ecf20Sopenharmony_ci	 * the end.
5458c2ecf20Sopenharmony_ci	 */
5468c2ecf20Sopenharmony_ci};
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci/* Whitelist the FPU state from the task_struct for hardened usercopy. */
5498c2ecf20Sopenharmony_cistatic inline void arch_thread_struct_whitelist(unsigned long *offset,
5508c2ecf20Sopenharmony_ci						unsigned long *size)
5518c2ecf20Sopenharmony_ci{
5528c2ecf20Sopenharmony_ci	*offset = offsetof(struct thread_struct, fpu.state);
5538c2ecf20Sopenharmony_ci	*size = fpu_kernel_xstate_size;
5548c2ecf20Sopenharmony_ci}
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_cistatic inline void
5578c2ecf20Sopenharmony_cinative_load_sp0(unsigned long sp0)
5588c2ecf20Sopenharmony_ci{
5598c2ecf20Sopenharmony_ci	this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0);
5608c2ecf20Sopenharmony_ci}
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_cistatic __always_inline void native_swapgs(void)
5638c2ecf20Sopenharmony_ci{
5648c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
5658c2ecf20Sopenharmony_ci	asm volatile("swapgs" ::: "memory");
5668c2ecf20Sopenharmony_ci#endif
5678c2ecf20Sopenharmony_ci}
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_cistatic inline unsigned long current_top_of_stack(void)
5708c2ecf20Sopenharmony_ci{
5718c2ecf20Sopenharmony_ci	/*
5728c2ecf20Sopenharmony_ci	 *  We can't read directly from tss.sp0: sp0 on x86_32 is special in
5738c2ecf20Sopenharmony_ci	 *  and around vm86 mode and sp0 on x86_64 is special because of the
5748c2ecf20Sopenharmony_ci	 *  entry trampoline.
5758c2ecf20Sopenharmony_ci	 */
5768c2ecf20Sopenharmony_ci	return this_cpu_read_stable(cpu_current_top_of_stack);
5778c2ecf20Sopenharmony_ci}
5788c2ecf20Sopenharmony_ci
5798c2ecf20Sopenharmony_cistatic inline bool on_thread_stack(void)
5808c2ecf20Sopenharmony_ci{
5818c2ecf20Sopenharmony_ci	return (unsigned long)(current_top_of_stack() -
5828c2ecf20Sopenharmony_ci			       current_stack_pointer) < THREAD_SIZE;
5838c2ecf20Sopenharmony_ci}
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_ci#ifdef CONFIG_PARAVIRT_XXL
5868c2ecf20Sopenharmony_ci#include <asm/paravirt.h>
5878c2ecf20Sopenharmony_ci#else
5888c2ecf20Sopenharmony_ci#define __cpuid			native_cpuid
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_cistatic inline void load_sp0(unsigned long sp0)
5918c2ecf20Sopenharmony_ci{
5928c2ecf20Sopenharmony_ci	native_load_sp0(sp0);
5938c2ecf20Sopenharmony_ci}
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci#endif /* CONFIG_PARAVIRT_XXL */
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_ci/* Free all resources held by a thread. */
5988c2ecf20Sopenharmony_ciextern void release_thread(struct task_struct *);
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ciunsigned long get_wchan(struct task_struct *p);
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci/*
6038c2ecf20Sopenharmony_ci * Generic CPUID function
6048c2ecf20Sopenharmony_ci * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
6058c2ecf20Sopenharmony_ci * resulting in stale register contents being returned.
6068c2ecf20Sopenharmony_ci */
6078c2ecf20Sopenharmony_cistatic inline void cpuid(unsigned int op,
6088c2ecf20Sopenharmony_ci			 unsigned int *eax, unsigned int *ebx,
6098c2ecf20Sopenharmony_ci			 unsigned int *ecx, unsigned int *edx)
6108c2ecf20Sopenharmony_ci{
6118c2ecf20Sopenharmony_ci	*eax = op;
6128c2ecf20Sopenharmony_ci	*ecx = 0;
6138c2ecf20Sopenharmony_ci	__cpuid(eax, ebx, ecx, edx);
6148c2ecf20Sopenharmony_ci}
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_ci/* Some CPUID calls want 'count' to be placed in ecx */
6178c2ecf20Sopenharmony_cistatic inline void cpuid_count(unsigned int op, int count,
6188c2ecf20Sopenharmony_ci			       unsigned int *eax, unsigned int *ebx,
6198c2ecf20Sopenharmony_ci			       unsigned int *ecx, unsigned int *edx)
6208c2ecf20Sopenharmony_ci{
6218c2ecf20Sopenharmony_ci	*eax = op;
6228c2ecf20Sopenharmony_ci	*ecx = count;
6238c2ecf20Sopenharmony_ci	__cpuid(eax, ebx, ecx, edx);
6248c2ecf20Sopenharmony_ci}
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci/*
6278c2ecf20Sopenharmony_ci * CPUID functions returning a single datum
6288c2ecf20Sopenharmony_ci */
6298c2ecf20Sopenharmony_cistatic inline unsigned int cpuid_eax(unsigned int op)
6308c2ecf20Sopenharmony_ci{
6318c2ecf20Sopenharmony_ci	unsigned int eax, ebx, ecx, edx;
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	cpuid(op, &eax, &ebx, &ecx, &edx);
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_ci	return eax;
6368c2ecf20Sopenharmony_ci}
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_cistatic inline unsigned int cpuid_ebx(unsigned int op)
6398c2ecf20Sopenharmony_ci{
6408c2ecf20Sopenharmony_ci	unsigned int eax, ebx, ecx, edx;
6418c2ecf20Sopenharmony_ci
6428c2ecf20Sopenharmony_ci	cpuid(op, &eax, &ebx, &ecx, &edx);
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_ci	return ebx;
6458c2ecf20Sopenharmony_ci}
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_cistatic inline unsigned int cpuid_ecx(unsigned int op)
6488c2ecf20Sopenharmony_ci{
6498c2ecf20Sopenharmony_ci	unsigned int eax, ebx, ecx, edx;
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci	cpuid(op, &eax, &ebx, &ecx, &edx);
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci	return ecx;
6548c2ecf20Sopenharmony_ci}
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_cistatic inline unsigned int cpuid_edx(unsigned int op)
6578c2ecf20Sopenharmony_ci{
6588c2ecf20Sopenharmony_ci	unsigned int eax, ebx, ecx, edx;
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_ci	cpuid(op, &eax, &ebx, &ecx, &edx);
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	return edx;
6638c2ecf20Sopenharmony_ci}
6648c2ecf20Sopenharmony_ci
6658c2ecf20Sopenharmony_ciextern void select_idle_routine(const struct cpuinfo_x86 *c);
6668c2ecf20Sopenharmony_ciextern void amd_e400_c1e_apic_setup(void);
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ciextern unsigned long		boot_option_idle_override;
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_cienum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
6718c2ecf20Sopenharmony_ci			 IDLE_POLL};
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ciextern void enable_sep_cpu(void);
6748c2ecf20Sopenharmony_ciextern int sysenter_setup(void);
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci/* Defined in head.S */
6788c2ecf20Sopenharmony_ciextern struct desc_ptr		early_gdt_descr;
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_ciextern void switch_to_new_gdt(int);
6818c2ecf20Sopenharmony_ciextern void load_direct_gdt(int);
6828c2ecf20Sopenharmony_ciextern void load_fixmap_gdt(int);
6838c2ecf20Sopenharmony_ciextern void load_percpu_segment(int);
6848c2ecf20Sopenharmony_ciextern void cpu_init(void);
6858c2ecf20Sopenharmony_ciextern void cpu_init_secondary(void);
6868c2ecf20Sopenharmony_ciextern void cpu_init_exception_handling(void);
6878c2ecf20Sopenharmony_ciextern void cr4_init(void);
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_cistatic inline unsigned long get_debugctlmsr(void)
6908c2ecf20Sopenharmony_ci{
6918c2ecf20Sopenharmony_ci	unsigned long debugctlmsr = 0;
6928c2ecf20Sopenharmony_ci
6938c2ecf20Sopenharmony_ci#ifndef CONFIG_X86_DEBUGCTLMSR
6948c2ecf20Sopenharmony_ci	if (boot_cpu_data.x86 < 6)
6958c2ecf20Sopenharmony_ci		return 0;
6968c2ecf20Sopenharmony_ci#endif
6978c2ecf20Sopenharmony_ci	rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
6988c2ecf20Sopenharmony_ci
6998c2ecf20Sopenharmony_ci	return debugctlmsr;
7008c2ecf20Sopenharmony_ci}
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_cistatic inline void update_debugctlmsr(unsigned long debugctlmsr)
7038c2ecf20Sopenharmony_ci{
7048c2ecf20Sopenharmony_ci#ifndef CONFIG_X86_DEBUGCTLMSR
7058c2ecf20Sopenharmony_ci	if (boot_cpu_data.x86 < 6)
7068c2ecf20Sopenharmony_ci		return;
7078c2ecf20Sopenharmony_ci#endif
7088c2ecf20Sopenharmony_ci	wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
7098c2ecf20Sopenharmony_ci}
7108c2ecf20Sopenharmony_ci
7118c2ecf20Sopenharmony_ciextern void set_task_blockstep(struct task_struct *task, bool on);
7128c2ecf20Sopenharmony_ci
7138c2ecf20Sopenharmony_ci/* Boot loader type from the setup header: */
7148c2ecf20Sopenharmony_ciextern int			bootloader_type;
7158c2ecf20Sopenharmony_ciextern int			bootloader_version;
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ciextern char			ignore_fpu_irq;
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_ci#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
7208c2ecf20Sopenharmony_ci#define ARCH_HAS_PREFETCHW
7218c2ecf20Sopenharmony_ci#define ARCH_HAS_SPINLOCK_PREFETCH
7228c2ecf20Sopenharmony_ci
7238c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
7248c2ecf20Sopenharmony_ci# define BASE_PREFETCH		""
7258c2ecf20Sopenharmony_ci# define ARCH_HAS_PREFETCH
7268c2ecf20Sopenharmony_ci#else
7278c2ecf20Sopenharmony_ci# define BASE_PREFETCH		"prefetcht0 %P1"
7288c2ecf20Sopenharmony_ci#endif
7298c2ecf20Sopenharmony_ci
7308c2ecf20Sopenharmony_ci/*
7318c2ecf20Sopenharmony_ci * Prefetch instructions for Pentium III (+) and AMD Athlon (+)
7328c2ecf20Sopenharmony_ci *
7338c2ecf20Sopenharmony_ci * It's not worth to care about 3dnow prefetches for the K6
7348c2ecf20Sopenharmony_ci * because they are microcoded there and very slow.
7358c2ecf20Sopenharmony_ci */
7368c2ecf20Sopenharmony_cistatic inline void prefetch(const void *x)
7378c2ecf20Sopenharmony_ci{
7388c2ecf20Sopenharmony_ci	alternative_input(BASE_PREFETCH, "prefetchnta %P1",
7398c2ecf20Sopenharmony_ci			  X86_FEATURE_XMM,
7408c2ecf20Sopenharmony_ci			  "m" (*(const char *)x));
7418c2ecf20Sopenharmony_ci}
7428c2ecf20Sopenharmony_ci
7438c2ecf20Sopenharmony_ci/*
7448c2ecf20Sopenharmony_ci * 3dnow prefetch to get an exclusive cache line.
7458c2ecf20Sopenharmony_ci * Useful for spinlocks to avoid one state transition in the
7468c2ecf20Sopenharmony_ci * cache coherency protocol:
7478c2ecf20Sopenharmony_ci */
7488c2ecf20Sopenharmony_cistatic __always_inline void prefetchw(const void *x)
7498c2ecf20Sopenharmony_ci{
7508c2ecf20Sopenharmony_ci	alternative_input(BASE_PREFETCH, "prefetchw %P1",
7518c2ecf20Sopenharmony_ci			  X86_FEATURE_3DNOWPREFETCH,
7528c2ecf20Sopenharmony_ci			  "m" (*(const char *)x));
7538c2ecf20Sopenharmony_ci}
7548c2ecf20Sopenharmony_ci
7558c2ecf20Sopenharmony_cistatic inline void spin_lock_prefetch(const void *x)
7568c2ecf20Sopenharmony_ci{
7578c2ecf20Sopenharmony_ci	prefetchw(x);
7588c2ecf20Sopenharmony_ci}
7598c2ecf20Sopenharmony_ci
7608c2ecf20Sopenharmony_ci#define TOP_OF_INIT_STACK ((unsigned long)&init_stack + sizeof(init_stack) - \
7618c2ecf20Sopenharmony_ci			   TOP_OF_KERNEL_STACK_PADDING)
7628c2ecf20Sopenharmony_ci
7638c2ecf20Sopenharmony_ci#define task_top_of_stack(task) ((unsigned long)(task_pt_regs(task) + 1))
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci#define task_pt_regs(task) \
7668c2ecf20Sopenharmony_ci({									\
7678c2ecf20Sopenharmony_ci	unsigned long __ptr = (unsigned long)task_stack_page(task);	\
7688c2ecf20Sopenharmony_ci	__ptr += THREAD_SIZE - TOP_OF_KERNEL_STACK_PADDING;		\
7698c2ecf20Sopenharmony_ci	((struct pt_regs *)__ptr) - 1;					\
7708c2ecf20Sopenharmony_ci})
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
7738c2ecf20Sopenharmony_ci#define INIT_THREAD  {							  \
7748c2ecf20Sopenharmony_ci	.sp0			= TOP_OF_INIT_STACK,			  \
7758c2ecf20Sopenharmony_ci	.sysenter_cs		= __KERNEL_CS,				  \
7768c2ecf20Sopenharmony_ci}
7778c2ecf20Sopenharmony_ci
7788c2ecf20Sopenharmony_ci#define KSTK_ESP(task)		(task_pt_regs(task)->sp)
7798c2ecf20Sopenharmony_ci
7808c2ecf20Sopenharmony_ci#else
7818c2ecf20Sopenharmony_ci#define INIT_THREAD { }
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ciextern unsigned long KSTK_ESP(struct task_struct *task);
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci#endif /* CONFIG_X86_64 */
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ciextern void start_thread(struct pt_regs *regs, unsigned long new_ip,
7888c2ecf20Sopenharmony_ci					       unsigned long new_sp);
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_ci/*
7918c2ecf20Sopenharmony_ci * This decides where the kernel will search for a free chunk of vm
7928c2ecf20Sopenharmony_ci * space during mmap's.
7938c2ecf20Sopenharmony_ci */
7948c2ecf20Sopenharmony_ci#define __TASK_UNMAPPED_BASE(task_size)	(PAGE_ALIGN(task_size / 3))
7958c2ecf20Sopenharmony_ci#define TASK_UNMAPPED_BASE		__TASK_UNMAPPED_BASE(TASK_SIZE_LOW)
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci#define KSTK_EIP(task)		(task_pt_regs(task)->ip)
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_ci/* Get/set a process' ability to use the timestamp counter instruction */
8008c2ecf20Sopenharmony_ci#define GET_TSC_CTL(adr)	get_tsc_mode((adr))
8018c2ecf20Sopenharmony_ci#define SET_TSC_CTL(val)	set_tsc_mode((val))
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_ciextern int get_tsc_mode(unsigned long adr);
8048c2ecf20Sopenharmony_ciextern int set_tsc_mode(unsigned int val);
8058c2ecf20Sopenharmony_ci
8068c2ecf20Sopenharmony_ciDECLARE_PER_CPU(u64, msr_misc_features_shadow);
8078c2ecf20Sopenharmony_ci
8088c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_SUP_AMD
8098c2ecf20Sopenharmony_ciextern u16 amd_get_nb_id(int cpu);
8108c2ecf20Sopenharmony_ciextern u32 amd_get_nodes_per_socket(void);
8118c2ecf20Sopenharmony_ciextern bool cpu_has_ibpb_brtype_microcode(void);
8128c2ecf20Sopenharmony_ciextern void amd_clear_divider(void);
8138c2ecf20Sopenharmony_ci#else
8148c2ecf20Sopenharmony_cistatic inline u16 amd_get_nb_id(int cpu)		{ return 0; }
8158c2ecf20Sopenharmony_cistatic inline u32 amd_get_nodes_per_socket(void)	{ return 0; }
8168c2ecf20Sopenharmony_cistatic inline bool cpu_has_ibpb_brtype_microcode(void)	{ return false; }
8178c2ecf20Sopenharmony_cistatic inline void amd_clear_divider(void)		{ }
8188c2ecf20Sopenharmony_ci#endif
8198c2ecf20Sopenharmony_ci
8208c2ecf20Sopenharmony_cistatic inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
8218c2ecf20Sopenharmony_ci{
8228c2ecf20Sopenharmony_ci	uint32_t base, eax, signature[3];
8238c2ecf20Sopenharmony_ci
8248c2ecf20Sopenharmony_ci	for (base = 0x40000000; base < 0x40010000; base += 0x100) {
8258c2ecf20Sopenharmony_ci		cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_ci		if (!memcmp(sig, signature, 12) &&
8288c2ecf20Sopenharmony_ci		    (leaves == 0 || ((eax - base) >= leaves)))
8298c2ecf20Sopenharmony_ci			return base;
8308c2ecf20Sopenharmony_ci	}
8318c2ecf20Sopenharmony_ci
8328c2ecf20Sopenharmony_ci	return 0;
8338c2ecf20Sopenharmony_ci}
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_ciextern unsigned long arch_align_stack(unsigned long sp);
8368c2ecf20Sopenharmony_civoid free_init_pages(const char *what, unsigned long begin, unsigned long end);
8378c2ecf20Sopenharmony_ciextern void free_kernel_image_pages(const char *what, void *begin, void *end);
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_civoid default_idle(void);
8408c2ecf20Sopenharmony_ci#ifdef	CONFIG_XEN
8418c2ecf20Sopenharmony_cibool xen_set_default_idle(void);
8428c2ecf20Sopenharmony_ci#else
8438c2ecf20Sopenharmony_ci#define xen_set_default_idle 0
8448c2ecf20Sopenharmony_ci#endif
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_civoid __noreturn stop_this_cpu(void *dummy);
8478c2ecf20Sopenharmony_civoid microcode_check(struct cpuinfo_x86 *prev_info);
8488c2ecf20Sopenharmony_civoid store_cpu_caps(struct cpuinfo_x86 *info);
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_cienum l1tf_mitigations {
8518c2ecf20Sopenharmony_ci	L1TF_MITIGATION_OFF,
8528c2ecf20Sopenharmony_ci	L1TF_MITIGATION_FLUSH_NOWARN,
8538c2ecf20Sopenharmony_ci	L1TF_MITIGATION_FLUSH,
8548c2ecf20Sopenharmony_ci	L1TF_MITIGATION_FLUSH_NOSMT,
8558c2ecf20Sopenharmony_ci	L1TF_MITIGATION_FULL,
8568c2ecf20Sopenharmony_ci	L1TF_MITIGATION_FULL_FORCE
8578c2ecf20Sopenharmony_ci};
8588c2ecf20Sopenharmony_ci
8598c2ecf20Sopenharmony_ciextern enum l1tf_mitigations l1tf_mitigation;
8608c2ecf20Sopenharmony_ci
8618c2ecf20Sopenharmony_cienum mds_mitigations {
8628c2ecf20Sopenharmony_ci	MDS_MITIGATION_OFF,
8638c2ecf20Sopenharmony_ci	MDS_MITIGATION_FULL,
8648c2ecf20Sopenharmony_ci	MDS_MITIGATION_VMWERV,
8658c2ecf20Sopenharmony_ci};
8668c2ecf20Sopenharmony_ci
8678c2ecf20Sopenharmony_ciextern bool gds_ucode_mitigated(void);
8688c2ecf20Sopenharmony_ci
8698c2ecf20Sopenharmony_ci#endif /* _ASM_X86_PROCESSOR_H */
870