Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */ 2 : #ifndef _ASM_X86_INVPCID 3 : #define _ASM_X86_INVPCID 4 : 5 131 : static inline void __invpcid(unsigned long pcid, unsigned long addr, 6 : unsigned long type) 7 : { 8 131 : struct { u64 d[2]; } desc = { { pcid, addr } }; 9 : 10 : /* 11 : * The memory clobber is because the whole point is to invalidate 12 : * stale TLB entries and, especially if we're flushing global 13 : * mappings, we don't want the compiler to reorder any subsequent 14 : * memory accesses before the TLB flush. 15 : */ 16 131 : asm volatile("invpcid %[desc], %[type]" 17 : :: [desc] "m" (desc), [type] "r" (type) : "memory"); 18 : } 19 : 20 : #define INVPCID_TYPE_INDIV_ADDR 0 21 : #define INVPCID_TYPE_SINGLE_CTXT 1 22 : #define INVPCID_TYPE_ALL_INCL_GLOBAL 2 23 : #define INVPCID_TYPE_ALL_NON_GLOBAL 3 24 : 25 : /* Flush all mappings for a given pcid and addr, not including globals. */ 26 0 : static inline void invpcid_flush_one(unsigned long pcid, 27 : unsigned long addr) 28 : { 29 0 : __invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR); 30 0 : } 31 : 32 : /* Flush all mappings for a given PCID, not including globals. */ 33 : static inline void invpcid_flush_single_context(unsigned long pcid) 34 : { 35 : __invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT); 36 : } 37 : 38 : /* Flush all mappings, including globals, for all PCIDs. */ 39 131 : static inline void invpcid_flush_all(void) 40 : { 41 131 : __invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL); 42 : } 43 : 44 : /* Flush all mappings for all PCIDs except globals. */ 45 : static inline void invpcid_flush_all_nonglobals(void) 46 : { 47 : __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); 48 : } 49 : 50 : #endif /* _ASM_X86_INVPCID */