Merge "Add fast mmio support"
diff --git a/target-i386/hax-all.c b/target-i386/hax-all.c
index 2c13250..2540f54 100644
--- a/target-i386/hax-all.c
+++ b/target-i386/hax-all.c
@@ -120,7 +120,7 @@
 }
 
 /* Current version */
-uint32_t hax_cur_version = 0x1;
+uint32_t hax_cur_version = 0x2;
 /* Least HAX kernel version */
 uint32_t hax_lest_version = 0x1;
 
@@ -395,6 +395,31 @@
     return ret;
 }
 
+int  hax_handle_fastmmio(CPUState *env, struct hax_fastmmio *hft)
+{
+    uint64_t buf = 0;
+
+    /*
+     * With fast MMIO, QEMU need not sync vCPU state with HAXM
+     * driver because it will only invoke MMIO handler
+     * However, some MMIO operations utilize virtual address like qemu_pipe
+     * Thus we need to sync the CR0, CR3 and CR4 so that QEMU
+     * can translate the guest virtual address to guest physical
+     * address
+     */
+    env->cr[0] = hft->_cr0;
+    env->cr[2] = hft->_cr2;
+    env->cr[3] = hft->_cr3;
+    env->cr[4] = hft->_cr4;
+
+    buf = hft->value;
+    cpu_physical_memory_rw(hft->gpa, &buf, hft->size, hft->direction);
+    if (hft->direction == 0)
+        hft->value = buf;
+
+    return 0;
+}
+
 int hax_handle_io(CPUState *env, uint32_t df, uint16_t port, int direction,
   int size, int count, void *buffer)
 {
@@ -542,6 +567,10 @@
             case HAX_EXIT_MMIO:
                 ret = HAX_EMUL_ONE;
                 break;
+            case HAX_EXIT_FAST_MMIO:
+                ret = hax_handle_fastmmio(env,
+                        (struct hax_fastmmio *)vcpu->iobuf);
+                break;
             case HAX_EXIT_REAL:
                 ret = HAX_EMUL_REAL;
                 break;
diff --git a/target-i386/hax-interface.h b/target-i386/hax-interface.h
index cb6d7c8..22d4acc 100644
--- a/target-i386/hax-interface.h
+++ b/target-i386/hax-interface.h
@@ -316,6 +316,14 @@
      * Now the vcpu is only paused when to be destroid, so simply return to hax
      */
     HAX_EXIT_PAUSED,
+    /* from API 2.0 */
+    /*
+     * In API 1.0, HAXM driver utilizes QEMU to decode and emulate MMIO
+     * operations.
+     * From 2.0, HAXM driver will decode some MMIO instructions to improve
+     * MMIO handling performance, especially for GLES hardware acceleration
+     */
+    HAX_EXIT_FAST_MMIO,
 };
 
 /*
@@ -391,4 +399,20 @@
     uint64_t mem_quota;
 };
 
+/* API 2.0 */
+
+struct hax_fastmmio
+{
+    uint64_t gpa;
+    uint64_t value;
+    uint8_t size;
+    uint8_t direction;
+    uint16_t reg_index;
+    uint32_t pad0;
+    uint64_t _cr0;
+    uint64_t _cr2;
+    uint64_t _cr3;
+    uint64_t _cr4;
+};
+
 #endif