summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJake Oshins <jakeo@microsoft.com>2016-04-05 20:22:50 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-05-01 00:01:37 +0300
commite16dad6bfe1437aaee565f875a6713ca7ce81bdf (patch)
tree9b49cee2a34adeea5ada23ceffb08fa5ce6c8b21 /drivers
parentab028db41ca9174caab7f9e3fc0a2e7f4a418410 (diff)
downloadlinux-e16dad6bfe1437aaee565f875a6713ca7ce81bdf.tar.xz
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')
-rw-r--r--drivers/hv/vmbus_drv.c16
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);