From patchwork Mon Dec 19 10:29:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Palatin X-Patchwork-Id: 707032 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3thxzT2nbpz9snk for ; Mon, 19 Dec 2016 21:31:33 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="UKXb9CAx"; dkim-atps=neutral Received: from localhost ([::1]:44462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cIvEB-0007Cd-Ao for incoming@patchwork.ozlabs.org; Mon, 19 Dec 2016 05:31:31 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49341) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cIvCh-00062v-TN for qemu-devel@nongnu.org; Mon, 19 Dec 2016 05:30:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cIvCf-0000De-St for qemu-devel@nongnu.org; Mon, 19 Dec 2016 05:29:59 -0500 Received: from mail-wm0-x22d.google.com ([2a00:1450:400c:c09::22d]:36936) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cIvCf-0000DQ-Iq for qemu-devel@nongnu.org; Mon, 19 Dec 2016 05:29:57 -0500 Received: by mail-wm0-x22d.google.com with SMTP id t79so96558982wmt.0 for ; Mon, 19 Dec 2016 02:29:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=cGYnLf53f/8gOTWDkZ0kfoNS6F0gHDxpb8zGAlLEKfs=; b=UKXb9CAxvJQ6ZGzwN7IPYu/QyDix8+p77gRS3sEg4JAEprQg2pj2eH6+Du+Zh6IUoI vGrA/PJmn/FrUvitA6WHFvUXIYbsyGxy9yJYH2w2OcwK57fPr63sF6ZIeAHqndmFQEgY lA5lKGsR0j5G3hUSWV6D+OgVM6jz4euBA+RNZTTHnFBL5U7XE7fox81tLn1ZJ4sv2ycw 7BMDWi6HC7DqqkI8gGcqqas6M0Xxsxi9uKqocRcpyB2MBim/Ls3Mq5ryk2A2Kem6T7CZ P8xWJOlFXCLlFcg3ILe0rrXGrbswKgGJ7KFZ+FtR5pupcAhVKB7z1Qb8FXZBb9SOb7rN bDlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:in-reply-to:references; bh=cGYnLf53f/8gOTWDkZ0kfoNS6F0gHDxpb8zGAlLEKfs=; b=qCHZRcfABEK9mhBdKet1x1sI9DZfHCAlEitoe+YE4ZlrucnO10IQR01CW6wCb4x9iF y9fKsk3y07k9dwb9Z/MqWPRSwHbEqgGDHbYAg25xvsB3OG8WALZDIfDmIPo0Dz7a6GLV iGoXN4z0ocp9ZKUpBd4+ZU3rpFnIRf7bQCJ6+KGBBhQKiDzme0jnsx68evFCkDrlwija kQw5QHavXdC2/9CBYitBEu0GdljO4L7z8ywGMGayDy8W3wu5RSFLrh+y15Wy7lri1AYI jir5/7qCybfftJZKucUnVmSQivXFx4D53u/TqRE3EI8cAsWKrZdzk9ALPZztdf4MsFg5 bOfw== X-Gm-Message-State: AIkVDXJDaK+V/r87zOFE3ex39NMXkCrivy64q34xF4ePiJ5zwiJIgmXA34uz+Ytep3omeER4 X-Received: by 10.28.139.131 with SMTP id n125mr13062357wmd.116.1482143396224; Mon, 19 Dec 2016 02:29:56 -0800 (PST) Received: from vpalatin.zrh.corp.google.com ([172.16.114.40]) by smtp.gmail.com with ESMTPSA id i15sm19975223wjs.16.2016.12.19.02.29.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 19 Dec 2016 02:29:55 -0800 (PST) From: Vincent Palatin To: qemu-devel Date: Mon, 19 Dec 2016 11:29:05 +0100 Message-Id: <6eb546530b5563538d609ff204c594e06236adc9.1482143215.git.vpalatin@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::22d Subject: [Qemu-devel] [PATCH v4 4/4] hax: add Darwin support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Yu Ning , Vincent Palatin , Eduardo Habkost , "Michael S . Tsirkin" , Stefan Weil , Marcelo Tosatti , Paolo Bonzini Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 from emu-2.2-release branch in the external/qemu-android repository. Signed-off-by: Vincent Palatin --- cpus.c | 5 + target-i386/Makefile.objs | 3 + target-i386/hax-darwin.c | 316 ++++++++++++++++++++++++++++++++++++++++++++++ target-i386/hax-darwin.h | 63 +++++++++ target-i386/hax-i386.h | 8 ++ 5 files changed, 395 insertions(+) create mode 100644 target-i386/hax-darwin.c create mode 100644 target-i386/hax-darwin.h diff --git a/cpus.c b/cpus.c index 0e01791..b8db313 100644 --- a/cpus.c +++ b/cpus.c @@ -1264,6 +1264,11 @@ static void qemu_cpu_kick_thread(CPUState *cpu) return; } cpu->thread_kicked = true; +#ifdef CONFIG_DARWIN + if (hax_enabled()) { + cpu->exit_request = 1; + } +#endif err = pthread_kill(cpu->thread->thread, SIG_IPI); if (err) { fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); 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..240d8d3 --- /dev/null +++ b/target-i386/hax-darwin.c @@ -0,0 +1,316 @@ +/* + * QEMU HAXM support + * + * Copyright (c) 2011 Intel Corporation + * Written by: + * Jiang Yunhong + * + * 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 +#include +#include +#include +#include + +#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 + * Xin Xiaohui + * Zhang Xiantao + * + * 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 +#include +#include +#include + +#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 3f50bd9..b6becbd 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_region_init(void); +#ifdef CONFIG_DARWIN +#include "target-i386/hax-darwin.h" +#endif + #ifdef CONFIG_WIN32 #include "target-i386/hax-windows.h" #endif