1/**
2 * \file
3 * \brief VMKit Kernel interface.
4 */
5
6/*
7 * Copyright (c) 2009, 2010, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <string.h>
16#include <kernel.h>
17#include <paging_kernel_arch.h>
18#include <vmkit.h>
19#include <x86.h>
20#include <dispatch.h>
21#include <exec.h>
22#include <barrelfish_kpi/vmkit.h>
23#include <barrelfish_kpi/syscalls.h>
24
25#include <dev/amd_vmcb_dev.h>
26
27errval_t
28vmkit_enable_virtualization (void)
29{
30#ifdef CONFIG_SVM
31    return svm_enable_virtualization();
32#else
33    return vmx_enable_virtualization();
34#endif
35}
36
37void __attribute__ ((noreturn))
38vmkit_vmexec (struct dcb *dcb, lvaddr_t entry)
39{
40    dispatcher_handle_t handle = dcb->disp;
41    struct dispatcher_shared_generic *disp = get_dispatcher_shared_generic(handle);
42    lpaddr_t lpaddr = gen_phys_to_local_phys(dcb->guest_desc.ctrl.cap.u.frame.base);
43    struct guest_control *ctrl = (void *)local_phys_to_mem(lpaddr);
44    memset(&ctrl->regs, 0, sizeof(struct registers_x86_64));
45    ctrl->regs.rdi = disp->udisp;
46#ifdef CONFIG_SVM
47    lpaddr = gen_phys_to_local_phys(dcb->guest_desc.vmcb.cap.u.frame.base);
48    amd_vmcb_t vmcb;
49    amd_vmcb_initialize(&vmcb, (void *)local_phys_to_mem(lpaddr));
50
51    amd_vmcb_rip_wr(&vmcb, disp->dispatcher_run);
52    amd_vmcb_rsp_wr(&vmcb, 0);
53    amd_vmcb_rax_wr(&vmcb, 0);
54    amd_vmcb_rflags_wr_raw(&vmcb, USER_RFLAGS);
55    amd_vmcb_fs_selector_wr(&vmcb, 0);
56    amd_vmcb_gs_selector_wr(&vmcb, 0);
57    svm_vmkit_vmenter(dcb);
58#else
59    vmwrite(VMX_GUEST_RIP, disp->dispatcher_run);
60    vmwrite(VMX_GUEST_RSP, 0);
61    vmwrite(VMX_GUEST_RFLAGS, USER_RFLAGS);
62    vmwrite(VMX_GUEST_FS_SEL, 0);
63    vmwrite(VMX_GUEST_GS_SEL, 0);
64    vmx_vmkit_vmenter(dcb);
65#endif
66}
67
68void __attribute__ ((noreturn))
69vmkit_vmenter (struct dcb *dcb)
70{
71#ifdef CONFIG_SVM
72    svm_vmkit_vmenter(dcb);
73#else
74    vmx_vmkit_vmenter(dcb);
75#endif
76}
77