#ifndef _ASM_X86_KAISER_H #define _ASM_X86_KAISER_H #include /* For PCID constants */ /* * This file includes the definitions for the KAISER feature. * KAISER is a counter measure against x86_64 side channel attacks on * the kernel virtual memory. It has a shadow pgd for every process: the * shadow pgd has a minimalistic kernel-set mapped, but includes the whole * user memory. Within a kernel context switch, or when an interrupt is handled, * the pgd is switched to the normal one. When the system switches to user mode, * the shadow pgd is enabled. By this, the virtual memory caches are freed, * and the user may not attack the whole kernel memory. * * A minimalistic kernel mapping holds the parts needed to be mapped in user * mode, such as the entry/exit functions of the user space, or the stacks. */ #define KAISER_SHADOW_PGD_OFFSET 0x1000 #ifdef __ASSEMBLY__ #ifdef CONFIG_PAGE_TABLE_ISOLATION .macro _SWITCH_TO_KERNEL_CR3 reg movq %cr3, \reg andq $(~(X86_CR3_PCID_ASID_MASK | KAISER_SHADOW_PGD_OFFSET)), \reg /* If PCID enabled, set X86_CR3_PCID_NOFLUSH_BIT */ ALTERNATIVE "", "bts $63, \reg", X86_FEATURE_PCID movq \reg, %cr3 .endm .macro _SWITCH_TO_USER_CR3 reg regb /* * regb must be the low byte portion of reg: because we have arranged * for the low byte of the user PCID to serve as the high byte of NOFLUSH * (0x80 for each when PCID is enabled, or 0x00 when PCID and NOFLUSH are * not enabled): so that the one register can update both memory and cr3. */ movq %cr3, \reg orq PER_CPU_VAR(x86_cr3_pcid_user), \reg js 9f /* If PCID enabled, FLUSH this time, reset to NOFLUSH for next time */ movb \regb, PER_CPU_VAR(x86_cr3_pcid_user+7) 9: movq \reg, %cr3 .endm .macro SWITCH_KERNEL_CR3 ALTERNATIVE "jmp 8f", "pushq %rax", X86_FEATURE_KAISER _SWITCH_TO_KERNEL_CR3 %rax popq %rax 8: .endm .macro SWITCH_USER_CR3 ALTERNATIVE "jmp 8f", "pushq %rax", X86_FEATURE_KAISER _SWITCH_TO_USER_CR3 %rax %al popq %rax 8: .endm .macro SWITCH_KERNEL_CR3_NO_STACK ALTERNATIVE "jmp 8f", \ __stringify(movq %rax, PER_CPU_VAR(unsafe_stack_register_backup)), \ X86_FEATURE_KAISER _SWITCH_TO_KERNEL_CR3 %rax movq PER_CPU_VAR(unsafe_stack_register_backup), %rax 8: .endm #else /* CONFIG_PAGE_TABLE_ISOLATION */ .macro SWITCH_KERNEL_CR3 .endm .macro SWITCH_USER_CR3 .endm .macro SWITCH_KERNEL_CR3_NO_STACK .endm #endif /* CONFIG_PAGE_TABLE_ISOLATION */ #else /* __ASSEMBLY__ */ #ifdef CONFIG_PAGE_TABLE_ISOLATION /* * Upon kernel/user mode switch, it may happen that the address * space has to be switched before the registers have been * stored. To change the address space, another register is * needed. A register therefore has to be stored/restored. */ DECLARE_PER_CPU_USER_MAPPED(unsigned long, unsafe_stack_register_backup); DECLARE_PER_CPU(unsigned long, x86_cr3_pcid_user); extern char __per_cpu_user_mapped_start[], __per_cpu_user_mapped_end[]; extern int kaiser_enabled; extern void __init kaiser_check_boottime_disable(void); #else #define kaiser_enabled 0 static inline void __init kaiser_check_boottime_disable(void) {} #endif /* CONFIG_PAGE_TABLE_ISOLATION */ /* * Kaiser function prototypes are needed even when CONFIG_PAGE_TABLE_ISOLATION is not set, * so as to build with tests on kaiser_enabled instead of #ifdefs. */ /** * kaiser_add_mapping - map a virtual memory part to the shadow (user) mapping * @addr: the start address of the range * @size: the size of the range * @flags: The mapping flags of the pages * * The mapping is done on a global scope, so no bigger * synchronization has to be done. the pages have to be * manually unmapped again when they are not needed any longer. */ extern int kaiser_add_mapping(unsigned long addr, unsigned long size, unsigned long flags); /** * kaiser_remove_mapping - unmap a virtual memory part of the shadow mapping * @addr: the start address of the range * @size: the size of the range */ extern void kaiser_remove_mapping(unsigned long start, unsigned long size); /** * kaiser_init - Initialize the shadow mapping * * Most parts of the shadow mapping can be mapped upon boot * time. Only per-process things like the thread stacks * or a new LDT have to be mapped at runtime. These boot- * time mappings are permanent and never unmapped. */ extern void kaiser_init(void); #endif /* __ASSEMBLY */ #endif /* _ASM_X86_KAISER_H */