x86: Enable KVM mode for Android x86 emulator (update/rebase)

This patch enables KVM mode on x86 Linux to boost performance of x86 emulaiton
if the hardware-based virtualization feature is present on the host machine.

Change-Id: I4b24474b3ec115a3b9a7bf017801f4f610253b09
Signed-off-by: Xiaohui Xin <xiaohui.xin@intel.com>
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
diff --git a/hw/goldfish_device.c b/hw/goldfish_device.c
index 3ced4ce..e98161a 100644
--- a/hw/goldfish_device.c
+++ b/hw/goldfish_device.c
@@ -12,6 +12,9 @@
 #include "qemu_file.h"
 #include "arm_pic.h"
 #include "goldfish_device.h"
+#ifdef TARGET_I386
+#include "kvm.h"
+#endif
 
 #define PDEV_BUS_OP_DONE        (0x00)
 #define PDEV_BUS_OP_REMOVE_DEV  (0x04)
@@ -148,8 +151,13 @@
             };
             break;
         case PDEV_BUS_GET_NAME:
-            if(s->current)
+            if(s->current) {
+#ifdef TARGET_I386
+                if(kvm_enabled())
+                    cpu_synchronize_state(cpu_single_env, 0);
+#endif
                 cpu_memory_rw_debug(cpu_single_env, value, (void*)s->current->name, strlen(s->current->name), 1);
+            }
             break;
         default:
             cpu_abort (cpu_single_env, "goldfish_bus_write: Bad offset %x\n", offset);
diff --git a/hw/goldfish_nand.c b/hw/goldfish_nand.c
index 6d2182f..8d9b5db 100644
--- a/hw/goldfish_nand.c
+++ b/hw/goldfish_nand.c
@@ -16,6 +16,10 @@
 #include "qemu_debug.h"
 #include "android/android.h"
 
+#ifdef TARGET_I386
+#include "kvm.h"
+#endif
+
 #define  DEBUG  1
 #if DEBUG
 #  define  D(...)    VERBOSE_PRINT(init,__VA_ARGS__)
@@ -374,6 +378,10 @@
         if(!eof) {
             read_len = do_read(dev->fd, dev->data, read_len);
         }
+#ifdef TARGET_I386
+        if (kvm_enabled())
+            cpu_synchronize_state(cpu_single_env, 0);
+#endif
         cpu_memory_rw_debug(cpu_single_env, data, dev->data, read_len, 1);
         data += read_len;
         len -= read_len;
@@ -393,6 +401,10 @@
     while(len > 0) {
         if(len < write_len)
             write_len = len;
+#ifdef TARGET_I386
+        if (kvm_enabled())
+                cpu_synchronize_state(cpu_single_env, 0);
+#endif
         cpu_memory_rw_debug(cpu_single_env, data, dev->data, write_len, 0);
         ret = do_write(dev->fd, dev->data, write_len);
         if(ret < write_len) {
@@ -455,6 +467,10 @@
     case NAND_CMD_GET_DEV_NAME:
         if(size > dev->devname_len)
             size = dev->devname_len;
+#ifdef TARGET_I386
+        if (kvm_enabled())
+                cpu_synchronize_state(cpu_single_env, 0);
+#endif
         cpu_memory_rw_debug(cpu_single_env, s->data, (uint8_t*)dev->devname, size, 1);
         return size;
     case NAND_CMD_READ:
@@ -464,6 +480,10 @@
             size = dev->max_size - addr;
         if(dev->fd >= 0)
             return nand_dev_read_file(dev, s->data, addr, size);
+#ifdef TARGET_I386
+        if (kvm_enabled())
+                cpu_synchronize_state(cpu_single_env, 0);
+#endif
         cpu_memory_rw_debug(cpu_single_env,s->data, &dev->data[addr], size, 1);
         return size;
     case NAND_CMD_WRITE:
@@ -475,6 +495,10 @@
             size = dev->max_size - addr;
         if(dev->fd >= 0)
             return nand_dev_write_file(dev, s->data, addr, size);
+#ifdef TARGET_I386
+        if (kvm_enabled())
+                cpu_synchronize_state(cpu_single_env, 0);
+#endif
         cpu_memory_rw_debug(cpu_single_env,s->data, &dev->data[addr], size, 0);
         return size;
     case NAND_CMD_ERASE:
diff --git a/hw/goldfish_tty.c b/hw/goldfish_tty.c
index 904a07b..fd8eca8 100644
--- a/hw/goldfish_tty.c
+++ b/hw/goldfish_tty.c
@@ -13,6 +13,10 @@
 #include "qemu-char.h"
 #include "goldfish_device.h"
 
+#ifdef TARGET_I386
+#include "kvm.h"
+#endif
+
 enum {
     TTY_PUT_CHAR       = 0x00,
     TTY_BYTES_READY    = 0x04,
@@ -126,6 +130,10 @@
                             if (to_write > len)
                                 to_write = len;
 
+#ifdef TARGET_I386
+                            if (kvm_enabled())
+                                cpu_synchronize_state(cpu_single_env, 0);
+#endif
                             cpu_memory_rw_debug(cpu_single_env, buf, (uint8_t*)temp, to_write, 0);
                             qemu_chr_write(s->cs, (const uint8_t*)temp, to_write);
                             buf += to_write;
@@ -138,6 +146,10 @@
                 case TTY_CMD_READ_BUFFER:
                     if(s->ptr_len > s->data_count)
                         cpu_abort (cpu_single_env, "goldfish_tty_write: reading more data than available %d %d\n", s->ptr_len, s->data_count);
+#ifdef TARGET_I386
+                    if (kvm_enabled())
+                        cpu_synchronize_state(cpu_single_env, 0);
+#endif
                     cpu_memory_rw_debug(cpu_single_env,s->ptr, s->data, s->ptr_len,1);
                     //printf("goldfish_tty_write: read %d bytes to %x\n", s->ptr_len, s->ptr);
                     if(s->data_count > s->ptr_len)