mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-08-24 09:49:59 +03:00
qemu: switch PCI address alocation to use virDevicePCIAddress
Some functions were using virDomainDeviceInfo where virDevicePCIAddress would suffice. Some were only using integers for slots and functions, assuming the bus numbers are always 0. Switch from virDomainDeviceInfoPtr to virDevicePCIAddressPtr: qemuPCIAddressAsString qemuDomainPCIAddressCheckSlot qemuDomainPCIAddressReserveAddr qemuDomainPCIAddressReleaseAddr Switch from int slot to virDevicePCIAddressPtr: qemuDomainPCIAddressReserveSlot qemuDomainPCIAddressReleaseSlot qemuDomainPCIAddressGetNextSlot Deleted functions (they would take the same parameters as ReserveAddr/ReleaseAddr do now.) qemuDomainPCIAddressReserveFunction qemuDomainPCIAddressReleaseFunction
This commit is contained in:
@ -953,30 +953,30 @@ cleanup:
|
|||||||
#define QEMU_PCI_ADDRESS_LAST_FUNCTION 8
|
#define QEMU_PCI_ADDRESS_LAST_FUNCTION 8
|
||||||
struct _qemuDomainPCIAddressSet {
|
struct _qemuDomainPCIAddressSet {
|
||||||
virHashTablePtr used;
|
virHashTablePtr used;
|
||||||
int nextslot;
|
virDevicePCIAddress lastaddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev)
|
static char *qemuPCIAddressAsString(virDevicePCIAddressPtr addr)
|
||||||
{
|
{
|
||||||
char *addr;
|
char *str;
|
||||||
|
|
||||||
if (dev->addr.pci.domain != 0 ||
|
if (addr->domain != 0 ||
|
||||||
dev->addr.pci.bus != 0) {
|
addr->bus != 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Only PCI domain 0 and bus 0 are available"));
|
_("Only PCI domain 0 and bus 0 are available"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virAsprintf(&addr, "%d:%d:%d.%d",
|
if (virAsprintf(&str, "%d:%d:%d.%d",
|
||||||
dev->addr.pci.domain,
|
addr->domain,
|
||||||
dev->addr.pci.bus,
|
addr->bus,
|
||||||
dev->addr.pci.slot,
|
addr->slot,
|
||||||
dev->addr.pci.function) < 0) {
|
addr->function) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return addr;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -999,7 +999,7 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = qemuPCIAddressAsString(info);
|
addr = qemuPCIAddressAsString(&info->addr.pci);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -1024,12 +1024,11 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|||||||
if ((info->addr.pci.function == 0) &&
|
if ((info->addr.pci.function == 0) &&
|
||||||
(info->addr.pci.multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON)) {
|
(info->addr.pci.multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON)) {
|
||||||
/* a function 0 w/o multifunction=on must reserve the entire slot */
|
/* a function 0 w/o multifunction=on must reserve the entire slot */
|
||||||
int function;
|
virDevicePCIAddress tmp_addr = info->addr.pci;
|
||||||
virDomainDeviceInfo temp_info = *info;
|
unsigned int *func = &tmp_addr.function;
|
||||||
|
|
||||||
for (function = 1; function < QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) {
|
for (*func = 1; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
|
||||||
temp_info.addr.pci.function = function;
|
addr = qemuPCIAddressAsString(&tmp_addr);
|
||||||
addr = qemuPCIAddressAsString(&temp_info);
|
|
||||||
if (!addr)
|
if (!addr)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -1142,91 +1141,74 @@ error:
|
|||||||
* is used by the other device.
|
* is used by the other device.
|
||||||
*/
|
*/
|
||||||
static int qemuDomainPCIAddressCheckSlot(qemuDomainPCIAddressSetPtr addrs,
|
static int qemuDomainPCIAddressCheckSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev)
|
virDevicePCIAddressPtr addr)
|
||||||
{
|
{
|
||||||
char *addr;
|
char *str;
|
||||||
virDomainDeviceInfo temp_dev;
|
virDevicePCIAddress tmp_addr = *addr;
|
||||||
int function;
|
unsigned int *func = &(tmp_addr.function);
|
||||||
|
|
||||||
temp_dev = *dev;
|
for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
|
||||||
for (function = 0; function < QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) {
|
str = qemuPCIAddressAsString(&tmp_addr);
|
||||||
temp_dev.addr.pci.function = function;
|
if (!str)
|
||||||
addr = qemuPCIAddressAsString(&temp_dev);
|
|
||||||
if (!addr)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (virHashLookup(addrs->used, addr)) {
|
if (virHashLookup(addrs->used, str)) {
|
||||||
VIR_FREE(addr);
|
VIR_FREE(str);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(addr);
|
VIR_FREE(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev)
|
virDevicePCIAddressPtr addr)
|
||||||
{
|
{
|
||||||
char *addr;
|
char *str;
|
||||||
|
|
||||||
addr = qemuPCIAddressAsString(dev);
|
str = qemuPCIAddressAsString(addr);
|
||||||
if (!addr)
|
if (!str)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
VIR_DEBUG("Reserving PCI addr %s", addr);
|
VIR_DEBUG("Reserving PCI addr %s", str);
|
||||||
|
|
||||||
if (virHashLookup(addrs->used, addr)) {
|
if (virHashLookup(addrs->used, str)) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("unable to reserve PCI address %s"), addr);
|
_("unable to reserve PCI address %s"), str);
|
||||||
VIR_FREE(addr);
|
VIR_FREE(str);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virHashAddEntry(addrs->used, addr, addr)) {
|
if (virHashAddEntry(addrs->used, str, str)) {
|
||||||
VIR_FREE(addr);
|
VIR_FREE(str);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->addr.pci.slot > addrs->nextslot) {
|
addrs->lastaddr = *addr;
|
||||||
addrs->nextslot = dev->addr.pci.slot + 1;
|
addrs->lastaddr.function = 0;
|
||||||
if (QEMU_PCI_ADDRESS_LAST_SLOT < addrs->nextslot)
|
addrs->lastaddr.multi = 0;
|
||||||
addrs->nextslot = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemuDomainPCIAddressReserveFunction(qemuDomainPCIAddressSetPtr addrs,
|
|
||||||
int slot, int function)
|
|
||||||
{
|
|
||||||
virDomainDeviceInfo dev;
|
|
||||||
|
|
||||||
dev.addr.pci.domain = 0;
|
|
||||||
dev.addr.pci.bus = 0;
|
|
||||||
dev.addr.pci.slot = slot;
|
|
||||||
dev.addr.pci.function = function;
|
|
||||||
|
|
||||||
return qemuDomainPCIAddressReserveAddr(addrs, &dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||||
int slot)
|
virDevicePCIAddressPtr addr)
|
||||||
{
|
{
|
||||||
int function;
|
virDevicePCIAddress tmp_addr = *addr;
|
||||||
|
unsigned int *func = &tmp_addr.function;
|
||||||
|
unsigned int last;
|
||||||
|
|
||||||
for (function = 0; function < QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) {
|
for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
|
||||||
if (qemuDomainPCIAddressReserveFunction(addrs, slot, function) < 0)
|
if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
for (function--; function >= 0; function--) {
|
for (last = *func, *func = 0; *func < last; (*func)++)
|
||||||
qemuDomainPCIAddressReleaseFunction(addrs, slot, function);
|
qemuDomainPCIAddressReleaseAddr(addrs, &tmp_addr);
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1245,7 +1227,7 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemuDomainPCIAddressReserveSlot(addrs, dev->addr.pci.slot);
|
ret = qemuDomainPCIAddressReserveSlot(addrs, &dev->addr.pci);
|
||||||
} else {
|
} else {
|
||||||
ret = qemuDomainPCIAddressSetNextAddr(addrs, dev);
|
ret = qemuDomainPCIAddressSetNextAddr(addrs, dev);
|
||||||
}
|
}
|
||||||
@ -1254,59 +1236,43 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
|
|||||||
|
|
||||||
|
|
||||||
int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev)
|
virDevicePCIAddressPtr addr)
|
||||||
{
|
{
|
||||||
char *addr;
|
char *str;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
addr = qemuPCIAddressAsString(dev);
|
str = qemuPCIAddressAsString(addr);
|
||||||
if (!addr)
|
if (!str)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = virHashRemoveEntry(addrs->used, addr);
|
ret = virHashRemoveEntry(addrs->used, str);
|
||||||
|
|
||||||
VIR_FREE(addr);
|
VIR_FREE(str);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemuDomainPCIAddressReleaseFunction(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||||
int slot, int function)
|
virDevicePCIAddressPtr addr)
|
||||||
{
|
{
|
||||||
virDomainDeviceInfo dev;
|
char *str;
|
||||||
|
|
||||||
dev.addr.pci.domain = 0;
|
|
||||||
dev.addr.pci.bus = 0;
|
|
||||||
dev.addr.pci.slot = slot;
|
|
||||||
dev.addr.pci.function = function;
|
|
||||||
|
|
||||||
return qemuDomainPCIAddressReleaseAddr(addrs, &dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, int slot)
|
|
||||||
{
|
|
||||||
virDomainDeviceInfo dev;
|
|
||||||
char *addr;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int *function = &dev.addr.pci.function;
|
virDevicePCIAddress tmp_addr = *addr;
|
||||||
|
unsigned int *func = &tmp_addr.function;
|
||||||
|
|
||||||
dev.addr.pci.domain = 0;
|
for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
|
||||||
dev.addr.pci.bus = 0;
|
str = qemuPCIAddressAsString(&tmp_addr);
|
||||||
dev.addr.pci.slot = slot;
|
if (!str)
|
||||||
|
|
||||||
for (*function = 0; *function < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*function)++) {
|
|
||||||
addr = qemuPCIAddressAsString(&dev);
|
|
||||||
if (!addr)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!virHashLookup(addrs->used, addr)) {
|
if (!virHashLookup(addrs->used, str)) {
|
||||||
VIR_FREE(addr);
|
VIR_FREE(str);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_FREE(addr);
|
VIR_FREE(str);
|
||||||
|
|
||||||
if (qemuDomainPCIAddressReleaseFunction(addrs, slot, *function) < 0)
|
if (qemuDomainPCIAddressReleaseAddr(addrs, &tmp_addr) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1323,28 +1289,24 @@ void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs)
|
static int
|
||||||
|
qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||||
|
virDevicePCIAddressPtr next_addr)
|
||||||
{
|
{
|
||||||
|
virDevicePCIAddress tmp_addr = addrs->lastaddr;
|
||||||
int i;
|
int i;
|
||||||
int iteration;
|
char *addr;
|
||||||
|
|
||||||
for (i = addrs->nextslot, iteration = 0;
|
tmp_addr.slot++;
|
||||||
iteration <= QEMU_PCI_ADDRESS_LAST_SLOT; i++, iteration++) {
|
for (i = 0; i <= QEMU_PCI_ADDRESS_LAST_SLOT; i++, tmp_addr.slot++) {
|
||||||
virDomainDeviceInfo maybe;
|
if (QEMU_PCI_ADDRESS_LAST_SLOT < tmp_addr.slot) {
|
||||||
char *addr;
|
tmp_addr.slot = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (QEMU_PCI_ADDRESS_LAST_SLOT < i)
|
if (!(addr = qemuPCIAddressAsString(&tmp_addr)))
|
||||||
i = 0;
|
|
||||||
memset(&maybe, 0, sizeof(maybe));
|
|
||||||
maybe.addr.pci.domain = 0;
|
|
||||||
maybe.addr.pci.bus = 0;
|
|
||||||
maybe.addr.pci.slot = i;
|
|
||||||
maybe.addr.pci.function = 0;
|
|
||||||
|
|
||||||
if (!(addr = qemuPCIAddressAsString(&maybe)))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (qemuDomainPCIAddressCheckSlot(addrs, &maybe) < 0) {
|
if (qemuDomainPCIAddressCheckSlot(addrs, &tmp_addr) < 0) {
|
||||||
VIR_DEBUG("PCI addr %s already in use", addr);
|
VIR_DEBUG("PCI addr %s already in use", addr);
|
||||||
VIR_FREE(addr);
|
VIR_FREE(addr);
|
||||||
continue;
|
continue;
|
||||||
@ -1353,7 +1315,9 @@ static int qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs)
|
|||||||
VIR_DEBUG("Found free PCI addr %s", addr);
|
VIR_DEBUG("Found free PCI addr %s", addr);
|
||||||
VIR_FREE(addr);
|
VIR_FREE(addr);
|
||||||
|
|
||||||
return i;
|
addrs->lastaddr = tmp_addr;
|
||||||
|
*next_addr = tmp_addr;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -1364,24 +1328,17 @@ static int qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs)
|
|||||||
int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev)
|
virDomainDeviceInfoPtr dev)
|
||||||
{
|
{
|
||||||
int slot = qemuDomainPCIAddressGetNextSlot(addrs);
|
virDevicePCIAddress addr;
|
||||||
|
if (qemuDomainPCIAddressGetNextSlot(addrs, &addr) < 0)
|
||||||
if (slot < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (qemuDomainPCIAddressReserveSlot(addrs, slot) < 0)
|
if (qemuDomainPCIAddressReserveSlot(addrs, &addr) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||||
dev->addr.pci.bus = 0;
|
dev->addr.pci = addr;
|
||||||
dev->addr.pci.domain = 0;
|
|
||||||
dev->addr.pci.slot = slot;
|
|
||||||
dev->addr.pci.function = 0;
|
|
||||||
|
|
||||||
addrs->nextslot = slot + 1;
|
|
||||||
if (QEMU_PCI_ADDRESS_LAST_SLOT < addrs->nextslot)
|
|
||||||
addrs->nextslot = 0;
|
|
||||||
|
|
||||||
|
addrs->lastaddr = addr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1433,11 +1390,15 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|||||||
size_t i, j;
|
size_t i, j;
|
||||||
bool reservedIDE = false;
|
bool reservedIDE = false;
|
||||||
bool reservedUSB = false;
|
bool reservedUSB = false;
|
||||||
int function;
|
|
||||||
bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
|
bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
|
||||||
|
virDevicePCIAddress tmp_addr;
|
||||||
|
virDevicePCIAddressPtr addrptr;
|
||||||
|
unsigned int *func = &tmp_addr.function;
|
||||||
|
|
||||||
/* Host bridge */
|
|
||||||
if (qemuDomainPCIAddressReserveSlot(addrs, 0) < 0)
|
/* Reserve slot 0 for the host bridge */
|
||||||
|
memset(&tmp_addr, 0, sizeof(tmp_addr));
|
||||||
|
if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Verify that first IDE and USB controllers (if any) is on the PIIX3, fn 1 */
|
/* Verify that first IDE and USB controllers (if any) is on the PIIX3, fn 1 */
|
||||||
@ -1491,13 +1452,15 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|||||||
/* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller)
|
/* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller)
|
||||||
* hardcoded slot=1, multifunction device
|
* hardcoded slot=1, multifunction device
|
||||||
*/
|
*/
|
||||||
for (function = 0; function < QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) {
|
memset(&tmp_addr, 0, sizeof(tmp_addr));
|
||||||
if ((function == 1 && reservedIDE) ||
|
tmp_addr.slot = 1;
|
||||||
(function == 2 && reservedUSB))
|
for (*func = 0; *func < QEMU_PCI_ADDRESS_LAST_FUNCTION; (*func)++) {
|
||||||
|
if ((*func == 1 && reservedIDE) ||
|
||||||
|
(*func == 2 && reservedUSB))
|
||||||
/* we have reserved this pci address */
|
/* we have reserved this pci address */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (qemuDomainPCIAddressReserveFunction(addrs, 1, function) < 0)
|
if (qemuDomainPCIAddressReserveAddr(addrs, &tmp_addr) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1509,8 +1472,9 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|||||||
primaryVideo->info.addr.pci.bus = 0;
|
primaryVideo->info.addr.pci.bus = 0;
|
||||||
primaryVideo->info.addr.pci.slot = 2;
|
primaryVideo->info.addr.pci.slot = 2;
|
||||||
primaryVideo->info.addr.pci.function = 0;
|
primaryVideo->info.addr.pci.function = 0;
|
||||||
|
addrptr = &primaryVideo->info.addr.pci;
|
||||||
|
|
||||||
if (qemuDomainPCIAddressCheckSlot(addrs, &primaryVideo->info) < 0) {
|
if (qemuDomainPCIAddressCheckSlot(addrs, addrptr) < 0) {
|
||||||
if (qemuDeviceVideoUsable) {
|
if (qemuDeviceVideoUsable) {
|
||||||
virResetLastError();
|
virResetLastError();
|
||||||
if (qemuDomainPCIAddressSetNextAddr(addrs, &primaryVideo->info) < 0)
|
if (qemuDomainPCIAddressSetNextAddr(addrs, &primaryVideo->info) < 0)
|
||||||
@ -1521,7 +1485,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|||||||
"QEMU needs it for primary video"));
|
"QEMU needs it for primary video"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0) {
|
} else if (qemuDomainPCIAddressReserveSlot(addrs, addrptr) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else if (!qemuDeviceVideoUsable) {
|
} else if (!qemuDeviceVideoUsable) {
|
||||||
@ -1537,16 +1501,15 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|||||||
* has already reserved the address, so we must skip */
|
* has already reserved the address, so we must skip */
|
||||||
}
|
}
|
||||||
} else if (!qemuDeviceVideoUsable) {
|
} else if (!qemuDeviceVideoUsable) {
|
||||||
virDomainDeviceInfo dev;
|
memset(&tmp_addr, 0, sizeof(tmp_addr));
|
||||||
memset(&dev, 0, sizeof(dev));
|
tmp_addr.slot = 2;
|
||||||
dev.addr.pci.slot = 2;
|
|
||||||
|
|
||||||
if (qemuDomainPCIAddressCheckSlot(addrs, &dev) < 0) {
|
if (qemuDomainPCIAddressCheckSlot(addrs, &tmp_addr) < 0) {
|
||||||
VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a video"
|
VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a video"
|
||||||
" device will not be possible without manual"
|
" device will not be possible without manual"
|
||||||
" intervention");
|
" intervention");
|
||||||
virResetLastError();
|
virResetLastError();
|
||||||
} else if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0) {
|
} else if (qemuDomainPCIAddressReserveSlot(addrs, &tmp_addr) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1609,6 +1572,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|||||||
/* USB2 needs special handling to put all companions in the same slot */
|
/* USB2 needs special handling to put all companions in the same slot */
|
||||||
if (IS_USB2_CONTROLLER(def->controllers[i])) {
|
if (IS_USB2_CONTROLLER(def->controllers[i])) {
|
||||||
virDevicePCIAddress addr = { 0, 0, 0, 0, false };
|
virDevicePCIAddress addr = { 0, 0, 0, 0, false };
|
||||||
|
memset(&tmp_addr, 0, sizeof(tmp_addr));
|
||||||
for (j = 0 ; j < i ; j++) {
|
for (j = 0 ; j < i ; j++) {
|
||||||
if (IS_USB2_CONTROLLER(def->controllers[j]) &&
|
if (IS_USB2_CONTROLLER(def->controllers[j]) &&
|
||||||
def->controllers[j]->idx == def->controllers[i]->idx) {
|
def->controllers[j]->idx == def->controllers[i]->idx) {
|
||||||
@ -1636,19 +1600,14 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|||||||
if (addr.slot == 0) {
|
if (addr.slot == 0) {
|
||||||
/* This is the first part of the controller, so need
|
/* This is the first part of the controller, so need
|
||||||
* to find a free slot & then reserve a function */
|
* to find a free slot & then reserve a function */
|
||||||
int slot = qemuDomainPCIAddressGetNextSlot(addrs);
|
if (qemuDomainPCIAddressGetNextSlot(addrs, &tmp_addr) < 0)
|
||||||
if (slot < 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
addr.slot = slot;
|
addr.bus = tmp_addr.bus;
|
||||||
addrs->nextslot = addr.slot + 1;
|
addr.slot = tmp_addr.slot;
|
||||||
if (QEMU_PCI_ADDRESS_LAST_SLOT < addrs->nextslot)
|
|
||||||
addrs->nextslot = 0;
|
|
||||||
}
|
}
|
||||||
/* Finally we can reserve the slot+function */
|
/* Finally we can reserve the slot+function */
|
||||||
if (qemuDomainPCIAddressReserveFunction(addrs,
|
if (qemuDomainPCIAddressReserveAddr(addrs, &addr) < 0)
|
||||||
addr.slot,
|
|
||||||
addr.function) < 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||||
|
@ -194,21 +194,18 @@ int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
|
|||||||
virQEMUCapsPtr qemuCaps,
|
virQEMUCapsPtr qemuCaps,
|
||||||
virDomainObjPtr obj);
|
virDomainObjPtr obj);
|
||||||
qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def);
|
qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def);
|
||||||
int qemuDomainPCIAddressReserveFunction(qemuDomainPCIAddressSetPtr addrs,
|
|
||||||
int slot, int function);
|
|
||||||
int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||||
int slot);
|
virDevicePCIAddressPtr addr);
|
||||||
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev);
|
virDevicePCIAddressPtr addr);
|
||||||
int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev);
|
virDomainDeviceInfoPtr dev);
|
||||||
int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev);
|
virDomainDeviceInfoPtr dev);
|
||||||
int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr dev);
|
virDevicePCIAddressPtr addr);
|
||||||
int qemuDomainPCIAddressReleaseFunction(qemuDomainPCIAddressSetPtr addrs,
|
int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||||
int slot, int function);
|
virDevicePCIAddressPtr addr);
|
||||||
int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, int slot);
|
|
||||||
|
|
||||||
void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
|
void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
|
||||||
int qemuAssignDevicePCISlots(virDomainDefPtr def,
|
int qemuAssignDevicePCISlots(virDomainDefPtr def,
|
||||||
|
@ -325,7 +325,7 @@ error:
|
|||||||
(disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
(disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
||||||
releaseaddr &&
|
releaseaddr &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
disk->info.addr.pci.slot) < 0)
|
&disk->info.addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on %s", disk->src);
|
VIR_WARN("Unable to release PCI address on %s", disk->src);
|
||||||
|
|
||||||
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
if (virSecurityManagerRestoreImageLabel(driver->securityManager,
|
||||||
@ -402,7 +402,7 @@ cleanup:
|
|||||||
(controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
(controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
||||||
releaseaddr &&
|
releaseaddr &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
controller->info.addr.pci.slot) < 0)
|
&controller->info.addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on controller");
|
VIR_WARN("Unable to release PCI address on controller");
|
||||||
|
|
||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
@ -899,7 +899,7 @@ cleanup:
|
|||||||
(net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
(net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
||||||
releaseaddr &&
|
releaseaddr &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
net->info.addr.pci.slot) < 0)
|
&net->info.addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on NIC");
|
VIR_WARN("Unable to release PCI address on NIC");
|
||||||
|
|
||||||
if (iface_connected) {
|
if (iface_connected) {
|
||||||
@ -1042,7 +1042,7 @@ error:
|
|||||||
(hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
(hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
|
||||||
releaseaddr &&
|
releaseaddr &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
hostdev->info->addr.pci.slot) < 0)
|
&hostdev->info->addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on host device");
|
VIR_WARN("Unable to release PCI address on host device");
|
||||||
|
|
||||||
qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
|
qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
|
||||||
@ -2084,7 +2084,7 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
detach->info.addr.pci.slot) < 0)
|
&detach->info.addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src);
|
VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src);
|
||||||
|
|
||||||
virDomainDiskRemove(vm->def, i);
|
virDomainDiskRemove(vm->def, i);
|
||||||
@ -2321,7 +2321,7 @@ int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
detach->info.addr.pci.slot) < 0)
|
&detach->info.addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on controller");
|
VIR_WARN("Unable to release PCI address on controller");
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -2397,7 +2397,7 @@ qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
detach->info->addr.pci.slot) < 0)
|
&detach->info->addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on host device");
|
VIR_WARN("Unable to release PCI address on host device");
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@ -2649,7 +2649,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
|
||||||
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
|
||||||
detach->info.addr.pci.slot) < 0)
|
&detach->info.addr.pci) < 0)
|
||||||
VIR_WARN("Unable to release PCI address on NIC");
|
VIR_WARN("Unable to release PCI address on NIC");
|
||||||
|
|
||||||
virDomainConfNWFilterTeardown(detach);
|
virDomainConfNWFilterTeardown(detach);
|
||||||
|
Reference in New Issue
Block a user