Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/include/asm/hvm/vmx/vmx.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * vmx.h: VMX Architecture related definitions
3
 * Copyright (c) 2004, Intel Corporation.
4
 *
5
 * This program is free software; you can redistribute it and/or modify it
6
 * under the terms and conditions of the GNU General Public License,
7
 * version 2, as published by the Free Software Foundation.
8
 *
9
 * This program is distributed in the hope it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12
 * more details.
13
 *
14
 * You should have received a copy of the GNU General Public License along with
15
 * this program; If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 */
18
#ifndef __ASM_X86_HVM_VMX_VMX_H__
19
#define __ASM_X86_HVM_VMX_VMX_H__
20
21
#include <xen/sched.h>
22
#include <asm/types.h>
23
#include <asm/regs.h>
24
#include <asm/asm_defns.h>
25
#include <asm/processor.h>
26
#include <asm/i387.h>
27
#include <asm/hvm/support.h>
28
#include <asm/hvm/trace.h>
29
#include <asm/hvm/vmx/vmcs.h>
30
31
typedef union {
32
    struct {
33
        u64 r       :   1,  /* bit 0 - Read permission */
34
        w           :   1,  /* bit 1 - Write permission */
35
        x           :   1,  /* bit 2 - Execute permission */
36
        emt         :   3,  /* bits 5:3 - EPT Memory type */
37
        ipat        :   1,  /* bit 6 - Ignore PAT memory type */
38
        sp          :   1,  /* bit 7 - Is this a superpage? */
39
        a           :   1,  /* bit 8 - Access bit */
40
        d           :   1,  /* bit 9 - Dirty bit */
41
        recalc      :   1,  /* bit 10 - Software available 1 */
42
        snp         :   1,  /* bit 11 - VT-d snoop control in shared
43
                               EPT/VT-d usage */
44
        mfn         :   40, /* bits 51:12 - Machine physical frame number */
45
        sa_p2mt     :   6,  /* bits 57:52 - Software available 2 */
46
        access      :   4,  /* bits 61:58 - p2m_access_t */
47
        tm          :   1,  /* bit 62 - VT-d transient-mapping hint in
48
                               shared EPT/VT-d usage */
49
        suppress_ve :   1;  /* bit 63 - suppress #VE */
50
    };
51
    u64 epte;
52
} ept_entry_t;
53
54
typedef struct {
55
    /*use lxe[0] to save result */
56
    ept_entry_t lxe[5];
57
} ept_walk_t;
58
59
typedef enum {
60
    ept_access_n     = 0, /* No access permissions allowed */
61
    ept_access_r     = 1, /* Read only */
62
    ept_access_w     = 2, /* Write only */
63
    ept_access_rw    = 3, /* Read & Write */
64
    ept_access_x     = 4, /* Exec Only */
65
    ept_access_rx    = 5, /* Read & Exec */
66
    ept_access_wx    = 6, /* Write & Exec*/
67
    ept_access_all   = 7, /* Full permissions */
68
} ept_access_t;
69
70
40.8M
#define EPT_TABLE_ORDER         9
71
0
#define EPTE_SUPER_PAGE_MASK    0x80
72
#define EPTE_MFN_MASK           0xffffffffff000ULL
73
#define EPTE_AVAIL1_MASK        0xF00
74
0
#define EPTE_EMT_MASK           0x38
75
0
#define EPTE_IGMT_MASK          0x40
76
#define EPTE_AVAIL1_SHIFT       8
77
#define EPTE_EMT_SHIFT          3
78
#define EPTE_IGMT_SHIFT         6
79
0
#define EPTE_RWX_MASK           0x7
80
0
#define EPTE_FLAG_MASK          0x7f
81
82
#define EPT_EMT_UC              0
83
#define EPT_EMT_WC              1
84
0
#define EPT_EMT_RSV0            2
85
0
#define EPT_EMT_RSV1            3
86
#define EPT_EMT_WT              4
87
#define EPT_EMT_WP              5
88
#define EPT_EMT_WB              6
89
0
#define EPT_EMT_RSV2            7
90
91
#define PI_xAPIC_NDST_MASK      0xFF00
92
93
void vmx_asm_vmexit_handler(struct cpu_user_regs);
94
void vmx_asm_do_vmentry(void);
95
void vmx_intr_assist(void);
96
void noreturn vmx_do_resume(struct vcpu *);
97
void vmx_vlapic_msr_changed(struct vcpu *v);
98
void vmx_realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt);
99
void vmx_realmode(struct cpu_user_regs *regs);
100
void vmx_update_debug_state(struct vcpu *v);
101
void vmx_update_exception_bitmap(struct vcpu *v);
102
void vmx_update_cpu_exec_control(struct vcpu *v);
103
void vmx_update_secondary_exec_control(struct vcpu *v);
104
105
8.28k
#define POSTED_INTR_ON  0
106
4.14k
#define POSTED_INTR_SN  1
107
static inline int pi_test_and_set_pir(int vector, struct pi_desc *pi_desc)
108
4.14k
{
109
4.14k
    return test_and_set_bit(vector, pi_desc->pir);
110
4.14k
}
Unexecuted instantiation: iommu.c:pi_test_and_set_pir
Unexecuted instantiation: p2m-ept.c:pi_test_and_set_pir
Unexecuted instantiation: p2m.c:pi_test_and_set_pir
Unexecuted instantiation: vvmx.c:pi_test_and_set_pir
vmx.c:pi_test_and_set_pir
Line
Count
Source
108
4.14k
{
109
4.14k
    return test_and_set_bit(vector, pi_desc->pir);
110
4.14k
}
Unexecuted instantiation: vmcs.c:pi_test_and_set_pir
Unexecuted instantiation: realmode.c:pi_test_and_set_pir
Unexecuted instantiation: intr.c:pi_test_and_set_pir
Unexecuted instantiation: vlapic.c:pi_test_and_set_pir
Unexecuted instantiation: ioreq.c:pi_test_and_set_pir
Unexecuted instantiation: vpmu_intel.c:pi_test_and_set_pir
Unexecuted instantiation: vpmu.c:pi_test_and_set_pir
Unexecuted instantiation: nested_ept.c:pi_test_and_set_pir
111
112
static inline int pi_test_and_set_on(struct pi_desc *pi_desc)
113
0
{
114
0
    return test_and_set_bit(POSTED_INTR_ON, &pi_desc->control);
115
0
}
Unexecuted instantiation: vpmu.c:pi_test_and_set_on
Unexecuted instantiation: vpmu_intel.c:pi_test_and_set_on
Unexecuted instantiation: ioreq.c:pi_test_and_set_on
Unexecuted instantiation: vlapic.c:pi_test_and_set_on
Unexecuted instantiation: intr.c:pi_test_and_set_on
Unexecuted instantiation: realmode.c:pi_test_and_set_on
Unexecuted instantiation: vmcs.c:pi_test_and_set_on
Unexecuted instantiation: vmx.c:pi_test_and_set_on
Unexecuted instantiation: vvmx.c:pi_test_and_set_on
Unexecuted instantiation: p2m.c:pi_test_and_set_on
Unexecuted instantiation: p2m-ept.c:pi_test_and_set_on
Unexecuted instantiation: nested_ept.c:pi_test_and_set_on
Unexecuted instantiation: iommu.c:pi_test_and_set_on
116
117
static inline void pi_set_on(struct pi_desc *pi_desc)
118
3
{
119
3
    set_bit(POSTED_INTR_ON, &pi_desc->control);
120
3
}
Unexecuted instantiation: iommu.c:pi_set_on
Unexecuted instantiation: nested_ept.c:pi_set_on
Unexecuted instantiation: vpmu.c:pi_set_on
Unexecuted instantiation: vpmu_intel.c:pi_set_on
Unexecuted instantiation: ioreq.c:pi_set_on
Unexecuted instantiation: vlapic.c:pi_set_on
Unexecuted instantiation: intr.c:pi_set_on
Unexecuted instantiation: realmode.c:pi_set_on
Unexecuted instantiation: vmcs.c:pi_set_on
vmx.c:pi_set_on
Line
Count
Source
118
3
{
119
3
    set_bit(POSTED_INTR_ON, &pi_desc->control);
120
3
}
Unexecuted instantiation: vvmx.c:pi_set_on
Unexecuted instantiation: p2m.c:pi_set_on
Unexecuted instantiation: p2m-ept.c:pi_set_on
121
122
static inline int pi_test_and_clear_on(struct pi_desc *pi_desc)
123
7.08M
{
124
7.08M
    return test_and_clear_bit(POSTED_INTR_ON, &pi_desc->control);
125
7.08M
}
Unexecuted instantiation: p2m-ept.c:pi_test_and_clear_on
Unexecuted instantiation: iommu.c:pi_test_and_clear_on
Unexecuted instantiation: vpmu.c:pi_test_and_clear_on
Unexecuted instantiation: vpmu_intel.c:pi_test_and_clear_on
Unexecuted instantiation: ioreq.c:pi_test_and_clear_on
Unexecuted instantiation: vlapic.c:pi_test_and_clear_on
Unexecuted instantiation: intr.c:pi_test_and_clear_on
Unexecuted instantiation: realmode.c:pi_test_and_clear_on
Unexecuted instantiation: vmcs.c:pi_test_and_clear_on
vmx.c:pi_test_and_clear_on
Line
Count
Source
123
7.08M
{
124
7.08M
    return test_and_clear_bit(POSTED_INTR_ON, &pi_desc->control);
125
7.08M
}
Unexecuted instantiation: vvmx.c:pi_test_and_clear_on
Unexecuted instantiation: p2m.c:pi_test_and_clear_on
Unexecuted instantiation: nested_ept.c:pi_test_and_clear_on
126
127
static inline int pi_test_on(struct pi_desc *pi_desc)
128
4.14k
{
129
4.14k
    return pi_desc->on;
130
4.14k
}
Unexecuted instantiation: nested_ept.c:pi_test_on
Unexecuted instantiation: p2m-ept.c:pi_test_on
Unexecuted instantiation: p2m.c:pi_test_on
Unexecuted instantiation: vvmx.c:pi_test_on
vmx.c:pi_test_on
Line
Count
Source
128
4.14k
{
129
4.14k
    return pi_desc->on;
130
4.14k
}
Unexecuted instantiation: vmcs.c:pi_test_on
Unexecuted instantiation: realmode.c:pi_test_on
Unexecuted instantiation: intr.c:pi_test_on
Unexecuted instantiation: vlapic.c:pi_test_on
Unexecuted instantiation: ioreq.c:pi_test_on
Unexecuted instantiation: vpmu_intel.c:pi_test_on
Unexecuted instantiation: vpmu.c:pi_test_on
Unexecuted instantiation: iommu.c:pi_test_on
131
132
static inline unsigned long pi_get_pir(struct pi_desc *pi_desc, int group)
133
16.2k
{
134
16.2k
    return xchg(&pi_desc->pir[group], 0);
135
16.2k
}
Unexecuted instantiation: nested_ept.c:pi_get_pir
Unexecuted instantiation: p2m-ept.c:pi_get_pir
Unexecuted instantiation: p2m.c:pi_get_pir
Unexecuted instantiation: vvmx.c:pi_get_pir
vmx.c:pi_get_pir
Line
Count
Source
133
16.2k
{
134
16.2k
    return xchg(&pi_desc->pir[group], 0);
135
16.2k
}
Unexecuted instantiation: vmcs.c:pi_get_pir
Unexecuted instantiation: realmode.c:pi_get_pir
Unexecuted instantiation: intr.c:pi_get_pir
Unexecuted instantiation: vlapic.c:pi_get_pir
Unexecuted instantiation: ioreq.c:pi_get_pir
Unexecuted instantiation: vpmu_intel.c:pi_get_pir
Unexecuted instantiation: vpmu.c:pi_get_pir
Unexecuted instantiation: iommu.c:pi_get_pir
136
137
static inline int pi_test_sn(struct pi_desc *pi_desc)
138
4.14k
{
139
4.14k
    return pi_desc->sn;
140
4.14k
}
Unexecuted instantiation: nested_ept.c:pi_test_sn
Unexecuted instantiation: p2m-ept.c:pi_test_sn
Unexecuted instantiation: p2m.c:pi_test_sn
Unexecuted instantiation: vvmx.c:pi_test_sn
vmx.c:pi_test_sn
Line
Count
Source
138
4.14k
{
139
4.14k
    return pi_desc->sn;
140
4.14k
}
Unexecuted instantiation: vmcs.c:pi_test_sn
Unexecuted instantiation: realmode.c:pi_test_sn
Unexecuted instantiation: intr.c:pi_test_sn
Unexecuted instantiation: vlapic.c:pi_test_sn
Unexecuted instantiation: ioreq.c:pi_test_sn
Unexecuted instantiation: vpmu_intel.c:pi_test_sn
Unexecuted instantiation: vpmu.c:pi_test_sn
Unexecuted instantiation: iommu.c:pi_test_sn
141
142
static inline void pi_set_sn(struct pi_desc *pi_desc)
143
0
{
144
0
    set_bit(POSTED_INTR_SN, &pi_desc->control);
145
0
}
Unexecuted instantiation: p2m-ept.c:pi_set_sn
Unexecuted instantiation: p2m.c:pi_set_sn
Unexecuted instantiation: vvmx.c:pi_set_sn
Unexecuted instantiation: vmx.c:pi_set_sn
Unexecuted instantiation: vmcs.c:pi_set_sn
Unexecuted instantiation: realmode.c:pi_set_sn
Unexecuted instantiation: intr.c:pi_set_sn
Unexecuted instantiation: vlapic.c:pi_set_sn
Unexecuted instantiation: ioreq.c:pi_set_sn
Unexecuted instantiation: vpmu_intel.c:pi_set_sn
Unexecuted instantiation: vpmu.c:pi_set_sn
Unexecuted instantiation: iommu.c:pi_set_sn
Unexecuted instantiation: nested_ept.c:pi_set_sn
146
147
static inline void pi_clear_sn(struct pi_desc *pi_desc)
148
0
{
149
0
    clear_bit(POSTED_INTR_SN, &pi_desc->control);
150
0
}
Unexecuted instantiation: nested_ept.c:pi_clear_sn
Unexecuted instantiation: p2m-ept.c:pi_clear_sn
Unexecuted instantiation: p2m.c:pi_clear_sn
Unexecuted instantiation: vvmx.c:pi_clear_sn
Unexecuted instantiation: vmx.c:pi_clear_sn
Unexecuted instantiation: vmcs.c:pi_clear_sn
Unexecuted instantiation: realmode.c:pi_clear_sn
Unexecuted instantiation: intr.c:pi_clear_sn
Unexecuted instantiation: vlapic.c:pi_clear_sn
Unexecuted instantiation: ioreq.c:pi_clear_sn
Unexecuted instantiation: vpmu_intel.c:pi_clear_sn
Unexecuted instantiation: vpmu.c:pi_clear_sn
Unexecuted instantiation: iommu.c:pi_clear_sn
151
152
/*
153
 * Exit Reasons
154
 */
