]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/extra/0003-virtio-balloon-use-smaller-config-on-older-guests.patch
virtio-balloon: use smaller config on older guests
[pve-qemu.git] / debian / patches / extra / 0003-virtio-balloon-use-smaller-config-on-older-guests.patch
CommitLineData
d5699f03
TL
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3Date: Tue, 2 Jul 2019 09:23:43 +0200
4Subject: [PATCH] virtio-balloon: use smaller config on older guests
5
6The increased config size changes its alignment requirements
7preventing guests from migrating from old qemu versions if
8their balloon mapping isn't stricter aligned.
9So base the default config size on the machine version.
10
11Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
12---
13 hw/i386/pc.c | 2 ++
14 hw/virtio/virtio-balloon.c | 52 +++++++++++++++++++++++++++---
15 include/hw/virtio/virtio-balloon.h | 1 +
16 3 files changed, 51 insertions(+), 4 deletions(-)
17
18diff --git a/hw/i386/pc.c b/hw/i386/pc.c
19index f2c15bf1f2..a6c01203f5 100644
20--- a/hw/i386/pc.c
21+++ b/hw/i386/pc.c
22@@ -77,6 +77,7 @@
23 #include "hw/i386/intel_iommu.h"
24 #include "hw/net/ne2000-isa.h"
25 #include "standard-headers/asm-x86/bootparam.h"
26+#include "hw/virtio/virtio-balloon.h"
27
28 /* debug PC/ISA interrupts */
29 //#define DEBUG_IRQ
30@@ -137,6 +138,7 @@ GlobalProperty pc_compat_3_1[] = {
31 { "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
32 { "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" },
33 { TYPE_X86_CPU, "x-intel-pt-auto-level", "off" },
34+ { TYPE_VIRTIO_BALLOON, "x-use-large-balloon-config", "off" },
35 };
36 const size_t pc_compat_3_1_len = G_N_ELEMENTS(pc_compat_3_1);
37
38diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
39index 2112874055..d10298786d 100644
40--- a/hw/virtio/virtio-balloon.c
41+++ b/hw/virtio/virtio-balloon.c
42@@ -328,6 +328,28 @@ static void balloon_stats_set_poll_interval(Object *obj, Visitor *v,
43 balloon_stats_change_timer(s, 0);
44 }
45
46+static void balloon_get_large_config(Object *obj, Visitor *v,
47+ const char *name, void *opaque,
48+ Error **errp)
49+{
50+ VirtIOBalloon *s = opaque;
51+ visit_type_bool(v, name, &s->use_large_config, errp);
52+}
53+
54+static void balloon_set_large_config(Object *obj, Visitor *v,
55+ const char *name, void *opaque,
56+ Error **errp)
57+{
58+ VirtIOBalloon *s = opaque;
59+ DeviceState *dev = DEVICE(s);
60+
61+ if (dev->realized) {
62+ error_setg(errp, "balloon config size cannot be changed at runtime");
63+ } else {
64+ visit_type_bool(v, name, &s->use_large_config, errp);
65+ }
66+}
67+
68 static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
69 {
70 VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
71@@ -526,6 +548,17 @@ static bool virtio_balloon_free_page_support(void *opaque)
72 return virtio_vdev_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT);
73 }
74
75+static size_t virtio_balloon_config_size(void *opaque)
76+{
77+ VirtIOBalloon *s = opaque;
78+
79+ if (s->use_large_config) {
80+ return sizeof(struct virtio_balloon_config);
81+ } else {
82+ return offsetof(struct virtio_balloon_config, free_page_report_cmd_id);
83+ }
84+}
85+
86 static void virtio_balloon_free_page_start(VirtIOBalloon *s)
87 {
88 VirtIODevice *vdev = VIRTIO_DEVICE(s);
89@@ -635,7 +668,7 @@ static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
90 }
91
92 trace_virtio_balloon_get_config(config.num_pages, config.actual);
93- memcpy(config_data, &config, sizeof(struct virtio_balloon_config));
94+ memcpy(config_data, &config, virtio_balloon_config_size(dev));
95 }
96
97 static int build_dimm_list(Object *obj, void *opaque)
98@@ -679,7 +712,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
99 uint32_t oldactual = dev->actual;
100 ram_addr_t vm_ram_size = get_current_ram_size();
101
102- memcpy(&config, config_data, sizeof(struct virtio_balloon_config));
103+ memcpy(&config, config_data, virtio_balloon_config_size(dev));
104 dev->actual = le32_to_cpu(config.actual);
105 if (dev->actual != oldactual) {
106 qapi_event_send_balloon_change(vm_ram_size -
107@@ -766,7 +799,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
108 int ret;
109
110 virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON,
111- sizeof(struct virtio_balloon_config));
112+ virtio_balloon_config_size(s));
113
114 ret = qemu_add_balloon_handler(virtio_balloon_to_target,
115 virtio_balloon_stat, s);
116@@ -791,7 +824,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
117 s->free_page_report_notify.notify =
118 virtio_balloon_free_page_report_notify;
119 precopy_add_notifier(&s->free_page_report_notify);
120- if (s->iothread) {
121+ if (s->iothread && s->use_large_config) {
122 object_ref(OBJECT(s->iothread));
123 s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread),
124 virtio_ballloon_get_free_page_hints, s);
125@@ -804,6 +837,11 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
126 virtio_error(vdev, "iothread is missing");
127 }
128 }
129+
130+ if (!s->use_large_config) {
131+ s->host_features &= ~(1 << VIRTIO_BALLOON_F_PAGE_POISON);
132+ }
133+
134 reset_stats(s);
135 }
136
137@@ -880,6 +918,12 @@ static void virtio_balloon_instance_init(Object *obj)
138 balloon_stats_get_poll_interval,
139 balloon_stats_set_poll_interval,
140 NULL, s, NULL);
141+
142+ s->use_large_config = true;
143+ object_property_add(obj, "x-use-large-balloon-config", "bool",
144+ balloon_get_large_config,
145+ balloon_set_large_config,
146+ NULL, s, NULL);
147 }
148
149 static const VMStateDescription vmstate_virtio_balloon = {
150diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h
151index 1afafb12f6..f212c08bd7 100644
152--- a/include/hw/virtio/virtio-balloon.h
153+++ b/include/hw/virtio/virtio-balloon.h
154@@ -45,6 +45,7 @@ enum virtio_balloon_free_page_report_status {
155 typedef struct VirtIOBalloon {
156 VirtIODevice parent_obj;
157 VirtQueue *ivq, *dvq, *svq, *free_page_vq;
158+ bool use_large_config;
159 uint32_t free_page_report_status;
160 uint32_t num_pages;
161 uint32_t actual;