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