| 2968 | } |
| 2969 | |
| 2970 | static int |
| 2971 | vmx_run(void *arg, int vcpu, register_t rip, pmap_t pmap, |
| 2972 | struct vm_eventinfo *evinfo) |
| 2973 | { |
| 2974 | int rc, handled, launched; |
| 2975 | struct vmx *vmx; |
| 2976 | struct vm *vm; |
| 2977 | struct vmxctx *vmxctx; |
| 2978 | struct vmcs *vmcs; |
| 2979 | struct vm_exit *vmexit; |
| 2980 | struct vlapic *vlapic; |
| 2981 | uint32_t exit_reason; |
| 2982 | struct region_descriptor gdtr, idtr; |
| 2983 | uint16_t ldt_sel; |
| 2984 | |
| 2985 | vmx = arg; |
| 2986 | vm = vmx->vm; |
| 2987 | vmcs = &vmx->vmcs[vcpu]; |
| 2988 | vmxctx = &vmx->ctx[vcpu]; |
| 2989 | vlapic = vm_lapic(vm, vcpu); |
| 2990 | vmexit = vm_exitinfo(vm, vcpu); |
| 2991 | launched = 0; |
| 2992 | |
| 2993 | KASSERT(vmxctx->pmap == pmap, |
| 2994 | ("pmap %p different than ctx pmap %p", pmap, vmxctx->pmap)); |
| 2995 | |
| 2996 | vmx_msr_guest_enter(vmx, vcpu); |
| 2997 | |
| 2998 | VMPTRLD(vmcs); |
| 2999 | |
| 3000 | /* |
| 3001 | * XXX |
| 3002 | * We do this every time because we may setup the virtual machine |
| 3003 | * from a different process than the one that actually runs it. |
| 3004 | * |
| 3005 | * If the life of a virtual machine was spent entirely in the context |
| 3006 | * of a single process we could do this once in vmx_init(). |
| 3007 | */ |
| 3008 | vmcs_write(VMCS_HOST_CR3, rcr3()); |
| 3009 | |
| 3010 | vmcs_write(VMCS_GUEST_RIP, rip); |
| 3011 | vmx_set_pcpu_defaults(vmx, vcpu, pmap); |
| 3012 | do { |
| 3013 | KASSERT(vmcs_guest_rip() == rip, ("%s: vmcs guest rip mismatch " |
| 3014 | "%#lx/%#lx", __func__, vmcs_guest_rip(), rip)); |
| 3015 | |
| 3016 | handled = UNHANDLED; |
| 3017 | /* |
| 3018 | * Interrupts are disabled from this point on until the |
| 3019 | * guest starts executing. This is done for the following |
| 3020 | * reasons: |
| 3021 | * |
| 3022 | * If an AST is asserted on this thread after the check below, |
| 3023 | * then the IPI_AST notification will not be lost, because it |
| 3024 | * will cause a VM exit due to external interrupt as soon as |
| 3025 | * the guest state is loaded. |
| 3026 | * |
| 3027 | * A posted interrupt after 'vmx_inject_interrupts()' will |
nothing calls this directly
no test coverage detected