hax: Support for Linux hosts
authorAlexandro Sanchez Bach <asanchez@kryptoslogic.com>
Thu, 15 Nov 2018 01:33:30 +0000 (17:33 -0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 11 Jan 2019 12:57:24 +0000 (13:57 +0100)
Intel HAXM supports now 32-bit and 64-bit Linux hosts. This patch includes
the corresponding userland changes.

Since the Darwin userland backend is POSIX-compliant, the hax-darwin.{c,h}
files have been renamed to hax-posix.{c,h}. This prefix is consistent with
the naming used in the rest of QEMU.

Signed-off-by: Alexandro Sanchez Bach <asanchez@kryptoslogic.com>
Message-Id: <20181115013331.65820-1-asanchez@kryptoslogic.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
target/i386/Makefile.objs
target/i386/hax-darwin.c [deleted file]
target/i386/hax-darwin.h [deleted file]
target/i386/hax-i386.h
target/i386/hax-posix.c [new file with mode: 0644]
target/i386/hax-posix.h [new file with mode: 0644]

index 32bf9663002fbaaece6ec8bdefc2d725b3dd0bcd..cb9c2655259afc729cb0ed84bc1a2404168ff7fc 100644 (file)
@@ -12,10 +12,10 @@ obj-$(call lnot,$(CONFIG_HYPERV)) += hyperv-stub.o
 ifeq ($(CONFIG_WIN32),y)
 obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o
 endif
-ifeq ($(CONFIG_DARWIN),y)
-obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-darwin.o
-obj-$(CONFIG_HVF) += hvf/
+ifeq ($(CONFIG_POSIX),y)
+obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-posix.o
 endif
+obj-$(CONFIG_HVF) += hvf/
 obj-$(CONFIG_WHPX) += whpx-all.o
 endif
 obj-$(CONFIG_SEV) += sev.o
diff --git a/target/i386/hax-darwin.c b/target/i386/hax-darwin.c
deleted file mode 100644 (file)
index a5426a6..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * QEMU HAXM support
- *
- * Copyright (c) 2011 Intel Corporation
- *  Written by:
- *  Jiang Yunhong<yunhong.jiang@intel.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-/* HAX module interface - darwin version */
-#include "qemu/osdep.h"
-#include <sys/ioctl.h>
-
-#include "target/i386/hax-i386.h"
-
-hax_fd hax_mod_open(void)
-{
-    int fd = open("/dev/HAX", O_RDWR);
-    if (fd == -1) {
-        fprintf(stderr, "Failed to open the hax module\n");
-    }
-
-    fcntl(fd, F_SETFD, FD_CLOEXEC);
-
-    return fd;
-}
-
-int hax_populate_ram(uint64_t va, uint64_t size)
-{
-    int ret;
-
-    if (!hax_global.vm || !hax_global.vm->fd) {
-        fprintf(stderr, "Allocate memory before vm create?\n");
-        return -EINVAL;
-    }
-
-    if (hax_global.supports_64bit_ramblock) {
-        struct hax_ramblock_info ramblock = {
-            .start_va = va,
-            .size = size,
-            .reserved = 0
-        };
-
-        ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ADD_RAMBLOCK, &ramblock);
-    } else {
-        struct hax_alloc_ram_info info = {
-            .size = (uint32_t)size,
-            .pad = 0,
-            .va = va
-        };
-
-        ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info);
-    }
-    if (ret < 0) {
-        fprintf(stderr, "Failed to register RAM block: ret=%d, va=0x%" PRIx64
-                ", size=0x%" PRIx64 ", method=%s\n", ret, va, size,
-                hax_global.supports_64bit_ramblock ? "new" : "legacy");
-        return ret;
-    }
-    return 0;
-}
-
-int hax_set_ram(uint64_t start_pa, uint32_t size, uint64_t host_va, int flags)
-{
-    struct hax_set_ram_info info;
-    int ret;
-
-    info.pa_start = start_pa;
-    info.size = size;
-    info.va = host_va;
-    info.flags = (uint8_t) flags;
-
-    ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_SET_RAM, &info);
-    if (ret < 0) {
-        return -errno;
-    }
-    return 0;
-}
-
-int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap)
-{
-    int ret;
-
-    ret = ioctl(hax->fd, HAX_IOCTL_CAPABILITY, cap);
-    if (ret == -1) {
-        fprintf(stderr, "Failed to get HAX capability\n");
-        return -errno;
-    }
-
-    return 0;
-}
-
-int hax_mod_version(struct hax_state *hax, struct hax_module_version *version)
-{
-    int ret;
-
-    ret = ioctl(hax->fd, HAX_IOCTL_VERSION, version);
-    if (ret == -1) {
-        fprintf(stderr, "Failed to get HAX version\n");
-        return -errno;
-    }
-
-    return 0;
-}
-
-static char *hax_vm_devfs_string(int vm_id)
-{
-    char *name;
-
-    if (vm_id > MAX_VM_ID) {
-        fprintf(stderr, "Too big VM id\n");
-        return NULL;
-    }
-
-#define HAX_VM_DEVFS "/dev/hax_vm/vmxx"
-    name = g_strdup(HAX_VM_DEVFS);
-    if (!name) {
-        return NULL;
-    }
-
-    snprintf(name, sizeof HAX_VM_DEVFS, "/dev/hax_vm/vm%02d", vm_id);
-    return name;
-}
-
-static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id)
-{
-    char *name;
-
-    if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) {
-        fprintf(stderr, "Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id);
-        return NULL;
-    }
-
-#define HAX_VCPU_DEVFS "/dev/hax_vmxx/vcpuxx"
-    name = g_strdup(HAX_VCPU_DEVFS);
-    if (!name) {
-        return NULL;
-    }
-
-    snprintf(name, sizeof HAX_VCPU_DEVFS, "/dev/hax_vm%02d/vcpu%02d",
-             vm_id, vcpu_id);
-    return name;
-}
-
-int hax_host_create_vm(struct hax_state *hax, int *vmid)
-{
-    int ret;
-    int vm_id = 0;
-
-    if (hax_invalid_fd(hax->fd)) {
-        return -EINVAL;
-    }
-
-    if (hax->vm) {
-        return 0;
-    }
-
-    ret = ioctl(hax->fd, HAX_IOCTL_CREATE_VM, &vm_id);
-    *vmid = vm_id;
-    return ret;
-}
-
-hax_fd hax_host_open_vm(struct hax_state *hax, int vm_id)
-{
-    hax_fd fd;
-    char *vm_name = NULL;
-
-    vm_name = hax_vm_devfs_string(vm_id);
-    if (!vm_name) {
-        return -1;
-    }
-
-    fd = open(vm_name, O_RDWR);
-    g_free(vm_name);
-
-    fcntl(fd, F_SETFD, FD_CLOEXEC);
-
-    return fd;
-}
-
-int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion)
-{
-    int ret;
-
-    if (hax_invalid_fd(vm_fd)) {
-        return -EINVAL;
-    }
-
-    ret = ioctl(vm_fd, HAX_VM_IOCTL_NOTIFY_QEMU_VERSION, qversion);
-
-    if (ret < 0) {
-        fprintf(stderr, "Failed to notify qemu API version\n");
-        return ret;
-    }
-    return 0;
-}
-
-/* Simply assume the size should be bigger than the hax_tunnel,
- * since the hax_tunnel can be extended later with compatibility considered
- */
-int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid)
-{
-    int ret;
-
-    ret = ioctl(vm_fd, HAX_VM_IOCTL_VCPU_CREATE, &vcpuid);
-    if (ret < 0) {
-        fprintf(stderr, "Failed to create vcpu %x\n", vcpuid);
-    }
-
-    return ret;
-}
-
-hax_fd hax_host_open_vcpu(int vmid, int vcpuid)
-{
-    char *devfs_path = NULL;
-    hax_fd fd;
-
-    devfs_path = hax_vcpu_devfs_string(vmid, vcpuid);
-    if (!devfs_path) {
-        fprintf(stderr, "Failed to get the devfs\n");
-        return -EINVAL;
-    }
-
-    fd = open(devfs_path, O_RDWR);
-    g_free(devfs_path);
-    if (fd < 0) {
-        fprintf(stderr, "Failed to open the vcpu devfs\n");
-    }
-    fcntl(fd, F_SETFD, FD_CLOEXEC);
-    return fd;
-}
-
-int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu)
-{
-    int ret;
-    struct hax_tunnel_info info;
-
-    ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_SETUP_TUNNEL, &info);
-    if (ret) {
-        fprintf(stderr, "Failed to setup the hax tunnel\n");
-        return ret;
-    }
-
-    if (!valid_hax_tunnel_size(info.size)) {
-        fprintf(stderr, "Invalid hax tunnel size %x\n", info.size);
-        ret = -EINVAL;
-        return ret;
-    }
-
-    vcpu->tunnel = (struct hax_tunnel *) (intptr_t) (info.va);
-    vcpu->iobuf = (unsigned char *) (intptr_t) (info.io_va);
-    return 0;
-}
-
-int hax_vcpu_run(struct hax_vcpu_state *vcpu)
-{
-    return ioctl(vcpu->fd, HAX_VCPU_IOCTL_RUN, NULL);
-}
-
-int hax_sync_fpu(CPUArchState *env, struct fx_layout *fl, int set)
-{
-    int ret, fd;
-
-    fd = hax_vcpu_get_fd(env);
-    if (fd <= 0) {
-        return -1;
-    }
-
-    if (set) {
-        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_FPU, fl);
-    } else {
-        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_FPU, fl);
-    }
-    return ret;
-}
-
-int hax_sync_msr(CPUArchState *env, struct hax_msr_data *msrs, int set)
-{
-    int ret, fd;
-
-    fd = hax_vcpu_get_fd(env);
-    if (fd <= 0) {
-        return -1;
-    }
-    if (set) {
-        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_MSRS, msrs);
-    } else {
-        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_MSRS, msrs);
-    }
-    return ret;
-}
-
-int hax_sync_vcpu_state(CPUArchState *env, struct vcpu_state_t *state, int set)
-{
-    int ret, fd;
-
-    fd = hax_vcpu_get_fd(env);
-    if (fd <= 0) {
-        return -1;
-    }
-
-    if (set) {
-        ret = ioctl(fd, HAX_VCPU_SET_REGS, state);
-    } else {
-        ret = ioctl(fd, HAX_VCPU_GET_REGS, state);
-    }
-    return ret;
-}
-
-int hax_inject_interrupt(CPUArchState *env, int vector)
-{
-    int fd;
-
-    fd = hax_vcpu_get_fd(env);
-    if (fd <= 0) {
-        return -1;
-    }
-
-    return ioctl(fd, HAX_VCPU_IOCTL_INTERRUPT, &vector);
-}
diff --git a/target/i386/hax-darwin.h b/target/i386/hax-darwin.h
deleted file mode 100644 (file)
index 51af0e8..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * QEMU HAXM support
- *
- * Copyright (c) 2011 Intel Corporation
- *  Written by:
- *  Jiang Yunhong<yunhong.jiang@intel.com>
- *  Xin Xiaohui<xiaohui.xin@intel.com>
- *  Zhang Xiantao<xiantao.zhang@intel.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef TARGET_I386_HAX_DARWIN_H
-#define TARGET_I386_HAX_DARWIN_H
-
-#include <sys/ioctl.h>
-
-#define HAX_INVALID_FD  (-1)
-static inline int hax_invalid_fd(hax_fd fd)
-{
-    return fd <= 0;
-}
-
-static inline void hax_mod_close(struct hax_state *hax)
-{
-    close(hax->fd);
-}
-
-static inline void hax_close_fd(hax_fd fd)
-{
-    close(fd);
-}
-
-/* HAX model level ioctl */
-#define HAX_IOCTL_VERSION _IOWR(0, 0x20, struct hax_module_version)
-#define HAX_IOCTL_CREATE_VM _IOWR(0, 0x21, uint32_t)
-#define HAX_IOCTL_DESTROY_VM _IOW(0, 0x22, uint32_t)
-#define HAX_IOCTL_CAPABILITY _IOR(0, 0x23, struct hax_capabilityinfo)
-
-#define HAX_VM_IOCTL_VCPU_CREATE _IOWR(0, 0x80, uint32_t)
-#define HAX_VM_IOCTL_ALLOC_RAM _IOWR(0, 0x81, struct hax_alloc_ram_info)
-#define HAX_VM_IOCTL_SET_RAM _IOWR(0, 0x82, struct hax_set_ram_info)
-#define HAX_VM_IOCTL_VCPU_DESTROY _IOW(0, 0x83, uint32_t)
-#define HAX_VM_IOCTL_NOTIFY_QEMU_VERSION _IOW(0, 0x84, struct hax_qemu_version)
-#define HAX_VM_IOCTL_ADD_RAMBLOCK _IOW(0, 0x85, struct hax_ramblock_info)
-
-#define HAX_VCPU_IOCTL_RUN  _IO(0, 0xc0)
-#define HAX_VCPU_IOCTL_SET_MSRS _IOWR(0, 0xc1, struct hax_msr_data)
-#define HAX_VCPU_IOCTL_GET_MSRS _IOWR(0, 0xc2, struct hax_msr_data)
-
-#define HAX_VCPU_IOCTL_SET_FPU  _IOW(0, 0xc3, struct fx_layout)
-#define HAX_VCPU_IOCTL_GET_FPU  _IOR(0, 0xc4, struct fx_layout)
-
-#define HAX_VCPU_IOCTL_SETUP_TUNNEL _IOWR(0, 0xc5, struct hax_tunnel_info)
-#define HAX_VCPU_IOCTL_INTERRUPT _IOWR(0, 0xc6, uint32_t)
-#define HAX_VCPU_SET_REGS       _IOWR(0, 0xc7, struct vcpu_state_t)
-#define HAX_VCPU_GET_REGS       _IOWR(0, 0xc8, struct vcpu_state_t)
-
-#endif /* TARGET_I386_HAX_DARWIN_H */
index 6abc156f8871c0169475e02d78bf29086972649d..f13fa4638fc2bb2556b04019de4b5c39e7f22999 100644 (file)
@@ -16,7 +16,7 @@
 #include "cpu.h"
 #include "sysemu/hax.h"
 
