All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Vincent Palatin <vpalatin@chromium.org>
Subject: [Qemu-devel] [PULL 32/35] hax: add Darwin support
Date: Fri, 20 Jan 2017 14:31:36 +0100	[thread overview]
Message-ID: <20170120133139.31080-33-pbonzini@redhat.com> (raw)
In-Reply-To: <20170120133139.31080-1-pbonzini@redhat.com>

From: Vincent Palatin <vpalatin@chromium.org>

Re-add the MacOSX/Darwin support:
Use the Intel HAX is kernel-based hardware acceleration module
(similar to KVM on Linux).

Based on the original "target/i386: Add Intel HAX to android emulator" patch
from David Chou <david.j.chou@intel.com> from  emu-2.2-release branch in
the external/qemu-android repository.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Message-Id: <81b85c3032da902e73e77302af508b4b1a7c0ead.1484045952.git.vpalatin@chromium.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/Makefile.objs |   3 +
 target/i386/hax-darwin.c  | 316 ++++++++++++++++++++++++++++++++++++++++++++++
 target/i386/hax-darwin.h  |  63 +++++++++
 target/i386/hax-i386.h    |   8 ++
 4 files changed, 390 insertions(+)
 create mode 100644 target/i386/hax-darwin.c
 create mode 100644 target/i386/hax-darwin.h

diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index acbe7b0..4fcb7f3 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -9,3 +9,6 @@ obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 ifdef CONFIG_WIN32
 obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o
 endif
+ifdef CONFIG_DARWIN
+obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-darwin.o
+endif
diff --git a/target/i386/hax-darwin.c b/target/i386/hax-darwin.c
new file mode 100644
index 0000000..1c5bbd0
--- /dev/null
+++ b/target/i386/hax-darwin.c
@@ -0,0 +1,316 @@
+/*
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include "qemu/osdep.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, uint32_t size)
+{
+    int ret;
+    struct hax_alloc_ram_info info;
+
+    if (!hax_global.vm || !hax_global.vm->fd) {
+        fprintf(stderr, "Allocate memory before vm create?\n");
+        return -EINVAL;
+    }
+
+    info.size = size;
+    info.va = va;
+    ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info);
+    if (ret < 0) {
+        fprintf(stderr, "Failed to allocate %x memory\n", size);
+        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)
+{
+    int ret;
+
+    ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_RUN, NULL);
+    return ret;
+}
+
+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 ret, fd;
+
+    fd = hax_vcpu_get_fd(env);
+    if (fd <= 0) {
+        return -1;
+    }
+
+    ret = ioctl(fd, HAX_VCPU_IOCTL_INTERRUPT, &vector);
+    return ret;
+}
diff --git a/target/i386/hax-darwin.h b/target/i386/hax-darwin.h
new file mode 100644
index 0000000..0c0968b
--- /dev/null
+++ b/target/i386/hax-darwin.h
@@ -0,0 +1,63 @@
+/*
+ * 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/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdarg.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_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 */
diff --git a/target/i386/hax-i386.h b/target/i386/hax-i386.h
index bcbd105..8ffe91f 100644
--- a/target/i386/hax-i386.h
+++ b/target/i386/hax-i386.h
@@ -16,6 +16,10 @@
 #include "cpu.h"
 #include "sysemu/hax.h"
 
+#ifdef CONFIG_DARWIN
+typedef int hax_fd;
+#endif
+
 #ifdef CONFIG_WIN32
 typedef HANDLE hax_fd;
 #endif
@@ -77,6 +81,10 @@ hax_fd hax_mod_open(void);
 void hax_memory_init(void);
 
 
+#ifdef CONFIG_DARWIN
+#include "target/i386/hax-darwin.h"
+#endif
+
 #ifdef CONFIG_WIN32
 #include "target/i386/hax-windows.h"
 #endif
-- 
2.9.3

  parent reply	other threads:[~2017-01-20 13:32 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-20 13:31 [Qemu-devel] [PULL v3 00/32] Misc patches for 2017-01-11 Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 01/35] bugfix: vm halt when in reset looping Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 02/35] megasas: fix guest-triggered memory leak Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 03/35] qom: Make all interface types abstract Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 04/35] smbios: filter based on CONFIG_SMBIOS rather than TARGET Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 05/35] stubs: merge all monitor stubs in one file, remove monitor_cur_is_qmp stub Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 06/35] stubs: move smbios stubs to hw/smbios Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 07/35] stubs: move acpi stubs to hw/acpi Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 08/35] stubs: remove unused stub for serial_hd Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 09/35] hw: move reset handlers from vl.c to hw/core Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 10/35] stubs: group stubs for user-mode emulation Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 11/35] stubs: group all monitor_fdset_* functions in a single file Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 12/35] stubs: move vhost stubs to stubs/vhost.o Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 13/35] event_notifier: cleanups around event_notifier_set_handler Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 14/35] build: remove --enable-colo/--disable-colo Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 15/35] stubs: remove stubs/kvm.c Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 16/35] acpi: filter based on CONFIG_ACPI_X86 rather than TARGET Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 17/35] pc: fix crash in rtc_set_memory() if initial cpu is marked as hotplugged Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 18/35] scsi-block: fix direction of BYTCHK test for VERIFY commands Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 19/35] serial: fix memory leak in serial exit Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 20/35] qemu-thread: fix qemu_thread_set_name() race in qemu_thread_create() Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 21/35] hxtool: emit Texinfo headings as @subsection Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 22/35] x86: ioapic: add traces for ioapic Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 23/35] x86: ioapic: dump version for "info ioapic" Paolo Bonzini
2017-01-30 14:07   ` Peter Maydell
2017-01-30 19:33     ` Paolo Bonzini
2017-02-03  7:12       ` Peter Xu
2017-01-20 13:31 ` [Qemu-devel] [PULL 24/35] x86: ioapic: fix fail migration when irqchip=split Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 25/35] exec: Add missing rcu_read_unlock Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 26/35] char: fix ctrl-a b not working Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 27/35] ramblock-notifier: new Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 28/35] KVM: PPC: eliminate unnecessary duplicate constants Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 29/35] kvm: move cpu synchronization code Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 30/35] target/i386: Add Intel HAX files Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 31/35] Plumb the HAXM-based hardware acceleration support Paolo Bonzini
2017-01-20 13:31 ` Paolo Bonzini [this message]
2017-01-20 13:31 ` [Qemu-devel] [PULL 33/35] Revert "win32: don't run subprocess tests on Mingw32 platform" Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 34/35] bitmap: assert that start and nr are non negative Paolo Bonzini
2017-01-20 13:31 ` [Qemu-devel] [PULL 35/35] pc.h: move x-mach-use-reliable-get-clock compat entry to PC_COMPAT_2_8 Paolo Bonzini
2017-01-20 15:16 ` [Qemu-devel] [PULL v3 00/32] Misc patches for 2017-01-11 no-reply
2017-01-20 17:16 ` Paolo Bonzini
2017-01-23 10:07 ` Peter Maydell
2017-01-23 14:02   ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170120133139.31080-33-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=vpalatin@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.