Imported Upstream version 1.2.5
[archive/platform/upstream/libvirt.git] / src / conf / domain_addr.c
1 /*
2  * domain_addr.c: helper APIs for managing domain device addresses
3  *
4  * Copyright (C) 2006-2014 Red Hat, Inc.
5  * Copyright (C) 2006 Daniel P. Berrange
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library.  If not, see
19  * <http://www.gnu.org/licenses/>.
20  *
21  * Author: Daniel P. Berrange <berrange@redhat.com>
22  */
23
24 #include <config.h>
25
26 #include "viralloc.h"
27 #include "virlog.h"
28 #include "virstring.h"
29 #include "domain_addr.h"
30
31 #define VIR_FROM_THIS VIR_FROM_DOMAIN
32
33 VIR_LOG_INIT("conf.domain_addr");
34
35 bool
36 virDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
37                                    const char *addrStr,
38                                    virDomainPCIConnectFlags busFlags,
39                                    virDomainPCIConnectFlags devFlags,
40                                    bool reportError,
41                                    bool fromConfig)
42 {
43     virErrorNumber errType = (fromConfig
44                               ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
45     virDomainPCIConnectFlags flagsMatchMask = VIR_PCI_CONNECT_TYPES_MASK;
46
47     if (fromConfig)
48        flagsMatchMask |= VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG;
49
50     /* If this bus doesn't allow the type of connection (PCI
51      * vs. PCIe) required by the device, or if the device requires
52      * hot-plug and this bus doesn't have it, return false.
53      */
54     if (!(devFlags & busFlags & flagsMatchMask)) {
55         if (reportError) {
56             if (devFlags & VIR_PCI_CONNECT_TYPE_PCI) {
57                 virReportError(errType,
58                                _("PCI bus is not compatible with the device "
59                                  "at %s. Device requires a standard PCI slot, "
60                                  "which is not provided by bus %.4x:%.2x"),
61                                addrStr, addr->domain, addr->bus);
62             } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE) {
63                 virReportError(errType,
64                                _("PCI bus is not compatible with the device "
65                                  "at %s. Device requires a PCI Express slot, "
66                                  "which is not provided by bus %.4x:%.2x"),
67                                addrStr, addr->domain, addr->bus);
68             } else {
69                 /* this should never happen. If it does, there is a
70                  * bug in the code that sets the flag bits for devices.
71                  */
72                 virReportError(errType,
73                            _("The device information for %s has no PCI "
74                              "connection types listed"), addrStr);
75             }
76         }
77         return false;
78     }
79     if ((devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) &&
80         !(busFlags & VIR_PCI_CONNECT_HOTPLUGGABLE)) {
81         if (reportError) {
82             virReportError(errType,
83                            _("PCI bus is not compatible with the device "
84                              "at %s. Device requires hot-plug capability, "
85                              "which is not provided by bus %.4x:%.2x"),
86                            addrStr, addr->domain, addr->bus);
87         }
88         return false;
89     }
90     return true;
91 }
92
93
94 /* Verify that the address is in bounds for the chosen bus, and
95  * that the bus is of the correct type for the device (via
96  * comparing the flags).
97  */
98 bool
99 virDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs,
100                             virDevicePCIAddressPtr addr,
101                             const char *addrStr,
102                             virDomainPCIConnectFlags flags,
103                             bool fromConfig)
104 {
105     virDomainPCIAddressBusPtr bus;
106     virErrorNumber errType = (fromConfig
107                               ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
108
109     if (addrs->nbuses == 0) {
110         virReportError(errType, "%s", _("No PCI buses available"));
111         return false;
112     }
113     if (addr->domain != 0) {
114         virReportError(errType,
115                        _("Invalid PCI address %s. "
116                          "Only PCI domain 0 is available"),
117                        addrStr);
118         return false;
119     }
120     if (addr->bus >= addrs->nbuses) {
121         virReportError(errType,
122                        _("Invalid PCI address %s. "
123                          "Only PCI buses up to %zu are available"),
124                        addrStr, addrs->nbuses - 1);
125         return false;
126     }
127
128     bus = &addrs->buses[addr->bus];
129
130     /* assure that at least one of the requested connection types is
131      * provided by this bus
132      */
133     if (!virDomainPCIAddressFlagsCompatible(addr, addrStr, bus->flags,
134                                             flags, true, fromConfig))
135         return false;
136
137     /* some "buses" are really just a single port */
138     if (bus->minSlot && addr->slot < bus->minSlot) {
139         virReportError(errType,
140                        _("Invalid PCI address %s. slot must be >= %zu"),
141                        addrStr, bus->minSlot);
142         return false;
143     }
144     if (addr->slot > bus->maxSlot) {
145         virReportError(errType,
146                        _("Invalid PCI address %s. slot must be <= %zu"),
147                        addrStr, bus->maxSlot);
148         return false;
149     }
150     if (addr->function > VIR_PCI_ADDRESS_FUNCTION_LAST) {
151         virReportError(errType,
152                        _("Invalid PCI address %s. function must be <= %u"),
153                        addrStr, VIR_PCI_ADDRESS_FUNCTION_LAST);
154         return false;
155     }
156     return true;
157 }
158
159
160 int
161 virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
162                                virDomainControllerModelPCI model)
163 {
164     switch (model) {
165     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
166     case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
167         bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
168                       VIR_PCI_CONNECT_TYPE_PCI);
169         bus->minSlot = 1;
170         bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
171         break;
172     case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
173         /* slots 1 - 31, no hotplug, PCIe only unless the address was
174          * specified in user config *and* the particular device being
175          * attached also allows it
176          */
177         bus->flags = (VIR_PCI_CONNECT_TYPE_PCIE |
178                       VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
179         bus->minSlot = 1;
180         bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
181         break;
182     case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
183         /* slots 1 - 31, standard PCI slots,
184          * but *not* hot-pluggable */
185         bus->flags = VIR_PCI_CONNECT_TYPE_PCI;
186         bus->minSlot = 1;
187         bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
188         break;
189     default:
190         virReportError(VIR_ERR_INTERNAL_ERROR,
191                        _("Invalid PCI controller model %d"), model);
192         return -1;
193     }
194
195     bus->model = model;
196     return 0;
197 }
198
199
200 /* Ensure addr fits in the address set, by expanding it if needed.
201  * This will only grow if the flags say that we need a normal
202  * hot-pluggable PCI slot. If we need a different type of slot, it
203  * will fail.
204  *
205  * Return value:
206  * -1 = OOM
207  *  0 = no action performed
208  * >0 = number of buses added
209  */
210 int
211 virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs,
212                            virDevicePCIAddressPtr addr,
213                            virDomainPCIConnectFlags flags)
214 {
215     int add;
216     size_t i;
217
218     add = addr->bus - addrs->nbuses + 1;
219     i = addrs->nbuses;
220     if (add <= 0)
221         return 0;
222
223     /* auto-grow only works when we're adding plain PCI devices */
224     if (!(flags & VIR_PCI_CONNECT_TYPE_PCI)) {
225         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
226                        _("Cannot automatically add a new PCI bus for a "
227                          "device requiring a slot other than standard PCI."));
228         return -1;
229     }
230
231     if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, add) < 0)
232         return -1;
233
234     for (; i < addrs->nbuses; i++) {
235         /* Any time we auto-add a bus, we will want a multi-slot
236          * bus. Currently the only type of bus we will auto-add is a
237          * pci-bridge, which is hot-pluggable and provides standard
238          * PCI slots.
239          */
240         virDomainPCIAddressBusSetModel(&addrs->buses[i],
241                                        VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE);
242     }
243     return add;
244 }
245
246
247 char *
248 virDomainPCIAddressAsString(virDevicePCIAddressPtr addr)
249 {
250     char *str;
251
252     ignore_value(virAsprintf(&str, "%.4x:%.2x:%.2x.%.1x",
253                              addr->domain,
254                              addr->bus,
255                              addr->slot,
256                              addr->function));
257     return str;
258 }
259
260
261 /*
262  * Check if the PCI slot is used by another device.
263  */
264 bool
265 virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs,
266                              virDevicePCIAddressPtr addr)
267 {
268     return !!addrs->buses[addr->bus].slots[addr->slot];
269 }
270
271
272 /*
273  * Reserve a slot (or just one function) for a device. If
274  * reserveEntireSlot is true, all functions for the slot are reserved,
275  * otherwise only one. If fromConfig is true, the address being
276  * requested came directly from the config and errors should be worded
277  * appropriately. If fromConfig is false, the address was
278  * automatically created by libvirt, so it is an internal error (not
279  * XML).
280  */
281 int
282 virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
283                                virDevicePCIAddressPtr addr,
284                                virDomainPCIConnectFlags flags,
285                                bool reserveEntireSlot,
286                                bool fromConfig)
287 {
288     int ret = -1;
289     char *addrStr = NULL;
290     virDomainPCIAddressBusPtr bus;
291     virErrorNumber errType = (fromConfig
292                               ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
293
294     if (!(addrStr = virDomainPCIAddressAsString(addr)))
295         goto cleanup;
296
297     /* Add an extra bus if necessary */
298     if (addrs->dryRun && virDomainPCIAddressSetGrow(addrs, addr, flags) < 0)
299         goto cleanup;
300     /* Check that the requested bus exists, is the correct type, and we
301      * are asking for a valid slot
302      */
303     if (!virDomainPCIAddressValidate(addrs, addr, addrStr, flags, fromConfig))
304         goto cleanup;
305
306     bus = &addrs->buses[addr->bus];
307
308     if (reserveEntireSlot) {
309         if (bus->slots[addr->slot]) {
310             virReportError(errType,
311                            _("Attempted double use of PCI slot %s "
312                              "(may need \"multifunction='on'\" for "
313                              "device on function 0)"), addrStr);
314             goto cleanup;
315         }
316         bus->slots[addr->slot] = 0xFF; /* reserve all functions of slot */
317         VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr);
318     } else {
319         if (bus->slots[addr->slot] & (1 << addr->function)) {
320             if (addr->function == 0) {
321                 virReportError(errType,
322                                _("Attempted double use of PCI Address %s"),
323                                addrStr);
324             } else {
325                 virReportError(errType,
326                                _("Attempted double use of PCI Address %s "
327                                  "(may need \"multifunction='on'\" "
328                                  "for device on function 0)"), addrStr);
329             }
330             goto cleanup;
331         }
332         bus->slots[addr->slot] |= (1 << addr->function);
333         VIR_DEBUG("Reserving PCI address %s", addrStr);
334     }
335
336     ret = 0;
337  cleanup:
338     VIR_FREE(addrStr);
339     return ret;
340 }
341
342
343 int
344 virDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs,
345                                virDevicePCIAddressPtr addr,
346                                virDomainPCIConnectFlags flags)
347 {
348     return virDomainPCIAddressReserveAddr(addrs, addr, flags, true, false);
349 }
350
351 int
352 virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs,
353                               virDomainDeviceInfoPtr dev)
354 {
355     int ret = -1;
356     char *addrStr = NULL;
357     /* Flags should be set according to the particular device,
358      * but only the caller knows the type of device. Currently this
359      * function is only used for hot-plug, though, and hot-plug is
360      * only supported for standard PCI devices, so we can safely use
361      * the setting below */
362     virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
363                                       VIR_PCI_CONNECT_TYPE_PCI);
364
365     if (!(addrStr = virDomainPCIAddressAsString(&dev->addr.pci)))
366         goto cleanup;
367
368     if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
369         /* We do not support hotplug multi-function PCI device now, so we should
370          * reserve the whole slot. The function of the PCI device must be 0.
371          */
372         if (dev->addr.pci.function != 0) {
373             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
374                            _("Only PCI device addresses with function=0"
375                              " are supported"));
376             goto cleanup;
377         }
378
379         if (!virDomainPCIAddressValidate(addrs, &dev->addr.pci,
380                                          addrStr, flags, true))
381             goto cleanup;
382
383         ret = virDomainPCIAddressReserveSlot(addrs, &dev->addr.pci, flags);
384     } else {
385         ret = virDomainPCIAddressReserveNextSlot(addrs, dev, flags);
386     }
387
388  cleanup:
389     VIR_FREE(addrStr);
390     return ret;
391 }
392
393
394 int
395 virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
396                                virDevicePCIAddressPtr addr)
397 {
398     addrs->buses[addr->bus].slots[addr->slot] &= ~(1 << addr->function);
399     return 0;
400 }
401
402 int
403 virDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs,
404                                virDevicePCIAddressPtr addr)
405 {
406     /* permit any kind of connection type in validation, since we
407      * already had it, and are giving it back.
408      */
409     virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPES_MASK;
410     int ret = -1;
411     char *addrStr = NULL;
412
413     if (!(addrStr = virDomainPCIAddressAsString(addr)))
414         goto cleanup;
415
416     if (!virDomainPCIAddressValidate(addrs, addr, addrStr, flags, false))
417         goto cleanup;
418
419     addrs->buses[addr->bus].slots[addr->slot] = 0;
420     ret = 0;
421  cleanup:
422     VIR_FREE(addrStr);
423     return ret;
424 }
425
426
427 virDomainPCIAddressSetPtr
428 virDomainPCIAddressSetAlloc(unsigned int nbuses)
429 {
430     virDomainPCIAddressSetPtr addrs;
431
432     if (VIR_ALLOC(addrs) < 0)
433         goto error;
434
435     if (VIR_ALLOC_N(addrs->buses, nbuses) < 0)
436         goto error;
437
438     addrs->nbuses = nbuses;
439     return addrs;
440
441  error:
442     virDomainPCIAddressSetFree(addrs);
443     return NULL;
444 }
445
446
447 void
448 virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs)
449 {
450     if (!addrs)
451         return;
452
453     VIR_FREE(addrs->buses);
454     VIR_FREE(addrs);
455 }
456
457
458 int
459 virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
460                                virDevicePCIAddressPtr next_addr,
461                                virDomainPCIConnectFlags flags)
462 {
463     /* default to starting the search for a free slot from
464      * 0000:00:00.0
465      */
466     virDevicePCIAddress a = { 0, 0, 0, 0, false };
467     char *addrStr = NULL;
468
469     /* except if this search is for the exact same type of device as
470      * last time, continue the search from the previous match
471      */
472     if (flags == addrs->lastFlags)
473         a = addrs->lastaddr;
474
475     if (addrs->nbuses == 0) {
476         virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available"));
477         goto error;
478     }
479
480     /* Start the search at the last used bus and slot */
481     for (a.slot++; a.bus < addrs->nbuses; a.bus++) {
482         if (!(addrStr = virDomainPCIAddressAsString(&a)))
483             goto error;
484         if (!virDomainPCIAddressFlagsCompatible(&a, addrStr,
485                                                 addrs->buses[a.bus].flags,
486                                                 flags, false, false)) {
487             VIR_FREE(addrStr);
488             VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
489                       a.domain, a.bus);
490             continue;
491         }
492         for (; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
493             if (!virDomainPCIAddressSlotInUse(addrs, &a))
494                 goto success;
495
496             VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
497                       a.domain, a.bus, a.slot);
498         }
499         a.slot = 1;
500         VIR_FREE(addrStr);
501     }
502
503     /* There were no free slots after the last used one */
504     if (addrs->dryRun) {
505         /* a is already set to the first new bus and slot 1 */
506         if (virDomainPCIAddressSetGrow(addrs, &a, flags) < 0)
507             goto error;
508         goto success;
509     } else if (flags == addrs->lastFlags) {
510         /* Check the buses from 0 up to the last used one */
511         for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) {
512             addrStr = NULL;
513             if (!(addrStr = virDomainPCIAddressAsString(&a)))
514                 goto error;
515             if (!virDomainPCIAddressFlagsCompatible(&a, addrStr,
516                                                     addrs->buses[a.bus].flags,
517                                                     flags, false, false)) {
518                 VIR_DEBUG("PCI bus %.4x:%.2x is not compatible with the device",
519                           a.domain, a.bus);
520                 continue;
521             }
522             for (a.slot = 1; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
523                 if (!virDomainPCIAddressSlotInUse(addrs, &a))
524                     goto success;
525
526                 VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
527                           a.domain, a.bus, a.slot);
528             }
529         }
530     }
531
532     virReportError(VIR_ERR_INTERNAL_ERROR,
533                    "%s", _("No more available PCI slots"));
534  error:
535     VIR_FREE(addrStr);
536     return -1;
537
538  success:
539     VIR_DEBUG("Found free PCI slot %.4x:%.2x:%.2x",
540               a.domain, a.bus, a.slot);
541     *next_addr = a;
542     VIR_FREE(addrStr);
543     return 0;
544 }
545
546 int
547 virDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
548                                    virDomainDeviceInfoPtr dev,
549                                    virDomainPCIConnectFlags flags)
550 {
551     virDevicePCIAddress addr;
552     if (virDomainPCIAddressGetNextSlot(addrs, &addr, flags) < 0)
553         return -1;
554
555     if (virDomainPCIAddressReserveSlot(addrs, &addr, flags) < 0)
556         return -1;
557
558     if (!addrs->dryRun) {
559         dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
560         dev->addr.pci = addr;
561     }
562
563     addrs->lastaddr = addr;
564     addrs->lastFlags = flags;
565     return 0;
566 }