1*6cc6a7b9SPeter XuBackwards compatibility
2*6cc6a7b9SPeter Xu=======================
3*6cc6a7b9SPeter Xu
4*6cc6a7b9SPeter XuHow backwards compatibility works
5*6cc6a7b9SPeter Xu---------------------------------
6*6cc6a7b9SPeter Xu
7*6cc6a7b9SPeter XuWhen we do migration, we have two QEMU processes: the source and the
8*6cc6a7b9SPeter Xutarget.  There are two cases, they are the same version or they are
9*6cc6a7b9SPeter Xudifferent versions.  The easy case is when they are the same version.
10*6cc6a7b9SPeter XuThe difficult one is when they are different versions.
11*6cc6a7b9SPeter Xu
12*6cc6a7b9SPeter XuThere are two things that are different, but they have very similar
13*6cc6a7b9SPeter Xunames and sometimes get confused:
14*6cc6a7b9SPeter Xu
15*6cc6a7b9SPeter Xu- QEMU version
16*6cc6a7b9SPeter Xu- machine type version
17*6cc6a7b9SPeter Xu
18*6cc6a7b9SPeter XuLet's start with a practical example, we start with:
19*6cc6a7b9SPeter Xu
20*6cc6a7b9SPeter Xu- qemu-system-x86_64 (v5.2), from now on qemu-5.2.
21*6cc6a7b9SPeter Xu- qemu-system-x86_64 (v5.1), from now on qemu-5.1.
22*6cc6a7b9SPeter Xu
23*6cc6a7b9SPeter XuRelated to this are the "latest" machine types defined on each of
24*6cc6a7b9SPeter Xuthem:
25*6cc6a7b9SPeter Xu
26*6cc6a7b9SPeter Xu- pc-q35-5.2 (newer one in qemu-5.2) from now on pc-5.2
27*6cc6a7b9SPeter Xu- pc-q35-5.1 (newer one in qemu-5.1) from now on pc-5.1
28*6cc6a7b9SPeter Xu
29*6cc6a7b9SPeter XuFirst of all, migration is only supposed to work if you use the same
30*6cc6a7b9SPeter Xumachine type in both source and destination. The QEMU hardware
31*6cc6a7b9SPeter Xuconfiguration needs to be the same also on source and destination.
32*6cc6a7b9SPeter XuMost aspects of the backend configuration can be changed at will,
33*6cc6a7b9SPeter Xuexcept for a few cases where the backend features influence frontend
34*6cc6a7b9SPeter Xudevice feature exposure.  But that is not relevant for this section.
35*6cc6a7b9SPeter Xu
36*6cc6a7b9SPeter XuI am going to list the number of combinations that we can have.  Let's
37*6cc6a7b9SPeter Xustart with the trivial ones, QEMU is the same on source and
38*6cc6a7b9SPeter Xudestination:
39*6cc6a7b9SPeter Xu
40*6cc6a7b9SPeter Xu1 - qemu-5.2 -M pc-5.2  -> migrates to -> qemu-5.2 -M pc-5.2
41*6cc6a7b9SPeter Xu
42*6cc6a7b9SPeter Xu  This is the latest QEMU with the latest machine type.
43*6cc6a7b9SPeter Xu  This have to work, and if it doesn't work it is a bug.
44*6cc6a7b9SPeter Xu
45*6cc6a7b9SPeter Xu2 - qemu-5.1 -M pc-5.1  -> migrates to -> qemu-5.1 -M pc-5.1
46*6cc6a7b9SPeter Xu
47*6cc6a7b9SPeter Xu  Exactly the same case than the previous one, but for 5.1.
48*6cc6a7b9SPeter Xu  Nothing to see here either.
49*6cc6a7b9SPeter Xu
50*6cc6a7b9SPeter XuThis are the easiest ones, we will not talk more about them in this
51*6cc6a7b9SPeter Xusection.
52*6cc6a7b9SPeter Xu
53*6cc6a7b9SPeter XuNow we start with the more interesting cases.  Consider the case where
54*6cc6a7b9SPeter Xuwe have the same QEMU version in both sides (qemu-5.2) but we are using
55*6cc6a7b9SPeter Xuthe latest machine type for that version (pc-5.2) but one of an older
56*6cc6a7b9SPeter XuQEMU version, in this case pc-5.1.
57*6cc6a7b9SPeter Xu
58*6cc6a7b9SPeter Xu3 - qemu-5.2 -M pc-5.1  -> migrates to -> qemu-5.2 -M pc-5.1
59*6cc6a7b9SPeter Xu
60*6cc6a7b9SPeter Xu  It needs to use the definition of pc-5.1 and the devices as they
61*6cc6a7b9SPeter Xu  were configured on 5.1, but this should be easy in the sense that
62*6cc6a7b9SPeter Xu  both sides are the same QEMU and both sides have exactly the same
63*6cc6a7b9SPeter Xu  idea of what the pc-5.1 machine is.
64*6cc6a7b9SPeter Xu
65*6cc6a7b9SPeter Xu4 - qemu-5.1 -M pc-5.2  -> migrates to -> qemu-5.1 -M pc-5.2
66*6cc6a7b9SPeter Xu
67*6cc6a7b9SPeter Xu  This combination is not possible as the qemu-5.1 doesn't understand
68*6cc6a7b9SPeter Xu  pc-5.2 machine type.  So nothing to worry here.
69*6cc6a7b9SPeter Xu
70*6cc6a7b9SPeter XuNow it comes the interesting ones, when both QEMU processes are
71*6cc6a7b9SPeter Xudifferent.  Notice also that the machine type needs to be pc-5.1,
72*6cc6a7b9SPeter Xubecause we have the limitation than qemu-5.1 doesn't know pc-5.2.  So
73*6cc6a7b9SPeter Xuthe possible cases are:
74*6cc6a7b9SPeter Xu
75*6cc6a7b9SPeter Xu5 - qemu-5.2 -M pc-5.1  -> migrates to -> qemu-5.1 -M pc-5.1
76*6cc6a7b9SPeter Xu
77*6cc6a7b9SPeter Xu  This migration is known as newer to older.  We need to make sure
78*6cc6a7b9SPeter Xu  when we are developing 5.2 we need to take care about not to break
79*6cc6a7b9SPeter Xu  migration to qemu-5.1.  Notice that we can't make updates to
80*6cc6a7b9SPeter Xu  qemu-5.1 to understand whatever qemu-5.2 decides to change, so it is
81*6cc6a7b9SPeter Xu  in qemu-5.2 side to make the relevant changes.
82*6cc6a7b9SPeter Xu
83*6cc6a7b9SPeter Xu6 - qemu-5.1 -M pc-5.1  -> migrates to -> qemu-5.2 -M pc-5.1
84*6cc6a7b9SPeter Xu
85*6cc6a7b9SPeter Xu  This migration is known as older to newer.  We need to make sure
86*6cc6a7b9SPeter Xu  than we are able to receive migrations from qemu-5.1. The problem is
87*6cc6a7b9SPeter Xu  similar to the previous one.
88*6cc6a7b9SPeter Xu
89*6cc6a7b9SPeter XuIf qemu-5.1 and qemu-5.2 were the same, there will not be any
90*6cc6a7b9SPeter Xucompatibility problems.  But the reason that we create qemu-5.2 is to
91*6cc6a7b9SPeter Xuget new features, devices, defaults, etc.
92*6cc6a7b9SPeter Xu
93*6cc6a7b9SPeter XuIf we get a device that has a new feature, or change a default value,
94*6cc6a7b9SPeter Xuwe have a problem when we try to migrate between different QEMU
95*6cc6a7b9SPeter Xuversions.
96*6cc6a7b9SPeter Xu
97*6cc6a7b9SPeter XuSo we need a way to tell qemu-5.2 that when we are using machine type
98*6cc6a7b9SPeter Xupc-5.1, it needs to **not** use the feature, to be able to migrate to
99*6cc6a7b9SPeter Xureal qemu-5.1.
100*6cc6a7b9SPeter Xu
101*6cc6a7b9SPeter XuAnd the equivalent part when migrating from qemu-5.1 to qemu-5.2.
102*6cc6a7b9SPeter Xuqemu-5.2 has to expect that it is not going to get data for the new
103*6cc6a7b9SPeter Xufeature, because qemu-5.1 doesn't know about it.
104*6cc6a7b9SPeter Xu
105*6cc6a7b9SPeter XuHow do we tell QEMU about these device feature changes?  In
106*6cc6a7b9SPeter Xuhw/core/machine.c:hw_compat_X_Y arrays.
107*6cc6a7b9SPeter Xu
108*6cc6a7b9SPeter XuIf we change a default value, we need to put back the old value on
109*6cc6a7b9SPeter Xuthat array.  And the device, during initialization needs to look at
110*6cc6a7b9SPeter Xuthat array to see what value it needs to get for that feature.  And
111*6cc6a7b9SPeter Xuwhat are we going to put in that array, the value of a property.
112*6cc6a7b9SPeter Xu
113*6cc6a7b9SPeter XuTo create a property for a device, we need to use one of the
114*6cc6a7b9SPeter XuDEFINE_PROP_*() macros. See include/hw/qdev-properties.h to find the
115*6cc6a7b9SPeter Xumacros that exist.  With it, we set the default value for that
116*6cc6a7b9SPeter Xuproperty, and that is what it is going to get in the latest released
117*6cc6a7b9SPeter Xuversion.  But if we want a different value for a previous version, we
118*6cc6a7b9SPeter Xucan change that in the hw_compat_X_Y arrays.
119*6cc6a7b9SPeter Xu
120*6cc6a7b9SPeter Xuhw_compat_X_Y is an array of registers that have the format:
121*6cc6a7b9SPeter Xu
122*6cc6a7b9SPeter Xu- name_device
123*6cc6a7b9SPeter Xu- name_property
124*6cc6a7b9SPeter Xu- value
125*6cc6a7b9SPeter Xu
126*6cc6a7b9SPeter XuLet's see a practical example.
127*6cc6a7b9SPeter Xu
128*6cc6a7b9SPeter XuIn qemu-5.2 virtio-blk-device got multi queue support.  This is a
129*6cc6a7b9SPeter Xuchange that is not backward compatible.  In qemu-5.1 it has one
130*6cc6a7b9SPeter Xuqueue. In qemu-5.2 it has the same number of queues as the number of
131*6cc6a7b9SPeter Xucpus in the system.
132*6cc6a7b9SPeter Xu
133*6cc6a7b9SPeter XuWhen we are doing migration, if we migrate from a device that has 4
134*6cc6a7b9SPeter Xuqueues to a device that have only one queue, we don't know where to
135*6cc6a7b9SPeter Xuput the extra information for the other 3 queues, and we fail
136*6cc6a7b9SPeter Xumigration.
137*6cc6a7b9SPeter Xu
138*6cc6a7b9SPeter XuSimilar problem when we migrate from qemu-5.1 that has only one queue
139*6cc6a7b9SPeter Xuto qemu-5.2, we only sent information for one queue, but destination
140*6cc6a7b9SPeter Xuhas 4, and we have 3 queues that are not properly initialized and
141*6cc6a7b9SPeter Xuanything can happen.
142*6cc6a7b9SPeter Xu
143*6cc6a7b9SPeter XuSo, how can we address this problem.  Easy, just convince qemu-5.2
144*6cc6a7b9SPeter Xuthat when it is running pc-5.1, it needs to set the number of queues
145*6cc6a7b9SPeter Xufor virtio-blk-devices to 1.
146*6cc6a7b9SPeter Xu
147*6cc6a7b9SPeter XuThat way we fix the cases 5 and 6.
148*6cc6a7b9SPeter Xu
149*6cc6a7b9SPeter Xu5 - qemu-5.2 -M pc-5.1  -> migrates to -> qemu-5.1 -M pc-5.1
150*6cc6a7b9SPeter Xu
151*6cc6a7b9SPeter Xu    qemu-5.2 -M pc-5.1 sets number of queues to be 1.
152*6cc6a7b9SPeter Xu    qemu-5.1 -M pc-5.1 expects number of queues to be 1.
153*6cc6a7b9SPeter Xu
154*6cc6a7b9SPeter Xu    correct.  migration works.
155*6cc6a7b9SPeter Xu
156*6cc6a7b9SPeter Xu6 - qemu-5.1 -M pc-5.1  -> migrates to -> qemu-5.2 -M pc-5.1
157*6cc6a7b9SPeter Xu
158*6cc6a7b9SPeter Xu    qemu-5.1 -M pc-5.1 sets number of queues to be 1.
159*6cc6a7b9SPeter Xu    qemu-5.2 -M pc-5.1 expects number of queues to be 1.
160*6cc6a7b9SPeter Xu
161*6cc6a7b9SPeter Xu    correct.  migration works.
162*6cc6a7b9SPeter Xu
163*6cc6a7b9SPeter XuAnd now the other interesting case, case 3.  In this case we have:
164*6cc6a7b9SPeter Xu
165*6cc6a7b9SPeter Xu3 - qemu-5.2 -M pc-5.1  -> migrates to -> qemu-5.2 -M pc-5.1
166*6cc6a7b9SPeter Xu
167*6cc6a7b9SPeter Xu    Here we have the same QEMU in both sides.  So it doesn't matter a
168*6cc6a7b9SPeter Xu    lot if we have set the number of queues to 1 or not, because
169*6cc6a7b9SPeter Xu    they are the same.
170*6cc6a7b9SPeter Xu
171*6cc6a7b9SPeter Xu    WRONG!
172*6cc6a7b9SPeter Xu
173*6cc6a7b9SPeter Xu    Think what happens if we do one of this double migrations:
174*6cc6a7b9SPeter Xu
175*6cc6a7b9SPeter Xu    A -> migrates -> B -> migrates -> C
176*6cc6a7b9SPeter Xu
177*6cc6a7b9SPeter Xu    where:
178*6cc6a7b9SPeter Xu
179*6cc6a7b9SPeter Xu    A: qemu-5.1 -M pc-5.1
180*6cc6a7b9SPeter Xu    B: qemu-5.2 -M pc-5.1
181*6cc6a7b9SPeter Xu    C: qemu-5.2 -M pc-5.1
182*6cc6a7b9SPeter Xu
183*6cc6a7b9SPeter Xu    migration A -> B is case 6, so number of queues needs to be 1.
184*6cc6a7b9SPeter Xu
185*6cc6a7b9SPeter Xu    migration B -> C is case 3, so we don't care.  But actually we
186*6cc6a7b9SPeter Xu    care because we haven't started the guest in qemu-5.2, it came
187*6cc6a7b9SPeter Xu    migrated from qemu-5.1.  So to be in the safe place, we need to
188*6cc6a7b9SPeter Xu    always use number of queues 1 when we are using pc-5.1.
189*6cc6a7b9SPeter Xu
190*6cc6a7b9SPeter XuNow, how was this done in reality?  The following commit shows how it
191*6cc6a7b9SPeter Xuwas done::
192*6cc6a7b9SPeter Xu
193*6cc6a7b9SPeter Xu  commit 9445e1e15e66c19e42bea942ba810db28052cd05
194*6cc6a7b9SPeter Xu  Author: Stefan Hajnoczi <stefanha@redhat.com>
195*6cc6a7b9SPeter Xu  Date:   Tue Aug 18 15:33:47 2020 +0100
196*6cc6a7b9SPeter Xu
197*6cc6a7b9SPeter Xu  virtio-blk-pci: default num_queues to -smp N
198*6cc6a7b9SPeter Xu
199*6cc6a7b9SPeter XuThe relevant parts for migration are::
200*6cc6a7b9SPeter Xu
201*6cc6a7b9SPeter Xu    @@ -1281,7 +1284,8 @@ static Property virtio_blk_properties[] = {
202*6cc6a7b9SPeter Xu     #endif
203*6cc6a7b9SPeter Xu         DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
204*6cc6a7b9SPeter Xu                         true),
205*6cc6a7b9SPeter Xu    -    DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues, 1),
206*6cc6a7b9SPeter Xu    +    DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues,
207*6cc6a7b9SPeter Xu    +                       VIRTIO_BLK_AUTO_NUM_QUEUES),
208*6cc6a7b9SPeter Xu         DEFINE_PROP_UINT16("queue-size", VirtIOBlock, conf.queue_size, 256),
209*6cc6a7b9SPeter Xu
210*6cc6a7b9SPeter XuIt changes the default value of num_queues.  But it fishes it for old
211*6cc6a7b9SPeter Xumachine types to have the right value::
212*6cc6a7b9SPeter Xu
213*6cc6a7b9SPeter Xu    @@ -31,6 +31,7 @@
214*6cc6a7b9SPeter Xu     GlobalProperty hw_compat_5_1[] = {
215*6cc6a7b9SPeter Xu         ...
216*6cc6a7b9SPeter Xu    +    { "virtio-blk-device", "num-queues", "1"},
217*6cc6a7b9SPeter Xu         ...
218*6cc6a7b9SPeter Xu     };
219*6cc6a7b9SPeter Xu
220*6cc6a7b9SPeter XuA device with different features on both sides
221*6cc6a7b9SPeter Xu----------------------------------------------
222*6cc6a7b9SPeter Xu
223*6cc6a7b9SPeter XuLet's assume that we are using the same QEMU binary on both sides,
224*6cc6a7b9SPeter Xujust to make the things easier.  But we have a device that has
225*6cc6a7b9SPeter Xudifferent features on both sides of the migration.  That can be
226*6cc6a7b9SPeter Xubecause the devices are different, because the kernel driver of both
227*6cc6a7b9SPeter Xudevices have different features, whatever.
228*6cc6a7b9SPeter Xu
229*6cc6a7b9SPeter XuHow can we get this to work with migration.  The way to do that is
230*6cc6a7b9SPeter Xu"theoretically" easy.  You have to get the features that the device
231*6cc6a7b9SPeter Xuhas in the source of the migration.  The features that the device has
232*6cc6a7b9SPeter Xuon the target of the migration, you get the intersection of the
233*6cc6a7b9SPeter Xufeatures of both sides, and that is the way that you should launch
234*6cc6a7b9SPeter XuQEMU.
235*6cc6a7b9SPeter Xu
236*6cc6a7b9SPeter XuNotice that this is not completely related to QEMU.  The most
237*6cc6a7b9SPeter Xuimportant thing here is that this should be handled by the managing
238*6cc6a7b9SPeter Xuapplication that launches QEMU.  If QEMU is configured correctly, the
239*6cc6a7b9SPeter Xumigration will succeed.
240*6cc6a7b9SPeter Xu
241*6cc6a7b9SPeter XuThat said, actually doing it is complicated.  Almost all devices are
242*6cc6a7b9SPeter Xubad at being able to be launched with only some features enabled.
243*6cc6a7b9SPeter XuWith one big exception: cpus.
244*6cc6a7b9SPeter Xu
245*6cc6a7b9SPeter XuYou can read the documentation for QEMU x86 cpu models here:
246*6cc6a7b9SPeter Xu
247*6cc6a7b9SPeter Xuhttps://qemu-project.gitlab.io/qemu/system/qemu-cpu-models.html
248*6cc6a7b9SPeter Xu
249*6cc6a7b9SPeter XuSee when they talk about migration they recommend that one chooses the
250*6cc6a7b9SPeter Xunewest cpu model that is supported for all cpus.
251*6cc6a7b9SPeter Xu
252*6cc6a7b9SPeter XuLet's say that we have:
253*6cc6a7b9SPeter Xu
254*6cc6a7b9SPeter XuHost A:
255*6cc6a7b9SPeter Xu
256*6cc6a7b9SPeter XuDevice X has the feature Y
257*6cc6a7b9SPeter Xu
258*6cc6a7b9SPeter XuHost B:
259*6cc6a7b9SPeter Xu
260*6cc6a7b9SPeter XuDevice X has not the feature Y
261*6cc6a7b9SPeter Xu
262*6cc6a7b9SPeter XuIf we try to migrate without any care from host A to host B, it will
263*6cc6a7b9SPeter Xufail because when migration tries to load the feature Y on
264*6cc6a7b9SPeter Xudestination, it will find that the hardware is not there.
265*6cc6a7b9SPeter Xu
266*6cc6a7b9SPeter XuDoing this would be the equivalent of doing with cpus:
267*6cc6a7b9SPeter Xu
268*6cc6a7b9SPeter XuHost A:
269*6cc6a7b9SPeter Xu
270*6cc6a7b9SPeter Xu$ qemu-system-x86_64 -cpu host
271*6cc6a7b9SPeter Xu
272*6cc6a7b9SPeter XuHost B:
273*6cc6a7b9SPeter Xu
274*6cc6a7b9SPeter Xu$ qemu-system-x86_64 -cpu host
275*6cc6a7b9SPeter Xu
276*6cc6a7b9SPeter XuWhen both hosts have different cpu features this is guaranteed to
277*6cc6a7b9SPeter Xufail.  Especially if Host B has less features than host A.  If host A
278*6cc6a7b9SPeter Xuhas less features than host B, sometimes it works.  Important word of
279*6cc6a7b9SPeter Xulast sentence is "sometimes".
280*6cc6a7b9SPeter Xu
281*6cc6a7b9SPeter XuSo, forgetting about cpu models and continuing with the -cpu host
282*6cc6a7b9SPeter Xuexample, let's see that the differences of the cpus is that Host A and
283*6cc6a7b9SPeter XuB have the following features:
284*6cc6a7b9SPeter Xu
285*6cc6a7b9SPeter XuFeatures:   'pcid'  'stibp' 'taa-no'
286*6cc6a7b9SPeter XuHost A:        X       X
287*6cc6a7b9SPeter XuHost B:                        X
288*6cc6a7b9SPeter Xu
289*6cc6a7b9SPeter XuAnd we want to migrate between them, the way configure both QEMU cpu
290*6cc6a7b9SPeter Xuwill be:
291*6cc6a7b9SPeter Xu
292*6cc6a7b9SPeter XuHost A:
293*6cc6a7b9SPeter Xu
294*6cc6a7b9SPeter Xu$ qemu-system-x86_64 -cpu host,pcid=off,stibp=off
295*6cc6a7b9SPeter Xu
296*6cc6a7b9SPeter XuHost B:
297*6cc6a7b9SPeter Xu
298*6cc6a7b9SPeter Xu$ qemu-system-x86_64 -cpu host,taa-no=off
299*6cc6a7b9SPeter Xu
300*6cc6a7b9SPeter XuAnd you would be able to migrate between them.  It is responsibility
301*6cc6a7b9SPeter Xuof the management application or of the user to make sure that the
302*6cc6a7b9SPeter Xuconfiguration is correct.  QEMU doesn't know how to look at this kind
303*6cc6a7b9SPeter Xuof features in general.
304*6cc6a7b9SPeter Xu
305*6cc6a7b9SPeter XuNotice that we don't recommend to use -cpu host for migration.  It is
306*6cc6a7b9SPeter Xuused in this example because it makes the example simpler.
307*6cc6a7b9SPeter Xu
308*6cc6a7b9SPeter XuOther devices have worse control about individual features.  If they
309*6cc6a7b9SPeter Xuwant to be able to migrate between hosts that show different features,
310*6cc6a7b9SPeter Xuthe device needs a way to configure which ones it is going to use.
311*6cc6a7b9SPeter Xu
312*6cc6a7b9SPeter XuIn this section we have considered that we are using the same QEMU
313*6cc6a7b9SPeter Xubinary in both sides of the migration.  If we use different QEMU
314*6cc6a7b9SPeter Xuversions process, then we need to have into account all other
315*6cc6a7b9SPeter Xudifferences and the examples become even more complicated.
316*6cc6a7b9SPeter Xu
317*6cc6a7b9SPeter XuHow to mitigate when we have a backward compatibility error
318*6cc6a7b9SPeter Xu-----------------------------------------------------------
319*6cc6a7b9SPeter Xu
320*6cc6a7b9SPeter XuWe broke migration for old machine types continuously during
321*6cc6a7b9SPeter Xudevelopment.  But as soon as we find that there is a problem, we fix
322*6cc6a7b9SPeter Xuit.  The problem is what happens when we detect after we have done a
323*6cc6a7b9SPeter Xurelease that something has gone wrong.
324*6cc6a7b9SPeter Xu
325*6cc6a7b9SPeter XuLet see how it worked with one example.
326*6cc6a7b9SPeter Xu
327*6cc6a7b9SPeter XuAfter the release of qemu-8.0 we found a problem when doing migration
328*6cc6a7b9SPeter Xuof the machine type pc-7.2.
329*6cc6a7b9SPeter Xu
330*6cc6a7b9SPeter Xu- $ qemu-7.2 -M pc-7.2  ->  qemu-7.2 -M pc-7.2
331*6cc6a7b9SPeter Xu
332*6cc6a7b9SPeter Xu  This migration works
333*6cc6a7b9SPeter Xu
334*6cc6a7b9SPeter Xu- $ qemu-8.0 -M pc-7.2  ->  qemu-8.0 -M pc-7.2
335*6cc6a7b9SPeter Xu
336*6cc6a7b9SPeter Xu  This migration works
337*6cc6a7b9SPeter Xu
338*6cc6a7b9SPeter Xu- $ qemu-8.0 -M pc-7.2  ->  qemu-7.2 -M pc-7.2
339*6cc6a7b9SPeter Xu
340*6cc6a7b9SPeter Xu  This migration fails
341*6cc6a7b9SPeter Xu
342*6cc6a7b9SPeter Xu- $ qemu-7.2 -M pc-7.2  ->  qemu-8.0 -M pc-7.2
343*6cc6a7b9SPeter Xu
344*6cc6a7b9SPeter Xu  This migration fails
345*6cc6a7b9SPeter Xu
346*6cc6a7b9SPeter XuSo clearly something fails when migration between qemu-7.2 and
347*6cc6a7b9SPeter Xuqemu-8.0 with machine type pc-7.2.  The error messages, and git bisect
348*6cc6a7b9SPeter Xupointed to this commit.
349*6cc6a7b9SPeter Xu
350*6cc6a7b9SPeter XuIn qemu-8.0 we got this commit::
351*6cc6a7b9SPeter Xu
352*6cc6a7b9SPeter Xu    commit 010746ae1db7f52700cb2e2c46eb94f299cfa0d2
353*6cc6a7b9SPeter Xu    Author: Jonathan Cameron <Jonathan.Cameron@huawei.com>
354*6cc6a7b9SPeter Xu    Date:   Thu Mar 2 13:37:02 2023 +0000
355*6cc6a7b9SPeter Xu
356*6cc6a7b9SPeter Xu    hw/pci/aer: Implement PCI_ERR_UNCOR_MASK register
357*6cc6a7b9SPeter Xu
358*6cc6a7b9SPeter Xu
359*6cc6a7b9SPeter XuThe relevant bits of the commit for our example are this ones::
360*6cc6a7b9SPeter Xu
361*6cc6a7b9SPeter Xu    --- a/hw/pci/pcie_aer.c
362*6cc6a7b9SPeter Xu    +++ b/hw/pci/pcie_aer.c
363*6cc6a7b9SPeter Xu    @@ -112,6 +112,10 @@ int pcie_aer_init(PCIDevice *dev,
364*6cc6a7b9SPeter Xu
365*6cc6a7b9SPeter Xu         pci_set_long(dev->w1cmask + offset + PCI_ERR_UNCOR_STATUS,
366*6cc6a7b9SPeter Xu                      PCI_ERR_UNC_SUPPORTED);
367*6cc6a7b9SPeter Xu    +    pci_set_long(dev->config + offset + PCI_ERR_UNCOR_MASK,
368*6cc6a7b9SPeter Xu    +                 PCI_ERR_UNC_MASK_DEFAULT);
369*6cc6a7b9SPeter Xu    +    pci_set_long(dev->wmask + offset + PCI_ERR_UNCOR_MASK,
370*6cc6a7b9SPeter Xu    +                 PCI_ERR_UNC_SUPPORTED);
371*6cc6a7b9SPeter Xu
372*6cc6a7b9SPeter Xu         pci_set_long(dev->config + offset + PCI_ERR_UNCOR_SEVER,
373*6cc6a7b9SPeter Xu                     PCI_ERR_UNC_SEVERITY_DEFAULT);
374*6cc6a7b9SPeter Xu
375*6cc6a7b9SPeter XuThe patch changes how we configure PCI space for AER.  But QEMU fails
376*6cc6a7b9SPeter Xuwhen the PCI space configuration is different between source and
377*6cc6a7b9SPeter Xudestination.
378*6cc6a7b9SPeter Xu
379*6cc6a7b9SPeter XuThe following commit shows how this got fixed::
380*6cc6a7b9SPeter Xu
381*6cc6a7b9SPeter Xu    commit 5ed3dabe57dd9f4c007404345e5f5bf0e347317f
382*6cc6a7b9SPeter Xu    Author: Leonardo Bras <leobras@redhat.com>
383*6cc6a7b9SPeter Xu    Date:   Tue May 2 21:27:02 2023 -0300
384*6cc6a7b9SPeter Xu
385*6cc6a7b9SPeter Xu    hw/pci: Disable PCI_ERR_UNCOR_MASK register for machine type < 8.0
386*6cc6a7b9SPeter Xu
387*6cc6a7b9SPeter Xu    [...]
388*6cc6a7b9SPeter Xu
389*6cc6a7b9SPeter XuThe relevant parts of the fix in QEMU are as follow:
390*6cc6a7b9SPeter Xu
391*6cc6a7b9SPeter XuFirst, we create a new property for the device to be able to configure
392*6cc6a7b9SPeter Xuthe old behaviour or the new behaviour::
393*6cc6a7b9SPeter Xu
394*6cc6a7b9SPeter Xu    diff --git a/hw/pci/pci.c b/hw/pci/pci.c
395*6cc6a7b9SPeter Xu    index 8a87ccc8b0..5153ad63d6 100644
396*6cc6a7b9SPeter Xu    --- a/hw/pci/pci.c
397*6cc6a7b9SPeter Xu    +++ b/hw/pci/pci.c
398*6cc6a7b9SPeter Xu    @@ -79,6 +79,8 @@ static Property pci_props[] = {
399*6cc6a7b9SPeter Xu         DEFINE_PROP_STRING("failover_pair_id", PCIDevice,
400*6cc6a7b9SPeter Xu                            failover_pair_id),
401*6cc6a7b9SPeter Xu         DEFINE_PROP_UINT32("acpi-index",  PCIDevice, acpi_index, 0),
402*6cc6a7b9SPeter Xu    +    DEFINE_PROP_BIT("x-pcie-err-unc-mask", PCIDevice, cap_present,
403*6cc6a7b9SPeter Xu    +                    QEMU_PCIE_ERR_UNC_MASK_BITNR, true),
404*6cc6a7b9SPeter Xu         DEFINE_PROP_END_OF_LIST()
405*6cc6a7b9SPeter Xu     };
406*6cc6a7b9SPeter Xu
407*6cc6a7b9SPeter XuNotice that we enable the feature for new machine types.
408*6cc6a7b9SPeter Xu
409*6cc6a7b9SPeter XuNow we see how the fix is done.  This is going to depend on what kind
410*6cc6a7b9SPeter Xuof breakage happens, but in this case it is quite simple::
411*6cc6a7b9SPeter Xu
412*6cc6a7b9SPeter Xu    diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
413*6cc6a7b9SPeter Xu    index 103667c368..374d593ead 100644
414*6cc6a7b9SPeter Xu    --- a/hw/pci/pcie_aer.c
415*6cc6a7b9SPeter Xu    +++ b/hw/pci/pcie_aer.c
416*6cc6a7b9SPeter Xu    @@ -112,10 +112,13 @@ int pcie_aer_init(PCIDevice *dev, uint8_t cap_ver,
417*6cc6a7b9SPeter Xu    uint16_t offset,
418*6cc6a7b9SPeter Xu
419*6cc6a7b9SPeter Xu         pci_set_long(dev->w1cmask + offset + PCI_ERR_UNCOR_STATUS,
420*6cc6a7b9SPeter Xu                      PCI_ERR_UNC_SUPPORTED);
421*6cc6a7b9SPeter Xu    -    pci_set_long(dev->config + offset + PCI_ERR_UNCOR_MASK,
422*6cc6a7b9SPeter Xu    -                 PCI_ERR_UNC_MASK_DEFAULT);
423*6cc6a7b9SPeter Xu    -    pci_set_long(dev->wmask + offset + PCI_ERR_UNCOR_MASK,
424*6cc6a7b9SPeter Xu    -                 PCI_ERR_UNC_SUPPORTED);
425*6cc6a7b9SPeter Xu    +
426*6cc6a7b9SPeter Xu    +    if (dev->cap_present & QEMU_PCIE_ERR_UNC_MASK) {
427*6cc6a7b9SPeter Xu    +        pci_set_long(dev->config + offset + PCI_ERR_UNCOR_MASK,
428*6cc6a7b9SPeter Xu    +                     PCI_ERR_UNC_MASK_DEFAULT);
429*6cc6a7b9SPeter Xu    +        pci_set_long(dev->wmask + offset + PCI_ERR_UNCOR_MASK,
430*6cc6a7b9SPeter Xu    +                     PCI_ERR_UNC_SUPPORTED);
431*6cc6a7b9SPeter Xu    +    }
432*6cc6a7b9SPeter Xu
433*6cc6a7b9SPeter Xu         pci_set_long(dev->config + offset + PCI_ERR_UNCOR_SEVER,
434*6cc6a7b9SPeter Xu                      PCI_ERR_UNC_SEVERITY_DEFAULT);
435*6cc6a7b9SPeter Xu
436*6cc6a7b9SPeter XuI.e. If the property bit is enabled, we configure it as we did for
437*6cc6a7b9SPeter Xuqemu-8.0.  If the property bit is not set, we configure it as it was in 7.2.
438*6cc6a7b9SPeter Xu
439*6cc6a7b9SPeter XuAnd now, everything that is missing is disabling the feature for old
440*6cc6a7b9SPeter Xumachine types::
441*6cc6a7b9SPeter Xu
442*6cc6a7b9SPeter Xu    diff --git a/hw/core/machine.c b/hw/core/machine.c
443*6cc6a7b9SPeter Xu    index 47a34841a5..07f763eb2e 100644
444*6cc6a7b9SPeter Xu    --- a/hw/core/machine.c
445*6cc6a7b9SPeter Xu    +++ b/hw/core/machine.c
446*6cc6a7b9SPeter Xu    @@ -48,6 +48,7 @@ GlobalProperty hw_compat_7_2[] = {
447*6cc6a7b9SPeter Xu         { "e1000e", "migrate-timadj", "off" },
448*6cc6a7b9SPeter Xu         { "virtio-mem", "x-early-migration", "false" },
449*6cc6a7b9SPeter Xu         { "migration", "x-preempt-pre-7-2", "true" },
450*6cc6a7b9SPeter Xu    +    { TYPE_PCI_DEVICE, "x-pcie-err-unc-mask", "off" },
451*6cc6a7b9SPeter Xu     };
452*6cc6a7b9SPeter Xu     const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
453*6cc6a7b9SPeter Xu
454*6cc6a7b9SPeter XuAnd now, when qemu-8.0.1 is released with this fix, all combinations
455*6cc6a7b9SPeter Xuare going to work as supposed.
456*6cc6a7b9SPeter Xu
457*6cc6a7b9SPeter Xu- $ qemu-7.2 -M pc-7.2  ->  qemu-7.2 -M pc-7.2 (works)
458*6cc6a7b9SPeter Xu- $ qemu-8.0.1 -M pc-7.2  ->  qemu-8.0.1 -M pc-7.2 (works)
459*6cc6a7b9SPeter Xu- $ qemu-8.0.1 -M pc-7.2  ->  qemu-7.2 -M pc-7.2 (works)
460*6cc6a7b9SPeter Xu- $ qemu-7.2 -M pc-7.2  ->  qemu-8.0.1 -M pc-7.2 (works)
461*6cc6a7b9SPeter Xu
462*6cc6a7b9SPeter XuSo the normality has been restored and everything is ok, no?
463*6cc6a7b9SPeter Xu
464*6cc6a7b9SPeter XuNot really, now our matrix is much bigger.  We started with the easy
465*6cc6a7b9SPeter Xucases, migration from the same version to the same version always
466*6cc6a7b9SPeter Xuworks:
467*6cc6a7b9SPeter Xu
468*6cc6a7b9SPeter Xu- $ qemu-7.2 -M pc-7.2  ->  qemu-7.2 -M pc-7.2
469*6cc6a7b9SPeter Xu- $ qemu-8.0 -M pc-7.2  ->  qemu-8.0 -M pc-7.2
470*6cc6a7b9SPeter Xu- $ qemu-8.0.1 -M pc-7.2  ->  qemu-8.0.1 -M pc-7.2
471*6cc6a7b9SPeter Xu
472*6cc6a7b9SPeter XuNow the interesting ones.  When the QEMU processes versions are
473*6cc6a7b9SPeter Xudifferent.  For the 1st set, their fail and we can do nothing, both
474*6cc6a7b9SPeter Xuversions are released and we can't change anything.
475*6cc6a7b9SPeter Xu
476*6cc6a7b9SPeter Xu- $ qemu-7.2 -M pc-7.2  ->  qemu-8.0 -M pc-7.2
477*6cc6a7b9SPeter Xu- $ qemu-8.0 -M pc-7.2  ->  qemu-7.2 -M pc-7.2
478*6cc6a7b9SPeter Xu
479*6cc6a7b9SPeter XuThis two are the ones that work. The whole point of making the
480*6cc6a7b9SPeter Xuchange in qemu-8.0.1 release was to fix this issue:
481*6cc6a7b9SPeter Xu
482*6cc6a7b9SPeter Xu- $ qemu-7.2 -M pc-7.2  ->  qemu-8.0.1 -M pc-7.2
483*6cc6a7b9SPeter Xu- $ qemu-8.0.1 -M pc-7.2  ->  qemu-7.2 -M pc-7.2
484*6cc6a7b9SPeter Xu
485*6cc6a7b9SPeter XuBut now we found that qemu-8.0 neither can migrate to qemu-7.2 not
486*6cc6a7b9SPeter Xuqemu-8.0.1.
487*6cc6a7b9SPeter Xu
488*6cc6a7b9SPeter Xu- $ qemu-8.0 -M pc-7.2  ->  qemu-8.0.1 -M pc-7.2
489*6cc6a7b9SPeter Xu- $ qemu-8.0.1 -M pc-7.2  ->  qemu-8.0 -M pc-7.2
490*6cc6a7b9SPeter Xu
491*6cc6a7b9SPeter XuSo, if we start a pc-7.2 machine in qemu-8.0 we can't migrate it to
492*6cc6a7b9SPeter Xuanything except to qemu-8.0.
493*6cc6a7b9SPeter Xu
494*6cc6a7b9SPeter XuCan we do better?
495*6cc6a7b9SPeter Xu
496*6cc6a7b9SPeter XuYeap.  If we know that we are going to do this migration:
497*6cc6a7b9SPeter Xu
498*6cc6a7b9SPeter Xu- $ qemu-8.0 -M pc-7.2  ->  qemu-8.0.1 -M pc-7.2
499*6cc6a7b9SPeter Xu
500*6cc6a7b9SPeter XuWe can launch the appropriate devices with::
501*6cc6a7b9SPeter Xu
502*6cc6a7b9SPeter Xu  --device...,x-pci-e-err-unc-mask=on
503*6cc6a7b9SPeter Xu
504*6cc6a7b9SPeter XuAnd now we can receive a migration from 8.0.  And from now on, we can
505*6cc6a7b9SPeter Xudo that migration to new machine types if we remember to enable that
506*6cc6a7b9SPeter Xuproperty for pc-7.2.  Notice that we need to remember, it is not
507*6cc6a7b9SPeter Xuenough to know that the source of the migration is qemu-8.0.  Think of
508*6cc6a7b9SPeter Xuthis example:
509*6cc6a7b9SPeter Xu
510*6cc6a7b9SPeter Xu$ qemu-8.0 -M pc-7.2 -> qemu-8.0.1 -M pc-7.2 -> qemu-8.2 -M pc-7.2
511*6cc6a7b9SPeter Xu
512*6cc6a7b9SPeter XuIn the second migration, the source is not qemu-8.0, but we still have
513*6cc6a7b9SPeter Xuthat "problem" and have that property enabled.  Notice that we need to
514*6cc6a7b9SPeter Xucontinue having this mark/property until we have this machine
515*6cc6a7b9SPeter Xurebooted.  But it is not a normal reboot (that don't reload QEMU) we
516*6cc6a7b9SPeter Xuneed the machine to poweroff/poweron on a fixed QEMU.  And from now
517*6cc6a7b9SPeter Xuon we can use the proper real machine.
518