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