Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Showing
9 changed files
with
178 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
obj-y += hyperv.o | ||
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters