1 /*
2 * vmcb.c: VMCB management
3 * Copyright (c) 2005-2007, Advanced Micro Devices, Inc.
4 * Copyright (c) 2004, Intel Corporation.
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
20 #include <xen/init.h>
21 #include <xen/lib.h>
22 #include <xen/keyhandler.h>
23 #include <xen/mm.h>
24 #include <xen/rcupdate.h>
25 #include <xen/sched.h>
26 #include <asm/hvm/svm/vmcb.h>
27 #include <asm/msr-index.h>
28 #include <asm/p2m.h>
29 #include <asm/hvm/support.h>
30 #include <asm/hvm/svm/svm.h>
31 #include <asm/hvm/svm/svmdebug.h>
32
alloc_vmcb(void)33 struct vmcb_struct *alloc_vmcb(void)
34 {
35 struct vmcb_struct *vmcb;
36
37 vmcb = alloc_xenheap_page();
38 if ( vmcb == NULL )
39 {
40 printk(XENLOG_WARNING "Warning: failed to allocate vmcb.\n");
41 return NULL;
42 }
43
44 clear_page(vmcb);
45 return vmcb;
46 }
47
free_vmcb(struct vmcb_struct * vmcb)48 void free_vmcb(struct vmcb_struct *vmcb)
49 {
50 free_xenheap_page(vmcb);
51 }
52
53 /* This function can directly access fields which are covered by clean bits. */
construct_vmcb(struct vcpu * v)54 static int construct_vmcb(struct vcpu *v)
55 {
56 struct svm_vcpu *svm = &v->arch.hvm.svm;
57 struct vmcb_struct *vmcb = svm->vmcb;
58
59 vmcb->_general1_intercepts =
60 GENERAL1_INTERCEPT_INTR | GENERAL1_INTERCEPT_NMI |
61 GENERAL1_INTERCEPT_SMI | GENERAL1_INTERCEPT_INIT |
62 GENERAL1_INTERCEPT_CPUID | GENERAL1_INTERCEPT_INVD |
63 GENERAL1_INTERCEPT_HLT | GENERAL1_INTERCEPT_INVLPG |
64 GENERAL1_INTERCEPT_INVLPGA | GENERAL1_INTERCEPT_IOIO_PROT |
65 GENERAL1_INTERCEPT_MSR_PROT | GENERAL1_INTERCEPT_SHUTDOWN_EVT|
66 GENERAL1_INTERCEPT_TASK_SWITCH;
67 vmcb->_general2_intercepts =
68 GENERAL2_INTERCEPT_VMRUN | GENERAL2_INTERCEPT_VMMCALL |
69 GENERAL2_INTERCEPT_VMLOAD | GENERAL2_INTERCEPT_VMSAVE |
70 GENERAL2_INTERCEPT_STGI | GENERAL2_INTERCEPT_CLGI |
71 GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_MWAIT |
72 GENERAL2_INTERCEPT_WBINVD | GENERAL2_INTERCEPT_MONITOR |
73 GENERAL2_INTERCEPT_XSETBV | GENERAL2_INTERCEPT_ICEBP;
74
75 /* Intercept all debug-register writes. */
76 vmcb->_dr_intercepts = ~0u;
77
78 /* Intercept all control-register accesses except for CR2 and CR8. */
79 vmcb->_cr_intercepts = ~(CR_INTERCEPT_CR2_READ |
80 CR_INTERCEPT_CR2_WRITE |
81 CR_INTERCEPT_CR8_READ |
82 CR_INTERCEPT_CR8_WRITE);
83
84 svm->vmcb_sync_state = vmcb_needs_vmload;
85
86 /* I/O and MSR permission bitmaps. */
87 svm->msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE), 0);
88 if ( svm->msrpm == NULL )
89 return -ENOMEM;
90 memset(svm->msrpm, 0xff, MSRPM_SIZE);
91
92 svm_disable_intercept_for_msr(v, MSR_FS_BASE);
93 svm_disable_intercept_for_msr(v, MSR_GS_BASE);
94 svm_disable_intercept_for_msr(v, MSR_SHADOW_GS_BASE);
95 svm_disable_intercept_for_msr(v, MSR_CSTAR);
96 svm_disable_intercept_for_msr(v, MSR_LSTAR);
97 svm_disable_intercept_for_msr(v, MSR_STAR);
98 svm_disable_intercept_for_msr(v, MSR_SYSCALL_MASK);
99
100 vmcb->_msrpm_base_pa = virt_to_maddr(svm->msrpm);
101 vmcb->_iopm_base_pa = __pa(v->domain->arch.hvm.io_bitmap);
102
103 /* Virtualise EFLAGS.IF and LAPIC TPR (CR8). */
104 vmcb->_vintr.fields.intr_masking = 1;
105
106 /* Don't need to intercept RDTSC if CPU supports TSC rate scaling */
107 if ( v->domain->arch.vtsc && !cpu_has_tsc_ratio )
108 {
109 vmcb->_general1_intercepts |= GENERAL1_INTERCEPT_RDTSC;
110 vmcb->_general2_intercepts |= GENERAL2_INTERCEPT_RDTSCP;
111 }
112
113 /* Guest segment limits. */
114 vmcb->cs.limit = ~0u;
115 vmcb->es.limit = ~0u;
116 vmcb->ss.limit = ~0u;
117 vmcb->ds.limit = ~0u;
118 vmcb->fs.limit = ~0u;
119 vmcb->gs.limit = ~0u;
120
121 /* Guest segment AR bytes. */
122 vmcb->es.attr = 0xc93; /* read/write, accessed */
123 vmcb->ss.attr = 0xc93;
124 vmcb->ds.attr = 0xc93;
125 vmcb->fs.attr = 0xc93;
126 vmcb->gs.attr = 0xc93;
127 vmcb->cs.attr = 0xc9b; /* exec/read, accessed */
128
129 /* Guest TSS. */
130 vmcb->tr.attr = 0x08b; /* 32-bit TSS (busy) */
131 vmcb->tr.limit = 0xff;
132
133 v->arch.hvm.guest_cr[0] = X86_CR0_PE | X86_CR0_ET;
134 hvm_update_guest_efer(v);
135 hvm_update_guest_cr(v, 0);
136 hvm_update_guest_cr(v, 4);
137
138 paging_update_paging_modes(v);
139
140 vmcb->_exception_intercepts =
141 HVM_TRAP_MASK |
142 (v->arch.fully_eager_fpu ? 0 : (1U << TRAP_no_device));
143
144 if ( paging_mode_hap(v->domain) )
145 {
146 vmcb->_np_enable = 1; /* enable nested paging */
147 vmcb->_g_pat = MSR_IA32_CR_PAT_RESET; /* guest PAT */
148 vmcb->_h_cr3 = pagetable_get_paddr(
149 p2m_get_pagetable(p2m_get_hostp2m(v->domain)));
150
151 /* No point in intercepting CR3 reads/writes. */
152 vmcb->_cr_intercepts &=
153 ~(CR_INTERCEPT_CR3_READ|CR_INTERCEPT_CR3_WRITE);
154
155 /*
156 * No point in intercepting INVLPG if we don't have shadow pagetables
157 * that need to be fixed up.
158 */
159 vmcb->_general1_intercepts &= ~GENERAL1_INTERCEPT_INVLPG;
160
161 /* PAT is under complete control of SVM when using nested paging. */
162 svm_disable_intercept_for_msr(v, MSR_IA32_CR_PAT);
163 }
164 else
165 {
166 vmcb->_exception_intercepts |= (1U << TRAP_page_fault);
167 }
168
169 if ( cpu_has_pause_filter )
170 {
171 vmcb->_pause_filter_count = SVM_PAUSEFILTER_INIT;
172 vmcb->_general1_intercepts |= GENERAL1_INTERCEPT_PAUSE;
173
174 if ( cpu_has_pause_thresh )
175 vmcb->_pause_filter_thresh = SVM_PAUSETHRESH_INIT;
176 }
177
178 return 0;
179 }
180
svm_create_vmcb(struct vcpu * v)181 int svm_create_vmcb(struct vcpu *v)
182 {
183 struct nestedvcpu *nv = &vcpu_nestedhvm(v);
184 struct svm_vcpu *svm = &v->arch.hvm.svm;
185 int rc;
186
187 if ( (nv->nv_n1vmcx == NULL) &&
188 (nv->nv_n1vmcx = alloc_vmcb()) == NULL )
189 {
190 printk("Failed to create a new VMCB\n");
191 return -ENOMEM;
192 }
193
194 svm->vmcb = nv->nv_n1vmcx;
195 rc = construct_vmcb(v);
196 if ( rc != 0 )
197 {
198 free_vmcb(nv->nv_n1vmcx);
199 nv->nv_n1vmcx = NULL;
200 svm->vmcb = NULL;
201 return rc;
202 }
203
204 svm->vmcb_pa = nv->nv_n1vmcx_pa = virt_to_maddr(svm->vmcb);
205 return 0;
206 }
207
svm_destroy_vmcb(struct vcpu * v)208 void svm_destroy_vmcb(struct vcpu *v)
209 {
210 struct nestedvcpu *nv = &vcpu_nestedhvm(v);
211 struct svm_vcpu *svm = &v->arch.hvm.svm;
212
213 if ( nv->nv_n1vmcx != NULL )
214 free_vmcb(nv->nv_n1vmcx);
215
216 if ( svm->msrpm != NULL )
217 {
218 free_xenheap_pages(
219 svm->msrpm, get_order_from_bytes(MSRPM_SIZE));
220 svm->msrpm = NULL;
221 }
222
223 nv->nv_n1vmcx = NULL;
224 nv->nv_n1vmcx_pa = INVALID_PADDR;
225 svm->vmcb = NULL;
226 }
227
vmcb_dump(unsigned char ch)228 static void vmcb_dump(unsigned char ch)
229 {
230 struct domain *d;
231 struct vcpu *v;
232
233 printk("*********** VMCB Areas **************\n");
234
235 rcu_read_lock(&domlist_read_lock);
236
237 for_each_domain ( d )
238 {
239 if ( !is_hvm_domain(d) )
240 continue;
241 printk("\n>>> Domain %d <<<\n", d->domain_id);
242 for_each_vcpu ( d, v )
243 {
244 printk("\tVCPU %d\n", v->vcpu_id);
245 svm_vmcb_dump("key_handler", v->arch.hvm.svm.vmcb);
246 }
247 }
248
249 rcu_read_unlock(&domlist_read_lock);
250
251 printk("**************************************\n");
252 }
253
setup_vmcb_dump(void)254 void __init setup_vmcb_dump(void)
255 {
256 register_keyhandler('v', vmcb_dump, "dump AMD-V VMCBs", 1);
257 }
258
build_assertions(void)259 static void __init __maybe_unused build_assertions(void)
260 {
261 struct vmcb_struct vmcb;
262
263 /* Build-time check of the VMCB layout. */
264 BUILD_BUG_ON(sizeof(vmcb) != PAGE_SIZE);
265 BUILD_BUG_ON(offsetof(typeof(vmcb), _pause_filter_thresh) != 0x03c);
266 BUILD_BUG_ON(offsetof(typeof(vmcb), _vintr) != 0x060);
267 BUILD_BUG_ON(offsetof(typeof(vmcb), event_inj) != 0x0a8);
268 BUILD_BUG_ON(offsetof(typeof(vmcb), es) != 0x400);
269 BUILD_BUG_ON(offsetof(typeof(vmcb), _cpl) != 0x4cb);
270 BUILD_BUG_ON(offsetof(typeof(vmcb), _cr4) != 0x548);
271 BUILD_BUG_ON(offsetof(typeof(vmcb), rsp) != 0x5d8);
272 BUILD_BUG_ON(offsetof(typeof(vmcb), rax) != 0x5f8);
273 BUILD_BUG_ON(offsetof(typeof(vmcb), _g_pat) != 0x668);
274
275 /* Check struct segment_register against the VMCB segment layout. */
276 BUILD_BUG_ON(sizeof(vmcb.es) != 16);
277 BUILD_BUG_ON(sizeof(vmcb.es.sel) != 2);
278 BUILD_BUG_ON(sizeof(vmcb.es.attr) != 2);
279 BUILD_BUG_ON(sizeof(vmcb.es.limit) != 4);
280 BUILD_BUG_ON(sizeof(vmcb.es.base) != 8);
281 BUILD_BUG_ON(offsetof(typeof(vmcb.es), sel) != 0);
282 BUILD_BUG_ON(offsetof(typeof(vmcb.es), attr) != 2);
283 BUILD_BUG_ON(offsetof(typeof(vmcb.es), limit) != 4);
284 BUILD_BUG_ON(offsetof(typeof(vmcb.es), base) != 8);
285 }
286
287 /*
288 * Local variables:
289 * mode: C
290 * c-file-style: "BSD"
291 * c-basic-offset: 4
292 * tab-width: 4
293 * indent-tabs-mode: nil
294 * End:
295 */
296