From patchwork Thu Oct 18 20:32:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 986329 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FDlOV9lP"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42bj6x1zcjz9sC2 for ; Fri, 19 Oct 2018 08:36:57 +1100 (AEDT) Received: from localhost ([::1]:44878 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gDFyQ-0003eE-So for incoming@patchwork.ozlabs.org; Thu, 18 Oct 2018 17:36:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48439) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gDEyc-0007i8-Ef for qemu-devel@nongnu.org; Thu, 18 Oct 2018 16:33:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gDEyY-0006aW-RK for qemu-devel@nongnu.org; Thu, 18 Oct 2018 16:33:02 -0400 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]:33369) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gDEyY-0006Yc-DE for qemu-devel@nongnu.org; Thu, 18 Oct 2018 16:32:58 -0400 Received: by mail-wr1-x42d.google.com with SMTP id e4-v6so35111093wrs.0 for ; Thu, 18 Oct 2018 13:32:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=G6IqdhkrdvpyaHD/SXoNFXNQmc5Z5cgNTKqDy96ex1M=; b=FDlOV9lPIf4gGIuvd+SKMrSk29jD5scZQb3uZzPu+mbkR5xf5Iu1B2g9ID1pU2IHgt c6GvptZRsFhuX1O6wbOmL5+9irJ88xqPD9vMFOLc+63dSzL3yShbeA7JHWptEiUK6E1O UfcbGgUQG3JSPRd2ju7Ph+BTa58Huzs1tOvnQ9JGvopKwh+tgpsMNtPtPIwF6rsFUmS0 5koocrNEAYWq3BWq7uARDepL+UxxbF7xagYb4CNlDaylqMJSh6MwlCF4UHIqdrqKlc4J rW2bkZ0qhR5PO/JPPCHYaI2qbkZIZXll2bJ6LX364IM1E9fKy51ff6Pzw2lNxoixAGBC cDNw== 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; bh=G6IqdhkrdvpyaHD/SXoNFXNQmc5Z5cgNTKqDy96ex1M=; b=VNe3q1lAK+BgKHk44pOR9dDPkVQWcqG6d1eZePvHDnkUcM9AoXL7UCaD4hh9yJGPuI tU/vJ/S//Ypcn6+BCYF+k6AeB61Mscbnxvt2Z96GyMb9fI8GIZ2/s8xtT0vunehpMJRG 0czemfan5FgYaTgVAQGpJMaBzpSSFrae/zkzBrquMsewilWFOh5KGpPOGErTayxZ/qRN 73b0Xt49s9sdMT0/mE00AgXmQulGNW+/HpnGnvFx2feELDicJAYQZcCt0KUKIzm3boDE LGgnKHyVDdAQEQT05X571LOBL7qkTVJXfCQKnALHj5Kb0qj26w90cAJ72Jr/mIdVEK2A h33w== X-Gm-Message-State: ABuFfogobhG90e2B2mazKAHxRQi083EuYsxN8M7F664j239Fp1y7ow6d 4dJc+/knc67nET8jJ4eoxqZGG5yE X-Google-Smtp-Source: ACcGV62KjFIE0p46URym09vEZORNqQ1kHyqeHxyWekqmQRFgHDsH4Ox+LDYiLpS8fFa/jXWHZvgfdA== X-Received: by 2002:a5d:698b:: with SMTP id g11-v6mr32341424wru.159.1539894775057; Thu, 18 Oct 2018 13:32:55 -0700 (PDT) Received: from 640k.lan (dynamic-adsl-78-12-231-174.clienti.tiscali.it. [78.12.231.174]) by smtp.gmail.com with ESMTPSA id a12-v6sm14270952wrr.71.2018.10.18.13.32.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Oct 2018 13:32:54 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 18 Oct 2018 22:32:01 +0200 Message-Id: <1539894735-14232-35-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1539894735-14232-1-git-send-email-pbonzini@redhat.com> References: <1539894735-14232-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42d Subject: [Qemu-devel] [PULL 34/48] hyperv: factor out arch-independent API into hw/hyperv 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: Roman Kagan Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Roman Kagan A significant part of hyperv.c is not actually tied to x86, and can be moved to hw/. This will allow to maintain most of Hyper-V and VMBus target-independent, and to avoid conflicts with inclusion of arch-specific headers down the road in VMBus implementation. Also this stuff can now be opt-out with CONFIG_HYPERV. Signed-off-by: Roman Kagan Message-Id: <20180921082041.29380-4-rkagan@virtuozzo.com> Signed-off-by: Paolo Bonzini --- hw/Makefile.objs | 1 + hw/hyperv/Makefile.objs | 2 + hw/hyperv/hyperv.c | 138 +++++++++++++++++++++++++++++++++++ hw/{misc => hyperv}/hyperv_testdev.c | 2 +- hw/misc/Makefile.objs | 1 - include/hw/hyperv/hyperv.h | 31 ++++++++ target/i386/hyperv.c | 127 +------------------------------- target/i386/hyperv.h | 17 +---- target/i386/kvm.c | 5 +- 9 files changed, 178 insertions(+), 146 deletions(-) create mode 100644 hw/hyperv/Makefile.objs create mode 100644 hw/hyperv/hyperv.c rename hw/{misc => hyperv}/hyperv_testdev.c (99%) create mode 100644 include/hw/hyperv/hyperv.h diff --git a/hw/Makefile.objs b/hw/Makefile.objs index a19c141..30722cc 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -9,6 +9,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += cpu/ devices-dirs-$(CONFIG_SOFTMMU) += display/ devices-dirs-$(CONFIG_SOFTMMU) += dma/ devices-dirs-$(CONFIG_SOFTMMU) += gpio/ +devices-dirs-$(CONFIG_HYPERV) += hyperv/ devices-dirs-$(CONFIG_SOFTMMU) += i2c/ devices-dirs-$(CONFIG_SOFTMMU) += ide/ devices-dirs-$(CONFIG_SOFTMMU) += input/ diff --git a/hw/hyperv/Makefile.objs b/hw/hyperv/Makefile.objs new file mode 100644 index 0000000..edaca2f --- /dev/null +++ b/hw/hyperv/Makefile.objs @@ -0,0 +1,2 @@ +obj-y += hyperv.o +obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c new file mode 100644 index 0000000..97db875 --- /dev/null +++ b/hw/hyperv/hyperv.c @@ -0,0 +1,138 @@ +/* + * Hyper-V guest/hypervisor interaction + * + * Copyright (c) 2015-2018 Virtuozzo International GmbH. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "sysemu/kvm.h" +#include "hw/hyperv/hyperv.h" + +struct HvSintRoute { + uint32_t sint; + CPUState *cs; + int gsi; + EventNotifier sint_set_notifier; + EventNotifier sint_ack_notifier; + HvSintAckClb sint_ack_clb; + void *sint_ack_clb_data; + unsigned refcount; +}; + +static CPUState *hyperv_find_vcpu(uint32_t vp_index) +{ + CPUState *cs = qemu_get_cpu(vp_index); + assert(hyperv_vp_index(cs) == vp_index); + return cs; +} + +static void kvm_hv_sint_ack_handler(EventNotifier *notifier) +{ + HvSintRoute *sint_route = container_of(notifier, HvSintRoute, + sint_ack_notifier); + event_notifier_test_and_clear(notifier); + sint_route->sint_ack_clb(sint_route->sint_ack_clb_data); +} + +HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint, + HvSintAckClb sint_ack_clb, + void *sint_ack_clb_data) +{ + HvSintRoute *sint_route; + EventNotifier *ack_notifier; + int r, gsi; + CPUState *cs; + + cs = hyperv_find_vcpu(vp_index); + if (!cs) { + return NULL; + } + + sint_route = g_new0(HvSintRoute, 1); + r = event_notifier_init(&sint_route->sint_set_notifier, false); + if (r) { + goto err; + } + + ack_notifier = sint_ack_clb ? &sint_route->sint_ack_notifier : NULL; + if (ack_notifier) { + r = event_notifier_init(ack_notifier, false); + if (r) { + goto err_sint_set_notifier; + } + + event_notifier_set_handler(ack_notifier, kvm_hv_sint_ack_handler); + } + + gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vp_index, sint); + if (gsi < 0) { + goto err_gsi; + } + + r = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, + &sint_route->sint_set_notifier, + ack_notifier, gsi); + if (r) { + goto err_irqfd; + } + sint_route->gsi = gsi; + sint_route->sint_ack_clb = sint_ack_clb; + sint_route->sint_ack_clb_data = sint_ack_clb_data; + sint_route->cs = cs; + sint_route->sint = sint; + sint_route->refcount = 1; + + return sint_route; + +err_irqfd: + kvm_irqchip_release_virq(kvm_state, gsi); +err_gsi: + if (ack_notifier) { + event_notifier_set_handler(ack_notifier, NULL); + event_notifier_cleanup(ack_notifier); + } +err_sint_set_notifier: + event_notifier_cleanup(&sint_route->sint_set_notifier); +err: + g_free(sint_route); + + return NULL; +} + +void hyperv_sint_route_ref(HvSintRoute *sint_route) +{ + sint_route->refcount++; +} + +void hyperv_sint_route_unref(HvSintRoute *sint_route) +{ + if (!sint_route) { + return; + } + + assert(sint_route->refcount > 0); + + if (--sint_route->refcount) { + return; + } + + kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, + &sint_route->sint_set_notifier, + sint_route->gsi); + kvm_irqchip_release_virq(kvm_state, sint_route->gsi); + if (sint_route->sint_ack_clb) { + event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL); + event_notifier_cleanup(&sint_route->sint_ack_notifier); + } + event_notifier_cleanup(&sint_route->sint_set_notifier); + g_free(sint_route); +} + +int hyperv_sint_route_set_sint(HvSintRoute *sint_route) +{ + return event_notifier_set(&sint_route->sint_set_notifier); +} diff --git a/hw/misc/hyperv_testdev.c b/hw/hyperv/hyperv_testdev.c similarity index 99% rename from hw/misc/hyperv_testdev.c rename to hw/hyperv/hyperv_testdev.c index 33bbd28..fc3f6c5 100644 --- a/hw/misc/hyperv_testdev.c +++ b/hw/hyperv/hyperv_testdev.c @@ -15,7 +15,7 @@ #include "qemu/queue.h" #include "hw/qdev.h" #include "hw/isa/isa.h" -#include "target/i386/hyperv.h" +#include "hw/hyperv/hyperv.h" typedef struct TestSintRoute { QLIST_ENTRY(TestSintRoute) le; diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 6d50b03..680350b 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -71,7 +71,6 @@ obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o obj-$(CONFIG_PVPANIC) += pvpanic.o -obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o obj-$(CONFIG_AUX) += auxbus.o obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o obj-$(CONFIG_MSF2) += msf2-sysreg.o diff --git a/include/hw/hyperv/hyperv.h b/include/hw/hyperv/hyperv.h new file mode 100644 index 0000000..d6c8d78 --- /dev/null +++ b/include/hw/hyperv/hyperv.h @@ -0,0 +1,31 @@ +/* + * Hyper-V guest/hypervisor interaction + * + * Copyright (c) 2015-2018 Virtuozzo International GmbH. + * + * 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 HW_HYPERV_HYPERV_H +#define HW_HYPERV_HYPERV_H + +#include "cpu-qom.h" + +typedef struct HvSintRoute HvSintRoute; +typedef void (*HvSintAckClb)(void *data); + +HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint, + HvSintAckClb sint_ack_clb, + void *sint_ack_clb_data); +void hyperv_sint_route_ref(HvSintRoute *sint_route); +void hyperv_sint_route_unref(HvSintRoute *sint_route); + +int hyperv_sint_route_set_sint(HvSintRoute *sint_route); + +static inline uint32_t hyperv_vp_index(CPUState *cs) +{ + return cs->cpu_index; +} + +#endif diff --git a/target/i386/hyperv.c b/target/i386/hyperv.c index 6881664..1eac727 100644 --- a/target/i386/hyperv.c +++ b/target/i386/hyperv.c @@ -12,28 +12,10 @@ */ #include "qemu/osdep.h" -#include "qemu/main-loop.h" #include "hyperv.h" +#include "hw/hyperv/hyperv.h" #include "hyperv-proto.h" -struct HvSintRoute { - uint32_t sint; - X86CPU *cpu; - int gsi; - EventNotifier sint_set_notifier; - EventNotifier sint_ack_notifier; - HvSintAckClb sint_ack_clb; - void *sint_ack_clb_data; - unsigned refcount; -}; - -static X86CPU *hyperv_find_vcpu(uint32_t vp_index) -{ - X86CPU *cpu = X86_CPU(qemu_get_cpu(vp_index)); - assert(hyperv_vp_index(cpu) == vp_index); - return cpu; -} - int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) { CPUX86State *env = &cpu->env; @@ -79,110 +61,3 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) return -1; } } - -static void kvm_hv_sint_ack_handler(EventNotifier *notifier) -{ - HvSintRoute *sint_route = container_of(notifier, HvSintRoute, - sint_ack_notifier); - event_notifier_test_and_clear(notifier); - sint_route->sint_ack_clb(sint_route->sint_ack_clb_data); -} - -HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint, - HvSintAckClb sint_ack_clb, - void *sint_ack_clb_data) -{ - HvSintRoute *sint_route; - EventNotifier *ack_notifier; - int r, gsi; - X86CPU *cpu; - - cpu = hyperv_find_vcpu(vp_index); - if (!cpu) { - return NULL; - } - - sint_route = g_new0(HvSintRoute, 1); - r = event_notifier_init(&sint_route->sint_set_notifier, false); - if (r) { - goto err; - } - - ack_notifier = sint_ack_clb ? &sint_route->sint_ack_notifier : NULL; - if (ack_notifier) { - r = event_notifier_init(ack_notifier, false); - if (r) { - goto err_sint_set_notifier; - } - - event_notifier_set_handler(ack_notifier, kvm_hv_sint_ack_handler); - } - - gsi = kvm_irqchip_add_hv_sint_route(kvm_state, vp_index, sint); - if (gsi < 0) { - goto err_gsi; - } - - r = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, - &sint_route->sint_set_notifier, - ack_notifier, gsi); - if (r) { - goto err_irqfd; - } - sint_route->gsi = gsi; - sint_route->sint_ack_clb = sint_ack_clb; - sint_route->sint_ack_clb_data = sint_ack_clb_data; - sint_route->cpu = cpu; - sint_route->sint = sint; - sint_route->refcount = 1; - - return sint_route; - -err_irqfd: - kvm_irqchip_release_virq(kvm_state, gsi); -err_gsi: - if (ack_notifier) { - event_notifier_set_handler(ack_notifier, NULL); - event_notifier_cleanup(ack_notifier); - } -err_sint_set_notifier: - event_notifier_cleanup(&sint_route->sint_set_notifier); -err: - g_free(sint_route); - - return NULL; -} - -void hyperv_sint_route_ref(HvSintRoute *sint_route) -{ - sint_route->refcount++; -} - -void hyperv_sint_route_unref(HvSintRoute *sint_route) -{ - if (!sint_route) { - return; - } - - assert(sint_route->refcount > 0); - - if (--sint_route->refcount) { - return; - } - - kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, - &sint_route->sint_set_notifier, - sint_route->gsi); - kvm_irqchip_release_virq(kvm_state, sint_route->gsi); - if (sint_route->sint_ack_clb) { - event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL); - event_notifier_cleanup(&sint_route->sint_ack_notifier); - } - event_notifier_cleanup(&sint_route->sint_set_notifier); - g_free(sint_route); -} - -int hyperv_sint_route_set_sint(HvSintRoute *sint_route) -{ - return event_notifier_set(&sint_route->sint_set_notifier); -} diff --git a/target/i386/hyperv.h b/target/i386/hyperv.h index 8d4619c..5c49251 100644 --- a/target/i386/hyperv.h +++ b/target/i386/hyperv.h @@ -16,23 +16,8 @@ #include "cpu.h" #include "sysemu/kvm.h" - -typedef struct HvSintRoute HvSintRoute; -typedef void (*HvSintAckClb)(void *data); +#include "hw/hyperv/hyperv.h" int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit); -HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint, - HvSintAckClb sint_ack_clb, - void *sint_ack_clb_data); -void hyperv_sint_route_ref(HvSintRoute *sint_route); -void hyperv_sint_route_unref(HvSintRoute *sint_route); - -int hyperv_sint_route_set_sint(HvSintRoute *sint_route); - -static inline uint32_t hyperv_vp_index(X86CPU *cpu) -{ - return CPU(cpu)->cpu_index; -} - #endif diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 4e62b5c..b0b42d2 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -774,7 +774,7 @@ static int hyperv_init_vcpu(X86CPU *cpu) } assert(ret == 1); - if (msr_data.entries[0].data != hyperv_vp_index(cpu)) { + if (msr_data.entries[0].data != hyperv_vp_index(CPU(cpu))) { error_report("kernel's vp_index != QEMU's vp_index"); return -ENXIO; } @@ -1949,7 +1949,8 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, env->msr_hv_runtime); } if (cpu->hyperv_vpindex && hv_vpindex_settable) { - kvm_msr_entry_add(cpu, HV_X64_MSR_VP_INDEX, hyperv_vp_index(cpu)); + kvm_msr_entry_add(cpu, HV_X64_MSR_VP_INDEX, + hyperv_vp_index(CPU(cpu))); } if (cpu->hyperv_synic) { int j;