2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmx_handler.h>
21 #include <palacios/vmm_types.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vmcs.h>
24 #include <palacios/vmx_lowlevel.h>
25 #include <palacios/vmx_io.h>
28 static int inline check_vmcs_write(vmcs_field_t field, addr_t val)
31 ret = vmcs_write(field,val);
33 if (ret != VMX_SUCCESS) {
34 PrintError("VMWRITE error on %s!: %d\n", v3_vmcs_field_to_str(field), ret);
41 static int inline check_vmcs_read(vmcs_field_t field, void * val)
44 ret = vmcs_read(field,val);
46 if(ret != VMX_SUCCESS) {
47 PrintError("VMREAD error on %s!: %d\n", v3_vmcs_field_to_str(field), ret);
54 int v3_handle_vmx_exit(struct v3_gprs * gprs, struct guest_info * info)
59 check_vmcs_read(VMCS_EXIT_REASON, &exit_reason);
60 check_vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
62 PrintDebug("VMX Exit taken, id-qual: %d-%ld\n", exit_reason, exit_qual);
64 /* Update guest state */
65 check_vmcs_read(VMCS_GUEST_RIP, &(info->rip));
66 check_vmcs_read(VMCS_GUEST_RSP, &(info->vm_regs.rsp));
67 check_vmcs_read(VMCS_GUEST_CR0, &(info->ctrl_regs.cr0));
68 check_vmcs_read(VMCS_GUEST_CR3, &(info->ctrl_regs.cr3));
69 check_vmcs_read(VMCS_GUEST_CR4, &(info->ctrl_regs.cr4));
75 case VMEXIT_INFO_EXCEPTION_OR_NMI:
78 pf_error_t error_code;
79 check_vmcs_read(VMCS_EXIT_INT_INFO, &int_info);
80 check_vmcs_read(VMCS_EXIT_INT_ERR, &error_code);
82 if((uint8_t)int_info == 0x0e) {
83 PrintDebug("Page Fault at %p\n", (void*)exit_qual);
84 if(info->shdw_pg_mode == SHADOW_PAGING) {
85 if(v3_handle_shadow_pagefault(info, (addr_t)exit_qual, error_code) == -1) {
89 PrintError("Page fault in unimplemented paging mode\n");
98 struct vmcs_io_qual * io_qual = (struct vmcs_io_qual *)&exit_qual;
100 if(io_qual->dir == 0) {
101 if(io_qual->string) {
102 if(v3_handle_vmx_io_outs(info) == -1) {
106 if(v3_handle_vmx_io_out(info) == -1) {
111 if(io_qual->string) {
112 if(v3_handle_vmx_io_ins(info) == -1) {
116 if(v3_handle_vmx_io_in(info) == -1) {
125 PrintError("Unhandled VMEXIT\n");
129 check_vmcs_write(VMCS_GUEST_CR0, info->ctrl_regs.cr0);
130 check_vmcs_write(VMCS_GUEST_CR3, info->ctrl_regs.cr3);
131 check_vmcs_write(VMCS_GUEST_CR4, info->ctrl_regs.cr4);
132 check_vmcs_write(VMCS_GUEST_RIP, info->rip);
133 check_vmcs_write(VMCS_GUEST_RSP, info->vm_regs.rsp);
135 PrintDebug("Executing VMRESUME\n");