#include <linux/virtio.h>
#include <linux/virtio_mem.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/memory_hotplug.h>
#include <linux/memory.h>
#include <linux/hrtimer.h>
#include <linux/crash_dump.h>
#include <linux/mutex.h>
#include <linux/bitmap.h>
#include <linux/lockdep.h>
#include <linux/log2.h>
#include <linux/vmalloc.h>
#include <linux/suspend.h>
#include <acpi/acpi_numa.h>
static bool unplug_online = …;
module_param(unplug_online, bool, 0644);
MODULE_PARM_DESC(…) …;
static bool force_bbm;
module_param(force_bbm, bool, 0444);
MODULE_PARM_DESC(…) …;
static unsigned long bbm_block_size;
module_param(bbm_block_size, ulong, 0444);
MODULE_PARM_DESC(…) …;
enum virtio_mem_sbm_mb_state { … };
enum virtio_mem_bbm_bb_state { … };
struct virtio_mem { … };
static DEFINE_MUTEX(virtio_mem_mutex);
static LIST_HEAD(virtio_mem_devices);
static void virtio_mem_online_page_cb(struct page *page, unsigned int order);
static void virtio_mem_fake_offline_going_offline(unsigned long pfn,
unsigned long nr_pages);
static void virtio_mem_fake_offline_cancel_offline(unsigned long pfn,
unsigned long nr_pages);
static void virtio_mem_retry(struct virtio_mem *vm);
static int virtio_mem_create_resource(struct virtio_mem *vm);
static void virtio_mem_delete_resource(struct virtio_mem *vm);
static int register_virtio_mem_device(struct virtio_mem *vm)
{ … }
static void unregister_virtio_mem_device(struct virtio_mem *vm)
{ … }
static unsigned long virtio_mem_phys_to_mb_id(unsigned long addr)
{ … }
static unsigned long virtio_mem_mb_id_to_phys(unsigned long mb_id)
{ … }
static unsigned long virtio_mem_phys_to_bb_id(struct virtio_mem *vm,
uint64_t addr)
{ … }
static uint64_t virtio_mem_bb_id_to_phys(struct virtio_mem *vm,
unsigned long bb_id)
{ … }
static unsigned long virtio_mem_phys_to_sb_id(struct virtio_mem *vm,
unsigned long addr)
{ … }
static void virtio_mem_bbm_set_bb_state(struct virtio_mem *vm,
unsigned long bb_id,
enum virtio_mem_bbm_bb_state state)
{ … }
static enum virtio_mem_bbm_bb_state virtio_mem_bbm_get_bb_state(struct virtio_mem *vm,
unsigned long bb_id)
{ … }
static int virtio_mem_bbm_bb_states_prepare_next_bb(struct virtio_mem *vm)
{ … }
#define virtio_mem_bbm_for_each_bb(_vm, _bb_id, _state) …
#define virtio_mem_bbm_for_each_bb_rev(_vm, _bb_id, _state) …
static void virtio_mem_sbm_set_mb_state(struct virtio_mem *vm,
unsigned long mb_id, uint8_t state)
{ … }
static uint8_t virtio_mem_sbm_get_mb_state(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static int virtio_mem_sbm_mb_states_prepare_next_mb(struct virtio_mem *vm)
{ … }
#define virtio_mem_sbm_for_each_mb(_vm, _mb_id, _state) …
#define virtio_mem_sbm_for_each_mb_rev(_vm, _mb_id, _state) …
static int virtio_mem_sbm_sb_state_bit_nr(struct virtio_mem *vm,
unsigned long mb_id, int sb_id)
{ … }
static void virtio_mem_sbm_set_sb_plugged(struct virtio_mem *vm,
unsigned long mb_id, int sb_id,
int count)
{ … }
static void virtio_mem_sbm_set_sb_unplugged(struct virtio_mem *vm,
unsigned long mb_id, int sb_id,
int count)
{ … }
static bool virtio_mem_sbm_test_sb_plugged(struct virtio_mem *vm,
unsigned long mb_id, int sb_id,
int count)
{ … }
static bool virtio_mem_sbm_test_sb_unplugged(struct virtio_mem *vm,
unsigned long mb_id, int sb_id,
int count)
{ … }
static int virtio_mem_sbm_first_unplugged_sb(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static int virtio_mem_sbm_sb_states_prepare_next_mb(struct virtio_mem *vm)
{ … }
static bool virtio_mem_could_add_memory(struct virtio_mem *vm, uint64_t size)
{ … }
static int virtio_mem_add_memory(struct virtio_mem *vm, uint64_t addr,
uint64_t size)
{ … }
static int virtio_mem_sbm_add_mb(struct virtio_mem *vm, unsigned long mb_id)
{ … }
static int virtio_mem_bbm_add_bb(struct virtio_mem *vm, unsigned long bb_id)
{ … }
static int virtio_mem_remove_memory(struct virtio_mem *vm, uint64_t addr,
uint64_t size)
{ … }
static int virtio_mem_sbm_remove_mb(struct virtio_mem *vm, unsigned long mb_id)
{ … }
static int virtio_mem_offline_and_remove_memory(struct virtio_mem *vm,
uint64_t addr,
uint64_t size)
{ … }
static int virtio_mem_sbm_offline_and_remove_mb(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static int virtio_mem_sbm_try_remove_unplugged_mb(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static int virtio_mem_bbm_offline_and_remove_bb(struct virtio_mem *vm,
unsigned long bb_id)
{ … }
static void virtio_mem_retry(struct virtio_mem *vm)
{ … }
static int virtio_mem_translate_node_id(struct virtio_mem *vm, uint16_t node_id)
{ … }
static bool virtio_mem_overlaps_range(struct virtio_mem *vm, uint64_t start,
uint64_t size)
{ … }
static bool virtio_mem_contains_range(struct virtio_mem *vm, uint64_t start,
uint64_t size)
{ … }
static int virtio_mem_sbm_notify_going_online(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static void virtio_mem_sbm_notify_offline(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static void virtio_mem_sbm_notify_online(struct virtio_mem *vm,
unsigned long mb_id,
unsigned long start_pfn)
{ … }
static void virtio_mem_sbm_notify_going_offline(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static void virtio_mem_sbm_notify_cancel_offline(struct virtio_mem *vm,
unsigned long mb_id)
{ … }
static void virtio_mem_bbm_notify_going_offline(struct virtio_mem *vm,
unsigned long bb_id,
unsigned long pfn,
unsigned long nr_pages)
{ … }
static void virtio_mem_bbm_notify_cancel_offline(struct virtio_mem *vm,
unsigned long bb_id,
unsigned long pfn,
unsigned long nr_pages)
{ … }
static int virtio_mem_memory_notifier_cb(struct notifier_block *nb,
unsigned long action, void *arg)
{ … }
static int virtio_mem_pm_notifier_cb(struct notifier_block *nb,
unsigned long action, void *arg)
{ … }
static void virtio_mem_set_fake_offline(unsigned long pfn,
unsigned long nr_pages, bool onlined)
{ … }
static void virtio_mem_clear_fake_offline(unsigned long pfn,
unsigned long nr_pages, bool onlined)
{ … }
static void virtio_mem_fake_online(unsigned long pfn, unsigned long nr_pages)
{ … }
static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
unsigned long nr_pages)
{ … }
static void virtio_mem_fake_offline_going_offline(unsigned long pfn,
unsigned long nr_pages)
{ … }
static void virtio_mem_fake_offline_cancel_offline(unsigned long pfn,
unsigned long nr_pages)
{ … }
static void virtio_mem_online_page(struct virtio_mem *vm,
struct page *page, unsigned int order)
{ … }
static void virtio_mem_online_page_cb(struct page *page, unsigned int order)
{ … }
static uint64_t virtio_mem_send_request(struct virtio_mem *vm,
const struct virtio_mem_req *req)
{ … }
static int virtio_mem_send_plug_request(struct virtio_mem *vm, uint64_t addr,
uint64_t size)
{ … }
static int virtio_mem_send_unplug_request(struct virtio_mem *vm, uint64_t addr,
uint64_t size)
{ … }
static int virtio_mem_send_unplug_all_request(struct virtio_mem *vm)
{ … }
static int virtio_mem_sbm_plug_sb(struct virtio_mem *vm, unsigned long mb_id,
int sb_id, int count)
{ … }
static int virtio_mem_sbm_unplug_sb(struct virtio_mem *vm, unsigned long mb_id,
int sb_id, int count)
{ … }
static int virtio_mem_bbm_unplug_bb(struct virtio_mem *vm, unsigned long bb_id)
{ … }
static int virtio_mem_bbm_plug_bb(struct virtio_mem *vm, unsigned long bb_id)
{ … }
static int virtio_mem_sbm_unplug_any_sb_raw(struct virtio_mem *vm,
unsigned long mb_id, uint64_t *nb_sb)
{ … }
static int virtio_mem_sbm_unplug_mb(struct virtio_mem *vm, unsigned long mb_id)
{ … }
static int virtio_mem_sbm_prepare_next_mb(struct virtio_mem *vm,
unsigned long *mb_id)
{ … }
static int virtio_mem_sbm_plug_and_add_mb(struct virtio_mem *vm,
unsigned long mb_id, uint64_t *nb_sb)
{ … }
static int virtio_mem_sbm_plug_any_sb(struct virtio_mem *vm,
unsigned long mb_id, uint64_t *nb_sb)
{ … }
static int virtio_mem_sbm_plug_request(struct virtio_mem *vm, uint64_t diff)
{ … }
static int virtio_mem_bbm_plug_and_add_bb(struct virtio_mem *vm,
unsigned long bb_id)
{ … }
static int virtio_mem_bbm_prepare_next_bb(struct virtio_mem *vm,
unsigned long *bb_id)
{ … }
static int virtio_mem_bbm_plug_request(struct virtio_mem *vm, uint64_t diff)
{ … }
static int virtio_mem_plug_request(struct virtio_mem *vm, uint64_t diff)
{ … }
static int virtio_mem_sbm_unplug_any_sb_offline(struct virtio_mem *vm,
unsigned long mb_id,
uint64_t *nb_sb)
{ … }
static int virtio_mem_sbm_unplug_sb_online(struct virtio_mem *vm,
unsigned long mb_id, int sb_id,
int count)
{ … }
static int virtio_mem_sbm_unplug_any_sb_online(struct virtio_mem *vm,
unsigned long mb_id,
uint64_t *nb_sb)
{ … }
static int virtio_mem_sbm_unplug_any_sb(struct virtio_mem *vm,
unsigned long mb_id,
uint64_t *nb_sb)
{ … }
static int virtio_mem_sbm_unplug_request(struct virtio_mem *vm, uint64_t diff)
{ … }
static int virtio_mem_bbm_offline_remove_and_unplug_bb(struct virtio_mem *vm,
unsigned long bb_id)
{ … }
static bool virtio_mem_bbm_bb_is_offline(struct virtio_mem *vm,
unsigned long bb_id)
{ … }
static bool virtio_mem_bbm_bb_is_movable(struct virtio_mem *vm,
unsigned long bb_id)
{ … }
static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff)
{ … }
static int virtio_mem_unplug_request(struct virtio_mem *vm, uint64_t diff)
{ … }
static int virtio_mem_cleanup_pending_mb(struct virtio_mem *vm)
{ … }
static void virtio_mem_refresh_config(struct virtio_mem *vm)
{ … }
static void virtio_mem_run_wq(struct work_struct *work)
{ … }
static enum hrtimer_restart virtio_mem_timer_expired(struct hrtimer *timer)
{ … }
static void virtio_mem_handle_response(struct virtqueue *vq)
{ … }
static int virtio_mem_init_vq(struct virtio_mem *vm)
{ … }
static int virtio_mem_init_hotplug(struct virtio_mem *vm)
{ … }
#ifdef CONFIG_PROC_VMCORE
static int virtio_mem_send_state_request(struct virtio_mem *vm, uint64_t addr,
uint64_t size)
{ … }
static bool virtio_mem_vmcore_pfn_is_ram(struct vmcore_cb *cb,
unsigned long pfn)
{ … }
#endif
static int virtio_mem_init_kdump(struct virtio_mem *vm)
{ … }
static int virtio_mem_init(struct virtio_mem *vm)
{ … }
static int virtio_mem_create_resource(struct virtio_mem *vm)
{ … }
static void virtio_mem_delete_resource(struct virtio_mem *vm)
{ … }
static int virtio_mem_range_has_system_ram(struct resource *res, void *arg)
{ … }
static bool virtio_mem_has_memory_added(struct virtio_mem *vm)
{ … }
static int virtio_mem_probe(struct virtio_device *vdev)
{ … }
static void virtio_mem_deinit_hotplug(struct virtio_mem *vm)
{ … }
static void virtio_mem_deinit_kdump(struct virtio_mem *vm)
{ … }
static void virtio_mem_remove(struct virtio_device *vdev)
{ … }
static void virtio_mem_config_changed(struct virtio_device *vdev)
{ … }
#ifdef CONFIG_PM_SLEEP
static int virtio_mem_freeze(struct virtio_device *vdev)
{ … }
static int virtio_mem_restore(struct virtio_device *vdev)
{ … }
#endif
static unsigned int virtio_mem_features[] = …;
static const struct virtio_device_id virtio_mem_id_table[] = …;
static struct virtio_driver virtio_mem_driver = …;
module_virtio_driver(…) …;
MODULE_DEVICE_TABLE(virtio, virtio_mem_id_table);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;