xref: /openbmc/linux/arch/x86/include/asm/invpcid.h (revision 7e32a9da)
11a3b0caeSPeter Zijlstra /* SPDX-License-Identifier: GPL-2.0 */
21a3b0caeSPeter Zijlstra #ifndef _ASM_X86_INVPCID
31a3b0caeSPeter Zijlstra #define _ASM_X86_INVPCID
41a3b0caeSPeter Zijlstra 
__invpcid(unsigned long pcid,unsigned long addr,unsigned long type)51a3b0caeSPeter Zijlstra static inline void __invpcid(unsigned long pcid, unsigned long addr,
61a3b0caeSPeter Zijlstra 			     unsigned long type)
71a3b0caeSPeter Zijlstra {
81a3b0caeSPeter Zijlstra 	struct { u64 d[2]; } desc = { { pcid, addr } };
91a3b0caeSPeter Zijlstra 
101a3b0caeSPeter Zijlstra 	/*
111a3b0caeSPeter Zijlstra 	 * The memory clobber is because the whole point is to invalidate
121a3b0caeSPeter Zijlstra 	 * stale TLB entries and, especially if we're flushing global
131a3b0caeSPeter Zijlstra 	 * mappings, we don't want the compiler to reorder any subsequent
141a3b0caeSPeter Zijlstra 	 * memory accesses before the TLB flush.
151a3b0caeSPeter Zijlstra 	 */
167e32a9daSUros Bizjak 	asm volatile("invpcid %[desc], %[type]"
177e32a9daSUros Bizjak 		     :: [desc] "m" (desc), [type] "r" (type) : "memory");
181a3b0caeSPeter Zijlstra }
191a3b0caeSPeter Zijlstra 
201a3b0caeSPeter Zijlstra #define INVPCID_TYPE_INDIV_ADDR		0
211a3b0caeSPeter Zijlstra #define INVPCID_TYPE_SINGLE_CTXT	1
221a3b0caeSPeter Zijlstra #define INVPCID_TYPE_ALL_INCL_GLOBAL	2
231a3b0caeSPeter Zijlstra #define INVPCID_TYPE_ALL_NON_GLOBAL	3
241a3b0caeSPeter Zijlstra 
251a3b0caeSPeter Zijlstra /* Flush all mappings for a given pcid and addr, not including globals. */
invpcid_flush_one(unsigned long pcid,unsigned long addr)261a3b0caeSPeter Zijlstra static inline void invpcid_flush_one(unsigned long pcid,
271a3b0caeSPeter Zijlstra 				     unsigned long addr)
281a3b0caeSPeter Zijlstra {
291a3b0caeSPeter Zijlstra 	__invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR);
301a3b0caeSPeter Zijlstra }
311a3b0caeSPeter Zijlstra 
321a3b0caeSPeter Zijlstra /* Flush all mappings for a given PCID, not including globals. */
invpcid_flush_single_context(unsigned long pcid)331a3b0caeSPeter Zijlstra static inline void invpcid_flush_single_context(unsigned long pcid)
341a3b0caeSPeter Zijlstra {
351a3b0caeSPeter Zijlstra 	__invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT);
361a3b0caeSPeter Zijlstra }
371a3b0caeSPeter Zijlstra 
381a3b0caeSPeter Zijlstra /* Flush all mappings, including globals, for all PCIDs. */
invpcid_flush_all(void)391a3b0caeSPeter Zijlstra static inline void invpcid_flush_all(void)
401a3b0caeSPeter Zijlstra {
411a3b0caeSPeter Zijlstra 	__invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL);
421a3b0caeSPeter Zijlstra }
431a3b0caeSPeter Zijlstra 
441a3b0caeSPeter Zijlstra /* Flush all mappings for all PCIDs except globals. */
invpcid_flush_all_nonglobals(void)451a3b0caeSPeter Zijlstra static inline void invpcid_flush_all_nonglobals(void)
461a3b0caeSPeter Zijlstra {
471a3b0caeSPeter Zijlstra 	__invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL);
481a3b0caeSPeter Zijlstra }
491a3b0caeSPeter Zijlstra 
501a3b0caeSPeter Zijlstra #endif /* _ASM_X86_INVPCID */
51