aboutsummaryrefslogtreecommitdiff
path: root/include/hw/virtio/virtio-mem.h
blob: b23946b770c569b9cd7fc2e4a930e18acb89b965 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Virtio MEM device
 *
 * Copyright (C) 2020 Red Hat, Inc.
 *
 * Authors:
 *  David Hildenbrand <david@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 * See the COPYING file in the top-level directory.
 */

#ifndef HW_VIRTIO_MEM_H
#define HW_VIRTIO_MEM_H

#include "standard-headers/linux/virtio_mem.h"
#include "hw/resettable.h"
#include "hw/virtio/virtio.h"
#include "qapi/qapi-types-misc.h"
#include "system/hostmem.h"
#include "qom/object.h"

#define TYPE_VIRTIO_MEM "virtio-mem"

OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass,
                    VIRTIO_MEM)

#define VIRTIO_MEM_MEMDEV_PROP "memdev"
#define VIRTIO_MEM_NODE_PROP "node"
#define VIRTIO_MEM_SIZE_PROP "size"
#define VIRTIO_MEM_REQUESTED_SIZE_PROP "requested-size"
#define VIRTIO_MEM_BLOCK_SIZE_PROP "block-size"
#define VIRTIO_MEM_ADDR_PROP "memaddr"
#define VIRTIO_MEM_UNPLUGGED_INACCESSIBLE_PROP "unplugged-inaccessible"
#define VIRTIO_MEM_EARLY_MIGRATION_PROP "x-early-migration"
#define VIRTIO_MEM_PREALLOC_PROP "prealloc"
#define VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP "dynamic-memslots"

struct VirtIOMEM {
    VirtIODevice parent_obj;

    /* guest -> host request queue */
    VirtQueue *vq;

    /* bitmap used to track unplugged memory */
    int32_t bitmap_size;
    unsigned long *bitmap;

    /*
     * With "dynamic-memslots=on": Device memory region in which we dynamically
     * map the memslots.
     */
    MemoryRegion *mr;

    /*
     * With "dynamic-memslots=on": The individual memslots (aliases into the
     * memory backend).
     */
    MemoryRegion *memslots;

    /* With "dynamic-memslots=on": The total number of memslots. */
    uint16_t nb_memslots;

    /*
     * With "dynamic-memslots=on": Size of one memslot (the size of the
     * last one can differ).
     */
    uint64_t memslot_size;

    /* Assigned memory backend with the RAM memory region. */
    HostMemoryBackend *memdev;

    /* NUMA node */
    uint32_t node;

    /* assigned address of the region in guest physical memory */
    uint64_t addr;

    /* usable region size (<= region_size) */
    uint64_t usable_region_size;

    /* actual size (how much the guest plugged) */
    uint64_t size;

    /* requested size */
    uint64_t requested_size;

    /* block size and alignment */
    uint64_t block_size;

    /*
     * Whether we indicate VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE to the guest.
     * For !x86 targets this will always be "on" and consequently indicate
     * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE.
     */
    OnOffAuto unplugged_inaccessible;

    /* whether to prealloc memory when plugging new blocks */
    bool prealloc;

    /*
     * Whether we migrate properties that are immutable while migration is
     * active early, before state of other devices and especially, before
     * migrating any RAM content.
     */
    bool early_migration;

    /*
     * Whether we dynamically map (multiple, if possible) memslots instead of
     * statically mapping the whole RAM memory region.
     */
    bool dynamic_memslots;

    /* notifiers to notify when "size" changes */
    NotifierList size_change_notifiers;

    /* listeners to notify on plug/unplug activity. */
    QLIST_HEAD(, RamDiscardListener) rdl_list;

    /* State of the resettable container */
    ResettableState reset_state;
};

struct VirtIOMEMClass {
    /* private */
    VirtIODevice parent;

    /* public */
    void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
    MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
    void (*decide_memslots)(VirtIOMEM *vmem, unsigned int limit);
    unsigned int (*get_memslots)(VirtIOMEM *vmem);
    void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
    void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
    void (*unplug_request_check)(VirtIOMEM *vmem, Error **errp);
};

#endif