xref: /qemu/hw/virtio/virtio-mem.c (revision 10be11d0b48f508646509844bc32b983d4204d2b)
1 /*
2  * Virtio MEM device
3  *
4  * Copyright (C) 2020 Red Hat, Inc.
5  *
6  * Authors:
7  *  David Hildenbrand <david@redhat.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.
10  * See the COPYING file in the top-level directory.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "qemu-common.h"
15 #include "qemu/iov.h"
16 #include "qemu/cutils.h"
17 #include "qemu/error-report.h"
18 #include "qemu/units.h"
19 #include "sysemu/numa.h"
20 #include "sysemu/sysemu.h"
21 #include "sysemu/reset.h"
22 #include "hw/virtio/virtio.h"
23 #include "hw/virtio/virtio-bus.h"
24 #include "hw/virtio/virtio-access.h"
25 #include "hw/virtio/virtio-mem.h"
26 #include "qapi/error.h"
27 #include "qapi/visitor.h"
28 #include "exec/ram_addr.h"
29 #include "migration/misc.h"
30 #include "hw/boards.h"
31 #include "hw/qdev-properties.h"
32 #include CONFIG_DEVICES
33 #include "trace.h"
34 
35 /*
36  * Let's not allow blocks smaller than 1 MiB, for example, to keep the tracking
37  * bitmap small.
38  */
39 #define VIRTIO_MEM_MIN_BLOCK_SIZE ((uint32_t)(1 * MiB))
40 
41 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \
42     defined(__powerpc64__)
43 #define VIRTIO_MEM_DEFAULT_THP_SIZE ((uint32_t)(2 * MiB))
44 #else
45         /* fallback to 1 MiB (e.g., the THP size on s390x) */
46 #define VIRTIO_MEM_DEFAULT_THP_SIZE VIRTIO_MEM_MIN_BLOCK_SIZE
47 #endif
48 
49 /*
50  * We want to have a reasonable default block size such that
51  * 1. We avoid splitting THPs when unplugging memory, which degrades
52  *    performance.
53  * 2. We avoid placing THPs for plugged blocks that also cover unplugged
54  *    blocks.
55  *
56  * The actual THP size might differ between Linux kernels, so we try to probe
57  * it. In the future (if we ever run into issues regarding 2.), we might want
58  * to disable THP in case we fail to properly probe the THP size, or if the
59  * block size is configured smaller than the THP size.
60  */
61 static uint32_t thp_size;
62 
63 #define HPAGE_PMD_SIZE_PATH "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size"
64 static uint32_t virtio_mem_thp_size(void)
65 {
66     gchar *content = NULL;
67     const char *endptr;
68     uint64_t tmp;
69 
70     if (thp_size) {
71         return thp_size;
72     }
73 
74     /*
75      * Try to probe the actual THP size, fallback to (sane but eventually
76      * incorrect) default sizes.
77      */
78     if (g_file_get_contents(HPAGE_PMD_SIZE_PATH, &content, NULL, NULL) &&
79         !qemu_strtou64(content, &endptr, 0, &tmp) &&
80         (!endptr || *endptr == '\n')) {
81         /*
82          * Sanity-check the value, if it's too big (e.g., aarch64 with 64k base
83          * pages) or weird, fallback to something smaller.
84          */
85         if (!tmp || !is_power_of_2(tmp) || tmp > 16 * MiB) {
86             warn_report("Read unsupported THP size: %" PRIx64, tmp);
87         } else {
88             thp_size = tmp;
89         }
90     }
91 
92     if (!thp_size) {
93         thp_size = VIRTIO_MEM_DEFAULT_THP_SIZE;
94         warn_report("Could not detect THP size, falling back to %" PRIx64
95                     "  MiB.", thp_size / MiB);
96     }
97 
98     g_free(content);
99     return thp_size;
100 }
101 
102 static uint64_t virtio_mem_default_block_size(RAMBlock *rb)
103 {
104     const uint64_t page_size = qemu_ram_pagesize(rb);
105 
106     /* We can have hugetlbfs with a page size smaller than the THP size. */
107     if (page_size == qemu_real_host_page_size) {
108         return MAX(page_size, virtio_mem_thp_size());
109     }
110     return MAX(page_size, VIRTIO_MEM_MIN_BLOCK_SIZE);
111 }
112 
113 /*
114  * Size the usable region bigger than the requested size if possible. Esp.
115  * Linux guests will only add (aligned) memory blocks in case they fully
116  * fit into the usable region, but plug+online only a subset of the pages.
117  * The memory block size corresponds mostly to the section size.
118  *
119  * This allows e.g., to add 20MB with a section size of 128MB on x86_64, and
120  * a section size of 1GB on arm64 (as long as the start address is properly
121  * aligned, similar to ordinary DIMMs).
122  *
123  * We can change this at any time and maybe even make it configurable if
124  * necessary (as the section size can change). But it's more likely that the
125  * section size will rather get smaller and not bigger over time.
126  */
127 #if defined(TARGET_X86_64) || defined(TARGET_I386)
128 #define VIRTIO_MEM_USABLE_EXTENT (2 * (128 * MiB))
129 #else
130 #error VIRTIO_MEM_USABLE_EXTENT not defined
131 #endif
132 
133 static bool virtio_mem_is_busy(void)
134 {
135     /*
136      * Postcopy cannot handle concurrent discards and we don't want to migrate
137      * pages on-demand with stale content when plugging new blocks.
138      *
139      * For precopy, we don't want unplugged blocks in our migration stream, and
140      * when plugging new blocks, the page content might differ between source
141      * and destination (observable by the guest when not initializing pages
142      * after plugging them) until we're running on the destination (as we didn't
143      * migrate these blocks when they were unplugged).
144      */
145     return migration_in_incoming_postcopy() || !migration_is_idle();
146 }
147 
148 typedef int (*virtio_mem_range_cb)(const VirtIOMEM *vmem, void *arg,
149                                    uint64_t offset, uint64_t size);
150 
151 static int virtio_mem_for_each_unplugged_range(const VirtIOMEM *vmem, void *arg,
152                                                virtio_mem_range_cb cb)
153 {
154     unsigned long first_zero_bit, last_zero_bit;
155     uint64_t offset, size;
156     int ret = 0;
157 
158     first_zero_bit = find_first_zero_bit(vmem->bitmap, vmem->bitmap_size);
159     while (first_zero_bit < vmem->bitmap_size) {
160         offset = first_zero_bit * vmem->block_size;
161         last_zero_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size,
162                                       first_zero_bit + 1) - 1;
163         size = (last_zero_bit - first_zero_bit + 1) * vmem->block_size;
164 
165         ret = cb(vmem, arg, offset, size);
166         if (ret) {
167             break;
168         }
169         first_zero_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size,
170                                             last_zero_bit + 2);
171     }
172     return ret;
173 }
174 
175 /*
176  * Adjust the memory section to cover the intersection with the given range.
177  *
178  * Returns false if the intersection is empty, otherwise returns true.
179  */
180 static bool virito_mem_intersect_memory_section(MemoryRegionSection *s,
181                                                 uint64_t offset, uint64_t size)
182 {
183     uint64_t start = MAX(s->offset_within_region, offset);
184     uint64_t end = MIN(s->offset_within_region + int128_get64(s->size),
185                        offset + size);
186 
187     if (end <= start) {
188         return false;
189     }
190 
191     s->offset_within_address_space += start - s->offset_within_region;
192     s->offset_within_region = start;
193     s->size = int128_make64(end - start);
194     return true;
195 }
196 
197 typedef int (*virtio_mem_section_cb)(MemoryRegionSection *s, void *arg);
198 
199 static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem,
200                                                MemoryRegionSection *s,
201                                                void *arg,
202                                                virtio_mem_section_cb cb)
203 {
204     unsigned long first_bit, last_bit;
205     uint64_t offset, size;
206     int ret = 0;
207 
208     first_bit = s->offset_within_region / vmem->bitmap_size;
209     first_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
210     while (first_bit < vmem->bitmap_size) {
211         MemoryRegionSection tmp = *s;
212 
213         offset = first_bit * vmem->block_size;
214         last_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size,
215                                       first_bit + 1) - 1;
216         size = (last_bit - first_bit + 1) * vmem->block_size;
217 
218         if (!virito_mem_intersect_memory_section(&tmp, offset, size)) {
219             break;
220         }
221         ret = cb(&tmp, arg);
222         if (ret) {
223             break;
224         }
225         first_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size,
226                                   last_bit + 2);
227     }
228     return ret;
229 }
230 
231 static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem,
232                                                  MemoryRegionSection *s,
233                                                  void *arg,
234                                                  virtio_mem_section_cb cb)
235 {
236     unsigned long first_bit, last_bit;
237     uint64_t offset, size;
238     int ret = 0;
239 
240     first_bit = s->offset_within_region / vmem->bitmap_size;
241     first_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
242     while (first_bit < vmem->bitmap_size) {
243         MemoryRegionSection tmp = *s;
244 
245         offset = first_bit * vmem->block_size;
246         last_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size,
247                                  first_bit + 1) - 1;
248         size = (last_bit - first_bit + 1) * vmem->block_size;
249 
250         if (!virito_mem_intersect_memory_section(&tmp, offset, size)) {
251             break;
252         }
253         ret = cb(&tmp, arg);
254         if (ret) {
255             break;
256         }
257         first_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size,
258                                        last_bit + 2);
259     }
260     return ret;
261 }
262 
263 static int virtio_mem_notify_populate_cb(MemoryRegionSection *s, void *arg)
264 {
265     RamDiscardListener *rdl = arg;
266 
267     return rdl->notify_populate(rdl, s);
268 }
269 
270 static int virtio_mem_notify_discard_cb(MemoryRegionSection *s, void *arg)
271 {
272     RamDiscardListener *rdl = arg;
273 
274     rdl->notify_discard(rdl, s);
275     return 0;
276 }
277 
278 static void virtio_mem_notify_unplug(VirtIOMEM *vmem, uint64_t offset,
279                                      uint64_t size)
280 {
281     RamDiscardListener *rdl;
282 
283     QLIST_FOREACH(rdl, &vmem->rdl_list, next) {
284         MemoryRegionSection tmp = *rdl->section;
285 
286         if (!virito_mem_intersect_memory_section(&tmp, offset, size)) {
287             continue;
288         }
289         rdl->notify_discard(rdl, &tmp);
290     }
291 }
292 
293 static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset,
294                                   uint64_t size)
295 {
296     RamDiscardListener *rdl, *rdl2;
297     int ret = 0;
298 
299     QLIST_FOREACH(rdl, &vmem->rdl_list, next) {
300         MemoryRegionSection tmp = *rdl->section;
301 
302         if (!virito_mem_intersect_memory_section(&tmp, offset, size)) {
303             continue;
304         }
305         ret = rdl->notify_populate(rdl, &tmp);
306         if (ret) {
307             break;
308         }
309     }
310 
311     if (ret) {
312         /* Notify all already-notified listeners. */
313         QLIST_FOREACH(rdl2, &vmem->rdl_list, next) {
314             MemoryRegionSection tmp = *rdl->section;
315 
316             if (rdl2 == rdl) {
317                 break;
318             }
319             if (!virito_mem_intersect_memory_section(&tmp, offset, size)) {
320                 continue;
321             }
322             rdl2->notify_discard(rdl2, &tmp);
323         }
324     }
325     return ret;
326 }
327 
328 static void virtio_mem_notify_unplug_all(VirtIOMEM *vmem)
329 {
330     RamDiscardListener *rdl;
331 
332     if (!vmem->size) {
333         return;
334     }
335 
336     QLIST_FOREACH(rdl, &vmem->rdl_list, next) {
337         if (rdl->double_discard_supported) {
338             rdl->notify_discard(rdl, rdl->section);
339         } else {
340             virtio_mem_for_each_plugged_section(vmem, rdl->section, rdl,
341                                                 virtio_mem_notify_discard_cb);
342         }
343     }
344 }
345 
346 static bool virtio_mem_test_bitmap(const VirtIOMEM *vmem, uint64_t start_gpa,
347                                    uint64_t size, bool plugged)
348 {
349     const unsigned long first_bit = (start_gpa - vmem->addr) / vmem->block_size;
350     const unsigned long last_bit = first_bit + (size / vmem->block_size) - 1;
351     unsigned long found_bit;
352 
353     /* We fake a shorter bitmap to avoid searching too far. */
354     if (plugged) {
355         found_bit = find_next_zero_bit(vmem->bitmap, last_bit + 1, first_bit);
356     } else {
357         found_bit = find_next_bit(vmem->bitmap, last_bit + 1, first_bit);
358     }
359     return found_bit > last_bit;
360 }
361 
362 static void virtio_mem_set_bitmap(VirtIOMEM *vmem, uint64_t start_gpa,
363                                   uint64_t size, bool plugged)
364 {
365     const unsigned long bit = (start_gpa - vmem->addr) / vmem->block_size;
366     const unsigned long nbits = size / vmem->block_size;
367 
368     if (plugged) {
369         bitmap_set(vmem->bitmap, bit, nbits);
370     } else {
371         bitmap_clear(vmem->bitmap, bit, nbits);
372     }
373 }
374 
375 static void virtio_mem_send_response(VirtIOMEM *vmem, VirtQueueElement *elem,
376                                      struct virtio_mem_resp *resp)
377 {
378     VirtIODevice *vdev = VIRTIO_DEVICE(vmem);
379     VirtQueue *vq = vmem->vq;
380 
381     trace_virtio_mem_send_response(le16_to_cpu(resp->type));
382     iov_from_buf(elem->in_sg, elem->in_num, 0, resp, sizeof(*resp));
383 
384     virtqueue_push(vq, elem, sizeof(*resp));
385     virtio_notify(vdev, vq);
386 }
387 
388 static void virtio_mem_send_response_simple(VirtIOMEM *vmem,
389                                             VirtQueueElement *elem,
390                                             uint16_t type)
391 {
392     struct virtio_mem_resp resp = {
393         .type = cpu_to_le16(type),
394     };
395 
396     virtio_mem_send_response(vmem, elem, &resp);
397 }
398 
399 static bool virtio_mem_valid_range(const VirtIOMEM *vmem, uint64_t gpa,
400                                    uint64_t size)
401 {
402     if (!QEMU_IS_ALIGNED(gpa, vmem->block_size)) {
403         return false;
404     }
405     if (gpa + size < gpa || !size) {
406         return false;
407     }
408     if (gpa < vmem->addr || gpa >= vmem->addr + vmem->usable_region_size) {
409         return false;
410     }
411     if (gpa + size > vmem->addr + vmem->usable_region_size) {
412         return false;
413     }
414     return true;
415 }
416 
417 static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa,
418                                       uint64_t size, bool plug)
419 {
420     const uint64_t offset = start_gpa - vmem->addr;
421     RAMBlock *rb = vmem->memdev->mr.ram_block;
422 
423     if (virtio_mem_is_busy()) {
424         return -EBUSY;
425     }
426 
427     if (!plug) {
428         if (ram_block_discard_range(rb, offset, size)) {
429             return -EBUSY;
430         }
431         virtio_mem_notify_unplug(vmem, offset, size);
432     } else if (virtio_mem_notify_plug(vmem, offset, size)) {
433         /* Could be a mapping attempt resulted in memory getting populated. */
434         ram_block_discard_range(vmem->memdev->mr.ram_block, offset, size);
435         return -EBUSY;
436     }
437     virtio_mem_set_bitmap(vmem, start_gpa, size, plug);
438     return 0;
439 }
440 
441 static int virtio_mem_state_change_request(VirtIOMEM *vmem, uint64_t gpa,
442                                            uint16_t nb_blocks, bool plug)
443 {
444     const uint64_t size = nb_blocks * vmem->block_size;
445     int ret;
446 
447     if (!virtio_mem_valid_range(vmem, gpa, size)) {
448         return VIRTIO_MEM_RESP_ERROR;
449     }
450 
451     if (plug && (vmem->size + size > vmem->requested_size)) {
452         return VIRTIO_MEM_RESP_NACK;
453     }
454 
455     /* test if really all blocks are in the opposite state */
456     if (!virtio_mem_test_bitmap(vmem, gpa, size, !plug)) {
457         return VIRTIO_MEM_RESP_ERROR;
458     }
459 
460     ret = virtio_mem_set_block_state(vmem, gpa, size, plug);
461     if (ret) {
462         return VIRTIO_MEM_RESP_BUSY;
463     }
464     if (plug) {
465         vmem->size += size;
466     } else {
467         vmem->size -= size;
468     }
469     notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
470     return VIRTIO_MEM_RESP_ACK;
471 }
472 
473 static void virtio_mem_plug_request(VirtIOMEM *vmem, VirtQueueElement *elem,
474                                     struct virtio_mem_req *req)
475 {
476     const uint64_t gpa = le64_to_cpu(req->u.plug.addr);
477     const uint16_t nb_blocks = le16_to_cpu(req->u.plug.nb_blocks);
478     uint16_t type;
479 
480     trace_virtio_mem_plug_request(gpa, nb_blocks);
481     type = virtio_mem_state_change_request(vmem, gpa, nb_blocks, true);
482     virtio_mem_send_response_simple(vmem, elem, type);
483 }
484 
485 static void virtio_mem_unplug_request(VirtIOMEM *vmem, VirtQueueElement *elem,
486                                       struct virtio_mem_req *req)
487 {
488     const uint64_t gpa = le64_to_cpu(req->u.unplug.addr);
489     const uint16_t nb_blocks = le16_to_cpu(req->u.unplug.nb_blocks);
490     uint16_t type;
491 
492     trace_virtio_mem_unplug_request(gpa, nb_blocks);
493     type = virtio_mem_state_change_request(vmem, gpa, nb_blocks, false);
494     virtio_mem_send_response_simple(vmem, elem, type);
495 }
496 
497 static void virtio_mem_resize_usable_region(VirtIOMEM *vmem,
498                                             uint64_t requested_size,
499                                             bool can_shrink)
500 {
501     uint64_t newsize = MIN(memory_region_size(&vmem->memdev->mr),
502                            requested_size + VIRTIO_MEM_USABLE_EXTENT);
503 
504     /* The usable region size always has to be multiples of the block size. */
505     newsize = QEMU_ALIGN_UP(newsize, vmem->block_size);
506 
507     if (!requested_size) {
508         newsize = 0;
509     }
510 
511     if (newsize < vmem->usable_region_size && !can_shrink) {
512         return;
513     }
514 
515     trace_virtio_mem_resized_usable_region(vmem->usable_region_size, newsize);
516     vmem->usable_region_size = newsize;
517 }
518 
519 static int virtio_mem_unplug_all(VirtIOMEM *vmem)
520 {
521     RAMBlock *rb = vmem->memdev->mr.ram_block;
522 
523     if (virtio_mem_is_busy()) {
524         return -EBUSY;
525     }
526 
527     if (ram_block_discard_range(rb, 0, qemu_ram_get_used_length(rb))) {
528         return -EBUSY;
529     }
530     virtio_mem_notify_unplug_all(vmem);
531 
532     bitmap_clear(vmem->bitmap, 0, vmem->bitmap_size);
533     if (vmem->size) {
534         vmem->size = 0;
535         notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
536     }
537     trace_virtio_mem_unplugged_all();
538     virtio_mem_resize_usable_region(vmem, vmem->requested_size, true);
539     return 0;
540 }
541 
542 static void virtio_mem_unplug_all_request(VirtIOMEM *vmem,
543                                           VirtQueueElement *elem)
544 {
545     trace_virtio_mem_unplug_all_request();
546     if (virtio_mem_unplug_all(vmem)) {
547         virtio_mem_send_response_simple(vmem, elem, VIRTIO_MEM_RESP_BUSY);
548     } else {
549         virtio_mem_send_response_simple(vmem, elem, VIRTIO_MEM_RESP_ACK);
550     }
551 }
552 
553 static void virtio_mem_state_request(VirtIOMEM *vmem, VirtQueueElement *elem,
554                                      struct virtio_mem_req *req)
555 {
556     const uint16_t nb_blocks = le16_to_cpu(req->u.state.nb_blocks);
557     const uint64_t gpa = le64_to_cpu(req->u.state.addr);
558     const uint64_t size = nb_blocks * vmem->block_size;
559     struct virtio_mem_resp resp = {
560         .type = cpu_to_le16(VIRTIO_MEM_RESP_ACK),
561     };
562 
563     trace_virtio_mem_state_request(gpa, nb_blocks);
564     if (!virtio_mem_valid_range(vmem, gpa, size)) {
565         virtio_mem_send_response_simple(vmem, elem, VIRTIO_MEM_RESP_ERROR);
566         return;
567     }
568 
569     if (virtio_mem_test_bitmap(vmem, gpa, size, true)) {
570         resp.u.state.state = cpu_to_le16(VIRTIO_MEM_STATE_PLUGGED);
571     } else if (virtio_mem_test_bitmap(vmem, gpa, size, false)) {
572         resp.u.state.state = cpu_to_le16(VIRTIO_MEM_STATE_UNPLUGGED);
573     } else {
574         resp.u.state.state = cpu_to_le16(VIRTIO_MEM_STATE_MIXED);
575     }
576     trace_virtio_mem_state_response(le16_to_cpu(resp.u.state.state));
577     virtio_mem_send_response(vmem, elem, &resp);
578 }
579 
580 static void virtio_mem_handle_request(VirtIODevice *vdev, VirtQueue *vq)
581 {
582     const int len = sizeof(struct virtio_mem_req);
583     VirtIOMEM *vmem = VIRTIO_MEM(vdev);
584     VirtQueueElement *elem;
585     struct virtio_mem_req req;
586     uint16_t type;
587 
588     while (true) {
589         elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
590         if (!elem) {
591             return;
592         }
593 
594         if (iov_to_buf(elem->out_sg, elem->out_num, 0, &req, len) < len) {
595             virtio_error(vdev, "virtio-mem protocol violation: invalid request"
596                          " size: %d", len);
597             virtqueue_detach_element(vq, elem, 0);
598             g_free(elem);
599             return;
600         }
601 
602         if (iov_size(elem->in_sg, elem->in_num) <
603             sizeof(struct virtio_mem_resp)) {
604             virtio_error(vdev, "virtio-mem protocol violation: not enough space"
605                          " for response: %zu",
606                          iov_size(elem->in_sg, elem->in_num));
607             virtqueue_detach_element(vq, elem, 0);
608             g_free(elem);
609             return;
610         }
611 
612         type = le16_to_cpu(req.type);
613         switch (type) {
614         case VIRTIO_MEM_REQ_PLUG:
615             virtio_mem_plug_request(vmem, elem, &req);
616             break;
617         case VIRTIO_MEM_REQ_UNPLUG:
618             virtio_mem_unplug_request(vmem, elem, &req);
619             break;
620         case VIRTIO_MEM_REQ_UNPLUG_ALL:
621             virtio_mem_unplug_all_request(vmem, elem);
622             break;
623         case VIRTIO_MEM_REQ_STATE:
624             virtio_mem_state_request(vmem, elem, &req);
625             break;
626         default:
627             virtio_error(vdev, "virtio-mem protocol violation: unknown request"
628                          " type: %d", type);
629             virtqueue_detach_element(vq, elem, 0);
630             g_free(elem);
631             return;
632         }
633 
634         g_free(elem);
635     }
636 }
637 
638 static void virtio_mem_get_config(VirtIODevice *vdev, uint8_t *config_data)
639 {
640     VirtIOMEM *vmem = VIRTIO_MEM(vdev);
641     struct virtio_mem_config *config = (void *) config_data;
642 
643     config->block_size = cpu_to_le64(vmem->block_size);
644     config->node_id = cpu_to_le16(vmem->node);
645     config->requested_size = cpu_to_le64(vmem->requested_size);
646     config->plugged_size = cpu_to_le64(vmem->size);
647     config->addr = cpu_to_le64(vmem->addr);
648     config->region_size = cpu_to_le64(memory_region_size(&vmem->memdev->mr));
649     config->usable_region_size = cpu_to_le64(vmem->usable_region_size);
650 }
651 
652 static uint64_t virtio_mem_get_features(VirtIODevice *vdev, uint64_t features,
653                                         Error **errp)
654 {
655     MachineState *ms = MACHINE(qdev_get_machine());
656 
657     if (ms->numa_state) {
658 #if defined(CONFIG_ACPI)
659         virtio_add_feature(&features, VIRTIO_MEM_F_ACPI_PXM);
660 #endif
661     }
662     return features;
663 }
664 
665 static void virtio_mem_system_reset(void *opaque)
666 {
667     VirtIOMEM *vmem = VIRTIO_MEM(opaque);
668 
669     /*
670      * During usual resets, we will unplug all memory and shrink the usable
671      * region size. This is, however, not possible in all scenarios. Then,
672      * the guest has to deal with this manually (VIRTIO_MEM_REQ_UNPLUG_ALL).
673      */
674     virtio_mem_unplug_all(vmem);
675 }
676 
677 static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
678 {
679     MachineState *ms = MACHINE(qdev_get_machine());
680     int nb_numa_nodes = ms->numa_state ? ms->numa_state->num_nodes : 0;
681     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
682     VirtIOMEM *vmem = VIRTIO_MEM(dev);
683     uint64_t page_size;
684     RAMBlock *rb;
685     int ret;
686 
687     if (!vmem->memdev) {
688         error_setg(errp, "'%s' property is not set", VIRTIO_MEM_MEMDEV_PROP);
689         return;
690     } else if (host_memory_backend_is_mapped(vmem->memdev)) {
691         error_setg(errp, "'%s' property specifies a busy memdev: %s",
692                    VIRTIO_MEM_MEMDEV_PROP,
693                    object_get_canonical_path_component(OBJECT(vmem->memdev)));
694         return;
695     } else if (!memory_region_is_ram(&vmem->memdev->mr) ||
696         memory_region_is_rom(&vmem->memdev->mr) ||
697         !vmem->memdev->mr.ram_block) {
698         error_setg(errp, "'%s' property specifies an unsupported memdev",
699                    VIRTIO_MEM_MEMDEV_PROP);
700         return;
701     }
702 
703     if ((nb_numa_nodes && vmem->node >= nb_numa_nodes) ||
704         (!nb_numa_nodes && vmem->node)) {
705         error_setg(errp, "'%s' property has value '%" PRIu32 "', which exceeds"
706                    "the number of numa nodes: %d", VIRTIO_MEM_NODE_PROP,
707                    vmem->node, nb_numa_nodes ? nb_numa_nodes : 1);
708         return;
709     }
710 
711     if (enable_mlock) {
712         error_setg(errp, "Incompatible with mlock");
713         return;
714     }
715 
716     rb = vmem->memdev->mr.ram_block;
717     page_size = qemu_ram_pagesize(rb);
718 
719     /*
720      * If the block size wasn't configured by the user, use a sane default. This
721      * allows using hugetlbfs backends of any page size without manual
722      * intervention.
723      */
724     if (!vmem->block_size) {
725         vmem->block_size = virtio_mem_default_block_size(rb);
726     }
727 
728     if (vmem->block_size < page_size) {
729         error_setg(errp, "'%s' property has to be at least the page size (0x%"
730                    PRIx64 ")", VIRTIO_MEM_BLOCK_SIZE_PROP, page_size);
731         return;
732     } else if (vmem->block_size < virtio_mem_default_block_size(rb)) {
733         warn_report("'%s' property is smaller than the default block size (%"
734                     PRIx64 " MiB)", VIRTIO_MEM_BLOCK_SIZE_PROP,
735                     virtio_mem_default_block_size(rb) / MiB);
736     }
737     if (!QEMU_IS_ALIGNED(vmem->requested_size, vmem->block_size)) {
738         error_setg(errp, "'%s' property has to be multiples of '%s' (0x%" PRIx64
739                    ")", VIRTIO_MEM_REQUESTED_SIZE_PROP,
740                    VIRTIO_MEM_BLOCK_SIZE_PROP, vmem->block_size);
741         return;
742     } else if (!QEMU_IS_ALIGNED(vmem->addr, vmem->block_size)) {
743         error_setg(errp, "'%s' property has to be multiples of '%s' (0x%" PRIx64
744                    ")", VIRTIO_MEM_ADDR_PROP, VIRTIO_MEM_BLOCK_SIZE_PROP,
745                    vmem->block_size);
746         return;
747     } else if (!QEMU_IS_ALIGNED(memory_region_size(&vmem->memdev->mr),
748                                 vmem->block_size)) {
749         error_setg(errp, "'%s' property memdev size has to be multiples of"
750                    "'%s' (0x%" PRIx64 ")", VIRTIO_MEM_MEMDEV_PROP,
751                    VIRTIO_MEM_BLOCK_SIZE_PROP, vmem->block_size);
752         return;
753     }
754 
755     if (ram_block_coordinated_discard_require(true)) {
756         error_setg(errp, "Discarding RAM is disabled");
757         return;
758     }
759 
760     ret = ram_block_discard_range(rb, 0, qemu_ram_get_used_length(rb));
761     if (ret) {
762         error_setg_errno(errp, -ret, "Unexpected error discarding RAM");
763         ram_block_coordinated_discard_require(false);
764         return;
765     }
766 
767     virtio_mem_resize_usable_region(vmem, vmem->requested_size, true);
768 
769     vmem->bitmap_size = memory_region_size(&vmem->memdev->mr) /
770                         vmem->block_size;
771     vmem->bitmap = bitmap_new(vmem->bitmap_size);
772 
773     virtio_init(vdev, TYPE_VIRTIO_MEM, VIRTIO_ID_MEM,
774                 sizeof(struct virtio_mem_config));
775     vmem->vq = virtio_add_queue(vdev, 128, virtio_mem_handle_request);
776 
777     host_memory_backend_set_mapped(vmem->memdev, true);
778     vmstate_register_ram(&vmem->memdev->mr, DEVICE(vmem));
779     qemu_register_reset(virtio_mem_system_reset, vmem);
780 
781     /*
782      * Set ourselves as RamDiscardManager before the plug handler maps the
783      * memory region and exposes it via an address space.
784      */
785     memory_region_set_ram_discard_manager(&vmem->memdev->mr,
786                                           RAM_DISCARD_MANAGER(vmem));
787 }
788 
789 static void virtio_mem_device_unrealize(DeviceState *dev)
790 {
791     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
792     VirtIOMEM *vmem = VIRTIO_MEM(dev);
793 
794     /*
795      * The unplug handler unmapped the memory region, it cannot be
796      * found via an address space anymore. Unset ourselves.
797      */
798     memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL);
799     qemu_unregister_reset(virtio_mem_system_reset, vmem);
800     vmstate_unregister_ram(&vmem->memdev->mr, DEVICE(vmem));
801     host_memory_backend_set_mapped(vmem->memdev, false);
802     virtio_del_queue(vdev, 0);
803     virtio_cleanup(vdev);
804     g_free(vmem->bitmap);
805     ram_block_coordinated_discard_require(false);
806 }
807 
808 static int virtio_mem_discard_range_cb(const VirtIOMEM *vmem, void *arg,
809                                        uint64_t offset, uint64_t size)
810 {
811     RAMBlock *rb = vmem->memdev->mr.ram_block;
812 
813     return ram_block_discard_range(rb, offset, size) ? -EINVAL : 0;
814 }
815 
816 static int virtio_mem_restore_unplugged(VirtIOMEM *vmem)
817 {
818     /* Make sure all memory is really discarded after migration. */
819     return virtio_mem_for_each_unplugged_range(vmem, NULL,
820                                                virtio_mem_discard_range_cb);
821 }
822 
823 static int virtio_mem_post_load(void *opaque, int version_id)
824 {
825     VirtIOMEM *vmem = VIRTIO_MEM(opaque);
826     RamDiscardListener *rdl;
827     int ret;
828 
829     /*
830      * We started out with all memory discarded and our memory region is mapped
831      * into an address space. Replay, now that we updated the bitmap.
832      */
833     QLIST_FOREACH(rdl, &vmem->rdl_list, next) {
834         ret = virtio_mem_for_each_plugged_section(vmem, rdl->section, rdl,
835                                                  virtio_mem_notify_populate_cb);
836         if (ret) {
837             return ret;
838         }
839     }
840 
841     if (migration_in_incoming_postcopy()) {
842         return 0;
843     }
844 
845     return virtio_mem_restore_unplugged(vmem);
846 }
847 
848 typedef struct VirtIOMEMMigSanityChecks {
849     VirtIOMEM *parent;
850     uint64_t addr;
851     uint64_t region_size;
852     uint64_t block_size;
853     uint32_t node;
854 } VirtIOMEMMigSanityChecks;
855 
856 static int virtio_mem_mig_sanity_checks_pre_save(void *opaque)
857 {
858     VirtIOMEMMigSanityChecks *tmp = opaque;
859     VirtIOMEM *vmem = tmp->parent;
860 
861     tmp->addr = vmem->addr;
862     tmp->region_size = memory_region_size(&vmem->memdev->mr);
863     tmp->block_size = vmem->block_size;
864     tmp->node = vmem->node;
865     return 0;
866 }
867 
868 static int virtio_mem_mig_sanity_checks_post_load(void *opaque, int version_id)
869 {
870     VirtIOMEMMigSanityChecks *tmp = opaque;
871     VirtIOMEM *vmem = tmp->parent;
872     const uint64_t new_region_size = memory_region_size(&vmem->memdev->mr);
873 
874     if (tmp->addr != vmem->addr) {
875         error_report("Property '%s' changed from 0x%" PRIx64 " to 0x%" PRIx64,
876                      VIRTIO_MEM_ADDR_PROP, tmp->addr, vmem->addr);
877         return -EINVAL;
878     }
879     /*
880      * Note: Preparation for resizeable memory regions. The maximum size
881      * of the memory region must not change during migration.
882      */
883     if (tmp->region_size != new_region_size) {
884         error_report("Property '%s' size changed from 0x%" PRIx64 " to 0x%"
885                      PRIx64, VIRTIO_MEM_MEMDEV_PROP, tmp->region_size,
886                      new_region_size);
887         return -EINVAL;
888     }
889     if (tmp->block_size != vmem->block_size) {
890         error_report("Property '%s' changed from 0x%" PRIx64 " to 0x%" PRIx64,
891                      VIRTIO_MEM_BLOCK_SIZE_PROP, tmp->block_size,
892                      vmem->block_size);
893         return -EINVAL;
894     }
895     if (tmp->node != vmem->node) {
896         error_report("Property '%s' changed from %" PRIu32 " to %" PRIu32,
897                      VIRTIO_MEM_NODE_PROP, tmp->node, vmem->node);
898         return -EINVAL;
899     }
900     return 0;
901 }
902 
903 static const VMStateDescription vmstate_virtio_mem_sanity_checks = {
904     .name = "virtio-mem-device/sanity-checks",
905     .pre_save = virtio_mem_mig_sanity_checks_pre_save,
906     .post_load = virtio_mem_mig_sanity_checks_post_load,
907     .fields = (VMStateField[]) {
908         VMSTATE_UINT64(addr, VirtIOMEMMigSanityChecks),
909         VMSTATE_UINT64(region_size, VirtIOMEMMigSanityChecks),
910         VMSTATE_UINT64(block_size, VirtIOMEMMigSanityChecks),
911         VMSTATE_UINT32(node, VirtIOMEMMigSanityChecks),
912         VMSTATE_END_OF_LIST(),
913     },
914 };
915 
916 static const VMStateDescription vmstate_virtio_mem_device = {
917     .name = "virtio-mem-device",
918     .minimum_version_id = 1,
919     .version_id = 1,
920     .priority = MIG_PRI_VIRTIO_MEM,
921     .post_load = virtio_mem_post_load,
922     .fields = (VMStateField[]) {
923         VMSTATE_WITH_TMP(VirtIOMEM, VirtIOMEMMigSanityChecks,
924                          vmstate_virtio_mem_sanity_checks),
925         VMSTATE_UINT64(usable_region_size, VirtIOMEM),
926         VMSTATE_UINT64(size, VirtIOMEM),
927         VMSTATE_UINT64(requested_size, VirtIOMEM),
928         VMSTATE_BITMAP(bitmap, VirtIOMEM, 0, bitmap_size),
929         VMSTATE_END_OF_LIST()
930     },
931 };
932 
933 static const VMStateDescription vmstate_virtio_mem = {
934     .name = "virtio-mem",
935     .minimum_version_id = 1,
936     .version_id = 1,
937     .fields = (VMStateField[]) {
938         VMSTATE_VIRTIO_DEVICE,
939         VMSTATE_END_OF_LIST()
940     },
941 };
942 
943 static void virtio_mem_fill_device_info(const VirtIOMEM *vmem,
944                                         VirtioMEMDeviceInfo *vi)
945 {
946     vi->memaddr = vmem->addr;
947     vi->node = vmem->node;
948     vi->requested_size = vmem->requested_size;
949     vi->size = vmem->size;
950     vi->max_size = memory_region_size(&vmem->memdev->mr);
951     vi->block_size = vmem->block_size;
952     vi->memdev = object_get_canonical_path(OBJECT(vmem->memdev));
953 }
954 
955 static MemoryRegion *virtio_mem_get_memory_region(VirtIOMEM *vmem, Error **errp)
956 {
957     if (!vmem->memdev) {
958         error_setg(errp, "'%s' property must be set", VIRTIO_MEM_MEMDEV_PROP);
959         return NULL;
960     }
961 
962     return &vmem->memdev->mr;
963 }
964 
965 static void virtio_mem_add_size_change_notifier(VirtIOMEM *vmem,
966                                                 Notifier *notifier)
967 {
968     notifier_list_add(&vmem->size_change_notifiers, notifier);
969 }
970 
971 static void virtio_mem_remove_size_change_notifier(VirtIOMEM *vmem,
972                                                    Notifier *notifier)
973 {
974     notifier_remove(notifier);
975 }
976 
977 static void virtio_mem_get_size(Object *obj, Visitor *v, const char *name,
978                                 void *opaque, Error **errp)
979 {
980     const VirtIOMEM *vmem = VIRTIO_MEM(obj);
981     uint64_t value = vmem->size;
982 
983     visit_type_size(v, name, &value, errp);
984 }
985 
986 static void virtio_mem_get_requested_size(Object *obj, Visitor *v,
987                                           const char *name, void *opaque,
988                                           Error **errp)
989 {
990     const VirtIOMEM *vmem = VIRTIO_MEM(obj);
991     uint64_t value = vmem->requested_size;
992 
993     visit_type_size(v, name, &value, errp);
994 }
995 
996 static void virtio_mem_set_requested_size(Object *obj, Visitor *v,
997                                           const char *name, void *opaque,
998                                           Error **errp)
999 {
1000     VirtIOMEM *vmem = VIRTIO_MEM(obj);
1001     Error *err = NULL;
1002     uint64_t value;
1003 
1004     visit_type_size(v, name, &value, &err);
1005     if (err) {
1006         error_propagate(errp, err);
1007         return;
1008     }
1009 
1010     /*
1011      * The block size and memory backend are not fixed until the device was
1012      * realized. realize() will verify these properties then.
1013      */
1014     if (DEVICE(obj)->realized) {
1015         if (!QEMU_IS_ALIGNED(value, vmem->block_size)) {
1016             error_setg(errp, "'%s' has to be multiples of '%s' (0x%" PRIx64
1017                        ")", name, VIRTIO_MEM_BLOCK_SIZE_PROP,
1018                        vmem->block_size);
1019             return;
1020         } else if (value > memory_region_size(&vmem->memdev->mr)) {
1021             error_setg(errp, "'%s' cannot exceed the memory backend size"
1022                        "(0x%" PRIx64 ")", name,
1023                        memory_region_size(&vmem->memdev->mr));
1024             return;
1025         }
1026 
1027         if (value != vmem->requested_size) {
1028             virtio_mem_resize_usable_region(vmem, value, false);
1029             vmem->requested_size = value;
1030         }
1031         /*
1032          * Trigger a config update so the guest gets notified. We trigger
1033          * even if the size didn't change (especially helpful for debugging).
1034          */
1035         virtio_notify_config(VIRTIO_DEVICE(vmem));
1036     } else {
1037         vmem->requested_size = value;
1038     }
1039 }
1040 
1041 static void virtio_mem_get_block_size(Object *obj, Visitor *v, const char *name,
1042                                       void *opaque, Error **errp)
1043 {
1044     const VirtIOMEM *vmem = VIRTIO_MEM(obj);
1045     uint64_t value = vmem->block_size;
1046 
1047     /*
1048      * If not configured by the user (and we're not realized yet), use the
1049      * default block size we would use with the current memory backend.
1050      */
1051     if (!value) {
1052         if (vmem->memdev && memory_region_is_ram(&vmem->memdev->mr)) {
1053             value = virtio_mem_default_block_size(vmem->memdev->mr.ram_block);
1054         } else {
1055             value = virtio_mem_thp_size();
1056         }
1057     }
1058 
1059     visit_type_size(v, name, &value, errp);
1060 }
1061 
1062 static void virtio_mem_set_block_size(Object *obj, Visitor *v, const char *name,
1063                                       void *opaque, Error **errp)
1064 {
1065     VirtIOMEM *vmem = VIRTIO_MEM(obj);
1066     Error *err = NULL;
1067     uint64_t value;
1068 
1069     if (DEVICE(obj)->realized) {
1070         error_setg(errp, "'%s' cannot be changed", name);
1071         return;
1072     }
1073 
1074     visit_type_size(v, name, &value, &err);
1075     if (err) {
1076         error_propagate(errp, err);
1077         return;
1078     }
1079 
1080     if (value < VIRTIO_MEM_MIN_BLOCK_SIZE) {
1081         error_setg(errp, "'%s' property has to be at least 0x%" PRIx32, name,
1082                    VIRTIO_MEM_MIN_BLOCK_SIZE);
1083         return;
1084     } else if (!is_power_of_2(value)) {
1085         error_setg(errp, "'%s' property has to be a power of two", name);
1086         return;
1087     }
1088     vmem->block_size = value;
1089 }
1090 
1091 static void virtio_mem_instance_init(Object *obj)
1092 {
1093     VirtIOMEM *vmem = VIRTIO_MEM(obj);
1094 
1095     notifier_list_init(&vmem->size_change_notifiers);
1096     QLIST_INIT(&vmem->rdl_list);
1097 
1098     object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_size,
1099                         NULL, NULL, NULL);
1100     object_property_add(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, "size",
1101                         virtio_mem_get_requested_size,
1102                         virtio_mem_set_requested_size, NULL, NULL);
1103     object_property_add(obj, VIRTIO_MEM_BLOCK_SIZE_PROP, "size",
1104                         virtio_mem_get_block_size, virtio_mem_set_block_size,
1105                         NULL, NULL);
1106 }
1107 
1108 static Property virtio_mem_properties[] = {
1109     DEFINE_PROP_UINT64(VIRTIO_MEM_ADDR_PROP, VirtIOMEM, addr, 0),
1110     DEFINE_PROP_UINT32(VIRTIO_MEM_NODE_PROP, VirtIOMEM, node, 0),
1111     DEFINE_PROP_LINK(VIRTIO_MEM_MEMDEV_PROP, VirtIOMEM, memdev,
1112                      TYPE_MEMORY_BACKEND, HostMemoryBackend *),
1113     DEFINE_PROP_END_OF_LIST(),
1114 };
1115 
1116 static uint64_t virtio_mem_rdm_get_min_granularity(const RamDiscardManager *rdm,
1117                                                    const MemoryRegion *mr)
1118 {
1119     const VirtIOMEM *vmem = VIRTIO_MEM(rdm);
1120 
1121     g_assert(mr == &vmem->memdev->mr);
1122     return vmem->block_size;
1123 }
1124 
1125 static bool virtio_mem_rdm_is_populated(const RamDiscardManager *rdm,
1126                                         const MemoryRegionSection *s)
1127 {
1128     const VirtIOMEM *vmem = VIRTIO_MEM(rdm);
1129     uint64_t start_gpa = vmem->addr + s->offset_within_region;
1130     uint64_t end_gpa = start_gpa + int128_get64(s->size);
1131 
1132     g_assert(s->mr == &vmem->memdev->mr);
1133 
1134     start_gpa = QEMU_ALIGN_DOWN(start_gpa, vmem->block_size);
1135     end_gpa = QEMU_ALIGN_UP(end_gpa, vmem->block_size);
1136 
1137     if (!virtio_mem_valid_range(vmem, start_gpa, end_gpa - start_gpa)) {
1138         return false;
1139     }
1140 
1141     return virtio_mem_test_bitmap(vmem, start_gpa, end_gpa - start_gpa, true);
1142 }
1143 
1144 struct VirtIOMEMReplayData {
1145     void *fn;
1146     void *opaque;
1147 };
1148 
1149 static int virtio_mem_rdm_replay_populated_cb(MemoryRegionSection *s, void *arg)
1150 {
1151     struct VirtIOMEMReplayData *data = arg;
1152 
1153     return ((ReplayRamPopulate)data->fn)(s, data->opaque);
1154 }
1155 
1156 static int virtio_mem_rdm_replay_populated(const RamDiscardManager *rdm,
1157                                            MemoryRegionSection *s,
1158                                            ReplayRamPopulate replay_fn,
1159                                            void *opaque)
1160 {
1161     const VirtIOMEM *vmem = VIRTIO_MEM(rdm);
1162     struct VirtIOMEMReplayData data = {
1163         .fn = replay_fn,
1164         .opaque = opaque,
1165     };
1166 
1167     g_assert(s->mr == &vmem->memdev->mr);
1168     return virtio_mem_for_each_plugged_section(vmem, s, &data,
1169                                             virtio_mem_rdm_replay_populated_cb);
1170 }
1171 
1172 static int virtio_mem_rdm_replay_discarded_cb(MemoryRegionSection *s,
1173                                               void *arg)
1174 {
1175     struct VirtIOMEMReplayData *data = arg;
1176 
1177     ((ReplayRamDiscard)data->fn)(s, data->opaque);
1178     return 0;
1179 }
1180 
1181 static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm,
1182                                             MemoryRegionSection *s,
1183                                             ReplayRamDiscard replay_fn,
1184                                             void *opaque)
1185 {
1186     const VirtIOMEM *vmem = VIRTIO_MEM(rdm);
1187     struct VirtIOMEMReplayData data = {
1188         .fn = replay_fn,
1189         .opaque = opaque,
1190     };
1191 
1192     g_assert(s->mr == &vmem->memdev->mr);
1193     virtio_mem_for_each_unplugged_section(vmem, s, &data,
1194                                           virtio_mem_rdm_replay_discarded_cb);
1195 }
1196 
1197 static void virtio_mem_rdm_register_listener(RamDiscardManager *rdm,
1198                                              RamDiscardListener *rdl,
1199                                              MemoryRegionSection *s)
1200 {
1201     VirtIOMEM *vmem = VIRTIO_MEM(rdm);
1202     int ret;
1203 
1204     g_assert(s->mr == &vmem->memdev->mr);
1205     rdl->section = memory_region_section_new_copy(s);
1206 
1207     QLIST_INSERT_HEAD(&vmem->rdl_list, rdl, next);
1208     ret = virtio_mem_for_each_plugged_section(vmem, rdl->section, rdl,
1209                                               virtio_mem_notify_populate_cb);
1210     if (ret) {
1211         error_report("%s: Replaying plugged ranges failed: %s", __func__,
1212                      strerror(-ret));
1213     }
1214 }
1215 
1216 static void virtio_mem_rdm_unregister_listener(RamDiscardManager *rdm,
1217                                                RamDiscardListener *rdl)
1218 {
1219     VirtIOMEM *vmem = VIRTIO_MEM(rdm);
1220 
1221     g_assert(rdl->section->mr == &vmem->memdev->mr);
1222     if (vmem->size) {
1223         if (rdl->double_discard_supported) {
1224             rdl->notify_discard(rdl, rdl->section);
1225         } else {
1226             virtio_mem_for_each_plugged_section(vmem, rdl->section, rdl,
1227                                                 virtio_mem_notify_discard_cb);
1228         }
1229     }
1230 
1231     memory_region_section_free_copy(rdl->section);
1232     rdl->section = NULL;
1233     QLIST_REMOVE(rdl, next);
1234 }
1235 
1236 static void virtio_mem_class_init(ObjectClass *klass, void *data)
1237 {
1238     DeviceClass *dc = DEVICE_CLASS(klass);
1239     VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
1240     VirtIOMEMClass *vmc = VIRTIO_MEM_CLASS(klass);
1241     RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_CLASS(klass);
1242 
1243     device_class_set_props(dc, virtio_mem_properties);
1244     dc->vmsd = &vmstate_virtio_mem;
1245 
1246     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
1247     vdc->realize = virtio_mem_device_realize;
1248     vdc->unrealize = virtio_mem_device_unrealize;
1249     vdc->get_config = virtio_mem_get_config;
1250     vdc->get_features = virtio_mem_get_features;
1251     vdc->vmsd = &vmstate_virtio_mem_device;
1252 
1253     vmc->fill_device_info = virtio_mem_fill_device_info;
1254     vmc->get_memory_region = virtio_mem_get_memory_region;
1255     vmc->add_size_change_notifier = virtio_mem_add_size_change_notifier;
1256     vmc->remove_size_change_notifier = virtio_mem_remove_size_change_notifier;
1257 
1258     rdmc->get_min_granularity = virtio_mem_rdm_get_min_granularity;
1259     rdmc->is_populated = virtio_mem_rdm_is_populated;
1260     rdmc->replay_populated = virtio_mem_rdm_replay_populated;
1261     rdmc->replay_discarded = virtio_mem_rdm_replay_discarded;
1262     rdmc->register_listener = virtio_mem_rdm_register_listener;
1263     rdmc->unregister_listener = virtio_mem_rdm_unregister_listener;
1264 }
1265 
1266 static const TypeInfo virtio_mem_info = {
1267     .name = TYPE_VIRTIO_MEM,
1268     .parent = TYPE_VIRTIO_DEVICE,
1269     .instance_size = sizeof(VirtIOMEM),
1270     .instance_init = virtio_mem_instance_init,
1271     .class_init = virtio_mem_class_init,
1272     .class_size = sizeof(VirtIOMEMClass),
1273     .interfaces = (InterfaceInfo[]) {
1274         { TYPE_RAM_DISCARD_MANAGER },
1275         { }
1276     },
1277 };
1278 
1279 static void virtio_register_types(void)
1280 {
1281     type_register_static(&virtio_mem_info);
1282 }
1283 
1284 type_init(virtio_register_types)
1285