Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/include/asm/hvm/vmx/vvmx.h
Line
Count
Source (jump to first uncovered line)
1
2
/*
3
 * vvmx.h: Support virtual VMX for nested virtualization.
4
 *
5
 * Copyright (c) 2010, Intel Corporation.
6
 * Author: Qing He <qing.he@intel.com>
7
 *         Eddie Dong <eddie.dong@intel.com>
8
 *
9
 * This program is free software; you can redistribute it and/or modify it
10
 * under the terms and conditions of the GNU General Public License,
11
 * version 2, as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope it will be useful, but WITHOUT
14
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16
 * more details.
17
 *
18
 * You should have received a copy of the GNU General Public License along with
19
 * this program; If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
#ifndef __ASM_X86_HVM_VVMX_H__
23
#define __ASM_X86_HVM_VVMX_H__
24
25
struct vvmcs_list {
26
    unsigned long vvmcs_mfn;
27
    struct list_head node;
28
};
29
30
struct nestedvmx {
31
    /*
32
     * vmxon_region_pa is also used to indicate whether a vcpu is in
33
     * the VMX operation. When a vcpu is out of the VMX operation, its
34
     * vmxon_region_pa is set to an invalid address INVALID_PADDR. We
35
     * cannot use 0 for this purpose, because it's a valid VMXON region
36
     * address.
37
     */
38
    paddr_t    vmxon_region_pa;
39
    void       *iobitmap[2];    /* map (va) of L1 guest I/O bitmap */
40
    void       *msrbitmap;    /* map (va) of L1 guest MSR bitmap */
41
    /* deferred nested interrupt */
42
    struct {
43
        unsigned long intr_info;
44
        u32           error_code;
45
        u8            source;
46
    } intr;
47
    struct {
48
        bool_t   enabled;
49
        uint32_t exit_reason;
50
        uint32_t exit_qual;
51
    } ept;
52
    uint32_t guest_vpid;
53
    struct list_head launched_list;
54
};
55
56
0
#define vcpu_2_nvmx(v)  (vcpu_nestedhvm(v).u.nvmx)
57
58
/* bit 1, 2, 4 must be 1 */
59
#define VMX_PINBASED_CTLS_DEFAULT1  0x16
60
/* bit 1, 4-6,8,13-16,26 must be 1 */
61
0
#define VMX_PROCBASED_CTLS_DEFAULT1 0x401e172
62
/* bit 0-8, 10,11,13,14,16,17 must be 1 */
63
#define VMX_EXIT_CTLS_DEFAULT1    0x36dff
64
/* bit 0-8, and 12 must be 1 */
65
#define VMX_ENTRY_CTLS_DEFAULT1   0x11ff
66
67
/*
68
 * Encode of VMX instructions base on Table 24-11 & 24-12 of SDM 3B
69
 */
70
71
enum vmx_regs_enc {
72
    VMX_REG_RAX,
73
    VMX_REG_RCX,
74
    VMX_REG_RDX,
75
    VMX_REG_RBX,
76
    VMX_REG_RSP,
77
    VMX_REG_RBP,
78
    VMX_REG_RSI,
79
    VMX_REG_RDI,
80
    VMX_REG_R8,
81
    VMX_REG_R9,
82
    VMX_REG_R10,
83
    VMX_REG_R11,
84
    VMX_REG_R12,
85
    VMX_REG_R13,
86
    VMX_REG_R14,
87
    VMX_REG_R15,
88
};
89
90
union vmx_inst_info {
91
    struct {
92
        unsigned int scaling           :2; /* bit 0-1 */
93
        unsigned int __rsvd0           :1; /* bit 2 */
94
        unsigned int reg1              :4; /* bit 3-6 */
95
        unsigned int addr_size         :3; /* bit 7-9 */
96
        unsigned int memreg            :1; /* bit 10 */
97
        unsigned int __rsvd1           :4; /* bit 11-14 */
98
        unsigned int segment           :3; /* bit 15-17 */
99
        unsigned int index_reg         :4; /* bit 18-21 */
100
        unsigned int index_reg_invalid :1; /* bit 22 */
101
        unsigned int base_reg          :4; /* bit 23-26 */
102
        unsigned int base_reg_invalid  :1; /* bit 27 */
103
        unsigned int reg2              :4; /* bit 28-31 */
104
    } fields;
105
    u32 word;
106
};
107
108
int nvmx_vcpu_initialise(struct vcpu *v);
109
void nvmx_vcpu_destroy(struct vcpu *v);
110
int nvmx_vcpu_reset(struct vcpu *v);
111
uint64_t nvmx_vcpu_eptp_base(struct vcpu *v);
112
enum hvm_intblk nvmx_intr_blocked(struct vcpu *v);
113
bool_t nvmx_intercepts_exception(
114
    struct vcpu *v, unsigned int vector, int error_code);
