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 --- |