diff mbox series

[3/5] hyperv: factor out arch-independent API into hw/hyperv

Message ID 20180921082041.29380-4-rkagan@virtuozzo.com (mailing list archive)
State New, archived
Headers show
Series hyperv: move to hw/ and allow opt-out | expand

Commit Message

Roman Kagan Sept. 21, 2018, 8:20 a.m. UTC
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 <rkagan@virtuozzo.com>
---
 {target/i386 => include/hw/hyperv}/hyperv.h |  21 ++--
 target/i386/hyperv.h                        |  17 +--
 {target/i386 => hw/hyperv}/hyperv.c         |  76 ++----------
 hw/misc/hyperv_testdev.c                    |   2 +-
 target/i386/hyperv.c                        | 127 +-------------------
 target/i386/kvm.c                           |   5 +-
 hw/Makefile.objs                            |   1 +
 hw/hyperv/Makefile.objs                     |   1 +
 8 files changed, 28 insertions(+), 222 deletions(-)
 copy {target/i386 => include/hw/hyperv}/hyperv.h (59%)
 copy {target/i386 => hw/hyperv}/hyperv.c (65%)
 create mode 100644 hw/hyperv/Makefile.objs

Comments

Paolo Bonzini Oct. 3, 2018, 10:56 a.m. UTC | #1
On 21/09/2018 10:20, Roman Kagan wrote:
> 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 <rkagan@virtuozzo.com>

We can squash this in too:

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index b8f4675219..30722ccf98 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -9,7 +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_SOFTMMU) += hyperv/
+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
index 19928b726e..edaca2f763 100644
--- a/hw/hyperv/Makefile.objs
+++ b/hw/hyperv/Makefile.objs
@@ -1 +1,2 @@
-obj-$(CONFIG_HYPERV) += hyperv.o
+obj-y += hyperv.o
+obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
diff --git a/hw/misc/hyperv_testdev.c b/hw/hyperv/hyperv_testdev.c
similarity index 100%
rename from hw/misc/hyperv_testdev.c
rename to hw/hyperv/hyperv_testdev.c
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 6d50b03cfd..680350b3c3 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


Paolo
Roman Kagan Oct. 3, 2018, 11:34 a.m. UTC | #2
On Wed, Oct 03, 2018 at 12:56:00PM +0200, Paolo Bonzini wrote:
> On 21/09/2018 10:20, Roman Kagan wrote:
> > 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 <rkagan@virtuozzo.com>
> 
> We can squash this in too:
> 
> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> index b8f4675219..30722ccf98 100644
> --- a/hw/Makefile.objs
> +++ b/hw/Makefile.objs
...
> -devices-dirs-$(CONFIG_SOFTMMU) += hyperv/
> +devices-dirs-$(CONFIG_HYPERV) += hyperv/
...
> --- a/hw/hyperv/Makefile.objs
> +++ b/hw/hyperv/Makefile.objs
...
> -obj-$(CONFIG_HYPERV) += hyperv.o
> +obj-y += hyperv.o

Actually I did it this way at first, but then decided to follow the
pattern of virtio/, xen/, and most other subdirectories there just for
consistency.  Is there any preference for this?

> +obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
> diff --git a/hw/misc/hyperv_testdev.c b/hw/hyperv/hyperv_testdev.c
> similarity index 100%
> rename from hw/misc/hyperv_testdev.c
> rename to hw/hyperv/hyperv_testdev.c
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index 6d50b03cfd..680350b3c3 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

Fine by me.

Thanks,
Roman.
Paolo Bonzini Oct. 3, 2018, 11:47 a.m. UTC | #3
On 03/10/2018 13:34, Roman Kagan wrote:
> On Wed, Oct 03, 2018 at 12:56:00PM +0200, Paolo Bonzini wrote:
>> On 21/09/2018 10:20, Roman Kagan wrote:
>>> 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 <rkagan@virtuozzo.com>
>>
>> We can squash this in too:
>>
>> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
>> index b8f4675219..30722ccf98 100644
>> --- a/hw/Makefile.objs
>> +++ b/hw/Makefile.objs
> ...
>> -devices-dirs-$(CONFIG_SOFTMMU) += hyperv/
>> +devices-dirs-$(CONFIG_HYPERV) += hyperv/
> ...
>> --- a/hw/hyperv/Makefile.objs
>> +++ b/hw/hyperv/Makefile.objs
> ...
>> -obj-$(CONFIG_HYPERV) += hyperv.o
>> +obj-y += hyperv.o
> 
> Actually I did it this way at first, but then decided to follow the
> pattern of virtio/, xen/, and most other subdirectories there just for
> consistency.  Is there any preference for this?

It's half-and-half.  For example, CONFIG_IPMI, CONFIG_SCSI,
CONFIG_VIRTFS work this way.

acpi/ and virtio/ use CONFIG_SOFTMMU just because they need to compile
acpi-stub.o/ipmi-stub.o/vhost-stub.o unconditionally.  xen/ could be
changed if one was inclined to do it.

Paolo
diff mbox series

Patch