155
0
#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
156
157
12
#define EXIT_REASON_EXCEPTION_NMI       0
158
35.5k
#define EXIT_REASON_EXTERNAL_INTERRUPT  1
159
0
#define EXIT_REASON_TRIPLE_FAULT        2
160
0
#define EXIT_REASON_INIT                3
161
0
#define EXIT_REASON_SIPI                4
162
#define EXIT_REASON_IO_SMI              5
163
#define EXIT_REASON_OTHER_SMI           6
164
93.3k
#define EXIT_REASON_PENDING_VIRT_INTR   7
165
0
#define EXIT_REASON_PENDING_VIRT_NMI    8
166
5.18M
#define EXIT_REASON_TASK_SWITCH         9
167
2.66k
#define EXIT_REASON_CPUID               10
168
0
#define EXIT_REASON_GETSEC              11
169
65.4k
#define EXIT_REASON_HLT                 12
170
44
#define EXIT_REASON_INVD                13
171
0
#define EXIT_REASON_INVLPG              14
172
0
#define EXIT_REASON_RDPMC               15
173
0
#define EXIT_REASON_RDTSC               16
174
#define EXIT_REASON_RSM                 17
175
304k
#define EXIT_REASON_VMCALL              18
176
0
#define EXIT_REASON_VMCLEAR             19
177
0
#define EXIT_REASON_VMLAUNCH            20
178
0
#define EXIT_REASON_VMPTRLD             21
179
0
#define EXIT_REASON_VMPTRST             22
180
0
#define EXIT_REASON_VMREAD              23
181
0
#define EXIT_REASON_VMRESUME            24
182
0
#define EXIT_REASON_VMWRITE             25
183
0
#define EXIT_REASON_VMXOFF              26
184
0
#define EXIT_REASON_VMXON               27
185
7.76k
#define EXIT_REASON_CR_ACCESS           28
186
0
#define EXIT_REASON_DR_ACCESS           29
187
20.1k
#define EXIT_REASON_IO_INSTRUCTION      30
188
271
#define EXIT_REASON_MSR_READ            31
189
563
#define EXIT_REASON_MSR_WRITE           32
190
0
#define EXIT_REASON_INVALID_GUEST_STATE 33
191
0
#define EXIT_REASON_MSR_LOADING         34
192
0
#define EXIT_REASON_MWAIT_INSTRUCTION   36
193
0
#define EXIT_REASON_MONITOR_TRAP_FLAG   37
194
0
#define EXIT_REASON_MONITOR_INSTRUCTION 39
195
4.52M
#define EXIT_REASON_PAUSE_INSTRUCTION   40
196
0
#define EXIT_REASON_MCE_DURING_VMENTRY  41
197
0
#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
198
0
#define EXIT_REASON_APIC_ACCESS         44
199
296
#define EXIT_REASON_EOI_INDUCED         45
200
0
#define EXIT_REASON_ACCESS_GDTR_OR_IDTR 46
201
0
#define EXIT_REASON_ACCESS_LDTR_OR_TR   47
202
60.1k
#define EXIT_REASON_EPT_VIOLATION       48
203
3.15k
#define EXIT_REASON_EPT_MISCONFIG       49
204
0
#define EXIT_REASON_INVEPT              50
205
0
#define EXIT_REASON_RDTSCP              51
206
0
#define EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED 52
207
0
#define EXIT_REASON_INVVPID             53
208
44
#define EXIT_REASON_WBINVD              54
209
11
#define EXIT_REASON_XSETBV              55
210
0
#define EXIT_REASON_APIC_WRITE          56
211
0
#define EXIT_REASON_INVPCID             58
212
0
#define EXIT_REASON_VMFUNC              59
213
0
#define EXIT_REASON_PML_FULL            62
214
0
#define EXIT_REASON_XSAVES              63
215
0
#define EXIT_REASON_XRSTORS             64
216
217
/*
218
 * Interruption-information format
219
 */
