Commit 1e10eb53 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream-hvf' into staging



Initial support for the HVF accelerator

# gpg: Signature made Sat 23 Dec 2017 07:51:18 GMT
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream-hvf:
  i386: hvf: cleanup x86_gen.h
  i386: hvf: remove VM_PANIC from "in"
  i386: hvf: remove addr_t
  i386: hvf: simplify flag handling
  i386: hvf: abort on decoding error
  i386: hvf: remove ZERO_INIT macro
  i386: hvf: remove more dead emulator code
  i386: hvf: unify register enums between HVF and the rest
  i386: hvf: header cleanup
  i386: hvf: move all hvf files in the same directory
  i386: hvf: inject General Protection Fault when vmexit through vmcall
  i386: hvf: refactor event injection code for hvf
  i386: hvf: implement vga dirty page tracking
  i386: refactor KVM cpuid code so that it applies to hvf as well
  i386: hvf: implement hvf_get_supported_cpuid
  i386: hvf: use new helper functions for put/get xsave
  i386: hvf: fix licensing issues; isolate task handling code (GPL v2-only)
  i386: hvf: add code base from Google's QEMU repository
  apic: add function to apic that will be used by hvf

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents b1e513ae 895f9fdf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
obj-$(call lnot,$(CONFIG_HAX)) += hax-stub.o
obj-$(call lnot,$(CONFIG_HVF)) += hvf-stub.o
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-$(call lnot,$(CONFIG_TCG)) += tcg-stub.o

accel/stubs/hvf-stub.c

0 → 100644
+31 −0
Original line number Diff line number Diff line
/*
 * QEMU HVF support
 *
 * Copyright 2017 Red Hat, Inc.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2 or later, as published by the Free Software Foundation,
 * and may be copied, distributed, and modified under those terms.
 *
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu-common.h"
#include "cpu.h"
#include "sysemu/hvf.h"

int hvf_init_vcpu(CPUState *cpu)
{
    return -ENOSYS;
}

int hvf_vcpu_exec(CPUState *cpu)
{
    return -ENOSYS;
}

void hvf_vcpu_destroy(CPUState *cpu)
{
}
+38 −0
Original line number Diff line number Diff line
@@ -211,6 +211,17 @@ supported_xen_target() {
    return 1
}

supported_hvf_target() {
    test "$hvf" = "yes" || return 1
    glob "$1" "*-softmmu" || return 1
    case "${1%-softmmu}" in
        x86_64)
            return 0
        ;;
    esac
    return 1
}

supported_target() {
    case "$1" in
        *-softmmu)
@@ -236,6 +247,7 @@ supported_target() {
    supported_kvm_target "$1" && return 0
    supported_xen_target "$1" && return 0
    supported_hax_target "$1" && return 0
    supported_hvf_target "$1" && return 0
    print_error "TCG disabled, but hardware accelerator not available for '$target'"
    return 1
}
@@ -325,6 +337,7 @@ vhost_vsock="no"
vhost_user=""
kvm="no"
hax="no"
hvf="no"
rdma=""
gprof="no"
debug_tcg="no"
@@ -741,6 +754,7 @@ Darwin)
  bsd="yes"
  darwin="yes"
  hax="yes"
  hvf="yes"
  LDFLAGS_SHARED="-bundle -undefined dynamic_lookup"
  if [ "$cpu" = "x86_64" ] ; then
    QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
@@ -1036,6 +1050,10 @@ for opt do
  ;;
  --enable-hax) hax="yes"
  ;;
  --disable-hvf) hvf="no"
  ;;
  --enable-hvf) hvf="yes"
  ;;
  --disable-tcg-interpreter) tcg_interpreter="no"
  ;;
  --enable-tcg-interpreter) tcg_interpreter="yes"
@@ -1529,6 +1547,7 @@ disabled with --disable-FEATURE, default is enabled if available:
  bluez           bluez stack connectivity
  kvm             KVM acceleration support
  hax             HAX acceleration support
  hvf             Hypervisor.framework acceleration support
  rdma            RDMA-based migration support
  vde             support for vde network
  netmap          support for netmap network
@@ -5055,6 +5074,21 @@ then
fi


#################################################
# Check to see if we have the Hypervisor framework
if [ "$darwin" == "yes" ] ; then
  cat > $TMPC << EOF
#include <Hypervisor/hv.h>
int main() { return 0;}
EOF
  if ! compile_object ""; then
    hvf='no'
  else
    hvf='yes'
    LDFLAGS="-framework Hypervisor $LDFLAGS"
  fi
fi

#################################################
# Sparc implicitly links with --relax, which is
# incompatible with -r, so --no-relax should be
@@ -5530,6 +5564,7 @@ echo "ATTR/XATTR support $attr"
echo "Install blobs     $blobs"
echo "KVM support       $kvm"
echo "HAX support       $hax"
echo "HVF support       $hvf"
echo "TCG support       $tcg"
if test "$tcg" = "yes" ; then
    echo "TCG debug enabled $debug_tcg"
@@ -6602,6 +6637,9 @@ fi
if supported_hax_target $target; then
    echo "CONFIG_HAX=y" >> $config_target_mak
fi
if supported_hvf_target $target; then
    echo "CONFIG_HVF=y" >> $config_target_mak
fi
if test "$target_bigendian" = "yes" ; then
  echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
fi
+86 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "sysemu/hw_accel.h"
#include "sysemu/kvm.h"
#include "sysemu/hax.h"
#include "sysemu/hvf.h"
#include "qmp-commands.h"
#include "exec/exec-all.h"

@@ -900,6 +901,10 @@ void cpu_synchronize_all_states(void)

    CPU_FOREACH(cpu) {
        cpu_synchronize_state(cpu);
        /* TODO: move to cpu_synchronize_state() */
        if (hvf_enabled()) {
            hvf_cpu_synchronize_state(cpu);
        }
    }
}

