};
 
 struct resource *hyperv_mmio;
+DEFINE_SEMAPHORE(hyperv_mmio_lock);
 
 static int vmbus_exists(void)
 {
        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))
                        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);