220
17.8k
#define INTR_INFO_VECTOR_MASK           0xff            /* 7:0 */
221
0
#define INTR_INFO_INTR_TYPE_MASK        0x700           /* 10:8 */
222
0
#define INTR_INFO_DELIVER_CODE_MASK     0x800           /* 11 */
223
#define INTR_INFO_NMI_UNBLOCKED_BY_IRET 0x1000          /* 12 */
224
41.9k
#define INTR_INFO_VALID_MASK            0x80000000      /* 31 */
225
0
#define INTR_INFO_RESVD_BITS_MASK       0x7ffff000
226
227
/*
228
 * Exit Qualifications for MOV for Control Register Access
229
 */
230
 /* 3:0 - control register number (CRn) */
231
2.93k
#define VMX_CONTROL_REG_ACCESS_NUM(eq)  ((eq) & 0xf)
232
 /* 5:4 - access type (CR write, CR read, CLTS, LMSW) */
233
7.76k
#define VMX_CONTROL_REG_ACCESS_TYPE(eq) (((eq) >> 4) & 0x3)
234
2.93k
# define VMX_CONTROL_REG_ACCESS_TYPE_MOV_TO_CR   0
235
0
# define VMX_CONTROL_REG_ACCESS_TYPE_MOV_FROM_CR 1
236
3.79k
# define VMX_CONTROL_REG_ACCESS_TYPE_CLTS        2
237
1.03k
# define VMX_CONTROL_REG_ACCESS_TYPE_LMSW        3
238
 /* 11:8 - general purpose register operand */
239
2.93k
#define VMX_CONTROL_REG_ACCESS_GPR(eq)  (((eq) >> 8) & 0xf)
240
 /* 31:16 - LMSW source data */
241
1.03k
#define VMX_CONTROL_REG_ACCESS_DATA(eq)  ((uint32_t)(eq) >> 16)
242
243
/*
244
 * Access Rights
245
 */
246
#define X86_SEG_AR_SEG_TYPE     0xf        /* 3:0, segment type */
247
#define X86_SEG_AR_DESC_TYPE    (1u << 4)  /* 4, descriptor type */
248
#define X86_SEG_AR_DPL          0x60       /* 6:5, descriptor privilege level */
249
#define X86_SEG_AR_SEG_PRESENT  (1u << 7)  /* 7, segment present */
250
#define X86_SEG_AR_AVL          (1u << 12) /* 12, available for system software */
251
#define X86_SEG_AR_CS_LM_ACTIVE (1u << 13) /* 13, long mode active (CS only) */
252
#define X86_SEG_AR_DEF_OP_SIZE  (1u << 14) /* 14, default operation size */
253
#define X86_SEG_AR_GRANULARITY  (1u << 15) /* 15, granularity */
254
#define X86_SEG_AR_SEG_UNUSABLE (1u << 16) /* 16, segment unusable */
255
256
#define VMCALL_OPCODE   ".byte 0x0f,0x01,0xc1\n"
257
#define VMCLEAR_OPCODE  ".byte 0x66,0x0f,0xc7\n"        /* reg/opcode: /6 */
258
#define VMLAUNCH_OPCODE ".byte 0x0f,0x01,0xc2\n"
259
#define VMPTRLD_OPCODE  ".byte 0x0f,0xc7\n"             /* reg/opcode: /6 */
260
#define VMPTRST_OPCODE  ".byte 0x0f,0xc7\n"             /* reg/opcode: /7 */
261
#define VMREAD_OPCODE   ".byte 0x0f,0x78\n"
262
#define VMRESUME_OPCODE ".byte 0x0f,0x01,0xc3\n"
263
#define VMWRITE_OPCODE  ".byte 0x0f,0x79\n"
264
#define INVEPT_OPCODE   ".byte 0x66,0x0f,0x38,0x80\n"   /* m128,r64/32 */
265
#define INVVPID_OPCODE  ".byte 0x66,0x0f,0x38,0x81\n"   /* m128,r64/32 */
266
#define VMXOFF_OPCODE   ".byte 0x0f,0x01,0xc4\n"
267
#define VMXON_OPCODE    ".byte 0xf3,0x0f,0xc7\n"
268
269
#define MODRM_EAX_08    ".byte 0x08\n" /* ECX, [EAX] */
270
#define MODRM_EAX_06    ".byte 0x30\n" /* [EAX], with reg/opcode: /6 */
271
#define MODRM_EAX_07    ".byte 0x38\n" /* [EAX], with reg/opcode: /7 */
272
#define MODRM_EAX_ECX   ".byte 0xc1\n" /* EAX, ECX */
273
274
extern uint8_t posted_intr_vector;
275
276
#define cpu_has_vmx_ept_exec_only_supported        \
277
0
    (vmx_ept_vpid_cap & VMX_EPT_EXEC_ONLY_SUPPORTED)
278
279
#define cpu_has_vmx_ept_wl4_supported           \
280
    (vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED)