@@ -909,6 +914,10 @@ void cpu_synchronize_all_post_reset(void)

    CPU_FOREACH(cpu) {
        cpu_synchronize_post_reset(cpu);
        /* TODO: move to cpu_synchronize_post_reset() */
        if (hvf_enabled()) {
            hvf_cpu_synchronize_post_reset(cpu);
        }
    }
}

@@ -918,6 +927,10 @@ void cpu_synchronize_all_post_init(void)

    CPU_FOREACH(cpu) {
        cpu_synchronize_post_init(cpu);
        /* TODO: move to cpu_synchronize_post_init() */
        if (hvf_enabled()) {
            hvf_cpu_synchronize_post_init(cpu);
        }
    }
}

@@ -1107,6 +1120,14 @@ static void qemu_kvm_wait_io_event(CPUState *cpu)
    qemu_wait_io_event_common(cpu);
}

static void qemu_hvf_wait_io_event(CPUState *cpu)
{
    while (cpu_thread_is_idle(cpu)) {
        qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
    }
    qemu_wait_io_event_common(cpu);
}

static void *qemu_kvm_cpu_thread_fn(void *arg)
{
    CPUState *cpu = arg;
@@ -1444,6 +1465,48 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
    return NULL;
}

/* The HVF-specific vCPU thread function. This one should only run when the host
 * CPU supports the VMX "unrestricted guest" feature. */
static void *qemu_hvf_cpu_thread_fn(void *arg)
{
    CPUState *cpu = arg;

    int r;

    assert(hvf_enabled());

    rcu_register_thread();

    qemu_mutex_lock_iothread();
    qemu_thread_get_self(cpu->thread);

    cpu->thread_id = qemu_get_thread_id();
    cpu->can_do_io = 1;
    current_cpu = cpu;

    hvf_init_vcpu(cpu);

    /* signal CPU creation */
    cpu->created = true;
    qemu_cond_signal(&qemu_cpu_cond);

    do {
        if (cpu_can_run(cpu)) {
            r = hvf_vcpu_exec(cpu);
            if (r == EXCP_DEBUG) {
                cpu_handle_guest_debug(cpu);
            }
        }
        qemu_hvf_wait_io_event(cpu);
    } while (!cpu->unplug || cpu_can_run(cpu));

    hvf_vcpu_destroy(cpu);
    cpu->created = false;
    qemu_cond_signal(&qemu_cpu_cond);
    qemu_mutex_unlock_iothread();
    return NULL;
}

#ifdef _WIN32
static void CALLBACK dummy_apc_func(ULONG_PTR unused)
{
@@ -1761,6 +1824,27 @@ static void qemu_kvm_start_vcpu(CPUState *cpu)
    }
}

static void qemu_hvf_start_vcpu(CPUState *cpu)
{
    char thread_name[VCPU_THREAD_NAME_SIZE];

    /* HVF currently does not support TCG, and only runs in
     * unrestricted-guest mode. */
    assert(hvf_enabled());

    cpu->thread = g_malloc0(sizeof(QemuThread));
    cpu->halt_cond = g_malloc0(sizeof(QemuCond));
    qemu_cond_init(cpu->halt_cond);

    snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/HVF",
             cpu->cpu_index);
    qemu_thread_create(cpu->thread, thread_name, qemu_hvf_cpu_thread_fn,
                       cpu, QEMU_THREAD_JOINABLE);
    while (!cpu->created) {
        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
    }
}

static void qemu_dummy_start_vcpu(CPUState *cpu)
{
    char thread_name[VCPU_THREAD_NAME_SIZE];
@@ -1795,6 +1879,8 @@ void qemu_init_vcpu(CPUState *cpu)
        qemu_kvm_start_vcpu(cpu);
    } else if (hax_enabled()) {
        qemu_hax_start_vcpu(cpu);
    } else if (hvf_enabled()) {
        qemu_hvf_start_vcpu(cpu);
    } else if (tcg_enabled()) {
        qemu_tcg_init_vcpu(cpu);
    } else {
+12 −0
Original line number Diff line number Diff line
@@ -305,6 +305,18 @@ static void apic_set_tpr(APICCommonState *s, uint8_t val)
    }
}

int apic_get_highest_priority_irr(DeviceState *dev)
{
    APICCommonState *s;

    if (!dev) {
        /* no interrupts */
        return -1;
    }
    s = APIC_COMMON(dev);
    return get_highest_priority_int(s->irr);
}

static uint8_t apic_get_tpr(APICCommonState *s)
{
    apic_sync_vapic(s, SYNC_FROM_VAPIC);
Loading