115
void nvmx_domain_relinquish_resources(struct domain *d);
116
117
bool_t nvmx_ept_enabled(struct vcpu *v);
118
119
int nvmx_handle_vmxon(struct cpu_user_regs *regs);
120
int nvmx_handle_vmxoff(struct cpu_user_regs *regs);
121
122
0
#define EPT_TRANSLATE_SUCCEED       0
123
0
#define EPT_TRANSLATE_VIOLATION     1
124
0
#define EPT_TRANSLATE_MISCONFIG     2
125
0
#define EPT_TRANSLATE_RETRY         3
126
127
int
128
nvmx_hap_walk_L1_p2m(struct vcpu *v, paddr_t L2_gpa, paddr_t *L1_gpa,
129
                     unsigned int *page_order, uint8_t *p2m_acc,
130
                     bool_t access_r, bool_t access_w, bool_t access_x);
131
/*
132
 * Virtual VMCS layout
133
 *
134
 * Since physical VMCS layout is unknown, a custom layout is used
135
 * for virtual VMCS seen by guest. It occupies a 4k page, and the
136
 * field is offset by an 9-bit offset into u64[], The offset is as
137
 * follow, which means every <width, type> pair has a max of 32
138
 * fields available.
139
 *
140
 *             9       7      5               0
141
 *             --------------------------------
142
 *     offset: | width | type |     index     |
143
 *             --------------------------------
144
 *
145
 * Also, since the lower range <width=0, type={0,1}> has only one
146
 * field: VPID, it is moved to a higher offset (63), and leaves the
147
 * lower range to non-indexed field like VMCS revision.
148
 *
149
 */
150
151
struct vvmcs_header {
152
    u32 revision;
153
    u32 abort;
154
};
155
156
union vmcs_encoding {
157
    struct {
158
        u32 access_type : 1;
159
        u32 index : 9;
160
        u32 type : 2;
161
        u32 rsv1 : 1;
162
        u32 width : 2;
163
        u32 rsv2 : 17;
164
    };
165
    u32 word;
166
};
167
168
enum vvmcs_encoding_width {
169
    VVMCS_WIDTH_16 = 0,
170
    VVMCS_WIDTH_64,
171
    VVMCS_WIDTH_32,
172
    VVMCS_WIDTH_NATURAL,
173
};
174
175
enum vvmcs_encoding_type {
176
    VVMCS_TYPE_CONTROL = 0,
177
    VVMCS_TYPE_RO,
178
    VVMCS_TYPE_GSTATE,
179
    VVMCS_TYPE_HSTATE,
180
};
181
182
u64 get_vvmcs_virtual(void *vvmcs, u32 encoding);
183
u64 get_vvmcs_real(const struct vcpu *, u32 encoding);
184
void set_vvmcs_virtual(void *vvmcs, u32 encoding, u64 val);
185
void set_vvmcs_real(const struct vcpu *, u32 encoding, u64 val);
186
enum vmx_insn_errno get_vvmcs_virtual_safe(void *vvmcs, u32 encoding, u64 *val);
187
enum vmx_insn_errno get_vvmcs_real_safe(const struct vcpu *, u32 encoding,
188
                                        u64 *val);