281
#define cpu_has_vmx_ept_mt_uc (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_UC)
282
#define cpu_has_vmx_ept_mt_wb (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_WB)
283
1
#define cpu_has_vmx_ept_2mb   (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_2MB)
284
1
#define cpu_has_vmx_ept_1gb   (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_1GB)
285
1.43M
#define cpu_has_vmx_ept_ad    (vmx_ept_vpid_cap & VMX_EPT_AD_BIT)
286
#define cpu_has_vmx_ept_invept_single_context   \
287
411
    (vmx_ept_vpid_cap & VMX_EPT_INVEPT_SINGLE_CONTEXT)
288
289
1
#define EPT_2MB_SHIFT     16
290
1
#define EPT_1GB_SHIFT     17
291
1
#define ept_has_2mb(c)    ((c >> EPT_2MB_SHIFT) & 1)
292
1
#define ept_has_1gb(c)    ((c >> EPT_1GB_SHIFT) & 1)
293
294
795
#define INVEPT_SINGLE_CONTEXT   1
295
12
#define INVEPT_ALL_CONTEXT      2
296
297
#define cpu_has_vmx_vpid_invvpid_individual_addr                    \
298
    (vmx_ept_vpid_cap & VMX_VPID_INVVPID_INDIVIDUAL_ADDR)
299
#define cpu_has_vmx_vpid_invvpid_single_context                     \
300
0
    (vmx_ept_vpid_cap & VMX_VPID_INVVPID_SINGLE_CONTEXT)
301
#define cpu_has_vmx_vpid_invvpid_single_context_retaining_global    \
302
    (vmx_ept_vpid_cap & VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL)
303
304
0
#define INVVPID_INDIVIDUAL_ADDR                 0
305
0
#define INVVPID_SINGLE_CONTEXT                  1
306
24
#define INVVPID_ALL_CONTEXT                     2
307
#define INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL 3
308
309
#ifdef HAVE_GAS_VMX
310
# define GAS_VMX_OP(yes, no) yes
311
#else
312
# define GAS_VMX_OP(yes, no) no
313
#endif
314
315
static always_inline void __vmptrld(u64 addr)
316
34.7k
{
317
34.7k
    asm volatile (
318
34.7k
#ifdef HAVE_GAS_VMX
319
34.7k
                   "vmptrld %0\n"
320
34.7k
#else
321
                   VMPTRLD_OPCODE MODRM_EAX_06
322
#endif
323
34.7k
                   /* CF==1 or ZF==1 --> BUG() */
324
34.7k
                   UNLIKELY_START(be, vmptrld)
325
34.7k
                   _ASM_BUGFRAME_TEXT(0)
326
34.7k
                   UNLIKELY_END_SECTION
327
34.7k
                   :
328
34.7k
#ifdef HAVE_GAS_VMX
329
34.7k
                   : "m" (addr),
330
34.7k
#else
331
                   : "a" (&addr),
332
#endif
333
34.7k
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
334
34.7k
                   : "memory");
335
34.7k
}
Unexecuted instantiation: nested_ept.c:__vmptrld
Unexecuted instantiation: vpmu.c:__vmptrld
Unexecuted instantiation: vpmu_intel.c:__vmptrld
Unexecuted instantiation: ioreq.c:__vmptrld
Unexecuted instantiation: vlapic.c:__vmptrld
Unexecuted instantiation: intr.c:__vmptrld
Unexecuted instantiation: realmode.c:__vmptrld
Unexecuted instantiation: iommu.c:__vmptrld
vmcs.c:__vmptrld
Line
Count
Source
316
34.7k
{
317
34.7k
    asm volatile (
318
34.7k
#ifdef HAVE_GAS_VMX
319
34.7k
                   "vmptrld %0\n"
320
34.7k
#else
321
                   VMPTRLD_OPCODE MODRM_EAX_06
322
#endif
323
34.7k
                   /* CF==1 or ZF==1 --> BUG() */
324
34.7k
                   UNLIKELY_START(be, vmptrld)
325
34.7k
                   _ASM_BUGFRAME_TEXT(0)
326
34.7k
                   UNLIKELY_END_SECTION
327
34.7k
                   :
328
34.7k
#ifdef HAVE_GAS_VMX
329
34.7k
                   : "m" (addr),
330
34.7k
#else
331
                   : "a" (&addr),
332
#endif
333
34.7k
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
334
34.7k
                   : "memory");
335
34.7k
}
Unexecuted instantiation: vmx.c:__vmptrld
Unexecuted instantiation: vvmx.c:__vmptrld
Unexecuted instantiation: p2m.c:__vmptrld
Unexecuted instantiation: p2m-ept.c:__vmptrld
336
337
static always_inline void __vmpclear(u64 addr)
338
819
{
339
819
    asm volatile (
340
819
#ifdef HAVE_GAS_VMX
341
819
                   "vmclear %0\n"
342
819
#else
343
                   VMCLEAR_OPCODE MODRM_EAX_06
344
#endif
345
819
                   /* CF==1 or ZF==1 --> BUG() */
346
819
                   UNLIKELY_START(be, vmclear)
347
819
                   _ASM_BUGFRAME_TEXT(0)
348
819
                   UNLIKELY_END_SECTION
349
819
                   :
350
819
#ifdef HAVE_GAS_VMX
351
819
                   : "m" (addr),
352
819
#else
353
                   : "a" (&addr),
354
#endif
355
819
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
356
819
                   : "memory");
357
819
}
Unexecuted instantiation: iommu.c:__vmpclear
Unexecuted instantiation: vpmu.c:__vmpclear
Unexecuted instantiation: vpmu_intel.c:__vmpclear
Unexecuted instantiation: ioreq.c:__vmpclear
Unexecuted instantiation: vlapic.c:__vmpclear
Unexecuted instantiation: intr.c:__vmpclear
vmcs.c:__vmpclear
Line
Count
Source
338
819
{
339
819
    asm volatile (
340
819
#ifdef HAVE_GAS_VMX
341
819
                   "vmclear %0\n"
342
819
#else
343
                   VMCLEAR_OPCODE MODRM_EAX_06
344
#endif
345
819
                   /* CF==1 or ZF==1 --> BUG() */
346
819
                   UNLIKELY_START(be, vmclear)
347
819
                   _ASM_BUGFRAME_TEXT(0)
348
819
                   UNLIKELY_END_SECTION
349
819
                   :
350
819
#ifdef HAVE_GAS_VMX
351
819
                   : "m" (addr),
352
819
#else
353
                   : "a" (&addr),
354
#endif
355
819
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
356
819
                   : "memory");
357
819
}
Unexecuted instantiation: vmx.c:__vmpclear
Unexecuted instantiation: vvmx.c:__vmpclear
Unexecuted instantiation: p2m.c:__vmpclear
Unexecuted instantiation: p2m-ept.c:__vmpclear
Unexecuted instantiation: nested_ept.c:__vmpclear
Unexecuted instantiation: realmode.c:__vmpclear
358
359
static always_inline void __vmread(unsigned long field, unsigned long *value)
360
37.0M
{
361
37.0M
    asm volatile (
362
37.0M
#ifdef HAVE_GAS_VMX
363
37.0M
                   "vmread %1, %0\n\t"
364
37.0M
#else
365
                   VMREAD_OPCODE MODRM_EAX_ECX
366
#endif
367
37.0M
                   /* CF==1 or ZF==1 --> BUG() */
368
37.0M
                   UNLIKELY_START(be, vmread)
369
37.0M
                   _ASM_BUGFRAME_TEXT(0)
370
37.0M
                   UNLIKELY_END_SECTION
371
37.0M
#ifdef HAVE_GAS_VMX
372
37.0M
                   : "=rm" (*value)
373
37.0M
                   : "r" (field),
374
37.0M
#else
375
                   : "=c" (*value)
376
                   : "a" (field),
377
#endif
378
37.0M
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
379
37.0M
        );
380
37.0M
}
Unexecuted instantiation: iommu.c:__vmread
Unexecuted instantiation: vpmu.c:__vmread
Unexecuted instantiation: vpmu_intel.c:__vmread
Unexecuted instantiation: ioreq.c:__vmread
Unexecuted instantiation: vlapic.c:__vmread
intr.c:__vmread
Line
Count
Source
360
150k
{
361
150k
    asm volatile (
362
150k
#ifdef HAVE_GAS_VMX
363
150k
                   "vmread %1, %0\n\t"
364
150k
#else
365
                   VMREAD_OPCODE MODRM_EAX_ECX
366
#endif
367
150k
                   /* CF==1 or ZF==1 --> BUG() */
368
150k
                   UNLIKELY_START(be, vmread)
369
150k
                   _ASM_BUGFRAME_TEXT(0)
370
150k
                   UNLIKELY_END_SECTION
371
150k
#ifdef HAVE_GAS_VMX
372
150k
                   : "=rm" (*value)
373
150k
                   : "r" (field),
374
150k
#else
375
                   : "=c" (*value)
376
                   : "a" (field),
377
#endif
378
150k
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
379
150k
        );
380
150k
}
Unexecuted instantiation: realmode.c:__vmread
Unexecuted instantiation: vmcs.c:__vmread
vmx.c:__vmread
Line
Count
Source
360
36.8M
{
361
36.8M
    asm volatile (
362
36.8M
#ifdef HAVE_GAS_VMX
363
36.8M
                   "vmread %1, %0\n\t"
364
36.8M
#else
365
                   VMREAD_OPCODE MODRM_EAX_ECX
366
#endif
367
36.8M
                   /* CF==1 or ZF==1 --> BUG() */
368
36.8M
                   UNLIKELY_START(be, vmread)
369
36.8M
                   _ASM_BUGFRAME_TEXT(0)
370
36.8M
                   UNLIKELY_END_SECTION
371
36.8M
#ifdef HAVE_GAS_VMX
372
36.8M
                   : "=rm" (*value)
373
36.8M
                   : "r" (field),
374
36.8M
#else
375
                   : "=c" (*value)
376
                   : "a" (field),
377
#endif
378
36.8M
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
379
36.8M
        );
380
36.8M
}
Unexecuted instantiation: vvmx.c:__vmread
Unexecuted instantiation: p2m.c:__vmread
Unexecuted instantiation: p2m-ept.c:__vmread
Unexecuted instantiation: nested_ept.c:__vmread
381
382
static always_inline void __vmwrite(unsigned long field, unsigned long value)
383
16.0M
{
384
16.0M
    asm volatile (
385
16.0M
#ifdef HAVE_GAS_VMX
386
16.0M
                   "vmwrite %1, %0\n"
387
16.0M
#else
388
                   VMWRITE_OPCODE MODRM_EAX_ECX
389
#endif
390
16.0M
                   /* CF==1 or ZF==1 --> BUG() */
391
16.0M
                   UNLIKELY_START(be, vmwrite)
392
16.0M
                   _ASM_BUGFRAME_TEXT(0)
393
16.0M
                   UNLIKELY_END_SECTION
394
16.0M
                   :
395
16.0M
#ifdef HAVE_GAS_VMX
396
16.0M
                   : "r" (field) , "rm" (value),
397
16.0M
#else
398
                   : "a" (field) , "c" (value),
399
#endif
400
16.0M
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
401
16.0M
        );
402
16.0M
}
Unexecuted instantiation: vpmu.c:__vmwrite
Unexecuted instantiation: vpmu_intel.c:__vmwrite
Unexecuted instantiation: ioreq.c:__vmwrite
Unexecuted instantiation: vlapic.c:__vmwrite
intr.c:__vmwrite
Line
Count
Source
383
4.21k
{
384
4.21k
    asm volatile (
385
4.21k
#ifdef HAVE_GAS_VMX
386
4.21k
                   "vmwrite %1, %0\n"
387
4.21k
#else
388
                   VMWRITE_OPCODE MODRM_EAX_ECX
389
#endif
390
4.21k
                   /* CF==1 or ZF==1 --> BUG() */
391
4.21k
                   UNLIKELY_START(be, vmwrite)
392
4.21k
                   _ASM_BUGFRAME_TEXT(0)
393
4.21k
                   UNLIKELY_END_SECTION
394
4.21k
                   :
395
4.21k
#ifdef HAVE_GAS_VMX
396
4.21k
                   : "r" (field) , "rm" (value),
397
4.21k
#else
398
                   : "a" (field) , "c" (value),
399
#endif
400
4.21k
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
401
4.21k
        );
402
4.21k
}
Unexecuted instantiation: realmode.c:__vmwrite
vmcs.c:__vmwrite
Line
Count
Source
383
4.20k
{
384
4.20k
    asm volatile (
385
4.20k
#ifdef HAVE_GAS_VMX
386
4.20k
                   "vmwrite %1, %0\n"
387
4.20k
#else
388
                   VMWRITE_OPCODE MODRM_EAX_ECX
389
#endif
390
4.20k
                   /* CF==1 or ZF==1 --> BUG() */
391
4.20k
                   UNLIKELY_START(be, vmwrite)
392
4.20k
                   _ASM_BUGFRAME_TEXT(0)
393
4.20k
                   UNLIKELY_END_SECTION
394
4.20k
                   :
395
4.20k
#ifdef HAVE_GAS_VMX
396
4.20k
                   : "r" (field) , "rm" (value),
397
4.20k
#else
398
                   : "a" (field) , "c" (value),
399
#endif
400
4.20k
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
401
4.20k
        );
402
4.20k
}
vmx.c:__vmwrite
Line
Count
Source
383
15.9M
{
384
15.9M
    asm volatile (
385
15.9M
#ifdef HAVE_GAS_VMX
386
15.9M
                   "vmwrite %1, %0\n"
387
15.9M
#else
388
                   VMWRITE_OPCODE MODRM_EAX_ECX
389
#endif
390
15.9M
                   /* CF==1 or ZF==1 --> BUG() */
391
15.9M
                   UNLIKELY_START(be, vmwrite)
392
15.9M
                   _ASM_BUGFRAME_TEXT(0)
393
15.9M
                   UNLIKELY_END_SECTION
394
15.9M
                   :
395
15.9M
#ifdef HAVE_GAS_VMX
396
15.9M
                   : "r" (field) , "rm" (value),
397
15.9M
#else
398
                   : "a" (field) , "c" (value),
399
#endif
400
15.9M
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
401
15.9M
        );
402
15.9M
}
Unexecuted instantiation: vvmx.c:__vmwrite
Unexecuted instantiation: p2m.c:__vmwrite
Unexecuted instantiation: p2m-ept.c:__vmwrite
Unexecuted instantiation: nested_ept.c:__vmwrite
Unexecuted instantiation: iommu.c:__vmwrite
403
404
static inline enum vmx_insn_errno vmread_safe(unsigned long field,
405
                                              unsigned long *value)
