2014-04-12 19:37:53 +00:00
|
|
|
/*
|
|
|
|
* bhyve_device.c: bhyve device management
|
|
|
|
*
|
|
|
|
* Copyright (C) 2014 Roman Bogorodskiy
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Author: Roman Bogorodskiy
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "bhyve_device.h"
|
|
|
|
#include "domain_addr.h"
|
|
|
|
#include "viralloc.h"
|
|
|
|
#include "virlog.h"
|
|
|
|
#include "virstring.h"
|
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_BHYVE
|
|
|
|
|
|
|
|
VIR_LOG_INIT("bhyve.bhyve_device");
|
|
|
|
|
|
|
|
static int
|
|
|
|
bhyveCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
|
|
|
|
virDomainDeviceInfoPtr info,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
bhyve: fix SATA address allocation
As bhyve for a long time didn't have a notion of the explicit SATA
controller and created a controller for each drive, the bhyve driver
in libvirt acted in a similar way and didn't care about the SATA
controllers and assigned PCI addresses to drives directly, as
the generated command will look like this anyway:
2:0,ahci-hd,somedisk.img
This no longer makes sense because:
1. After commit c07d1c1c4f it's not possible to assign
PCI addresses to disks
2. Bhyve now supports multiple disk drives for a controller,
so it's going away from 1:1 controller:disk mapping, so
the controller object starts to make more sense now
So, this patch does the following:
- Assign PCI address to SATA controllers (previously we didn't do this)
- Assign disk addresses instead of PCI addresses for disks. Now, when
building a bhyve command, we take PCI address not from the disk
itself but from its controller
- Assign addresses at XML parsing time using the
assignAddressesCallback. This is done mainly for being able to
verify address allocation via xml2xml tests
- Adjust existing bhyvexml2{xml,argv} tests to chase the new
address allocation
This patch is largely based on work of Fabian Freyer.
2017-01-05 12:51:25 +00:00
|
|
|
if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
|
|
|
|
return 0;
|
|
|
|
|
2014-04-12 19:37:53 +00:00
|
|
|
virDomainPCIAddressSetPtr addrs = opaque;
|
2016-04-03 18:16:51 +00:00
|
|
|
virPCIDeviceAddressPtr addr = &info->addr.pci;
|
2014-04-12 19:37:53 +00:00
|
|
|
|
|
|
|
if (addr->domain == 0 && addr->bus == 0) {
|
|
|
|
if (addr->slot == 0) {
|
|
|
|
return 0;
|
|
|
|
} else if (addr->slot == 1) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("PCI bus 0 slot 1 is reserved for the implicit "
|
|
|
|
"LPC PCI-ISA bridge"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-23 16:14:16 +00:00
|
|
|
if (virDomainPCIAddressReserveAddr(addrs, addr,
|
2017-06-15 08:38:33 +00:00
|
|
|
VIR_PCI_CONNECT_TYPE_PCI_DEVICE, 0) < 0) {
|
2014-04-12 19:37:53 +00:00
|
|
|
goto cleanup;
|
2016-10-23 16:14:16 +00:00
|
|
|
}
|
2014-04-12 19:37:53 +00:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
virDomainPCIAddressSetPtr
|
2014-11-12 21:11:33 +00:00
|
|
|
bhyveDomainPCIAddressSetCreate(virDomainDefPtr def, unsigned int nbuses)
|
2014-04-12 19:37:53 +00:00
|
|
|
{
|
|
|
|
virDomainPCIAddressSetPtr addrs;
|
|
|
|
|
2018-11-08 11:00:24 +00:00
|
|
|
if ((addrs = virDomainPCIAddressSetAlloc(nbuses,
|
|
|
|
VIR_PCI_ADDRESS_EXTENSION_NONE)) == NULL)
|
2014-04-12 19:37:53 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (virDomainPCIAddressBusSetModel(&addrs->buses[0],
|
|
|
|
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (virDomainDeviceInfoIterate(def, bhyveCollectPCIAddress, addrs) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return addrs;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virDomainPCIAddressSetFree(addrs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
bhyveAssignDevicePCISlots(virDomainDefPtr def,
|
|
|
|
virDomainPCIAddressSetPtr addrs)
|
|
|
|
{
|
|
|
|
size_t i;
|
2016-04-03 18:16:51 +00:00
|
|
|
virPCIDeviceAddress lpc_addr;
|
2014-04-12 19:37:53 +00:00
|
|
|
|
|
|
|
/* explicitly reserve slot 1 for LPC-ISA bridge */
|
|
|
|
memset(&lpc_addr, 0, sizeof(lpc_addr));
|
|
|
|
lpc_addr.slot = 0x1;
|
|
|
|
|
2016-10-23 16:14:16 +00:00
|
|
|
if (virDomainPCIAddressReserveAddr(addrs, &lpc_addr,
|
2017-06-15 08:38:33 +00:00
|
|
|
VIR_PCI_CONNECT_TYPE_PCI_DEVICE, 0) < 0) {
|
2014-04-12 19:37:53 +00:00
|
|
|
goto error;
|
2016-10-23 16:14:16 +00:00
|
|
|
}
|
2014-04-12 19:37:53 +00:00
|
|
|
|
|
|
|
for (i = 0; i < def->ncontrollers; i++) {
|
bhyve: fix SATA address allocation
As bhyve for a long time didn't have a notion of the explicit SATA
controller and created a controller for each drive, the bhyve driver
in libvirt acted in a similar way and didn't care about the SATA
controllers and assigned PCI addresses to drives directly, as
the generated command will look like this anyway:
2:0,ahci-hd,somedisk.img
This no longer makes sense because:
1. After commit c07d1c1c4f it's not possible to assign
PCI addresses to disks
2. Bhyve now supports multiple disk drives for a controller,
so it's going away from 1:1 controller:disk mapping, so
the controller object starts to make more sense now
So, this patch does the following:
- Assign PCI address to SATA controllers (previously we didn't do this)
- Assign disk addresses instead of PCI addresses for disks. Now, when
building a bhyve command, we take PCI address not from the disk
itself but from its controller
- Assign addresses at XML parsing time using the
assignAddressesCallback. This is done mainly for being able to
verify address allocation via xml2xml tests
- Adjust existing bhyvexml2{xml,argv} tests to chase the new
address allocation
This patch is largely based on work of Fabian Freyer.
2017-01-05 12:51:25 +00:00
|
|
|
if ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) ||
|
2017-03-20 13:58:51 +00:00
|
|
|
(def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) ||
|
|
|
|
((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) &&
|
|
|
|
(def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI))) {
|
2016-05-17 18:06:36 +00:00
|
|
|
if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
|
2018-08-17 13:12:42 +00:00
|
|
|
!virDeviceInfoPCIAddressIsWanted(&def->controllers[i]->info))
|
2014-04-12 19:37:53 +00:00
|
|
|
continue;
|
|
|
|
|
2016-10-22 17:28:07 +00:00
|
|
|
if (virDomainPCIAddressReserveNextAddr(addrs,
|
2014-04-12 19:37:53 +00:00
|
|
|
&def->controllers[i]->info,
|
2016-10-22 17:28:07 +00:00
|
|
|
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
|
|
|
|
-1) < 0)
|
2014-04-12 19:37:53 +00:00
|
|
|
goto error;
|
|
|
|
}
|
bhyve: fix SATA address allocation
As bhyve for a long time didn't have a notion of the explicit SATA
controller and created a controller for each drive, the bhyve driver
in libvirt acted in a similar way and didn't care about the SATA
controllers and assigned PCI addresses to drives directly, as
the generated command will look like this anyway:
2:0,ahci-hd,somedisk.img
This no longer makes sense because:
1. After commit c07d1c1c4f it's not possible to assign
PCI addresses to disks
2. Bhyve now supports multiple disk drives for a controller,
so it's going away from 1:1 controller:disk mapping, so
the controller object starts to make more sense now
So, this patch does the following:
- Assign PCI address to SATA controllers (previously we didn't do this)
- Assign disk addresses instead of PCI addresses for disks. Now, when
building a bhyve command, we take PCI address not from the disk
itself but from its controller
- Assign addresses at XML parsing time using the
assignAddressesCallback. This is done mainly for being able to
verify address allocation via xml2xml tests
- Adjust existing bhyvexml2{xml,argv} tests to chase the new
address allocation
This patch is largely based on work of Fabian Freyer.
2017-01-05 12:51:25 +00:00
|
|
|
}
|
2014-04-12 19:37:53 +00:00
|
|
|
|
bhyve: fix SATA address allocation
As bhyve for a long time didn't have a notion of the explicit SATA
controller and created a controller for each drive, the bhyve driver
in libvirt acted in a similar way and didn't care about the SATA
controllers and assigned PCI addresses to drives directly, as
the generated command will look like this anyway:
2:0,ahci-hd,somedisk.img
This no longer makes sense because:
1. After commit c07d1c1c4f it's not possible to assign
PCI addresses to disks
2. Bhyve now supports multiple disk drives for a controller,
so it's going away from 1:1 controller:disk mapping, so
the controller object starts to make more sense now
So, this patch does the following:
- Assign PCI address to SATA controllers (previously we didn't do this)
- Assign disk addresses instead of PCI addresses for disks. Now, when
building a bhyve command, we take PCI address not from the disk
itself but from its controller
- Assign addresses at XML parsing time using the
assignAddressesCallback. This is done mainly for being able to
verify address allocation via xml2xml tests
- Adjust existing bhyvexml2{xml,argv} tests to chase the new
address allocation
This patch is largely based on work of Fabian Freyer.
2017-01-05 12:51:25 +00:00
|
|
|
for (i = 0; i < def->nnets; i++) {
|
2018-08-17 13:12:42 +00:00
|
|
|
if (!virDeviceInfoPCIAddressIsWanted(&def->nets[i]->info))
|
bhyve: fix SATA address allocation
As bhyve for a long time didn't have a notion of the explicit SATA
controller and created a controller for each drive, the bhyve driver
in libvirt acted in a similar way and didn't care about the SATA
controllers and assigned PCI addresses to drives directly, as
the generated command will look like this anyway:
2:0,ahci-hd,somedisk.img
This no longer makes sense because:
1. After commit c07d1c1c4f it's not possible to assign
PCI addresses to disks
2. Bhyve now supports multiple disk drives for a controller,
so it's going away from 1:1 controller:disk mapping, so
the controller object starts to make more sense now
So, this patch does the following:
- Assign PCI address to SATA controllers (previously we didn't do this)
- Assign disk addresses instead of PCI addresses for disks. Now, when
building a bhyve command, we take PCI address not from the disk
itself but from its controller
- Assign addresses at XML parsing time using the
assignAddressesCallback. This is done mainly for being able to
verify address allocation via xml2xml tests
- Adjust existing bhyvexml2{xml,argv} tests to chase the new
address allocation
This patch is largely based on work of Fabian Freyer.
2017-01-05 12:51:25 +00:00
|
|
|
continue;
|
|
|
|
if (virDomainPCIAddressReserveNextAddr(addrs,
|
|
|
|
&def->nets[i]->info,
|
|
|
|
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
|
2017-02-01 16:19:31 +00:00
|
|
|
-1) < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
|
|
|
/* We only handle virtio disk addresses as SATA disks are
|
|
|
|
* attached to a controller and don't have their own PCI
|
|
|
|
* addresses */
|
|
|
|
if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
|
|
|
|
!virPCIDeviceAddressIsEmpty(&def->disks[i]->info.addr.pci))
|
|
|
|
continue;
|
|
|
|
if (virDomainPCIAddressReserveNextAddr(addrs, &def->disks[i]->info,
|
|
|
|
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
|
bhyve: fix SATA address allocation
As bhyve for a long time didn't have a notion of the explicit SATA
controller and created a controller for each drive, the bhyve driver
in libvirt acted in a similar way and didn't care about the SATA
controllers and assigned PCI addresses to drives directly, as
the generated command will look like this anyway:
2:0,ahci-hd,somedisk.img
This no longer makes sense because:
1. After commit c07d1c1c4f it's not possible to assign
PCI addresses to disks
2. Bhyve now supports multiple disk drives for a controller,
so it's going away from 1:1 controller:disk mapping, so
the controller object starts to make more sense now
So, this patch does the following:
- Assign PCI address to SATA controllers (previously we didn't do this)
- Assign disk addresses instead of PCI addresses for disks. Now, when
building a bhyve command, we take PCI address not from the disk
itself but from its controller
- Assign addresses at XML parsing time using the
assignAddressesCallback. This is done mainly for being able to
verify address allocation via xml2xml tests
- Adjust existing bhyvexml2{xml,argv} tests to chase the new
address allocation
This patch is largely based on work of Fabian Freyer.
2017-01-05 12:51:25 +00:00
|
|
|
-1) < 0)
|
|
|
|
goto error;
|
2014-04-12 19:37:53 +00:00
|
|
|
}
|
|
|
|
|
2016-07-16 21:03:33 +00:00
|
|
|
for (i = 0; i < def->nvideos; i++) {
|
2018-08-17 13:12:42 +00:00
|
|
|
if (!virDeviceInfoPCIAddressIsWanted(&def->videos[i]->info))
|
2016-07-16 21:03:33 +00:00
|
|
|
continue;
|
|
|
|
if (virDomainPCIAddressReserveNextAddr(addrs,
|
|
|
|
&def->videos[i]->info,
|
|
|
|
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
|
|
|
|
-1) < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-04-12 19:37:53 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int bhyveDomainAssignPCIAddresses(virDomainDefPtr def,
|
|
|
|
virDomainObjPtr obj)
|
|
|
|
{
|
|
|
|
virDomainPCIAddressSetPtr addrs = NULL;
|
|
|
|
bhyveDomainObjPrivatePtr priv = NULL;
|
|
|
|
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!(addrs = bhyveDomainPCIAddressSetCreate(def, 1)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (bhyveAssignDevicePCISlots(def, addrs) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (obj && obj->privateData) {
|
|
|
|
priv = obj->privateData;
|
|
|
|
if (addrs) {
|
|
|
|
virDomainPCIAddressSetFree(priv->pciaddrs);
|
|
|
|
priv->persistentAddrs = 1;
|
|
|
|
priv->pciaddrs = addrs;
|
|
|
|
} else {
|
|
|
|
priv->persistentAddrs = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int bhyveDomainAssignAddresses(virDomainDefPtr def, virDomainObjPtr obj)
|
|
|
|
{
|
|
|
|
return bhyveDomainAssignPCIAddresses(def, obj);
|
|
|
|
}
|