diff --git a/target/i386/hyperv.h b/include/hw/hyperv/hyperv.h
similarity index 59%
copy from target/i386/hyperv.h
copy to include/hw/hyperv/hyperv.h
index 8d4619c078..d6c8d78353 100644
--- a/target/i386/hyperv.h
+++ b/include/hw/hyperv/hyperv.h
@@ -1,27 +1,20 @@ 
 /*
- * QEMU KVM Hyper-V support
+ * Hyper-V guest/hypervisor interaction
  *
- * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
- *
- * Authors:
- *  Andrey Smetanin <asmetanin@virtuozzo.com>
+ * 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 TARGET_I386_HYPERV_H
-#define TARGET_I386_HYPERV_H
+#ifndef HW_HYPERV_HYPERV_H
+#define HW_HYPERV_HYPERV_H
 
-#include "cpu.h"
-#include "sysemu/kvm.h"
+#include "cpu-qom.h"
 
 typedef struct HvSintRoute HvSintRoute;
 typedef void (*HvSintAckClb)(void *data);
 
-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);
@@ -30,9 +23,9 @@  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)
+static inline uint32_t hyperv_vp_index(CPUState *cs)
 {
-    return CPU(cpu)->cpu_index;
+    return cs->cpu_index;
 }
 
 #endif
diff --git a/target/i386/hyperv.h b/target/i386/hyperv.h
index 8d4619c078..5c49251ecb 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/hyperv.c b/hw/hyperv/hyperv.c
similarity index 65%
copy from target/i386/hyperv.c
copy to hw/hyperv/hyperv.c
index 68816642c9..97db87561e 100644
--- a/target/i386/hyperv.c
+++ b/hw/hyperv/hyperv.c
@@ -1,24 +1,20 @@ 
 /*
- * QEMU KVM Hyper-V support
+ * Hyper-V guest/hypervisor interaction
  *
- * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
- *
- * Authors:
- *  Andrey Smetanin <asmetanin@virtuozzo.com>
+ * 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 "hyperv.h"
-#include "hyperv-proto.h"
+#include "sysemu/kvm.h"
+#include "hw/hyperv/hyperv.h"
 
 struct HvSintRoute {
     uint32_t sint;
-    X86CPU *cpu;
+    CPUState *cs;
     int gsi;
     EventNotifier sint_set_notifier;
     EventNotifier sint_ack_notifier;
@@ -27,57 +23,11 @@  struct HvSintRoute {
     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)
+static CPUState *hyperv_find_vcpu(uint32_t vp_index)
 {
-    CPUX86State *env = &cpu->env;
-
-    switch (exit->type) {
-    case KVM_EXIT_HYPERV_SYNIC:
-        if (!cpu->hyperv_synic) {
-            return -1;
-        }
-
-        /*
-         * For now just track changes in SynIC control and msg/evt pages msr's.
-         * When SynIC messaging/events processing will be added in future
-         * here we will do messages queues flushing and pages remapping.
-         */
-        switch (exit->u.synic.msr) {
-        case HV_X64_MSR_SCONTROL:
-            env->msr_hv_synic_control = exit->u.synic.control;
-            break;
-        case HV_X64_MSR_SIMP:
-            env->msr_hv_synic_msg_page = exit->u.synic.msg_page;
-            break;
-        case HV_X64_MSR_SIEFP:
-            env->msr_hv_synic_evt_page = exit->u.synic.evt_page;
-            break;
-        default:
-            return -1;
-        }
-        return 0;
-    case KVM_EXIT_HYPERV_HCALL: {
-        uint16_t code;
-
-        code  = exit->u.hcall.input & 0xffff;
-        switch (code) {
-        case HV_POST_MESSAGE:
-        case HV_SIGNAL_EVENT:
-        default:
-            exit->u.hcall.result = HV_STATUS_INVALID_HYPERCALL_CODE;
-            return 0;
-        }
-    }
-    default:
-        return -1;
-    }
+    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)
@@ -95,10 +45,10 @@  HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint,
     HvSintRoute *sint_route;
     EventNotifier *ack_notifier;
     int r, gsi;
-    X86CPU *cpu;
+    CPUState *cs;
 
-    cpu = hyperv_find_vcpu(vp_index);
-    if (!cpu) {
+    cs = hyperv_find_vcpu(vp_index);
+    if (!cs) {
         return NULL;
     }
 
@@ -132,7 +82,7 @@  HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint,
     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->cs = cs;
     sint_route->sint = sint;
     sint_route->refcount = 1;
 
diff --git a/hw/misc/hyperv_testdev.c b/hw/misc/hyperv_testdev.c
index 8654b13d76..02ef606469 100644
--- a/hw/misc/hyperv_testdev.c
+++ b/hw/misc/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/target/i386/hyperv.c b/target/i386/hyperv.c
index 68816642c9..1eac727774 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/kvm.c b/target/i386/kvm.c
index 0b2a07d3a4..892d4f46c1 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -773,7 +773,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;
         }
@@ -1937,7 +1937,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;
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index a19c1417ed..b8f4675219 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_SOFTMMU) += 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 0000000000..19928b726e
--- /dev/null
+++ b/hw/hyperv/Makefile.objs
@@ -0,0 +1 @@ 
+obj-$(CONFIG_HYPERV) += hyperv.o