On Sun, May 08, 2022 at 10:30:46PM -0400, Dave Voutila wrote:
> tech@,
>
> Another vmm/vmd update: fix `vmctl receive` on Intel hosts by adding
> another fault enum value to disambiguate fault reasons.
>
> It's expected that the guest will trigger nested page faults after being
> received by vmd. When you connect to the vm using `vmctl console` and
> interact with the guest, it generates both a page fault and interrupt.
>
> This combo is special because while the page fault will be handled by
> vmm via uvm_fault(9), it will still exit to userland/vmd to handle the
> interrupt.
>
> vmd always checks the vm-exit reason after the return from vmm before
> looping around and servicing interrupts before re-entering vmm. vmd has
> a single userland handler for nested page faults for when we have a
> protection fault. In this case, it reboots the vm. :-(
>
> Since the enum we used for the fault type flag has only one value, vmm
> isn't able to properly convey the type of nested fault. In this case, I
> chose to add a "VEE_FAULT_HANDLED" value to indicate the fault has
> already been handled by vmm and no userland assist is needed. (And
> HANDLED is the same num of characters of PROTECT.)
>
> This prevents the ambiguity and vm happily skips rebooting the vm.
>
> It's possible this reboot could occur at any point in a vm's lifetime,
> though I think the probability is low, so this is worth fixing
> regardless.
>
> ok?
>

This is ok mlarkin. Thanks!

> -dv
>
>
> Index: sys/arch/amd64/amd64/vmm.c
> ===================================================================
> RCS file: /opt/cvs/src/sys/arch/amd64/amd64/vmm.c,v
> retrieving revision 1.308
> diff -u -p -r1.308 vmm.c
> --- sys/arch/amd64/amd64/vmm.c        4 May 2022 02:24:26 -0000       1.308
> +++ sys/arch/amd64/amd64/vmm.c        9 May 2022 13:45:02 -0000
> @@ -5732,14 +5732,16 @@ vmx_fault_page(struct vcpu *vcpu, paddr_
>       int fault_type, ret;
>
>       fault_type = vmx_get_guest_faulttype();
> -     if (fault_type == -1) {
> +     switch (fault_type) {
> +     case -1:
>               printf("%s: invalid fault type\n", __func__);
>               return (EINVAL);
> -     }
> -
> -     if (fault_type == VM_FAULT_PROTECT) {
> +     case VM_FAULT_PROTECT:
>               vcpu->vc_exit.vee.vee_fault_type = VEE_FAULT_PROTECT;
>               return (EAGAIN);
> +     default:
> +             vcpu->vc_exit.vee.vee_fault_type = VEE_FAULT_HANDLED;
> +             break;
>       }
>
>       /* We may sleep during uvm_fault(9), so reload VMCS. */
> Index: sys/arch/amd64/include/vmmvar.h
> ===================================================================
> RCS file: /opt/cvs/src/sys/arch/amd64/include/vmmvar.h,v
> retrieving revision 1.75
> diff -u -p -r1.75 vmmvar.h
> --- sys/arch/amd64/include/vmmvar.h   3 May 2022 21:39:19 -0000       1.75
> +++ sys/arch/amd64/include/vmmvar.h   9 May 2022 13:38:18 -0000
> @@ -324,7 +324,8 @@ enum {
>  };
>
>  enum {
> -     VEE_FAULT_PROTECT
> +     VEE_FAULT_HANDLED,
> +     VEE_FAULT_PROTECT,
>  };
>
>  enum {
>

Reply via email to