406
0
{
407
0
    unsigned long ret = VMX_INSN_SUCCEED;
408
0
    bool fail_invalid, fail_valid;
409
0
410
0
    asm volatile ( GAS_VMX_OP("vmread %[field], %[value]\n\t",
411
0
                              VMREAD_OPCODE MODRM_EAX_ECX)
412
0
                   ASM_FLAG_OUT(, "setc %[invalid]\n\t")
413
0
                   ASM_FLAG_OUT(, "setz %[valid]\n\t")
414
0
                   : ASM_FLAG_OUT("=@ccc", [invalid] "=rm") (fail_invalid),
415
0
                     ASM_FLAG_OUT("=@ccz", [valid] "=rm") (fail_valid),
416
0
                     [value] GAS_VMX_OP("=rm", "=c") (*value)
417
0
                   : [field] GAS_VMX_OP("r", "a") (field));
418
0
419
0
    if ( unlikely(fail_invalid) )
420
0
        ret = VMX_INSN_FAIL_INVALID;
421
0
    else if ( unlikely(fail_valid) )
422
0
        __vmread(VM_INSTRUCTION_ERROR, &ret);
423
0
424
0
    return ret;
425
0
}
Unexecuted instantiation: vpmu.c:vmread_safe
Unexecuted instantiation: vpmu_intel.c:vmread_safe
Unexecuted instantiation: ioreq.c:vmread_safe
Unexecuted instantiation: vlapic.c:vmread_safe
Unexecuted instantiation: intr.c:vmread_safe
Unexecuted instantiation: realmode.c:vmread_safe
Unexecuted instantiation: vmcs.c:vmread_safe
Unexecuted instantiation: vmx.c:vmread_safe
Unexecuted instantiation: vvmx.c:vmread_safe
Unexecuted instantiation: p2m.c:vmread_safe
Unexecuted instantiation: p2m-ept.c:vmread_safe
Unexecuted instantiation: nested_ept.c:vmread_safe
Unexecuted instantiation: iommu.c:vmread_safe
426
427
static inline enum vmx_insn_errno vmwrite_safe(unsigned long field,
428
                                               unsigned long value)
