1ae53fa18SH. Peter Anvin (Intel) /* SPDX-License-Identifier: GPL-2.0-only */ 2ae53fa18SH. Peter Anvin (Intel) #ifndef _ASM_X86_GSSEG_H 3ae53fa18SH. Peter Anvin (Intel) #define _ASM_X86_GSSEG_H 4ae53fa18SH. Peter Anvin (Intel) 5ae53fa18SH. Peter Anvin (Intel) #include <linux/types.h> 6ae53fa18SH. Peter Anvin (Intel) 7ae53fa18SH. Peter Anvin (Intel) #include <asm/asm.h> 8ae53fa18SH. Peter Anvin (Intel) #include <asm/cpufeature.h> 9ae53fa18SH. Peter Anvin (Intel) #include <asm/alternative.h> 10ae53fa18SH. Peter Anvin (Intel) #include <asm/processor.h> 11ae53fa18SH. Peter Anvin (Intel) #include <asm/nops.h> 12ae53fa18SH. Peter Anvin (Intel) 13ae53fa18SH. Peter Anvin (Intel) #ifdef CONFIG_X86_64 14ae53fa18SH. Peter Anvin (Intel) 15ae53fa18SH. Peter Anvin (Intel) extern asmlinkage void asm_load_gs_index(u16 selector); 16ae53fa18SH. Peter Anvin (Intel) 17*92cbbadfSH. Peter Anvin (Intel) /* Replace with "lkgs %di" once binutils support LKGS instruction */ 18*92cbbadfSH. Peter Anvin (Intel) #define LKGS_DI _ASM_BYTES(0xf2,0x0f,0x00,0xf7) 19*92cbbadfSH. Peter Anvin (Intel) native_lkgs(unsigned int selector)20*92cbbadfSH. Peter Anvin (Intel)static inline void native_lkgs(unsigned int selector) 21*92cbbadfSH. Peter Anvin (Intel) { 22*92cbbadfSH. Peter Anvin (Intel) u16 sel = selector; 23*92cbbadfSH. Peter Anvin (Intel) asm_inline volatile("1: " LKGS_DI 24*92cbbadfSH. Peter Anvin (Intel) _ASM_EXTABLE_TYPE_REG(1b, 1b, EX_TYPE_ZERO_REG, %k[sel]) 25*92cbbadfSH. Peter Anvin (Intel) : [sel] "+D" (sel)); 26*92cbbadfSH. Peter Anvin (Intel) } 27*92cbbadfSH. Peter Anvin (Intel) native_load_gs_index(unsigned int selector)28ae53fa18SH. Peter Anvin (Intel)static inline void native_load_gs_index(unsigned int selector) 29ae53fa18SH. Peter Anvin (Intel) { 30*92cbbadfSH. Peter Anvin (Intel) if (cpu_feature_enabled(X86_FEATURE_LKGS)) { 31*92cbbadfSH. Peter Anvin (Intel) native_lkgs(selector); 32*92cbbadfSH. Peter Anvin (Intel) } else { 33ae53fa18SH. Peter Anvin (Intel) unsigned long flags; 34ae53fa18SH. Peter Anvin (Intel) 35ae53fa18SH. Peter Anvin (Intel) local_irq_save(flags); 36ae53fa18SH. Peter Anvin (Intel) asm_load_gs_index(selector); 37ae53fa18SH. Peter Anvin (Intel) local_irq_restore(flags); 38ae53fa18SH. Peter Anvin (Intel) } 39*92cbbadfSH. Peter Anvin (Intel) } 40ae53fa18SH. Peter Anvin (Intel) 41ae53fa18SH. Peter Anvin (Intel) #endif /* CONFIG_X86_64 */ 42ae53fa18SH. Peter Anvin (Intel) lkgs_init(void)43*92cbbadfSH. Peter Anvin (Intel)static inline void __init lkgs_init(void) 44*92cbbadfSH. Peter Anvin (Intel) { 45*92cbbadfSH. Peter Anvin (Intel) #ifdef CONFIG_PARAVIRT_XXL 46*92cbbadfSH. Peter Anvin (Intel) #ifdef CONFIG_X86_64 47*92cbbadfSH. Peter Anvin (Intel) if (cpu_feature_enabled(X86_FEATURE_LKGS)) 48*92cbbadfSH. Peter Anvin (Intel) pv_ops.cpu.load_gs_index = native_lkgs; 49*92cbbadfSH. Peter Anvin (Intel) #endif 50*92cbbadfSH. Peter Anvin (Intel) #endif 51*92cbbadfSH. Peter Anvin (Intel) } 52*92cbbadfSH. Peter Anvin (Intel) 53ae53fa18SH. Peter Anvin (Intel) #ifndef CONFIG_PARAVIRT_XXL 54ae53fa18SH. Peter Anvin (Intel) load_gs_index(unsigned int selector)55ae53fa18SH. Peter Anvin (Intel)static inline void load_gs_index(unsigned int selector) 56ae53fa18SH. Peter Anvin (Intel) { 57ae53fa18SH. Peter Anvin (Intel) #ifdef CONFIG_X86_64 58ae53fa18SH. Peter Anvin (Intel) native_load_gs_index(selector); 59ae53fa18SH. Peter Anvin (Intel) #else 60ae53fa18SH. Peter Anvin (Intel) loadsegment(gs, selector); 61ae53fa18SH. Peter Anvin (Intel) #endif 62ae53fa18SH. Peter Anvin (Intel) } 63ae53fa18SH. Peter Anvin (Intel) 64ae53fa18SH. Peter Anvin (Intel) #endif /* CONFIG_PARAVIRT_XXL */ 65ae53fa18SH. Peter Anvin (Intel) 66ae53fa18SH. Peter Anvin (Intel) #endif /* _ASM_X86_GSSEG_H */ 67