1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#ifndef _ASM_X86_INVPCID_H_
#define _ASM_X86_INVPCID_H_
#include <xen/types.h>
extern bool use_invpcid;
#define INVPCID_OPCODE ".byte 0x66, 0x0f, 0x38, 0x82\n"
#define MODRM_ECX_01 ".byte 0x01\n"
static inline void invpcid(unsigned int pcid, unsigned long addr,
unsigned int type)
{
struct {
uint64_t pcid:12;
uint64_t reserved:52;
uint64_t addr;
} desc = { .pcid = pcid, .addr = addr };
asm volatile (
#ifdef HAVE_AS_INVPCID
"invpcid %[desc], %q[type]"
: /* No output */
: [desc] "m" (desc), [type] "r" (type)
#else
INVPCID_OPCODE MODRM_ECX_01
: /* No output */
: "a" (type), "c" (&desc)
#endif
: "memory" );
}
/* Flush all mappings for a given PCID and addr, not including globals */
static inline void invpcid_flush_one(unsigned int pcid, unsigned long addr)
{
invpcid(pcid, addr, X86_INVPCID_INDIV_ADDR);
}
/* Flush all mappings for a given PCID, not including globals */
static inline void invpcid_flush_single_context(unsigned int pcid)
{
invpcid(pcid, 0, X86_INVPCID_SINGLE_CTXT);
}
/* Flush all mappings, including globals, for all PCIDs */
static inline void invpcid_flush_all(void)
{
invpcid(0, 0, X86_INVPCID_ALL_INCL_GLOBAL);
}
/* Flush all mappings for all PCIDs, excluding globals */
static inline void invpcid_flush_all_nonglobals(void)
{
invpcid(0, 0, X86_INVPCID_ALL_NON_GLOBAL);
}
#endif /* _ASM_X86_INVPCID_H_ */
/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
|