remove some magic numbers in the flush-by-asid code and check if the CPU
authormlarkin <mlarkin@openbsd.org>
Tue, 20 Jun 2017 06:25:01 +0000 (06:25 +0000)
committermlarkin <mlarkin@openbsd.org>
Tue, 20 Jun 2017 06:25:01 +0000 (06:25 +0000)
supports that feature before we try to use it.

discussed with deraadt

sys/arch/amd64/amd64/vmm.c
sys/arch/amd64/include/specialreg.h

index 66e5501..a1c7b1a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmm.c,v 1.153 2017/06/20 05:34:41 mlarkin Exp $       */
+/*     $OpenBSD: vmm.c,v 1.154 2017/06/20 06:25:01 mlarkin Exp $       */
 /*
  * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
  *
@@ -1767,8 +1767,8 @@ vcpu_reset_regs_svm(struct vcpu *vcpu, struct vcpu_reg_state *vrs)
        vmcb->v_asid = asid;
        vcpu->vc_vpid = asid;
 
-       /* TLB Control */
-       vmcb->v_tlb_control = 1;        /* First time in, flush all */
+       /* TLB Control - First time in, flush all*/
+       vmcb->v_tlb_control = SVM_TLB_CONTROL_FLUSH_ALL;
 
        /* INTR masking */
        vmcb->v_intr_masking = 1;
@@ -5539,7 +5539,17 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp)
                        setregion(&gdt, ci->ci_gdt, GDT_SIZE - 1);
 
                        if (ci != vcpu->vc_last_pcpu) {
-                               vmcb->v_tlb_control = 3; /* Flush TLB */
+                               /*
+                                * Flush TLB by guest ASID if feature
+                                * available, flush entire TLB if not.
+                                */
+                               if (ci->ci_vmm_cap.vcc_svm.svm_flush_by_asid)
+                                       vmcb->v_tlb_control =
+                                           SVM_TLB_CONTROL_FLUSH_ASID;
+                               else
+                                       vmcb->v_tlb_control =
+                                           SVM_TLB_CONTROL_FLUSH_ALL;
+
                                svm_set_dirty(vcpu, SVM_CLEANBITS_ALL);
                        }
 
@@ -5660,7 +5670,7 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp)
                enable_intr();
 
                vcpu->vc_gueststate.vg_rip = vmcb->v_rip;
-               vmcb->v_tlb_control = 0;
+               vmcb->v_tlb_control = SVM_TLB_CONTROL_FLUSH_NONE;
                svm_set_clean(vcpu, SVM_CLEANBITS_ALL);
 
                if (ret || exit_reason != SVM_VMEXIT_INTR) {
index 00a8523..63b4909 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: specialreg.h,v 1.57 2017/06/20 05:34:41 mlarkin Exp $ */
+/*     $OpenBSD: specialreg.h,v 1.58 2017/06/20 06:25:01 mlarkin Exp $ */
 /*     $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $      */
 /*     $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $  */
 
 #define AMD_SVM_FLUSH_BY_ASID_CAP      (1 << 6)
 #define AMD_SVMDIS                     0x10
 
+#define SVM_TLB_CONTROL_FLUSH_NONE     0
+#define SVM_TLB_CONTROL_FLUSH_ALL      1
+#define SVM_TLB_CONTROL_FLUSH_ASID     3
+#define SVM_TLB_CONTROL_FLUSH_ASID_GLB 7
+
 #define SVM_CLEANBITS_I                        (1 << 0)
 #define SVM_CLEANBITS_IOPM             (1 << 1)
 #define SVM_CLEANBITS_ASID             (1 << 2)