Deleted Added
full compact
vmx.c (242331) vmx.c (243640)
1/*-
2 * Copyright (c) 2011 NetApp, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 49 unchanged lines hidden (view full) ---

58#include "vmm_stat.h"
59
60#include "vmx_msr.h"
61#include "ept.h"
62#include "vmx_cpufunc.h"
63#include "vmx.h"
64#include "x86.h"
65#include "vmx_controls.h"
1/*-
2 * Copyright (c) 2011 NetApp, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 49 unchanged lines hidden (view full) ---

58#include "vmm_stat.h"
59
60#include "vmx_msr.h"
61#include "ept.h"
62#include "vmx_cpufunc.h"
63#include "vmx.h"
64#include "x86.h"
65#include "vmx_controls.h"
66#include "vmm_instruction_emul.h"
67
68#define PINBASED_CTLS_ONE_SETTING \
69 (PINBASED_EXTINT_EXITING | \
70 PINBASED_NMI_EXITING | \
71 PINBASED_VIRTUAL_NMI)
72#define PINBASED_CTLS_ZERO_SETTING 0
73
74#define PROCBASED_CTLS_WINDOW_SETTING \

--- 1070 unchanged lines hidden (view full) ---

1145 panic("vmx_emulate_cr_access: error %d writing cr%d",
1146 error, cr);
1147 }
1148
1149 return (HANDLED);
1150}
1151
1152static int
66
67#define PINBASED_CTLS_ONE_SETTING \
68 (PINBASED_EXTINT_EXITING | \
69 PINBASED_NMI_EXITING | \
70 PINBASED_VIRTUAL_NMI)
71#define PINBASED_CTLS_ZERO_SETTING 0
72
73#define PROCBASED_CTLS_WINDOW_SETTING \

--- 1070 unchanged lines hidden (view full) ---

1144 panic("vmx_emulate_cr_access: error %d writing cr%d",
1145 error, cr);
1146 }
1147
1148 return (HANDLED);
1149}
1150
1151static int
1153vmx_lapic_fault(struct vm *vm, int cpu,
1154 uint64_t gpa, uint64_t rip, int inst_length,
1155 uint64_t cr3, uint64_t ept_qual)
1152vmx_ept_fault(struct vm *vm, int cpu,
1153 uint64_t gla, uint64_t gpa, uint64_t rip, int inst_length,
1154 uint64_t cr3, uint64_t ept_qual, struct vie *vie)
1156{
1155{
1157 int read, write, handled;
1158 struct vie vie;
1156 int read, write, error;
1159
1157
1160 /*
1161 * For this to be a legitimate access to the local apic:
1162 * - the GPA in the local apic page
1163 * - the GPA must be aligned on a 16 byte boundary
1164 */
1165 if (gpa < DEFAULT_APIC_BASE || gpa >= DEFAULT_APIC_BASE + PAGE_SIZE)
1166 return (UNHANDLED);
1167
1168 if ((gpa & 0xF) != 0)
1169 return (UNHANDLED);
1170
1171 /* EPT violation on an instruction fetch doesn't make sense here */
1172 if (ept_qual & EPT_VIOLATION_INST_FETCH)
1173 return (UNHANDLED);
1174
1175 /* EPT violation must be a read fault or a write fault but not both */
1176 read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0;
1177 write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0;
1178 if ((read ^ write) == 0)

--- 4 unchanged lines hidden (view full) ---

1183 * address that is a translation of a guest-linear address.
1184 */
1185 if ((ept_qual & EPT_VIOLATION_GLA_VALID) == 0 ||
1186 (ept_qual & EPT_VIOLATION_XLAT_VALID) == 0) {
1187 return (UNHANDLED);
1188 }
1189
1190 /* Fetch, decode and emulate the faulting instruction */
1158 /* EPT violation on an instruction fetch doesn't make sense here */
1159 if (ept_qual & EPT_VIOLATION_INST_FETCH)
1160 return (UNHANDLED);
1161
1162 /* EPT violation must be a read fault or a write fault but not both */
1163 read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0;
1164 write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0;
1165 if ((read ^ write) == 0)

--- 4 unchanged lines hidden (view full) ---

1170 * address that is a translation of a guest-linear address.
1171 */
1172 if ((ept_qual & EPT_VIOLATION_GLA_VALID) == 0 ||
1173 (ept_qual & EPT_VIOLATION_XLAT_VALID) == 0) {
1174 return (UNHANDLED);
1175 }
1176
1177 /* Fetch, decode and emulate the faulting instruction */
1191 if (vmm_fetch_instruction(vm, rip, inst_length, cr3, &vie) != 0)
1178 if (vmm_fetch_instruction(vm, cpu, rip, inst_length, cr3, vie) != 0)
1192 return (UNHANDLED);
1193
1179 return (UNHANDLED);
1180
1194 if (vmm_decode_instruction(&vie) != 0)
1181 if (vmm_decode_instruction(vm, cpu, gla, vie) != 0)
1195 return (UNHANDLED);
1196
1182 return (UNHANDLED);
1183
1197 handled = lapic_mmio(vm, cpu, gpa - DEFAULT_APIC_BASE, read, &vie);
1184 /*
1185 * Check if this is a local apic access
1186 */
1187 if (gpa < DEFAULT_APIC_BASE || gpa >= DEFAULT_APIC_BASE + PAGE_SIZE)
1188 return (UNHANDLED);
1198
1189
1199 return (handled);
1190 error = vmm_emulate_instruction(vm, cpu, gpa, vie,
1191 lapic_mmio_read, lapic_mmio_write, 0);
1192
1193 return (error ? UNHANDLED : HANDLED);
1200}
1201
1202static int
1203vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
1204{
1205 int error, handled;
1206 struct vmcs *vmcs;
1207 struct vmxctx *vmxctx;
1208 uint32_t eax, ecx, edx;
1194}
1195
1196static int
1197vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
1198{
1199 int error, handled;
1200 struct vmcs *vmcs;
1201 struct vmxctx *vmxctx;
1202 uint32_t eax, ecx, edx;
1209 uint64_t qual, gpa, cr3, intr_info;
1203 uint64_t qual, gla, gpa, cr3, intr_info;
1210
1211 handled = 0;
1212 vmcs = &vmx->vmcs[vcpu];
1213 vmxctx = &vmx->ctx[vcpu];
1214 qual = vmexit->u.vmx.exit_qualification;
1215 vmexit->exitcode = VM_EXITCODE_BOGUS;
1216
1217 switch (vmexit->u.vmx.exit_reason) {

--- 76 unchanged lines hidden (view full) ---

1294 vmexit->u.inout.rep = (qual & 0x20) ? 1 : 0;
1295 vmexit->u.inout.port = (uint16_t)(qual >> 16);
1296 vmexit->u.inout.eax = (uint32_t)(vmxctx->guest_rax);
1297 break;
1298 case EXIT_REASON_CPUID:
1299 handled = vmx_handle_cpuid(vmx->vm, vcpu, vmxctx);
1300 break;
1301 case EXIT_REASON_EPT_FAULT:
1204
1205 handled = 0;
1206 vmcs = &vmx->vmcs[vcpu];
1207 vmxctx = &vmx->ctx[vcpu];
1208 qual = vmexit->u.vmx.exit_qualification;
1209 vmexit->exitcode = VM_EXITCODE_BOGUS;
1210
1211 switch (vmexit->u.vmx.exit_reason) {

--- 76 unchanged lines hidden (view full) ---

1288 vmexit->u.inout.rep = (qual & 0x20) ? 1 : 0;
1289 vmexit->u.inout.port = (uint16_t)(qual >> 16);
1290 vmexit->u.inout.eax = (uint32_t)(vmxctx->guest_rax);
1291 break;
1292 case EXIT_REASON_CPUID:
1293 handled = vmx_handle_cpuid(vmx->vm, vcpu, vmxctx);
1294 break;
1295 case EXIT_REASON_EPT_FAULT:
1296 gla = vmcs_gla();
1302 gpa = vmcs_gpa();
1303 cr3 = vmcs_guest_cr3();
1297 gpa = vmcs_gpa();
1298 cr3 = vmcs_guest_cr3();
1304 handled = vmx_lapic_fault(vmx->vm, vcpu,
1305 gpa, vmexit->rip, vmexit->inst_length,
1306 cr3, qual);
1299 handled = vmx_ept_fault(vmx->vm, vcpu, gla, gpa,
1300 vmexit->rip, vmexit->inst_length,
1301 cr3, qual, &vmexit->u.paging.vie);
1307 if (!handled) {
1308 vmexit->exitcode = VM_EXITCODE_PAGING;
1309 vmexit->u.paging.cr3 = cr3;
1310 vmexit->u.paging.gpa = gpa;
1311 vmexit->u.paging.rwx = qual & 0x7;
1312 }
1313 break;
1314 default:

--- 535 unchanged lines hidden ---
1302 if (!handled) {
1303 vmexit->exitcode = VM_EXITCODE_PAGING;
1304 vmexit->u.paging.cr3 = cr3;
1305 vmexit->u.paging.gpa = gpa;
1306 vmexit->u.paging.rwx = qual & 0x7;
1307 }
1308 break;
1309 default:

--- 535 unchanged lines hidden ---