aboutsummaryrefslogtreecommitdiff
path: root/target/i386
diff options
context:
space:
mode:
authorRoman Kagan <rkagan@virtuozzo.com>2018-09-21 11:18:35 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2018-10-19 13:44:13 +0200
commit3d3e6e85c3ebd5cd551133af9bace084360307a3 (patch)
treeb4a318d46069a2ee8c18b62b86ad467164aa1115 /target/i386
parent09cfb2f6350512eb3ef7e9e2136daabbcf265880 (diff)
hyperv: make HvSintRoute reference-counted
Multiple entities (e.g. VMBus devices) can use the same SINT route. To make their lives easier in maintaining SINT route ownership, make it reference-counted. Adjust the respective API names accordingly. Signed-off-by: Roman Kagan <rkagan@virtuozzo.com> Message-Id: <20180921081836.29230-8-rkagan@virtuozzo.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386')
-rw-r--r--target/i386/hyperv.c25
-rw-r--r--target/i386/hyperv.h10
2 files changed, 26 insertions, 9 deletions
diff --git a/target/i386/hyperv.c b/target/i386/hyperv.c
index 0ce8a7aa2f..4d8ef6f2da 100644
--- a/target/i386/hyperv.c
+++ b/target/i386/hyperv.c
@@ -24,6 +24,7 @@ struct HvSintRoute {
EventNotifier sint_ack_notifier;
HvSintAckClb sint_ack_clb;
void *sint_ack_clb_data;
+ unsigned refcount;
};
uint32_t hyperv_vp_index(X86CPU *cpu)
@@ -90,9 +91,9 @@ static void kvm_hv_sint_ack_handler(EventNotifier *notifier)
sint_route->sint_ack_clb(sint_route->sint_ack_clb_data);
}
-HvSintRoute *kvm_hv_sint_route_create(uint32_t vp_index, uint32_t sint,
- HvSintAckClb sint_ack_clb,
- void *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;
@@ -136,6 +137,7 @@ HvSintRoute *kvm_hv_sint_route_create(uint32_t vp_index, uint32_t sint,
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;
@@ -154,8 +156,23 @@ err:
return NULL;
}
-void kvm_hv_sint_route_destroy(HvSintRoute *sint_route)
+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);
diff --git a/target/i386/hyperv.h b/target/i386/hyperv.h
index ab99047bf8..cdf44a7757 100644
--- a/target/i386/hyperv.h
+++ b/target/i386/hyperv.h
@@ -22,11 +22,11 @@ typedef void (*HvSintAckClb)(void *data);
int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit);
-HvSintRoute *kvm_hv_sint_route_create(uint32_t vp_index, uint32_t sint,
- HvSintAckClb sint_ack_clb,
- void *sint_ack_clb_data);
-
-void kvm_hv_sint_route_destroy(HvSintRoute *sint_route);
+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 kvm_hv_sint_route_set_sint(HvSintRoute *sint_route);