-#ifdef CONFIG_DARWIN
+#ifdef CONFIG_POSIX
 typedef int hax_fd;
 #endif
 
@@ -82,8 +82,8 @@ hax_fd hax_mod_open(void);
 void hax_memory_init(void);
 
 
-#ifdef CONFIG_DARWIN
-#include "target/i386/hax-darwin.h"
+#ifdef CONFIG_POSIX
+#include "target/i386/hax-posix.h"
 #endif
 
 #ifdef CONFIG_WIN32
diff --git a/target/i386/hax-posix.c b/target/i386/hax-posix.c
new file mode 100644 (file)
index 0000000..a5426a6
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * QEMU HAXM support
+ *
+ * Copyright (c) 2011 Intel Corporation
+ *  Written by:
+ *  Jiang Yunhong<yunhong.jiang@intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/* HAX module interface - darwin version */
+#include "qemu/osdep.h"
+#include <sys/ioctl.h>
+
+#include "target/i386/hax-i386.h"
+
+hax_fd hax_mod_open(void)
+{
+    int fd = open("/dev/HAX", O_RDWR);
+    if (fd == -1) {
+        fprintf(stderr, "Failed to open the hax module\n");
+    }
+
+    fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+    return fd;
+}
+
+int hax_populate_ram(uint64_t va, uint64_t size)
+{
+    int ret;
+
+    if (!hax_global.vm || !hax_global.vm->fd) {
+        fprintf(stderr, "Allocate memory before vm create?\n");
+        return -EINVAL;
+    }
+
+    if (hax_global.supports_64bit_ramblock) {
+        struct hax_ramblock_info ramblock = {
+            .start_va = va,
+            .size = size,
+            .reserved = 0
+        };
+
+        ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ADD_RAMBLOCK, &ramblock);
+    } else {
+        struct hax_alloc_ram_info info = {
+            .size = (uint32_t)size,
+            .pad = 0,
+            .va = va
+        };
+
+        ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info);
+    }
+    if (ret < 0) {
+        fprintf(stderr, "Failed to register RAM block: ret=%d, va=0x%" PRIx64
+                ", size=0x%" PRIx64 ", method=%s\n", ret, va, size,
+                hax_global.supports_64bit_ramblock ? "new" : "legacy");
+        return ret;
+    }
+    return 0;
+}
+
+int hax_set_ram(uint64_t start_pa, uint32_t size, uint64_t host_va, int flags)
+{
+    struct hax_set_ram_info info;
+    int ret;
+
+    info.pa_start = start_pa;
+    info.size = size;
+    info.va = host_va;
+    info.flags = (uint8_t) flags;
+
+    ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_SET_RAM, &info);
+    if (ret < 0) {
+        return -errno;
+    }
+    return 0;
+}
+
+int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap)
+{
+    int ret;
+
+    ret = ioctl(hax->fd, HAX_IOCTL_CAPABILITY, cap);
+    if (ret == -1) {
+        fprintf(stderr, "Failed to get HAX capability\n");
+        return -errno;
+    }
+
+    return 0;
+}
+
+int hax_mod_version(struct hax_state *hax, struct hax_module_version *version)
+{
+    int ret;
+
+    ret = ioctl(hax->fd, HAX_IOCTL_VERSION, version);
+    if (ret == -1) {
+        fprintf(stderr, "Failed to get HAX version\n");
+        return -errno;
+    }
+
+    return 0;
+}
+
+static char *hax_vm_devfs_string(int vm_id)
+{
+    char *name;
+
+    if (vm_id > MAX_VM_ID) {
+        fprintf(stderr, "Too big VM id\n");
+        return NULL;
+    }
+
+#define HAX_VM_DEVFS "/dev/hax_vm/vmxx"
+    name = g_strdup(HAX_VM_DEVFS);
+    if (!name) {
+        return NULL;
+    }
+
+    snprintf(name, sizeof HAX_VM_DEVFS, "/dev/hax_vm/vm%02d", vm_id);
+    return name;
+}
+
+static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id)
+{
+    char *name;
+
+    if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) {
+        fprintf(stderr, "Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id);
+        return NULL;
+    }
+
+#define HAX_VCPU_DEVFS "/dev/hax_vmxx/vcpuxx"
+    name = g_strdup(HAX_VCPU_DEVFS);
+    if (!name) {
+        return NULL;
+    }
+
+    snprintf(name, sizeof HAX_VCPU_DEVFS, "/dev/hax_vm%02d/vcpu%02d",
+             vm_id, vcpu_id);
+    return name;
+}
+
+int hax_host_create_vm(struct hax_state *hax, int *vmid)
+{
+    int ret;
+    int vm_id = 0;
+
+    if (hax_invalid_fd(hax->fd)) {
+        return -EINVAL;
+    }
+
+    if (hax->vm) {
+        return 0;
+    }
+
+    ret = ioctl(hax->fd, HAX_IOCTL_CREATE_VM, &vm_id);
+    *vmid = vm_id;
+    return ret;
+}
+
+hax_fd hax_host_open_vm(struct hax_state *hax, int vm_id)
+{
+    hax_fd fd;
+    char *vm_name = NULL;
+
+    vm_name = hax_vm_devfs_string(vm_id);
+    if (!vm_name) {
+        return -1;
+    }
+
+    fd = open(vm_name, O_RDWR);
+    g_free(vm_name);
+
+    fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+    return fd;
+}
+
+int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion)
+{
+    int ret;
+
+    if (hax_invalid_fd(vm_fd)) {
+        return -EINVAL;
+    }
+
+    ret = ioctl(vm_fd, HAX_VM_IOCTL_NOTIFY_QEMU_VERSION, qversion);
+
+    if (ret < 0) {
+        fprintf(stderr, "Failed to notify qemu API version\n");
+        return ret;
+    }
+    return 0;
+}
+
+/* Simply assume the size should be bigger than the hax_tunnel,
+ * since the hax_tunnel can be extended later with compatibility considered
+ */
+int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid)
+{
+    int ret;
+
+    ret = ioctl(vm_fd, HAX_VM_IOCTL_VCPU_CREATE, &vcpuid);
+    if (ret < 0) {
+        fprintf(stderr, "Failed to create vcpu %x\n", vcpuid);
+    }
+
+    return ret;
+}
+
+hax_fd hax_host_open_vcpu(int vmid, int vcpuid)
+{
+    char *devfs_path = NULL;
+    hax_fd fd;
+
+    devfs_path = hax_vcpu_devfs_string(vmid, vcpuid);
+    if (!devfs_path) {
+        fprintf(stderr, "Failed to get the devfs\n");
+        return -EINVAL;
+    }
+
+    fd = open(devfs_path, O_RDWR);
+    g_free(devfs_path);
+    if (fd < 0) {
+        fprintf(stderr, "Failed to open the vcpu devfs\n");
+    }
+    fcntl(fd, F_SETFD, FD_CLOEXEC);
+    return fd;
+}
+
+int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu)
+{
+    int ret;
+    struct hax_tunnel_info info;
+
+    ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_SETUP_TUNNEL, &info);
+    if (ret) {
+        fprintf(stderr, "Failed to setup the hax tunnel\n");
+        return ret;
+    }
+
+    if (!valid_hax_tunnel_size(info.size)) {
+        fprintf(stderr, "Invalid hax tunnel size %x\n", info.size);
+        ret = -EINVAL;
+        return ret;
+    }
+
+    vcpu->tunnel = (struct hax_tunnel *) (intptr_t) (info.va);
+    vcpu->iobuf = (unsigned char *) (intptr_t) (info.io_va);
+    return 0;
+}
+
+int hax_vcpu_run(struct hax_vcpu_state *vcpu)
+{
+    return ioctl(vcpu->fd, HAX_VCPU_IOCTL_RUN, NULL);
+}
+
+int hax_sync_fpu(CPUArchState *env, struct fx_layout *fl, int set)
+{
+    int ret, fd;
+
+    fd = hax_vcpu_get_fd(env);
+    if (fd <= 0) {
+        return -1;
+    }
+
+    if (set) {
+        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_FPU, fl);
+    } else {
+        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_FPU, fl);
+    }
+    return ret;
+}
+
+int hax_sync_msr(CPUArchState *env, struct hax_msr_data *msrs, int set)
+{
+    int ret, fd;
+
+    fd = hax_vcpu_get_fd(env);
+    if (fd <= 0) {
+        return -1;
+    }
+    if (set) {
+        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_MSRS, msrs);
+    } else {
+        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_MSRS, msrs);
+    }
+    return ret;
+}
+
+int hax_sync_vcpu_state(CPUArchState *env, struct vcpu_state_t *state, int set)
+{
+    int ret, fd;
+
+    fd = hax_vcpu_get_fd(env);
+    if (fd <= 0) {
+        return -1;
+    }
+
+    if (set) {
+        ret = ioctl(fd, HAX_VCPU_SET_REGS, state);
+    } else {
+        ret = ioctl(fd, HAX_VCPU_GET_REGS, state);
+    }
+    return ret;
+}
+
+int hax_inject_interrupt(CPUArchState *env, int vector)
+{
+    int fd;
+
+    fd = hax_vcpu_get_fd(env);
+    if (fd <= 0) {
+        return -1;
+    }
+
+    return ioctl(fd, HAX_VCPU_IOCTL_INTERRUPT, &vector);
+}
diff --git a/target/i386/hax-posix.h b/target/i386/hax-posix.h
new file mode 100644 (file)
index 0000000..51af0e8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * QEMU HAXM support
+ *
+ * Copyright (c) 2011 Intel Corporation
+ *  Written by:
+ *  Jiang Yunhong<yunhong.jiang@intel.com>
+ *  Xin Xiaohui<xiaohui.xin@intel.com>
+ *  Zhang Xiantao<xiantao.zhang@intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef TARGET_I386_HAX_DARWIN_H
+#define TARGET_I386_HAX_DARWIN_H
+
+#include <sys/ioctl.h>
+
+#define HAX_INVALID_FD  (-1)
+static inline int hax_invalid_fd(hax_fd fd)
+{
+    return fd <= 0;
+}
+
+static inline void hax_mod_close(struct hax_state *hax)
+{
+    close(hax->fd);
+}
+
+static inline void hax_close_fd(hax_fd fd)
+{
+    close(fd);
+}
+
+/* HAX model level ioctl */
+#define HAX_IOCTL_VERSION _IOWR(0, 0x20, struct hax_module_version)
+#define HAX_IOCTL_CREATE_VM _IOWR(0, 0x21, uint32_t)
+#define HAX_IOCTL_DESTROY_VM _IOW(0, 0x22, uint32_t)
+#define HAX_IOCTL_CAPABILITY _IOR(0, 0x23, struct hax_capabilityinfo)
+
+#define HAX_VM_IOCTL_VCPU_CREATE _IOWR(0, 0x80, uint32_t)
+#define HAX_VM_IOCTL_ALLOC_RAM _IOWR(0, 0x81, struct hax_alloc_ram_info)
+#define HAX_VM_IOCTL_SET_RAM _IOWR(0, 0x82, struct hax_set_ram_info)
+#define HAX_VM_IOCTL_VCPU_DESTROY _IOW(0, 0x83, uint32_t)
+#define HAX_VM_IOCTL_NOTIFY_QEMU_VERSION _IOW(0, 0x84, struct hax_qemu_version)
+#define HAX_VM_IOCTL_ADD_RAMBLOCK _IOW(0, 0x85, struct hax_ramblock_info)
+
+#define HAX_VCPU_IOCTL_RUN  _IO(0, 0xc0)
+#define HAX_VCPU_IOCTL_SET_MSRS _IOWR(0, 0xc1, struct hax_msr_data)
+#define HAX_VCPU_IOCTL_GET_MSRS _IOWR(0, 0xc2, struct hax_msr_data)
+
+#define HAX_VCPU_IOCTL_SET_FPU  _IOW(0, 0xc3, struct fx_layout)
+#define HAX_VCPU_IOCTL_GET_FPU  _IOR(0, 0xc4, struct fx_layout)
+
+#define HAX_VCPU_IOCTL_SETUP_TUNNEL _IOWR(0, 0xc5, struct hax_tunnel_info)
+#define HAX_VCPU_IOCTL_INTERRUPT _IOWR(0, 0xc6, uint32_t)
+#define HAX_VCPU_SET_REGS       _IOWR(0, 0xc7, struct vcpu_state_t)
+#define HAX_VCPU_GET_REGS       _IOWR(0, 0xc8, struct vcpu_state_t)
+
+#endif /* TARGET_I386_HAX_DARWIN_H */