429
0
{
430
0
    unsigned long ret = VMX_INSN_SUCCEED;
431
0
    bool fail_invalid, fail_valid;
432
0
433
0
    asm volatile ( GAS_VMX_OP("vmwrite %[value], %[field]\n\t",
434
0
                              VMWRITE_OPCODE MODRM_EAX_ECX)
435
0
                   ASM_FLAG_OUT(, "setc %[invalid]\n\t")
436
0
                   ASM_FLAG_OUT(, "setz %[valid]\n\t")
437
0
                   : ASM_FLAG_OUT("=@ccc", [invalid] "=rm") (fail_invalid),
438
0
                     ASM_FLAG_OUT("=@ccz", [valid] "=rm") (fail_valid)
439
0
                   : [field] GAS_VMX_OP("r", "a") (field),
440
0
                     [value] GAS_VMX_OP("rm", "c") (value));
441
0
442
0
    if ( unlikely(fail_invalid) )
443
0
        ret = VMX_INSN_FAIL_INVALID;
444
0
    else if ( unlikely(fail_valid) )
445
0
        __vmread(VM_INSTRUCTION_ERROR, &ret);
446
0
447
0
    return ret;
448
0
}
Unexecuted instantiation: nested_ept.c:vmwrite_safe
Unexecuted instantiation: iommu.c:vmwrite_safe
Unexecuted instantiation: p2m-ept.c:vmwrite_safe
Unexecuted instantiation: p2m.c:vmwrite_safe
Unexecuted instantiation: vvmx.c:vmwrite_safe
Unexecuted instantiation: vmx.c:vmwrite_safe
Unexecuted instantiation: vmcs.c:vmwrite_safe
Unexecuted instantiation: realmode.c:vmwrite_safe
Unexecuted instantiation: intr.c:vmwrite_safe
Unexecuted instantiation: vlapic.c:vmwrite_safe
Unexecuted instantiation: ioreq.c:vmwrite_safe
Unexecuted instantiation: vpmu_intel.c:vmwrite_safe
Unexecuted instantiation: vpmu.c:vmwrite_safe
449
450
static always_inline void __invept(unsigned long type, u64 eptp, u64 gpa)
451
423
{
452
423
    struct {
453
423
        u64 eptp, gpa;
454
423
    } operand = {eptp, gpa};
455
423
456
423
    /*
457
423
     * If single context invalidation is not supported, we escalate to
458
423
     * use all context invalidation.
459
423
     */
460
423
    if ( (type == INVEPT_SINGLE_CONTEXT) &&
461
411
         !cpu_has_vmx_ept_invept_single_context )
462
0
        type = INVEPT_ALL_CONTEXT;
463
423
464
423
    asm volatile (
465
423
#ifdef HAVE_GAS_EPT
466
423
                   "invept %0, %1\n"
467
423
#else
468
                   INVEPT_OPCODE MODRM_EAX_08
469
#endif
470
423
                   /* CF==1 or ZF==1 --> BUG() */
471
423
                   UNLIKELY_START(be, invept)
472
423
                   _ASM_BUGFRAME_TEXT(0)
473
423
                   UNLIKELY_END_SECTION
474
423
                   :
475
423
#ifdef HAVE_GAS_EPT
476
423
                   : "m" (operand), "r" (type),
477
423
#else
478
                   : "a" (&operand), "c" (type),
479
#endif
480
423
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
481
423
                   : "memory" );
482
423
}
Unexecuted instantiation: realmode.c:__invept
Unexecuted instantiation: iommu.c:__invept
Unexecuted instantiation: vpmu.c:__invept
Unexecuted instantiation: vpmu_intel.c:__invept
Unexecuted instantiation: ioreq.c:__invept
Unexecuted instantiation: vlapic.c:__invept
Unexecuted instantiation: intr.c:__invept
Unexecuted instantiation: nested_ept.c:__invept
vmcs.c:__invept
Line
Count
Source
451
12
{
452
12
    struct {
453
12
        u64 eptp, gpa;
454
12
    } operand = {eptp, gpa};
455
12
456
12
    /*
457
12
     * If single context invalidation is not supported, we escalate to
458
12
     * use all context invalidation.
459
12
     */
460
12
    if ( (type == INVEPT_SINGLE_CONTEXT) &&
461
0
         !cpu_has_vmx_ept_invept_single_context )
462
0
        type = INVEPT_ALL_CONTEXT;
463
12
464
12
    asm volatile (
465
12
#ifdef HAVE_GAS_EPT
466
12
                   "invept %0, %1\n"
467
12
#else
468
                   INVEPT_OPCODE MODRM_EAX_08
469
#endif
470
12
                   /* CF==1 or ZF==1 --> BUG() */
471
12
                   UNLIKELY_START(be, invept)
472
12
                   _ASM_BUGFRAME_TEXT(0)
473
12
                   UNLIKELY_END_SECTION
474
12
                   :
475
12
#ifdef HAVE_GAS_EPT
476
12
                   : "m" (operand), "r" (type),
477
12
#else
478
                   : "a" (&operand), "c" (type),
479
#endif
480
12
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
481
12
                   : "memory" );
482
12
}
vmx.c:__invept
Line
Count
Source
451
411
{
452
411
    struct {
453
411
        u64 eptp, gpa;
454
411
    } operand = {eptp, gpa};
455
411
456
411
    /*
457
411
     * If single context invalidation is not supported, we escalate to
458
411
     * use all context invalidation.
459
411
     */
460
411
    if ( (type == INVEPT_SINGLE_CONTEXT) &&
461
411
         !cpu_has_vmx_ept_invept_single_context )
462
0
        type = INVEPT_ALL_CONTEXT;
463
411
464
411
    asm volatile (
465
411
#ifdef HAVE_GAS_EPT
466
411
                   "invept %0, %1\n"
467
411
#else
468
                   INVEPT_OPCODE MODRM_EAX_08
469
#endif
470
411
                   /* CF==1 or ZF==1 --> BUG() */
471
411
                   UNLIKELY_START(be, invept)
472
411
                   _ASM_BUGFRAME_TEXT(0)
473
411
                   UNLIKELY_END_SECTION
474
411
                   :
475
411
#ifdef HAVE_GAS_EPT
476
411
                   : "m" (operand), "r" (type),
477
411
#else
478
                   : "a" (&operand), "c" (type),
479
#endif
480
411
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
481
411
                   : "memory" );
482
411
}
Unexecuted instantiation: vvmx.c:__invept
Unexecuted instantiation: p2m.c:__invept
Unexecuted instantiation: p2m-ept.c:__invept
483
484
static always_inline void __invvpid(unsigned long type, u16 vpid, u64 gva)
485
24
{
486
24
    struct __packed {
487
24
        u64 vpid:16;
488
24
        u64 rsvd:48;
489
24
        u64 gva;
490
24
    }  operand = {vpid, 0, gva};
491
24
492
24
    /* Fix up #UD exceptions which occur when TLBs are flushed before VMXON. */
493
24
    asm volatile ( "1: "
494
24
#ifdef HAVE_GAS_EPT
495
24
                   "invvpid %0, %1\n"
496
24
#else
497
                   INVVPID_OPCODE MODRM_EAX_08
498
#endif
499
24
                   /* CF==1 or ZF==1 --> BUG() */
500
24
                   UNLIKELY_START(be, invvpid)
501
24
                   _ASM_BUGFRAME_TEXT(0)
502
24
                   UNLIKELY_END_SECTION "\n"
503
24
                   "2:"
504
24
                   _ASM_EXTABLE(1b, 2b)
505
24
                   :
506
24
#ifdef HAVE_GAS_EPT
507
24
                   : "m" (operand), "r" (type),
508
24
#else
509
                   : "a" (&operand), "c" (type),
510
#endif
511
24
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
512
24
                   : "memory" );
513
24
}
Unexecuted instantiation: iommu.c:__invvpid
Unexecuted instantiation: vpmu.c:__invvpid
Unexecuted instantiation: vpmu_intel.c:__invvpid
Unexecuted instantiation: ioreq.c:__invvpid
Unexecuted instantiation: vlapic.c:__invvpid
Unexecuted instantiation: intr.c:__invvpid
Unexecuted instantiation: realmode.c:__invvpid
vmcs.c:__invvpid
Line
Count
Source
485
12
{
486
12
    struct __packed {
487
12
        u64 vpid:16;
488
12
        u64 rsvd:48;
489
12
        u64 gva;
490
12
    }  operand = {vpid, 0, gva};
491
12
492
12
    /* Fix up #UD exceptions which occur when TLBs are flushed before VMXON. */
493
12
    asm volatile ( "1: "
494
12
#ifdef HAVE_GAS_EPT
495
12
                   "invvpid %0, %1\n"
496
12
#else
497
                   INVVPID_OPCODE MODRM_EAX_08
498
#endif
499
12
                   /* CF==1 or ZF==1 --> BUG() */
500
12
                   UNLIKELY_START(be, invvpid)
501
12
                   _ASM_BUGFRAME_TEXT(0)
502
12
                   UNLIKELY_END_SECTION "\n"
503
12
                   "2:"
504
12
                   _ASM_EXTABLE(1b, 2b)
505
12
                   :
506
12
#ifdef HAVE_GAS_EPT
507
12
                   : "m" (operand), "r" (type),
508
12
#else
509
                   : "a" (&operand), "c" (type),
510
#endif
511
12
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
512
12
                   : "memory" );
513
12
}
vmx.c:__invvpid
Line
Count
Source
485
12
{
486
12
    struct __packed {
487
12
        u64 vpid:16;
488
12
        u64 rsvd:48;
489
12
        u64 gva;
490
12
    }  operand = {vpid, 0, gva};
491
12
492
12
    /* Fix up #UD exceptions which occur when TLBs are flushed before VMXON. */
493
12
    asm volatile ( "1: "
494
12
#ifdef HAVE_GAS_EPT
495
12
                   "invvpid %0, %1\n"
496
12
#else
497
                   INVVPID_OPCODE MODRM_EAX_08
498
#endif
499
12
                   /* CF==1 or ZF==1 --> BUG() */
500
12
                   UNLIKELY_START(be, invvpid)
501
12
                   _ASM_BUGFRAME_TEXT(0)
502
12
                   UNLIKELY_END_SECTION "\n"
503
12
                   "2:"
504
12
                   _ASM_EXTABLE(1b, 2b)
505
12
                   :
506
12
#ifdef HAVE_GAS_EPT
507
12
                   : "m" (operand), "r" (type),
508
12
#else
509
                   : "a" (&operand), "c" (type),
510
#endif
511
12
                     _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__, __FILE__, 0)
512
12
                   : "memory" );