189
enum vmx_insn_errno set_vvmcs_virtual_safe(void *vvmcs, u32 encoding, u64 val);
190
enum vmx_insn_errno set_vvmcs_real_safe(const struct vcpu *, u32 encoding,
191
                                        u64 val);
192
193
#define get_vvmcs(vcpu, encoding) \
194
0
  (cpu_has_vmx_vmcs_shadowing ? \
195
0
   get_vvmcs_real(vcpu, encoding) : \
196
0
   get_vvmcs_virtual(vcpu_nestedhvm(vcpu).nv_vvmcx, encoding))
197
198
#define set_vvmcs(vcpu, encoding, val) \
199
0
  (cpu_has_vmx_vmcs_shadowing ? \
200
0
   set_vvmcs_real(vcpu, encoding, val) : \
201
0
   set_vvmcs_virtual(vcpu_nestedhvm(vcpu).nv_vvmcx, encoding, val))
202
203
#define get_vvmcs_safe(vcpu, encoding, val) \
204
0
  (cpu_has_vmx_vmcs_shadowing ? \
205
0
   get_vvmcs_real_safe(vcpu, encoding, val) : \
206
0
   get_vvmcs_virtual_safe(vcpu_nestedhvm(vcpu).nv_vvmcx, encoding, val))
207
208
#define set_vvmcs_safe(vcpu, encoding, val) \
209
0
  (cpu_has_vmx_vmcs_shadowing ? \
210
0
   set_vvmcs_real_safe(vcpu, encoding, val) : \
211
0
   set_vvmcs_virtual_safe(vcpu_nestedhvm(vcpu).nv_vvmcx, encoding, val))
212
213
uint64_t get_shadow_eptp(struct vcpu *v);
214
215
void nvmx_destroy_vmcs(struct vcpu *v);
216
int nvmx_handle_vmptrld(struct cpu_user_regs *regs);
217
int nvmx_handle_vmptrst(struct cpu_user_regs *regs);
218
int nvmx_handle_vmclear(struct cpu_user_regs *regs);
219
int nvmx_handle_vmread(struct cpu_user_regs *regs);
220
int nvmx_handle_vmwrite(struct cpu_user_regs *regs);
221
int nvmx_handle_vmresume(struct cpu_user_regs *regs);
222
int nvmx_handle_vmlaunch(struct cpu_user_regs *regs);
223
int nvmx_handle_invept(struct cpu_user_regs *regs);
224
int nvmx_handle_invvpid(struct cpu_user_regs *regs);
225
int nvmx_msr_read_intercept(unsigned int msr,
226
                                u64 *msr_content);
227
228
void nvmx_update_exec_control(struct vcpu *v, u32 value);
229
void nvmx_update_secondary_exec_control(struct vcpu *v,
230
                                        unsigned long value);
231
void nvmx_update_exception_bitmap(struct vcpu *v, unsigned long value);
232
void nvmx_switch_guest(void);
233
void nvmx_idtv_handling(void);
234
u64 nvmx_get_tsc_offset(struct vcpu *v);
235
int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs,
236
                          unsigned int exit_reason);
237
void nvmx_set_cr_read_shadow(struct vcpu *v, unsigned int cr);
238
239
uint64_t nept_get_ept_vpid_cap(void);
240
241
int nept_translate_l2ga(struct vcpu *v, paddr_t l2ga,
242
                        unsigned int *page_order, uint32_t rwx_acc,
243
                        unsigned long *l1gfn, uint8_t *p2m_acc,
244
                        uint64_t *exit_qual, uint32_t *exit_reason);
245
int nvmx_cpu_up_prepare(unsigned int cpu);
246
void nvmx_cpu_dead(unsigned int cpu);
247
#endif /* __ASM_X86_HVM_VVMX_H__ */
248