summary refs log tree commit diff
path: root/crosvm_plugin
diff options
context:
space:
mode:
authorMatt Delco <delco@chromium.org>2020-02-25 18:01:05 -0800
committerCommit Bot <commit-bot@chromium.org>2020-03-05 19:01:24 +0000
commitd2a862b41f07d387926f0b984c56dc838003102c (patch)
treef7f03c7c31673efc0b29cc4bf74804f638dac172 /crosvm_plugin
parentb9f4c9bca30e65eacfb055951fa994ad5127a8f0 (diff)
downloadcrosvm-d2a862b41f07d387926f0b984c56dc838003102c.tar
crosvm-d2a862b41f07d387926f0b984c56dc838003102c.tar.gz
crosvm-d2a862b41f07d387926f0b984c56dc838003102c.tar.bz2
crosvm-d2a862b41f07d387926f0b984c56dc838003102c.tar.lz
crosvm-d2a862b41f07d387926f0b984c56dc838003102c.tar.xz
crosvm-d2a862b41f07d387926f0b984c56dc838003102c.tar.zst
crosvm-d2a862b41f07d387926f0b984c56dc838003102c.zip
crosvm: add handling for hyperv exits
When features for Hyper-V are enabled there's a another type of exit
that can be triggered.  This change attempts to add support for those
types of exits.

BUG=b:150151095
TEST=ran build_test

Change-Id: I3131a2c8d9c610576ac177dbfe82f78e8d5dbfb1
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2073254
Reviewed-by: Matt Delco <delco@chromium.org>
Tested-by: Matt Delco <delco@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Matt Delco <delco@chromium.org>
Auto-Submit: Matt Delco <delco@chromium.org>
Diffstat (limited to 'crosvm_plugin')
-rw-r--r--crosvm_plugin/crosvm.h37
-rw-r--r--crosvm_plugin/src/lib.rs49
2 files changed, 85 insertions, 1 deletions
diff --git a/crosvm_plugin/crosvm.h b/crosvm_plugin/crosvm.h
index db824b9..d1bea2a 100644
--- a/crosvm_plugin/crosvm.h
+++ b/crosvm_plugin/crosvm.h
@@ -47,7 +47,7 @@ extern "C" {
  * do not indicate anything about what version of crosvm is running.
  */
 #define CROSVM_API_MAJOR 0
-#define CROSVM_API_MINOR 21
+#define CROSVM_API_MINOR 22
 #define CROSVM_API_PATCH 0
 
 enum crosvm_address_space {
@@ -495,6 +495,16 @@ enum crosvm_vcpu_event_kind {
    * a `crosvm_pause_vcpus` call.
    */
   CROSVM_VCPU_EVENT_KIND_PAUSED,
+
+  /*
+   * Hyper-V hypercall.
+   */
+  CROSVM_VCPU_EVENT_KIND_HYPERV_HCALL,
+
+  /*
+   * Hyper-V synic change.
+   */
+  CROSVM_VCPU_EVENT_KIND_HYPERV_SYNIC,
 };
 
 struct crosvm_vcpu_event {
@@ -553,6 +563,31 @@ struct crosvm_vcpu_event {
     /* CROSVM_VCPU_EVENT_KIND_PAUSED */
     void *user;
 
+    /* CROSVM_VCPU_EVENT_KIND_HYPERV_HCALL */
+    struct {
+      /*
+       * The |input| and |params| members are populated for the plugin to use.
+       * The |result| member is populated by the API to point to a uint64_t
+       * that the plugin should update before resuming.
+       */
+      uint64_t input;
+      uint64_t *result;
+      uint64_t params[2];
+    } hyperv_call;
+
+    /* CROSVM_VCPU_EVENT_KIND_HYPERV_SYNIC */
+    struct {
+      /*
+       * The |msr|, |control|, |evt_page|, and |msg_page| fields are populated
+       * for the plugin to use.
+       */
+      uint32_t msr;
+      uint32_t _reserved;
+      uint64_t control;
+      uint64_t evt_page;
+      uint64_t msg_page;
+    } hyperv_synic;
+
     uint8_t _reserved[64];
   };
 };
diff --git a/crosvm_plugin/src/lib.rs b/crosvm_plugin/src/lib.rs
index 8695d41..05c19bf 100644
--- a/crosvm_plugin/src/lib.rs
+++ b/crosvm_plugin/src/lib.rs
@@ -59,6 +59,8 @@ const CROSVM_IRQ_ROUTE_MSI: u32 = 1;
 const CROSVM_VCPU_EVENT_KIND_INIT: u32 = 0;
 const CROSVM_VCPU_EVENT_KIND_IO_ACCESS: u32 = 1;
 const CROSVM_VCPU_EVENT_KIND_PAUSED: u32 = 2;
+const CROSVM_VCPU_EVENT_KIND_HYPERV_HCALL: u32 = 3;
+const CROSVM_VCPU_EVENT_KIND_HYPERV_SYNIC: u32 = 4;
 
 #[repr(C)]
 #[derive(Copy, Clone)]
@@ -925,10 +927,30 @@ struct anon_io_access {
     __reserved1: [u8; 2],
 }
 
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct anon_hyperv_call {
+    input: u64,
+    result: *mut u8,
+    params: [u64; 2],
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct anon_hyperv_synic {
+    msr: u32,
+    reserved: u32,
+    control: u64,
+    evt_page: u64,
+    msg_page: u64,
+}
+
 #[repr(C)]
 union anon_vcpu_event {
     io_access: anon_io_access,
     user: *mut c_void,
+    hyperv_call: anon_hyperv_call,
+    hyperv_synic: anon_hyperv_synic,
     #[allow(dead_code)]
     __reserved: [u8; 64],
 }
@@ -1118,6 +1140,33 @@ impl crosvm_vcpu {
             self.sregs.get = false;
             self.debugregs.get = false;
             Ok(())
+        } else if wait.has_hyperv_call() {
+            let hv: &VcpuResponse_Wait_HypervCall = wait.get_hyperv_call();
+            event.kind = CROSVM_VCPU_EVENT_KIND_HYPERV_HCALL;
+            self.resume_data = vec![0; 8];
+            event.event.hyperv_call = anon_hyperv_call {
+                input: hv.input,
+                result: self.resume_data.as_mut_ptr(),
+                params: [hv.params0, hv.params1],
+            };
+            self.regs.get = false;
+            self.sregs.get = false;
+            self.debugregs.get = false;
+            Ok(())
+        } else if wait.has_hyperv_synic() {
+            let hv: &VcpuResponse_Wait_HypervSynic = wait.get_hyperv_synic();
+            event.kind = CROSVM_VCPU_EVENT_KIND_HYPERV_SYNIC;
+            event.event.hyperv_synic = anon_hyperv_synic {
+                msr: hv.msr,
+                reserved: 0,
+                control: hv.control,
+                evt_page: hv.evt_page,
+                msg_page: hv.msg_page,
+            };
+            self.regs.get = false;
+            self.sregs.get = false;
+            self.debugregs.get = false;
+            Ok(())
         } else {
             Err(EPROTO)
         }