513
12
}
Unexecuted instantiation: vvmx.c:__invvpid
Unexecuted instantiation: p2m.c:__invvpid
Unexecuted instantiation: p2m-ept.c:__invvpid
Unexecuted instantiation: nested_ept.c:__invvpid
514
515
static inline void ept_sync_all(void)
516
12
{
517
12
    __invept(INVEPT_ALL_CONTEXT, 0, 0);
518
12
}
Unexecuted instantiation: iommu.c:ept_sync_all
Unexecuted instantiation: nested_ept.c:ept_sync_all
Unexecuted instantiation: p2m-ept.c:ept_sync_all
Unexecuted instantiation: p2m.c:ept_sync_all
Unexecuted instantiation: vvmx.c:ept_sync_all
Unexecuted instantiation: vmx.c:ept_sync_all
vmcs.c:ept_sync_all
Line
Count
Source
516
12
{
517
12
    __invept(INVEPT_ALL_CONTEXT, 0, 0);
518
12
}
Unexecuted instantiation: realmode.c:ept_sync_all
Unexecuted instantiation: intr.c:ept_sync_all
Unexecuted instantiation: vlapic.c:ept_sync_all
Unexecuted instantiation: ioreq.c:ept_sync_all
Unexecuted instantiation: vpmu_intel.c:ept_sync_all
Unexecuted instantiation: vpmu.c:ept_sync_all
519
520
void ept_sync_domain(struct p2m_domain *p2m);
521
522
static inline void vpid_sync_vcpu_gva(struct vcpu *v, unsigned long gva)
523
0
{
524
0
    int type = INVVPID_INDIVIDUAL_ADDR;
525
0
526
0
    /*
527
0
     * If individual address invalidation is not supported, we escalate to
528
0
     * use single context invalidation.
529
0
     */
530
0
    if ( likely(cpu_has_vmx_vpid_invvpid_individual_addr) )
531
0
        goto execute_invvpid;
532
0
533
0
    type = INVVPID_SINGLE_CONTEXT;
534
0
535
0
    /*
536
0
     * If single context invalidation is not supported, we escalate to
537
0
     * use all context invalidation.
538
0
     */
539
0
    if ( !cpu_has_vmx_vpid_invvpid_single_context )
540
0
        type = INVVPID_ALL_CONTEXT;
541
0
542
0
execute_invvpid:
543
0
    __invvpid(type, v->arch.hvm_vcpu.n1asid.asid, (u64)gva);
544
0
}
Unexecuted instantiation: vpmu.c:vpid_sync_vcpu_gva
Unexecuted instantiation: p2m-ept.c:vpid_sync_vcpu_gva
Unexecuted instantiation: p2m.c:vpid_sync_vcpu_gva
Unexecuted instantiation: vvmx.c:vpid_sync_vcpu_gva
Unexecuted instantiation: vmx.c:vpid_sync_vcpu_gva
Unexecuted instantiation: vmcs.c:vpid_sync_vcpu_gva
Unexecuted instantiation: realmode.c:vpid_sync_vcpu_gva
Unexecuted instantiation: nested_ept.c:vpid_sync_vcpu_gva
Unexecuted instantiation: intr.c:vpid_sync_vcpu_gva
Unexecuted instantiation: vlapic.c:vpid_sync_vcpu_gva
Unexecuted instantiation: ioreq.c:vpid_sync_vcpu_gva
Unexecuted instantiation: vpmu_intel.c:vpid_sync_vcpu_gva
Unexecuted instantiation: iommu.c:vpid_sync_vcpu_gva
545
546
static inline void vpid_sync_all(void)
547
24
{
548
24
    __invvpid(INVVPID_ALL_CONTEXT, 0, 0);
549
24
}
Unexecuted instantiation: iommu.c:vpid_sync_all
Unexecuted instantiation: vpmu.c:vpid_sync_all
Unexecuted instantiation: vpmu_intel.c:vpid_sync_all
Unexecuted instantiation: ioreq.c:vpid_sync_all
Unexecuted instantiation: vlapic.c:vpid_sync_all
Unexecuted instantiation: intr.c:vpid_sync_all
vmcs.c:vpid_sync_all
Line
Count
Source
547
12
{
548
12
    __invvpid(INVVPID_ALL_CONTEXT, 0, 0);
549
12
}
vmx.c:vpid_sync_all
Line
Count
Source
547
12
{
548
12
    __invvpid(INVVPID_ALL_CONTEXT, 0, 0);
549
12
}
Unexecuted instantiation: vvmx.c:vpid_sync_all
Unexecuted instantiation: p2m.c:vpid_sync_all
Unexecuted instantiation: p2m-ept.c:vpid_sync_all
Unexecuted instantiation: nested_ept.c:vpid_sync_all
Unexecuted instantiation: realmode.c:vpid_sync_all
550
551
static inline void __vmxoff(void)
552
0
{
553
0
    asm volatile (
554
0
        VMXOFF_OPCODE
555
0
        : : : "memory" );
556
0
}
Unexecuted instantiation: vpmu.c:__vmxoff
Unexecuted instantiation: vpmu_intel.c:__vmxoff
Unexecuted instantiation: ioreq.c:__vmxoff
Unexecuted instantiation: vlapic.c:__vmxoff
Unexecuted instantiation: intr.c:__vmxoff
Unexecuted instantiation: realmode.c:__vmxoff
Unexecuted instantiation: vmcs.c:__vmxoff
Unexecuted instantiation: vmx.c:__vmxoff
Unexecuted instantiation: vvmx.c:__vmxoff
Unexecuted instantiation: p2m.c:__vmxoff
Unexecuted instantiation: p2m-ept.c:__vmxoff
Unexecuted instantiation: nested_ept.c:__vmxoff
Unexecuted instantiation: iommu.c:__vmxoff
557
558
static inline int __vmxon(u64 addr)
559
12
{
560
12
    int rc;
561
12
562
12
    asm volatile ( 
563
12
        "1: " VMXON_OPCODE MODRM_EAX_06 "\n"
564
12
        "   setna %b0 ; neg %0\n" /* CF==1 or ZF==1 --> rc = -1 */
565
12
        "2:\n"
566
12
        ".section .fixup,\"ax\"\n"
567
12
        "3: sub $2,%0 ; jmp 2b\n"    /* #UD or #GP --> rc = -2 */
568
12
        ".previous\n"
569
12
        _ASM_EXTABLE(1b, 3b)
570
12
        : "=q" (rc)
571
12
        : "0" (0), "a" (&addr)
572
12
        : "memory");
573
12
574
12
    return rc;
575
12
}
Unexecuted instantiation: iommu.c:__vmxon
Unexecuted instantiation: nested_ept.c:__vmxon
Unexecuted instantiation: p2m-ept.c:__vmxon
Unexecuted instantiation: p2m.c:__vmxon
Unexecuted instantiation: vvmx.c:__vmxon
Unexecuted instantiation: vmx.c:__vmxon
vmcs.c:__vmxon
Line
Count
Source
559
12
{
560
12
    int rc;
561
12
562
12
    asm volatile ( 
563
12
        "1: " VMXON_OPCODE MODRM_EAX_06 "\n"
564
12
        "   setna %b0 ; neg %0\n" /* CF==1 or ZF==1 --> rc = -1 */
565
12
        "2:\n"
566
12
        ".section .fixup,\"ax\"\n"
567
12
        "3: sub $2,%0 ; jmp 2b\n"    /* #UD or #GP --> rc = -2 */
568
12
        ".previous\n"
569
12
        _ASM_EXTABLE(1b, 3b)
570
12
        : "=q" (rc)
571
12
        : "0" (0), "a" (&addr)
572
12
        : "memory");
573
12
574
12
    return rc;
575
12
}
Unexecuted instantiation: realmode.c:__vmxon
Unexecuted instantiation: intr.c:__vmxon
Unexecuted instantiation: vlapic.c:__vmxon
Unexecuted instantiation: ioreq.c:__vmxon
Unexecuted instantiation: vpmu_intel.c:__vmxon
Unexecuted instantiation: vpmu.c:__vmxon
576
577
int vmx_guest_x86_mode(struct vcpu *v);
578
unsigned int vmx_get_cpl(void);
579
580
void vmx_inject_extint(int trap, uint8_t source);
581
void vmx_inject_nmi(void);
582
583
int ept_p2m_init(struct p2m_domain *p2m);
584
void ept_p2m_uninit(struct p2m_domain *p2m);
585
586
void ept_walk_table(struct domain *d, unsigned long gfn);
587
bool_t ept_handle_misconfig(uint64_t gpa);
588
void setup_ept_dump(void);
589
void p2m_init_altp2m_ept(struct domain *d, unsigned int i);
590
/* Locate an alternate p2m by its EPTP */
591
unsigned int p2m_find_altp2m_by_eptp(struct domain *d, uint64_t eptp);
592
593
void update_guest_eip(void);
594
595
int alloc_p2m_hap_data(struct p2m_domain *p2m);
596
void free_p2m_hap_data(struct p2m_domain *p2m);
597
void p2m_init_hap_data(struct p2m_domain *p2m);
598
599
void vmx_pi_per_cpu_init(unsigned int cpu);
600
void vmx_pi_desc_fixup(unsigned int cpu);
601
602
void vmx_pi_hooks_assign(struct domain *d);
603
void vmx_pi_hooks_deassign(struct domain *d);
604
605
0
#define APIC_INVALID_DEST           0xffffffff
606
607
/* EPT violation qualifications definitions */
608
typedef union ept_qual {
609
    unsigned long raw;
610
    struct {
611
        bool read:1, write:1, fetch:1,
612
            eff_read:1, eff_write:1, eff_exec:1, /* eff_user_exec */:1,
613
            gla_valid:1,
614
            gla_fault:1; /* Valid iff gla_valid. */
615
        unsigned long /* pad */:55;
616
    };
617
} __transparent__ ept_qual_t;
618
619
0
#define EPT_L4_PAGETABLE_SHIFT      39
620
7.01M
#define EPT_PAGETABLE_ENTRIES       512
621
622
/* #VE information page */
623
typedef struct {
624
    u32 exit_reason;
625
    u32 semaphore;
626
    u64 exit_qualification;
627
    u64 gla;
628
    u64 gpa;
629
    u16 eptp_index;
630
} ve_info_t;
631
632
/* VM-Exit instruction info for LIDT, LGDT, SIDT, SGDT */
633
typedef union idt_or_gdt_instr_info {
634
    unsigned long raw;
635
    struct {
636
        unsigned long scaling   :2,  /* bits 0:1 - Scaling */
637
                                :5,  /* bits 6:2 - Undefined */
638
        addr_size               :3,  /* bits 9:7 - Address size */
639
                                :1,  /* bit 10 - Cleared to 0 */
640
        operand_size            :1,  /* bit 11 - Operand size */
641
                                :3,  /* bits 14:12 - Undefined */
642
        segment_reg             :3,  /* bits 17:15 - Segment register */
643
        index_reg               :4,  /* bits 21:18 - Index register */
644
        index_reg_invalid       :1,  /* bit 22 - Index register invalid */
645
        base_reg                :4,  /* bits 26:23 - Base register */
646
        base_reg_invalid        :1,  /* bit 27 - Base register invalid */
647
        instr_identity          :1,  /* bit 28 - 0:GDT, 1:IDT */
648
        instr_write             :1,  /* bit 29 - 0:store, 1:load */
649
                                :34; /* bits 30:63 - Undefined */
650
    };
651
} idt_or_gdt_instr_info_t;
652
653
/* VM-Exit instruction info for LLDT, LTR, SLDT, STR */
654
typedef union ldt_or_tr_instr_info {
655
    unsigned long raw;
656
    struct {
657
        unsigned long scaling   :2,  /* bits 0:1 - Scaling */
658
                                :1,  /* bit 2 - Undefined */
659
        reg1                    :4,  /* bits 6:3 - Reg1 */
660
        addr_size               :3,  /* bits 9:7 - Address size */
661
        mem_reg                 :1,  /* bit 10 - Mem/Reg */
662
                                :4,  /* bits 14:11 - Undefined */
663
        segment_reg             :3,  /* bits 17:15 - Segment register */
664
        index_reg               :4,  /* bits 21:18 - Index register */
665
        index_reg_invalid       :1,  /* bit 22 - Index register invalid */
666
        base_reg                :4,  /* bits 26:23 - Base register */
667
        base_reg_invalid        :1,  /* bit 27 - Base register invalid */
668
        instr_identity          :1,  /* bit 28 - 0:LDT, 1:TR */
669
        instr_write             :1,  /* bit 29 - 0:store, 1:load */
670
                                :34; /* bits 31:63 - Undefined */
671
    };
672
} ldt_or_tr_instr_info_t;
673
674
#endif /* __ASM_X86_HVM_VMX_VMX_H__ */