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