]> xenbits.xensource.com Git - people/liuw/xen.git/commitdiff
x86/svm: Correct vm_event API for descriptor accesses
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 28 Nov 2019 11:28:51 +0000 (11:28 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 4 Dec 2019 19:05:00 +0000 (19:05 +0000)
c/s d0a699a389f1 "x86/monitor: add support for descriptor access events"
introduced logic looking for what appeared to be exitinfo (not that this
exists in SVM - exitinfo1 or 2 do), but actually passed the exit IDT vectoring
information.  There is never any IDT vectoring involved in these intercepts so
the value passed is always zero.

In fact, SVM doesn't provide any information, even in exitinfo1 and 2.  Drop
the svm struct entirely, and bump the interface version.

In the SVM vmexit handler itself, optimise the switch statement by observing
that there is a linear transformation between the SVM exit_reason and
VM_EVENT_DESC_* values.  (Bloat-o-meter reports 6028 => 5877 for a saving of
151 bytes).

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Reviewed-by: Alexandru Isaila <aisaila@bitdefender.com>
Acked-by: Adrian Pop <apop@bitdefender.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/hvm/monitor.c
xen/arch/x86/hvm/svm/svm.c
xen/include/public/vm_event.h

index 7fb1e2c04eaca3c3bc20e27ac06dd690ead64b6f..1f23fe25e88f36d67d2579d4997e7d509db978da 100644 (file)
@@ -113,10 +113,6 @@ void hvm_monitor_descriptor_access(uint64_t exit_info,
         req.u.desc_access.arch.vmx.instr_info = exit_info;
         req.u.desc_access.arch.vmx.exit_qualification = vmx_exit_qualification;
     }
-    else
-    {
-        req.u.desc_access.arch.svm.exitinfo = exit_info;
-    }
 
     monitor_traps(current, true, &req);
 }
index 0fb1908c18d71ae05af5e34e881453915c5272c7..776cf1145942c1628a884eed3dcfbe9d8704b27d 100644 (file)
@@ -2980,29 +2980,26 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
         svm_vmexit_do_pause(regs);
         break;
 
-    case VMEXIT_IDTR_READ:
-    case VMEXIT_IDTR_WRITE:
-        hvm_descriptor_access_intercept(vmcb->exitintinfo.bytes, 0,
-            VM_EVENT_DESC_IDTR, exit_reason == VMEXIT_IDTR_WRITE);
-        break;
-
-    case VMEXIT_GDTR_READ:
-    case VMEXIT_GDTR_WRITE:
-        hvm_descriptor_access_intercept(vmcb->exitintinfo.bytes, 0,
-            VM_EVENT_DESC_GDTR, exit_reason == VMEXIT_GDTR_WRITE);
-        break;
+    case VMEXIT_IDTR_READ ... VMEXIT_TR_WRITE:
+    {
+        /*
+         * Consecutive block of 8 exit codes (sadly not aligned).  Top bit
+         * indicates write (vs read), bottom 2 bits map linearly to
+         * VM_EVENT_DESC_* values.
+         */
+#define E2D(e)      ((((e)         - VMEXIT_IDTR_READ) & 3) + 1)
+        bool write = ((exit_reason - VMEXIT_IDTR_READ) & 4);
+        unsigned int desc = E2D(exit_reason);
 
-    case VMEXIT_LDTR_READ:
-    case VMEXIT_LDTR_WRITE:
-        hvm_descriptor_access_intercept(vmcb->exitintinfo.bytes, 0,
-            VM_EVENT_DESC_LDTR, exit_reason == VMEXIT_LDTR_WRITE);
-        break;
+        BUILD_BUG_ON(E2D(VMEXIT_IDTR_READ) != VM_EVENT_DESC_IDTR);
+        BUILD_BUG_ON(E2D(VMEXIT_GDTR_READ) != VM_EVENT_DESC_GDTR);
+        BUILD_BUG_ON(E2D(VMEXIT_LDTR_READ) != VM_EVENT_DESC_LDTR);
+        BUILD_BUG_ON(E2D(VMEXIT_TR_READ)   != VM_EVENT_DESC_TR);
+#undef E2D
 
-    case VMEXIT_TR_READ:
-    case VMEXIT_TR_WRITE:
-        hvm_descriptor_access_intercept(vmcb->exitintinfo.bytes, 0,
-            VM_EVENT_DESC_TR, exit_reason == VMEXIT_TR_WRITE);
+        hvm_descriptor_access_intercept(0, 0, desc, write);
         break;
+    }
 
     default:
     unexpected_exit_type:
index 959083d8c47a3f8742d709267f2c1c869eed5858..aa54c863255f8601764150056c3cb11948aba52f 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "xen.h"
 
-#define VM_EVENT_INTERFACE_VERSION 0x00000005
+#define VM_EVENT_INTERFACE_VERSION 0x00000006
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 
@@ -301,10 +301,6 @@ struct vm_event_desc_access {
             uint32_t _pad1;
             uint64_t exit_qualification; /* VMX: VMCS Exit Qualification */
         } vmx;
-        struct {
-            uint64_t exitinfo;           /* SVM: VMCB EXITINFO */
-            uint64_t _pad2;
-        } svm;
     } arch;
     uint8_t descriptor;                  /* VM_EVENT_DESC_* */
     uint8_t is_write;