1 /*
2 * Nested HVM
3 * Copyright (c) 2011, Advanced Micro Devices, Inc.
4 * Author: Christoph Egger <Christoph.Egger@amd.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef _HVM_NESTEDHVM_H
20 #define _HVM_NESTEDHVM_H
21
22 #include <xen/types.h> /* for uintNN_t */
23 #include <xen/sched.h> /* for struct vcpu, struct domain */
24 #include <asm/hvm/vcpu.h> /* for vcpu_nestedhvm */
25
26 enum nestedhvm_vmexits {
27 NESTEDHVM_VMEXIT_ERROR = 0, /* inject VMEXIT w/ invalid VMCB */
28 NESTEDHVM_VMEXIT_FATALERROR = 1, /* crash first level guest */
29 NESTEDHVM_VMEXIT_HOST = 2, /* exit handled on host level */
30 NESTEDHVM_VMEXIT_CONTINUE = 3, /* further handling */
31 NESTEDHVM_VMEXIT_INJECT = 4, /* inject VMEXIT */
32 NESTEDHVM_VMEXIT_DONE = 5, /* VMEXIT handled */
33 };
34
35 /* Nested HVM on/off per domain */
36 bool nestedhvm_enabled(const struct domain *d);
37
38 /* Nested VCPU */
39 int nestedhvm_vcpu_initialise(struct vcpu *v);
40 void nestedhvm_vcpu_destroy(struct vcpu *v);
41 void nestedhvm_vcpu_reset(struct vcpu *v);
42 bool_t nestedhvm_vcpu_in_guestmode(struct vcpu *v);
43 #define nestedhvm_vcpu_enter_guestmode(v) \
44 vcpu_nestedhvm(v).nv_guestmode = 1
45 #define nestedhvm_vcpu_exit_guestmode(v) \
46 vcpu_nestedhvm(v).nv_guestmode = 0
47
48 /* Nested paging */
49 #define NESTEDHVM_PAGEFAULT_DONE 0
50 #define NESTEDHVM_PAGEFAULT_INJECT 1
51 #define NESTEDHVM_PAGEFAULT_L1_ERROR 2
52 #define NESTEDHVM_PAGEFAULT_L0_ERROR 3
53 #define NESTEDHVM_PAGEFAULT_MMIO 4
54 #define NESTEDHVM_PAGEFAULT_RETRY 5
55 #define NESTEDHVM_PAGEFAULT_DIRECT_MMIO 6
56 int nestedhvm_hap_nested_page_fault(struct vcpu *v, paddr_t *L2_gpa,
57 bool_t access_r, bool_t access_w, bool_t access_x);
58
59 int nestedhap_walk_L1_p2m(struct vcpu *v, paddr_t L2_gpa, paddr_t *L1_gpa,
60 unsigned int *page_order, uint8_t *p2m_acc,
61 bool_t access_r, bool_t access_w, bool_t access_x);
62
63 /* IO permission map */
64 unsigned long *nestedhvm_vcpu_iomap_get(bool_t ioport_80, bool_t ioport_ed);
65
66 /* Misc */
67 #define nestedhvm_paging_mode_hap(v) (!!nhvm_vmcx_hap_enabled(v))
68 #define nestedhvm_vmswitch_in_progress(v) \
69 (!!vcpu_nestedhvm((v)).nv_vmswitch_in_progress)
70
71 void nestedhvm_vmcx_flushtlb(struct p2m_domain *p2m);
72
73 bool_t nestedhvm_is_n2(struct vcpu *v);
74
nestedhvm_set_cr(struct vcpu * v,unsigned int cr,unsigned long value)75 static inline void nestedhvm_set_cr(struct vcpu *v, unsigned int cr,
76 unsigned long value)
77 {
78 if ( !nestedhvm_vmswitch_in_progress(v) &&
79 nestedhvm_vcpu_in_guestmode(v) )
80 v->arch.hvm_vcpu.nvcpu.guest_cr[cr] = value;
81 }
82
83 #endif /* _HVM_NESTEDHVM_H */
84