-/* $OpenBSD: vmm_machdep.c,v 1.28 2024/06/26 01:40:49 jsg Exp $ */
+/* $OpenBSD: vmm_machdep.c,v 1.29 2024/07/14 07:57:42 dv Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
int vmx_fault_page(struct vcpu *, paddr_t);
int vmx_handle_np_fault(struct vcpu *);
int svm_handle_np_fault(struct vcpu *);
-int vmx_mprotect_ept(vm_map_t, paddr_t, paddr_t, int);
+int vmx_mprotect_ept(struct vcpu *, vm_map_t, paddr_t, paddr_t, int);
pt_entry_t *vmx_pmap_find_pte_ept(pmap_t, paddr_t);
int vmm_alloc_vpid(uint16_t *);
void vmm_free_vpid(uint16_t);
}
if (vmm_softc->mode == VMM_MODE_EPT)
- ret = vmx_mprotect_ept(vm->vm_map, sgpa, sgpa + size, prot);
+ ret = vmx_mprotect_ept(vcpu, vm->vm_map, sgpa, sgpa + size,
+ prot);
else if (vmm_softc->mode == VMM_MODE_RVI) {
pmap_write_protect(vm->vm_map->pmap, sgpa, sgpa + size, prot);
/* XXX requires a invlpga */
* required.
*/
int
-vmx_mprotect_ept(vm_map_t vm_map, paddr_t sgpa, paddr_t egpa, int prot)
+vmx_mprotect_ept(struct vcpu *vcpu, vm_map_t vm_map, paddr_t sgpa, paddr_t egpa,
+ int prot)
{
struct vmx_invept_descriptor vid;
pmap_t pmap;
vid.vid_eptp = pmap->eptp;
DPRINTF("%s: flushing EPT TLB for EPTP 0x%llx\n", __func__,
vid.vid_eptp);
- invept(IA32_VMX_INVEPT_SINGLE_CTX, &vid);
+ invept(vcpu->vc_vmx_invept_op, &vid);
}
KERNEL_UNLOCK();
ret = EINVAL;
goto exit;
}
+ if (msr & IA32_EPT_VPID_CAP_INVEPT_CONTEXT)
+ vcpu->vc_vmx_invept_op = IA32_VMX_INVEPT_SINGLE_CTX;
+ else
+ vcpu->vc_vmx_invept_op = IA32_VMX_INVEPT_GLOBAL_CTX;
if (msr & IA32_EPT_VPID_CAP_WB) {
/* WB cache type supported */
struct schedstate_percpu *spc;
struct vmx_msr_store *msr_store;
struct vmx_invvpid_descriptor vid;
+ struct vmx_invept_descriptor vid_ept;
uint64_t cr0, eii, procbased, int_st;
u_long s;
}
memset(&vcpu->vc_exit, 0, sizeof(vcpu->vc_exit));
- /* Host CR3 */
- cr3 = rcr3();
- if (vmwrite(VMCS_HOST_IA32_CR3, cr3)) {
- printf("%s: vmwrite(0x%04X, 0x%llx)\n", __func__,
- VMCS_HOST_IA32_CR3, cr3);
- return (EINVAL);
- }
-
/* Handle vmd(8) injected interrupts */
/* Is there an interrupt pending injection? */
if (vcpu->vc_inject.vie_type == VCPU_INJECT_INTR) {
ci = curcpu();
vcpu->vc_last_pcpu = ci;
+ /* Invalidate EPT cache. */
+ vid_ept.vid_reserved = 0;
+ vid_ept.vid_eptp = vcpu->vc_parent->vm_map->pmap->eptp;
+ if (invept(vcpu->vc_vmx_invept_op, &vid_ept)) {
+ printf("%s: invept\n", __func__);
+ return (EINVAL);
+ }
+
+ /* Host CR3 */
+ cr3 = rcr3();
+ if (vmwrite(VMCS_HOST_IA32_CR3, cr3)) {
+ printf("%s: vmwrite(0x%04X, 0x%llx)\n", __func__,
+ VMCS_HOST_IA32_CR3, cr3);
+ return (EINVAL);
+ }
+
setregion(&gdt, ci->ci_gdt, GDT_SIZE - 1);
if (gdt.rd_base == 0) {
printf("%s: setregion\n", __func__);