summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/virtio/virtio_mem.c55
1 files changed, 12 insertions, 43 deletions
diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c
index 80cdb9e6b3c4..8dd57b61b09b 100644
--- a/drivers/virtio/virtio_mem.c
+++ b/drivers/virtio/virtio_mem.c
@@ -1616,23 +1616,6 @@ static int virtio_mem_init_vq(struct virtio_mem *vm)
return 0;
}
-/*
- * Test if any memory in the range is present in Linux.
- */
-static bool virtio_mem_any_memory_present(unsigned long start,
- unsigned long size)
-{
- const unsigned long start_pfn = PFN_DOWN(start);
- const unsigned long end_pfn = PFN_UP(start + size);
- unsigned long pfn;
-
- for (pfn = start_pfn; pfn != end_pfn; pfn++)
- if (present_section_nr(pfn_to_section_nr(pfn)))
- return true;
-
- return false;
-}
-
static int virtio_mem_init(struct virtio_mem *vm)
{
const uint64_t phys_limit = 1UL << MAX_PHYSMEM_BITS;
@@ -1665,32 +1648,6 @@ static int virtio_mem_init(struct virtio_mem *vm)
&vm->region_size);
/*
- * If we still have memory plugged, we might have to unplug all
- * memory first. However, if somebody simply unloaded the driver
- * we would have to reinitialize the old state - something we don't
- * support yet. Detect if we have any memory in the area present.
- */
- if (vm->plugged_size) {
- uint64_t usable_region_size;
-
- virtio_cread(vm->vdev, struct virtio_mem_config,
- usable_region_size, &usable_region_size);
-
- if (virtio_mem_any_memory_present(vm->addr,
- usable_region_size)) {
- dev_err(&vm->vdev->dev,
- "reloading the driver is not supported\n");
- return -EINVAL;
- }
- /*
- * Note: it might happen that the device is busy and
- * unplugging all memory might take some time.
- */
- dev_info(&vm->vdev->dev, "unplugging all memory required\n");
- vm->unplug_all_required = 1;
- }
-
- /*
* We always hotplug memory in memory block granularity. This way,
* we have to wait for exactly one memory block to online.
*/
@@ -1760,6 +1717,8 @@ static int virtio_mem_create_resource(struct virtio_mem *vm)
if (!vm->parent_resource) {
kfree(name);
dev_warn(&vm->vdev->dev, "could not reserve device region\n");
+ dev_info(&vm->vdev->dev,
+ "reloading the driver is not supported\n");
return -EBUSY;
}
@@ -1816,6 +1775,16 @@ static int virtio_mem_probe(struct virtio_device *vdev)
if (rc)
goto out_del_vq;
+ /*
+ * If we still have memory plugged, we have to unplug all memory first.
+ * Registering our parent resource makes sure that this memory isn't
+ * actually in use (e.g., trying to reload the driver).
+ */
+ if (vm->plugged_size) {
+ vm->unplug_all_required = 1;
+ dev_info(&vm->vdev->dev, "unplugging all memory is required\n");
+ }
+
/* register callbacks */
vm->memory_notifier.notifier_call = virtio_mem_memory_notifier_cb;
rc = register_memory_notifier(&vm->memory_notifier);