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 arch_svm_struct *arch_svm = &v->arch.hvm_svm;
57 struct vmcb_struct *vmcb = arch_svm->vmcb;
58
59 /* Build-time check of the size of VMCB AMD structure. */
60 BUILD_BUG_ON(sizeof(*vmcb) != PAGE_SIZE);
61
62 vmcb->_general1_intercepts =
63 GENERAL1_INTERCEPT_INTR | GENERAL1_INTERCEPT_NMI |
64 GENERAL1_INTERCEPT_SMI | GENERAL1_INTERCEPT_INIT |
65 GENERAL1_INTERCEPT_CPUID | GENERAL1_INTERCEPT_INVD |
66 GENERAL1_INTERCEPT_HLT | GENERAL1_INTERCEPT_INVLPG |
67 GENERAL1_INTERCEPT_INVLPGA | GENERAL1_INTERCEPT_IOIO_PROT |
68 GENERAL1_INTERCEPT_MSR_PROT | GENERAL1_INTERCEPT_SHUTDOWN_EVT|
69 GENERAL1_INTERCEPT_TASK_SWITCH;
70 vmcb->_general2_intercepts =
71 GENERAL2_INTERCEPT_VMRUN | GENERAL2_INTERCEPT_VMMCALL |
72 GENERAL2_INTERCEPT_VMLOAD | GENERAL2_INTERCEPT_VMSAVE |
73 GENERAL2_INTERCEPT_STGI | GENERAL2_INTERCEPT_CLGI |
74 GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_MWAIT |
75 GENERAL2_INTERCEPT_WBINVD | GENERAL2_INTERCEPT_MONITOR |
76 GENERAL2_INTERCEPT_XSETBV;
77
78 /* Intercept all debug-register writes. */
79 vmcb->_dr_intercepts = ~0u;
80
81 /* Intercept all control-register accesses except for CR2 and CR8. */
82 vmcb->_cr_intercepts = ~(CR_INTERCEPT_CR2_READ |
83 CR_INTERCEPT_CR2_WRITE |
84 CR_INTERCEPT_CR8_READ |
85 CR_INTERCEPT_CR8_WRITE);
86
87 /* I/O and MSR permission bitmaps. */
88 arch_svm->msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE), 0);
89 if ( arch_svm->msrpm == NULL )
90 return -ENOMEM;
91 memset(arch_svm->msrpm, 0xff, MSRPM_SIZE);
92
93 svm_disable_intercept_for_msr(v, MSR_FS_BASE);
94 svm_disable_intercept_for_msr(v, MSR_GS_BASE);
95 svm_disable_intercept_for_msr(v, MSR_SHADOW_GS_BASE);
96 svm_disable_intercept_for_msr(v, MSR_CSTAR);
97 svm_disable_intercept_for_msr(v, MSR_LSTAR);
98 svm_disable_intercept_for_msr(v, MSR_STAR);
99 svm_disable_intercept_for_msr(v, MSR_SYSCALL_MASK);
100
101 /* LWP_CBADDR MSR is saved and restored by FPU code. So SVM doesn't need to
102 * intercept it. */
103 if ( cpu_has_lwp )
104 svm_disable_intercept_for_msr(v, MSR_AMD64_LWP_CBADDR);
105
106 vmcb->_msrpm_base_pa = (u64)virt_to_maddr(arch_svm->msrpm);
107 vmcb->_iopm_base_pa = __pa(v->domain->arch.hvm_domain.io_bitmap);
108
109 /* Virtualise EFLAGS.IF and LAPIC TPR (CR8). */
110 vmcb->_vintr.fields.intr_masking = 1;
111
112 /* Initialise event injection to no-op. */
113 vmcb->eventinj.bytes = 0;
114
115 /* TSC. */
116 vmcb->_tsc_offset = 0;
117
118 /* Don't need to intercept RDTSC if CPU supports TSC rate scaling */
119 if ( v->domain->arch.vtsc && !cpu_has_tsc_ratio )
120 {
121 vmcb->_general1_intercepts |= GENERAL1_INTERCEPT_RDTSC;
122 vmcb->_general2_intercepts |= GENERAL2_INTERCEPT_RDTSCP;
123 }
124
125 /* Guest EFER. */
126 v->arch.hvm_vcpu.guest_efer = 0;
127 hvm_update_guest_efer(v);
128
129 /* Guest segment limits. */
130 vmcb->cs.limit = ~0u;
131 vmcb->es.limit = ~0u;
132 vmcb->ss.limit = ~0u;
133 vmcb->ds.limit = ~0u;
134 vmcb->fs.limit = ~0u;
135 vmcb->gs.limit = ~0u;
136
137 /* Guest segment bases. */
138 vmcb->cs.base = 0;
139 vmcb->es.base = 0;
140 vmcb->ss.base = 0;
141 vmcb->ds.base = 0;
142 vmcb->fs.base = 0;
143 vmcb->gs.base = 0;
144
145 /* Guest segment AR bytes. */
146 vmcb->es.attr = 0xc93; /* read/write, accessed */
147 vmcb->ss.attr = 0xc93;
148 vmcb->ds.attr = 0xc93;
149 vmcb->fs.attr = 0xc93;
150 vmcb->gs.attr = 0xc93;
151 vmcb->cs.attr = 0xc9b; /* exec/read, accessed */
152
153 /* Guest IDT. */
154 vmcb->idtr.base = 0;
155 vmcb->idtr.limit = 0;
156
157 /* Guest GDT. */
158 vmcb->gdtr.base = 0;
159 vmcb->gdtr.limit = 0;
160
161 /* Guest LDT. */
162 vmcb->ldtr.sel = 0;
163 vmcb->ldtr.base = 0;
164 vmcb->ldtr.limit = 0;
165 vmcb->ldtr.attr = 0;
166
167 /* Guest TSS. */
168 vmcb->tr.attr = 0x08b; /* 32-bit TSS (busy) */
169 vmcb->tr.base = 0;
170 vmcb->tr.limit = 0xff;
171
172 v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_PE | X86_CR0_ET;
173 hvm_update_guest_cr(v, 0);
174
175 v->arch.hvm_vcpu.guest_cr[4] = 0;
176 hvm_update_guest_cr(v, 4);
177
178 paging_update_paging_modes(v);
179
180 vmcb->_exception_intercepts =
181 HVM_TRAP_MASK
182 | (1U << TRAP_no_device);
183
184 if ( paging_mode_hap(v->domain) )
185 {
186 vmcb->_np_enable = 1; /* enable nested paging */
187 vmcb->_g_pat = MSR_IA32_CR_PAT_RESET; /* guest PAT */
188 vmcb->_h_cr3 = pagetable_get_paddr(
189 p2m_get_pagetable(p2m_get_hostp2m(v->domain)));
190
191 /* No point in intercepting CR3 reads/writes. */
192 vmcb->_cr_intercepts &=
193 ~(CR_INTERCEPT_CR3_READ|CR_INTERCEPT_CR3_WRITE);
194
195 /*
196 * No point in intercepting INVLPG if we don't have shadow pagetables
197 * that need to be fixed up.
198 */
199 vmcb->_general1_intercepts &= ~GENERAL1_INTERCEPT_INVLPG;
200
201 /* PAT is under complete control of SVM when using nested paging. */
202 svm_disable_intercept_for_msr(v, MSR_IA32_CR_PAT);
203 }
204 else
205 {
206 vmcb->_exception_intercepts |= (1U << TRAP_page_fault);
207 }
208
209 if ( cpu_has_pause_filter )
210 {
211 vmcb->_pause_filter_count = SVM_PAUSEFILTER_INIT;
212 vmcb->_general1_intercepts |= GENERAL1_INTERCEPT_PAUSE;
213 }
214
215 vmcb->cleanbits.bytes = 0;
216
217 return 0;
218 }
219
svm_create_vmcb(struct vcpu * v)220 int svm_create_vmcb(struct vcpu *v)
221 {
222 struct nestedvcpu *nv = &vcpu_nestedhvm(v);
223 struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
224 int rc;
225
226 if ( (nv->nv_n1vmcx == NULL) &&
227 (nv->nv_n1vmcx = alloc_vmcb()) == NULL )
228 {
229 printk("Failed to create a new VMCB\n");
230 return -ENOMEM;
231 }
232
233 arch_svm->vmcb = nv->nv_n1vmcx;
234 rc = construct_vmcb(v);
235 if ( rc != 0 )
236 {
237 free_vmcb(nv->nv_n1vmcx);
238 nv->nv_n1vmcx = NULL;
239 arch_svm->vmcb = NULL;
240 return rc;
241 }
242
243 arch_svm->vmcb_pa = nv->nv_n1vmcx_pa = virt_to_maddr(arch_svm->vmcb);
244 return 0;
245 }
246
svm_destroy_vmcb(struct vcpu * v)247 void svm_destroy_vmcb(struct vcpu *v)
248 {
249 struct nestedvcpu *nv = &vcpu_nestedhvm(v);
250 struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
251
252 if ( nv->nv_n1vmcx != NULL )
253 free_vmcb(nv->nv_n1vmcx);
254
255 if ( arch_svm->msrpm != NULL )
256 {
257 free_xenheap_pages(
258 arch_svm->msrpm, get_order_from_bytes(MSRPM_SIZE));
259 arch_svm->msrpm = NULL;
260 }
261
262 nv->nv_n1vmcx = NULL;
263 nv->nv_n1vmcx_pa = INVALID_PADDR;
264 arch_svm->vmcb = NULL;
265 }
266
vmcb_dump(unsigned char ch)267 static void vmcb_dump(unsigned char ch)
268 {
269 struct domain *d;
270 struct vcpu *v;
271
272 printk("*********** VMCB Areas **************\n");
273
274 rcu_read_lock(&domlist_read_lock);
275
276 for_each_domain ( d )
277 {
278 if ( !is_hvm_domain(d) )
279 continue;
280 printk("\n>>> Domain %d <<<\n", d->domain_id);
281 for_each_vcpu ( d, v )
282 {
283 printk("\tVCPU %d\n", v->vcpu_id);
284 svm_vmcb_dump("key_handler", v->arch.hvm_svm.vmcb);
285 }
286 }
287
288 rcu_read_unlock(&domlist_read_lock);
289
290 printk("**************************************\n");
291 }
292
setup_vmcb_dump(void)293 void __init setup_vmcb_dump(void)
294 {
295 register_keyhandler('v', vmcb_dump, "dump AMD-V VMCBs", 1);
296 }
297
build_assertions(void)298 static void __init __maybe_unused build_assertions(void)
299 {
300 struct segment_register sreg;
301
302 /* Check struct segment_register against the VMCB segment layout. */
303 BUILD_BUG_ON(sizeof(sreg) != 16);
304 BUILD_BUG_ON(sizeof(sreg.sel) != 2);
305 BUILD_BUG_ON(sizeof(sreg.attr) != 2);
306 BUILD_BUG_ON(sizeof(sreg.limit) != 4);
307 BUILD_BUG_ON(sizeof(sreg.base) != 8);
308 BUILD_BUG_ON(offsetof(struct segment_register, sel) != 0);
309 BUILD_BUG_ON(offsetof(struct segment_register, attr) != 2);
310 BUILD_BUG_ON(offsetof(struct segment_register, limit) != 4);
311 BUILD_BUG_ON(offsetof(struct segment_register, base) != 8);
312 }
313
314 /*
315 * Local variables:
316 * mode: C
317 * c-file-style: "BSD"
318 * c-basic-offset: 4
319 * tab-width: 4
320 * indent-tabs-mode: nil
321 * End:
322 */
323