diff options
author | Jake Oshins <jakeo@microsoft.com> | 2016-04-05 19:22:50 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-04-30 23:01:37 +0200 |
commit | e16dad6bfe1437aaee565f875a6713ca7ce81bdf (patch) | |
tree | 9b49cee2a34adeea5ada23ceffb08fa5ce6c8b21 /drivers/hv | |
parent | Drivers: hv: vmbus: Implement APIs to support "in place" consumption of vmbus... (diff) | |
download | linux-e16dad6bfe1437aaee565f875a6713ca7ce81bdf.tar.xz linux-e16dad6bfe1437aaee565f875a6713ca7ce81bdf.zip |
drivers:hv: Lock access to hyperv_mmio resource tree
In existing code, this tree of resources is created
in single-threaded code and never modified after it is
created, and thus needs no locking. This patch introduces
a semaphore for tree access, as other patches in this
series introduce run-time modifications of this resource
tree which can happen on multiple threads.
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r-- | drivers/hv/vmbus_drv.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 64713ff47e36..799518b3cdc5 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -102,6 +102,7 @@ static struct notifier_block hyperv_panic_block = { }; struct resource *hyperv_mmio; +DEFINE_SEMAPHORE(hyperv_mmio_lock); static int vmbus_exists(void) { @@ -1132,7 +1133,10 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, resource_size_t range_min, range_max, start, local_min, local_max; const char *dev_n = dev_name(&device_obj->device); u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1); - int i; + int i, retval; + + retval = -ENXIO; + down(&hyperv_mmio_lock); for (iter = hyperv_mmio; iter; iter = iter->sibling) { if ((iter->start >= max) || (iter->end <= min)) @@ -1169,13 +1173,17 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, for (; start + size - 1 <= local_max; start += align) { *new = request_mem_region_exclusive(start, size, dev_n); - if (*new) - return 0; + if (*new) { + retval = 0; + goto exit; + } } } } - return -ENXIO; +exit: + up(&hyperv_mmio_lock); + return retval; } EXPORT_SYMBOL_GPL(vmbus_allocate_mmio); |