diff options
author | Roman Kagan <rkagan@virtuozzo.com> | 2018-09-21 11:18:35 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-10-19 13:44:13 +0200 |
commit | 3d3e6e85c3ebd5cd551133af9bace084360307a3 (patch) | |
tree | b4a318d46069a2ee8c18b62b86ad467164aa1115 /target/i386 | |
parent | 09cfb2f6350512eb3ef7e9e2136daabbcf265880 (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.c | 25 | ||||
-rw-r--r-- | target/i386/hyperv.h | 10 |
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); |