Print this page
13275 bhyve needs richer INIT/SIPI support
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/io/vmm/intel/vmx.c
          +++ new/usr/src/uts/i86pc/io/vmm/intel/vmx.c
↓ open down ↓ 2730 lines elided ↑ open up ↑
2731 2731          load_dr1(vmxctx->host_dr1);
2732 2732          load_dr2(vmxctx->host_dr2);
2733 2733          load_dr3(vmxctx->host_dr3);
2734 2734          load_dr6(vmxctx->host_dr6);
2735 2735          wrmsr(MSR_DEBUGCTLMSR, vmxctx->host_debugctl);
2736 2736          load_dr7(vmxctx->host_dr7);
2737 2737          write_rflags(read_rflags() | vmxctx->host_tf);
2738 2738  }
2739 2739  
2740 2740  static int
2741      -vmx_run(void *arg, int vcpu, uint64_t rip, pmap_t pmap,
2742      -    struct vm_eventinfo *evinfo)
     2741 +vmx_run(void *arg, int vcpu, uint64_t rip, pmap_t pmap)
2743 2742  {
2744 2743          int rc, handled, launched;
2745 2744          struct vmx *vmx;
2746 2745          struct vm *vm;
2747 2746          struct vmxctx *vmxctx;
2748 2747          uintptr_t vmcs_pa;
2749 2748          struct vm_exit *vmexit;
2750 2749          struct vlapic *vlapic;
2751 2750          uint32_t exit_reason;
2752 2751  #ifdef __FreeBSD__
↓ open down ↓ 74 lines elided ↑ open up ↑
2827 2826                  /*
2828 2827                   * If not precluded by existing events, inject any interrupt
2829 2828                   * pending on the vLAPIC.  As a lock-less operation, it is safe
2830 2829                   * (and prudent) to perform with host CPU interrupts disabled.
2831 2830                   */
2832 2831                  if (inject_state == EIS_CAN_INJECT) {
2833 2832                          inject_state = vmx_inject_vlapic(vmx, vcpu, vlapic);
2834 2833                  }
2835 2834  
2836 2835                  /*
2837      -                 * Check for vcpu suspension after injecting events because
2838      -                 * vmx_inject_events() can suspend the vcpu due to a
2839      -                 * triple fault.
     2836 +                 * Check for vCPU bail-out conditions.  This must be done after
     2837 +                 * vmx_inject_events() to detect a triple-fault condition.
2840 2838                   */
2841      -                if (vcpu_suspended(evinfo)) {
     2839 +                if (vcpu_entry_bailout_checks(vmx->vm, vcpu, rip)) {
2842 2840                          enable_intr();
2843      -                        vm_exit_suspended(vmx->vm, vcpu, rip);
2844 2841                          break;
2845 2842                  }
2846 2843  
2847      -                if (vcpu_runblocked(evinfo)) {
     2844 +                if (vcpu_run_state_pending(vm, vcpu)) {
2848 2845                          enable_intr();
2849      -                        vm_exit_runblock(vmx->vm, vcpu, rip);
     2846 +                        vm_exit_run_state(vmx->vm, vcpu, rip);
2850 2847                          break;
2851 2848                  }
2852 2849  
2853      -                if (vcpu_reqidle(evinfo)) {
2854      -                        enable_intr();
2855      -                        vm_exit_reqidle(vmx->vm, vcpu, rip);
2856      -                        break;
2857      -                }
2858      -
2859      -                if (vcpu_should_yield(vm, vcpu)) {
2860      -                        enable_intr();
2861      -                        vm_exit_astpending(vmx->vm, vcpu, rip);
2862      -                        vmx_astpending_trace(vmx, vcpu, rip);
2863      -                        handled = HANDLED;
2864      -                        break;
2865      -                }
2866      -
2867      -                if (vcpu_debugged(vm, vcpu)) {
2868      -                        enable_intr();
2869      -                        vm_exit_debug(vmx->vm, vcpu, rip);
2870      -                        break;
2871      -                }
2872      -
2873 2850                  /*
2874 2851                   * If subsequent activity queued events which require injection
2875 2852                   * handling, take another lap to handle them.
2876 2853                   */
2877 2854                  if (vmx_inject_recheck(vmx, vcpu, inject_state)) {
2878 2855                          enable_intr();
2879 2856                          handled = HANDLED;
2880 2857                          continue;
2881 2858                  }
2882 2859  
↓ open down ↓ 95 lines elided ↑ open up ↑
2978 2955                          vmx_exit_inst_error(vmxctx, rc, vmexit);
2979 2956                  }
2980 2957  #ifdef  __FreeBSD__
2981 2958                  launched = 1;
2982 2959  #endif
2983 2960                  DTRACE_PROBE3(vmm__vexit, int, vcpu, uint64_t, rip,
2984 2961                      uint32_t, exit_reason);
2985 2962                  rip = vmexit->rip;
2986 2963          } while (handled);
2987 2964  
2988      -        /*
2989      -         * If a VM exit has been handled then the exitcode must be BOGUS
2990      -         * If a VM exit is not handled then the exitcode must not be BOGUS
2991      -         */
2992      -        if ((handled && vmexit->exitcode != VM_EXITCODE_BOGUS) ||
2993      -            (!handled && vmexit->exitcode == VM_EXITCODE_BOGUS)) {
2994      -                panic("Mismatch between handled (%d) and exitcode (%d)",
2995      -                    handled, vmexit->exitcode);
     2965 +        /* If a VM exit has been handled then the exitcode must be BOGUS */
     2966 +        if (handled && vmexit->exitcode != VM_EXITCODE_BOGUS) {
     2967 +                panic("Non-BOGUS exitcode (%d) unexpected for handled VM exit",
     2968 +                    vmexit->exitcode);
2996 2969          }
2997 2970  
2998      -        if (!handled)
2999      -                vmm_stat_incr(vm, vcpu, VMEXIT_USERSPACE, 1);
3000      -
3001 2971          VCPU_CTR1(vm, vcpu, "returning from vmx_run: exitcode %d",
3002 2972              vmexit->exitcode);
3003 2973  
3004 2974          vmcs_clear(vmcs_pa);
3005 2975          vmx_msr_guest_exit(vmx, vcpu);
3006 2976  
3007 2977  #ifndef __FreeBSD__
3008 2978          VERIFY(vmx->vmcs_state != VS_NONE && curthread->t_preempt != 0);
3009 2979          vmx->vmcs_state[vcpu] = VS_NONE;
3010 2980  #endif
↓ open down ↓ 243 lines elided ↑ open up ↑
3254 3224                  desc->access = 0;
3255 3225          }
3256 3226  
3257 3227          if (!running) {
3258 3228                  vmcs_clear(vmx->vmcs_pa[vcpu]);
3259 3229          }
3260 3230          return (0);
3261 3231  }
3262 3232  
3263 3233  static int
3264      -vmx_setdesc(void *arg, int vcpu, int seg, struct seg_desc *desc)
     3234 +vmx_setdesc(void *arg, int vcpu, int seg, const struct seg_desc *desc)
3265 3235  {
3266 3236          int hostcpu, running;
3267 3237          struct vmx *vmx = arg;
3268 3238          uint32_t base, limit, access;
3269 3239  
3270 3240          running = vcpu_is_running(vmx->vm, vcpu, &hostcpu);
3271 3241          if (running && hostcpu != curcpu)
3272 3242                  panic("vmx_setdesc: %s%d is running", vm_name(vmx->vm), vcpu);
3273 3243  
3274 3244          if (!running) {
↓ open down ↓ 615 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX