|
@@ -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);
|
|
|
|