]> git.proxmox.com Git - mirror_qemu.git/blob - hw/virtio/virtio-balloon.c
Merge remote-tracking branch 'remotes/stefanberger/tags/pull-tpm-2019-02-25-1' into...
[mirror_qemu.git] / hw / virtio / virtio-balloon.c
1 /*
2 * Virtio Balloon Device
3 *
4 * Copyright IBM, Corp. 2008
5 * Copyright (C) 2011 Red Hat, Inc.
6 * Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
7 *
8 * Authors:
9 * Anthony Liguori <aliguori@us.ibm.com>
10 *
11 * This work is licensed under the terms of the GNU GPL, version 2. See
12 * the COPYING file in the top-level directory.
13 *
14 */
15
16 #include "qemu/osdep.h"
17 #include "qemu/iov.h"
18 #include "qemu/timer.h"
19 #include "qemu-common.h"
20 #include "hw/virtio/virtio.h"
21 #include "hw/mem/pc-dimm.h"
22 #include "sysemu/balloon.h"
23 #include "hw/virtio/virtio-balloon.h"
24 #include "exec/address-spaces.h"
25 #include "qapi/error.h"
26 #include "qapi/qapi-events-misc.h"
27 #include "qapi/visitor.h"
28 #include "trace.h"
29 #include "qemu/error-report.h"
30
31 #include "hw/virtio/virtio-bus.h"
32 #include "hw/virtio/virtio-access.h"
33
34 #define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT)
35
36 struct PartiallyBalloonedPage {
37 RAMBlock *rb;
38 ram_addr_t base;
39 unsigned long bitmap[];
40 };
41
42 static void balloon_inflate_page(VirtIOBalloon *balloon,
43 MemoryRegion *mr, hwaddr offset)
44 {
45 void *addr = memory_region_get_ram_ptr(mr) + offset;
46 RAMBlock *rb;
47 size_t rb_page_size;
48 int subpages;
49 ram_addr_t ram_offset, host_page_base;
50
51 /* XXX is there a better way to get to the RAMBlock than via a
52 * host address? */
53 rb = qemu_ram_block_from_host(addr, false, &ram_offset);
54 rb_page_size = qemu_ram_pagesize(rb);
55 host_page_base = ram_offset & ~(rb_page_size - 1);
56
57 if (rb_page_size == BALLOON_PAGE_SIZE) {
58 /* Easy case */
59
60 ram_block_discard_range(rb, ram_offset, rb_page_size);
61 /* We ignore errors from ram_block_discard_range(), because it
62 * has already reported them, and failing to discard a balloon
63 * page is not fatal */
64 return;
65 }
66
67 /* Hard case
68 *
69 * We've put a piece of a larger host page into the balloon - we
70 * need to keep track until we have a whole host page to
71 * discard
72 */
73 warn_report_once(
74 "Balloon used with backing page size > 4kiB, this may not be reliable");
75
76 subpages = rb_page_size / BALLOON_PAGE_SIZE;
77
78 if (balloon->pbp
79 && (rb != balloon->pbp->rb
80 || host_page_base != balloon->pbp->base)) {
81 /* We've partially ballooned part of a host page, but now
82 * we're trying to balloon part of a different one. Too hard,
83 * give up on the old partial page */
84 free(balloon->pbp);
85 balloon->pbp = NULL;
86 }
87
88 if (!balloon->pbp) {
89 /* Starting on a new host page */
90 size_t bitlen = BITS_TO_LONGS(subpages) * sizeof(unsigned long);
91 balloon->pbp = g_malloc0(sizeof(PartiallyBalloonedPage) + bitlen);
92 balloon->pbp->rb = rb;
93 balloon->pbp->base = host_page_base;
94 }
95
96 bitmap_set(balloon->pbp->bitmap,
97 (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE,
98 subpages);
99
100 if (bitmap_full(balloon->pbp->bitmap, subpages)) {
101 /* We've accumulated a full host page, we can actually discard
102 * it now */
103
104 ram_block_discard_range(rb, balloon->pbp->base, rb_page_size);
105 /* We ignore errors from ram_block_discard_range(), because it
106 * has already reported them, and failing to discard a balloon
107 * page is not fatal */
108
109 free(balloon->pbp);
110 balloon->pbp = NULL;
111 }
112 }
113
114 static const char *balloon_stat_names[] = {
115 [VIRTIO_BALLOON_S_SWAP_IN] = "stat-swap-in",
116 [VIRTIO_BALLOON_S_SWAP_OUT] = "stat-swap-out",
117 [VIRTIO_BALLOON_S_MAJFLT] = "stat-major-faults",
118 [VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults",
119 [VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory",
120 [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory",
121 [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory",
122 [VIRTIO_BALLOON_S_CACHES] = "stat-disk-caches",
123 [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-htlb-pgalloc",
124 [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-htlb-pgfail",
125 [VIRTIO_BALLOON_S_NR] = NULL
126 };
127
128 /*
129 * reset_stats - Mark all items in the stats array as unset
130 *
131 * This function needs to be called at device initialization and before
132 * updating to a set of newly-generated stats. This will ensure that no
133 * stale values stick around in case the guest reports a subset of the supported
134 * statistics.
135 */
136 static inline void reset_stats(VirtIOBalloon *dev)
137 {
138 int i;
139 for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1);
140 }
141
142 static bool balloon_stats_supported(const VirtIOBalloon *s)
143 {
144 VirtIODevice *vdev = VIRTIO_DEVICE(s);
145 return virtio_vdev_has_feature(vdev, VIRTIO_BALLOON_F_STATS_VQ);
146 }
147
148 static bool balloon_stats_enabled(const VirtIOBalloon *s)
149 {
150 return s->stats_poll_interval > 0;
151 }
152
153 static void balloon_stats_destroy_timer(VirtIOBalloon *s)
154 {
155 if (balloon_stats_enabled(s)) {
156 timer_del(s->stats_timer);
157 timer_free(s->stats_timer);
158 s->stats_timer = NULL;
159 s->stats_poll_interval = 0;
160 }
161 }
162
163 static void balloon_stats_change_timer(VirtIOBalloon *s, int64_t secs)
164 {
165 timer_mod(s->stats_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + secs * 1000);
166 }
167
168 static void balloon_stats_poll_cb(void *opaque)
169 {
170 VirtIOBalloon *s = opaque;
171 VirtIODevice *vdev = VIRTIO_DEVICE(s);
172
173 if (s->stats_vq_elem == NULL || !balloon_stats_supported(s)) {
174 /* re-schedule */
175 balloon_stats_change_timer(s, s->stats_poll_interval);
176 return;
177 }
178
179 virtqueue_push(s->svq, s->stats_vq_elem, s->stats_vq_offset);
180 virtio_notify(vdev, s->svq);
181 g_free(s->stats_vq_elem);
182 s->stats_vq_elem = NULL;
183 }
184
185 static void balloon_stats_get_all(Object *obj, Visitor *v, const char *name,
186 void *opaque, Error **errp)
187 {
188 Error *err = NULL;
189 VirtIOBalloon *s = opaque;
190 int i;
191
192 visit_start_struct(v, name, NULL, 0, &err);
193 if (err) {
194 goto out;
195 }
196 visit_type_int(v, "last-update", &s->stats_last_update, &err);
197 if (err) {
198 goto out_end;
199 }
200
201 visit_start_struct(v, "stats", NULL, 0, &err);
202 if (err) {
203 goto out_end;
204 }
205 for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
206 visit_type_uint64(v, balloon_stat_names[i], &s->stats[i], &err);
207 if (err) {
208 goto out_nested;
209 }
210 }
211 visit_check_struct(v, &err);
212 out_nested:
213 visit_end_struct(v, NULL);
214
215 if (!err) {
216 visit_check_struct(v, &err);
217 }
218 out_end:
219 visit_end_struct(v, NULL);
220 out:
221 error_propagate(errp, err);
222 }
223
224 static void balloon_stats_get_poll_interval(Object *obj, Visitor *v,
225 const char *name, void *opaque,
226 Error **errp)
227 {
228 VirtIOBalloon *s = opaque;
229 visit_type_int(v, name, &s->stats_poll_interval, errp);
230 }
231
232 static void balloon_stats_set_poll_interval(Object *obj, Visitor *v,
233 const char *name, void *opaque,
234 Error **errp)
235 {
236 VirtIOBalloon *s = opaque;
237 Error *local_err = NULL;
238 int64_t value;
239
240 visit_type_int(v, name, &value, &local_err);
241 if (local_err) {
242 error_propagate(errp, local_err);
243 return;
244 }
245
246 if (value < 0) {
247 error_setg(errp, "timer value must be greater than zero");
248 return;
249 }
250
251 if (value > UINT32_MAX) {
252 error_setg(errp, "timer value is too big");
253 return;
254 }
255
256 if (value == s->stats_poll_interval) {
257 return;
258 }
259
260 if (value == 0) {
261 /* timer=0 disables the timer */
262 balloon_stats_destroy_timer(s);
263 return;
264 }
265
266 if (balloon_stats_enabled(s)) {
267 /* timer interval change */
268 s->stats_poll_interval = value;
269 balloon_stats_change_timer(s, value);
270 return;
271 }
272
273 /* create a new timer */
274 g_assert(s->stats_timer == NULL);
275 s->stats_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, balloon_stats_poll_cb, s);
276 s->stats_poll_interval = value;
277 balloon_stats_change_timer(s, 0);
278 }
279
280 static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
281 {
282 VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
283 VirtQueueElement *elem;
284 MemoryRegionSection section;
285
286 for (;;) {
287 size_t offset = 0;
288 uint32_t pfn;
289 elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
290 if (!elem) {
291 return;
292 }
293
294 while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) {
295 hwaddr pa;
296 int p = virtio_ldl_p(vdev, &pfn);
297
298 pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT;
299 offset += 4;
300
301 section = memory_region_find(get_system_memory(), pa,
302 BALLOON_PAGE_SIZE);
303 if (!section.mr) {
304 trace_virtio_balloon_bad_addr(pa);
305 continue;
306 }
307 if (!memory_region_is_ram(section.mr) ||
308 memory_region_is_rom(section.mr) ||
309 memory_region_is_romd(section.mr)) {
310 trace_virtio_balloon_bad_addr(pa);
311 memory_region_unref(section.mr);
312 continue;
313 }
314
315 trace_virtio_balloon_handle_output(memory_region_name(section.mr),
316 pa);
317 if (!qemu_balloon_is_inhibited() && vq != s->dvq) {
318 balloon_inflate_page(s, section.mr, section.offset_within_region);
319 }
320 memory_region_unref(section.mr);
321 }
322
323 virtqueue_push(vq, elem, offset);
324 virtio_notify(vdev, vq);
325 g_free(elem);
326 }
327 }
328
329 static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
330 {
331 VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
332 VirtQueueElement *elem;
333 VirtIOBalloonStat stat;
334 size_t offset = 0;
335 qemu_timeval tv;
336
337 elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
338 if (!elem) {
339 goto out;
340 }
341
342 if (s->stats_vq_elem != NULL) {
343 /* This should never happen if the driver follows the spec. */
344 virtqueue_push(vq, s->stats_vq_elem, 0);
345 virtio_notify(vdev, vq);
346 g_free(s->stats_vq_elem);
347 }
348
349 s->stats_vq_elem = elem;
350
351 /* Initialize the stats to get rid of any stale values. This is only
352 * needed to handle the case where a guest supports fewer stats than it
353 * used to (ie. it has booted into an old kernel).
354 */
355 reset_stats(s);
356
357 while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat))
358 == sizeof(stat)) {
359 uint16_t tag = virtio_tswap16(vdev, stat.tag);
360 uint64_t val = virtio_tswap64(vdev, stat.val);
361
362 offset += sizeof(stat);
363 if (tag < VIRTIO_BALLOON_S_NR)
364 s->stats[tag] = val;
365 }
366 s->stats_vq_offset = offset;
367
368 if (qemu_gettimeofday(&tv) < 0) {
369 warn_report("%s: failed to get time of day", __func__);
370 goto out;
371 }
372
373 s->stats_last_update = tv.tv_sec;
374
375 out:
376 if (balloon_stats_enabled(s)) {
377 balloon_stats_change_timer(s, s->stats_poll_interval);
378 }
379 }
380
381 static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
382 {
383 VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
384 struct virtio_balloon_config config = {};
385
386 config.num_pages = cpu_to_le32(dev->num_pages);
387 config.actual = cpu_to_le32(dev->actual);
388
389 trace_virtio_balloon_get_config(config.num_pages, config.actual);
390 memcpy(config_data, &config, sizeof(struct virtio_balloon_config));
391 }
392
393 static int build_dimm_list(Object *obj, void *opaque)
394 {
395 GSList **list = opaque;
396
397 if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
398 DeviceState *dev = DEVICE(obj);
399 if (dev->realized) { /* only realized DIMMs matter */
400 *list = g_slist_prepend(*list, dev);
401 }
402 }
403
404 object_child_foreach(obj, build_dimm_list, opaque);
405 return 0;
406 }
407
408 static ram_addr_t get_current_ram_size(void)
409 {
410 GSList *list = NULL, *item;
411 ram_addr_t size = ram_size;
412
413 build_dimm_list(qdev_get_machine(), &list);
414 for (item = list; item; item = g_slist_next(item)) {
415 Object *obj = OBJECT(item->data);
416 if (!strcmp(object_get_typename(obj), TYPE_PC_DIMM)) {
417 size += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
418 &error_abort);
419 }
420 }
421 g_slist_free(list);
422
423 return size;
424 }
425
426 static void virtio_balloon_set_config(VirtIODevice *vdev,
427 const uint8_t *config_data)
428 {
429 VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
430 struct virtio_balloon_config config;
431 uint32_t oldactual = dev->actual;
432 ram_addr_t vm_ram_size = get_current_ram_size();
433
434 memcpy(&config, config_data, sizeof(struct virtio_balloon_config));
435 dev->actual = le32_to_cpu(config.actual);
436 if (dev->actual != oldactual) {
437 qapi_event_send_balloon_change(vm_ram_size -
438 ((ram_addr_t) dev->actual << VIRTIO_BALLOON_PFN_SHIFT));
439 }
440 trace_virtio_balloon_set_config(dev->actual, oldactual);
441 }
442
443 static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
444 Error **errp)
445 {
446 VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
447 f |= dev->host_features;
448 virtio_add_feature(&f, VIRTIO_BALLOON_F_STATS_VQ);
449 return f;
450 }
451
452 static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
453 {
454 VirtIOBalloon *dev = opaque;
455 info->actual = get_current_ram_size() - ((uint64_t) dev->actual <<
456 VIRTIO_BALLOON_PFN_SHIFT);
457 }
458
459 static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
460 {
461 VirtIOBalloon *dev = VIRTIO_BALLOON(opaque);
462 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
463 ram_addr_t vm_ram_size = get_current_ram_size();
464
465 if (target > vm_ram_size) {
466 target = vm_ram_size;
467 }
468 if (target) {
469 dev->num_pages = (vm_ram_size - target) >> VIRTIO_BALLOON_PFN_SHIFT;
470 virtio_notify_config(vdev);
471 }
472 trace_virtio_balloon_to_target(target, dev->num_pages);
473 }
474
475 static int virtio_balloon_post_load_device(void *opaque, int version_id)
476 {
477 VirtIOBalloon *s = VIRTIO_BALLOON(opaque);
478
479 if (balloon_stats_enabled(s)) {
480 balloon_stats_change_timer(s, s->stats_poll_interval);
481 }
482 return 0;
483 }
484
485 static const VMStateDescription vmstate_virtio_balloon_device = {
486 .name = "virtio-balloon-device",
487 .version_id = 1,
488 .minimum_version_id = 1,
489 .post_load = virtio_balloon_post_load_device,
490 .fields = (VMStateField[]) {
491 VMSTATE_UINT32(num_pages, VirtIOBalloon),
492 VMSTATE_UINT32(actual, VirtIOBalloon),
493 VMSTATE_END_OF_LIST()
494 },
495 };
496
497 static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
498 {
499 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
500 VirtIOBalloon *s = VIRTIO_BALLOON(dev);
501 int ret;
502
503 virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON,
504 sizeof(struct virtio_balloon_config));
505
506 ret = qemu_add_balloon_handler(virtio_balloon_to_target,
507 virtio_balloon_stat, s);
508
509 if (ret < 0) {
510 error_setg(errp, "Only one balloon device is supported");
511 virtio_cleanup(vdev);
512 return;
513 }
514
515 s->ivq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
516 s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
517 s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats);
518
519 reset_stats(s);
520 }
521
522 static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp)
523 {
524 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
525 VirtIOBalloon *s = VIRTIO_BALLOON(dev);
526
527 balloon_stats_destroy_timer(s);
528 qemu_remove_balloon_handler(s);
529 virtio_cleanup(vdev);
530 }
531
532 static void virtio_balloon_device_reset(VirtIODevice *vdev)
533 {
534 VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
535
536 if (s->stats_vq_elem != NULL) {
537 virtqueue_unpop(s->svq, s->stats_vq_elem, 0);
538 g_free(s->stats_vq_elem);
539 s->stats_vq_elem = NULL;
540 }
541 }
542
543 static void virtio_balloon_set_status(VirtIODevice *vdev, uint8_t status)
544 {
545 VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
546
547 if (!s->stats_vq_elem && vdev->vm_running &&
548 (status & VIRTIO_CONFIG_S_DRIVER_OK) && virtqueue_rewind(s->svq, 1)) {
549 /* poll stats queue for the element we have discarded when the VM
550 * was stopped */
551 virtio_balloon_receive_stats(vdev, s->svq);
552 }
553 }
554
555 static void virtio_balloon_instance_init(Object *obj)
556 {
557 VirtIOBalloon *s = VIRTIO_BALLOON(obj);
558
559 object_property_add(obj, "guest-stats", "guest statistics",
560 balloon_stats_get_all, NULL, NULL, s, NULL);
561
562 object_property_add(obj, "guest-stats-polling-interval", "int",
563 balloon_stats_get_poll_interval,
564 balloon_stats_set_poll_interval,
565 NULL, s, NULL);
566 }
567
568 static const VMStateDescription vmstate_virtio_balloon = {
569 .name = "virtio-balloon",
570 .minimum_version_id = 1,
571 .version_id = 1,
572 .fields = (VMStateField[]) {
573 VMSTATE_VIRTIO_DEVICE,
574 VMSTATE_END_OF_LIST()
575 },
576 };
577
578 static Property virtio_balloon_properties[] = {
579 DEFINE_PROP_BIT("deflate-on-oom", VirtIOBalloon, host_features,
580 VIRTIO_BALLOON_F_DEFLATE_ON_OOM, false),
581 DEFINE_PROP_END_OF_LIST(),
582 };
583
584 static void virtio_balloon_class_init(ObjectClass *klass, void *data)
585 {
586 DeviceClass *dc = DEVICE_CLASS(klass);
587 VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
588
589 dc->props = virtio_balloon_properties;
590 dc->vmsd = &vmstate_virtio_balloon;
591 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
592 vdc->realize = virtio_balloon_device_realize;
593 vdc->unrealize = virtio_balloon_device_unrealize;
594 vdc->reset = virtio_balloon_device_reset;
595 vdc->get_config = virtio_balloon_get_config;
596 vdc->set_config = virtio_balloon_set_config;
597 vdc->get_features = virtio_balloon_get_features;
598 vdc->set_status = virtio_balloon_set_status;
599 vdc->vmsd = &vmstate_virtio_balloon_device;
600 }
601
602 static const TypeInfo virtio_balloon_info = {
603 .name = TYPE_VIRTIO_BALLOON,
604 .parent = TYPE_VIRTIO_DEVICE,
605 .instance_size = sizeof(VirtIOBalloon),
606 .instance_init = virtio_balloon_instance_init,
607 .class_init = virtio_balloon_class_init,
608 };
609
610 static void virtio_register_types(void)
611 {
612 type_register_static(&virtio_balloon_info);
613 }
614
615 type_init(virtio_register_types)