diff options
author | Roman Kagan <rkagan@virtuozzo.com> | 2018-09-21 11:20:39 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-10-19 13:44:13 +0200 |
commit | 701189e31140a7c82ec02a7f4ca632cfd6a8559d (patch) | |
tree | 3d8be9e7f4a05214a33cf713a7f732be797ae0d9 /target/i386 | |
parent | 51f0ac63812abf41d3a9284a272c6275d7318705 (diff) | |
download | qemu-701189e31140a7c82ec02a7f4ca632cfd6a8559d.zip qemu-701189e31140a7c82ec02a7f4ca632cfd6a8559d.tar.gz qemu-701189e31140a7c82ec02a7f4ca632cfd6a8559d.tar.bz2 |
hyperv: factor out arch-independent API into hw/hyperv
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>
Message-Id: <20180921082041.29380-4-rkagan@virtuozzo.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386')
-rw-r--r-- | target/i386/hyperv.c | 127 | ||||
-rw-r--r-- | target/i386/hyperv.h | 17 | ||||
-rw-r--r-- | target/i386/kvm.c | 5 |
3 files changed, 5 insertions, 144 deletions
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; |