mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 09:43:56 -06:00
Revert "pcie_sriov: Reuse SR-IOV VF device instances"
This reverts commit 139610ae67
.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
9bab08da4e
commit
b1282f1e35
5 changed files with 62 additions and 56 deletions
|
@ -2895,7 +2895,7 @@ void pci_set_enabled(PCIDevice *d, bool state)
|
|||
memory_region_set_enabled(&d->bus_master_enable_region,
|
||||
(pci_get_word(d->config + PCI_COMMAND)
|
||||
& PCI_COMMAND_MASTER) && d->enabled);
|
||||
if (d->qdev.realized) {
|
||||
if (!d->enabled) {
|
||||
pci_device_reset(d);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,9 @@
|
|||
#include "qapi/error.h"
|
||||
#include "trace.h"
|
||||
|
||||
static void unparent_vfs(PCIDevice *dev, uint16_t total_vfs)
|
||||
{
|
||||
for (uint16_t i = 0; i < total_vfs; i++) {
|
||||
PCIDevice *vf = dev->exp.sriov_pf.vf[i];
|
||||
object_unparent(OBJECT(vf));
|
||||
object_unref(OBJECT(vf));
|
||||
}
|
||||
g_free(dev->exp.sriov_pf.vf);
|
||||
dev->exp.sriov_pf.vf = NULL;
|
||||
}
|
||||
static PCIDevice *register_vf(PCIDevice *pf, int devfn,
|
||||
const char *name, uint16_t vf_num);
|
||||
static void unregister_vfs(PCIDevice *dev);
|
||||
|
||||
bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
|
||||
const char *vfname, uint16_t vf_dev_id,
|
||||
|
@ -37,8 +30,6 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
|
|||
uint16_t vf_offset, uint16_t vf_stride,
|
||||
Error **errp)
|
||||
{
|
||||
BusState *bus = qdev_get_parent_bus(&dev->qdev);
|
||||
int32_t devfn = dev->devfn + vf_offset;
|
||||
uint8_t *cfg = dev->config + offset;
|
||||
uint8_t *wmask;
|
||||
|
||||
|
@ -58,6 +49,7 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
|
|||
offset, PCI_EXT_CAP_SRIOV_SIZEOF);
|
||||
dev->exp.sriov_cap = offset;
|
||||
dev->exp.sriov_pf.num_vfs = 0;
|
||||
dev->exp.sriov_pf.vfname = g_strdup(vfname);
|
||||
dev->exp.sriov_pf.vf = NULL;
|
||||
|
||||
pci_set_word(cfg + PCI_SRIOV_VF_OFFSET, vf_offset);
|
||||
|
@ -91,34 +83,14 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
|
|||
|
||||
qdev_prop_set_bit(&dev->qdev, "multifunction", true);
|
||||
|
||||
dev->exp.sriov_pf.vf = g_new(PCIDevice *, total_vfs);
|
||||
|
||||
for (uint16_t i = 0; i < total_vfs; i++) {
|
||||
PCIDevice *vf = pci_new(devfn, vfname);
|
||||
vf->exp.sriov_vf.pf = dev;
|
||||
vf->exp.sriov_vf.vf_number = i;
|
||||
|
||||
if (!qdev_realize(&vf->qdev, bus, errp)) {
|
||||
unparent_vfs(dev, i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* set vid/did according to sr/iov spec - they are not used */
|
||||
pci_config_set_vendor_id(vf->config, 0xffff);
|
||||
pci_config_set_device_id(vf->config, 0xffff);
|
||||
|
||||
dev->exp.sriov_pf.vf[i] = vf;
|
||||
devfn += vf_stride;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void pcie_sriov_pf_exit(PCIDevice *dev)
|
||||
{
|
||||
uint8_t *cfg = dev->config + dev->exp.sriov_cap;
|
||||
|
||||
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
|
||||
unregister_vfs(dev);
|
||||
g_free((char *)dev->exp.sriov_pf.vfname);
|
||||
dev->exp.sriov_pf.vfname = NULL;
|
||||
}
|
||||
|
||||
void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
|
||||
|
@ -184,11 +156,38 @@ void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
|
|||
}
|
||||
}
|
||||
|
||||
static PCIDevice *register_vf(PCIDevice *pf, int devfn, const char *name,
|
||||
uint16_t vf_num)
|
||||
{
|
||||
PCIDevice *dev = pci_new(devfn, name);
|
||||
dev->exp.sriov_vf.pf = pf;
|
||||
dev->exp.sriov_vf.vf_number = vf_num;
|
||||
PCIBus *bus = pci_get_bus(pf);
|
||||
Error *local_err = NULL;
|
||||
|
||||
qdev_realize(&dev->qdev, &bus->qbus, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set vid/did according to sr/iov spec - they are not used */
|
||||
pci_config_set_vendor_id(dev->config, 0xffff);
|
||||
pci_config_set_device_id(dev->config, 0xffff);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void register_vfs(PCIDevice *dev)
|
||||
{
|
||||
uint16_t num_vfs;
|
||||
uint16_t i;
|
||||
uint16_t sriov_cap = dev->exp.sriov_cap;
|
||||
uint16_t vf_offset =
|
||||
pci_get_word(dev->config + sriov_cap + PCI_SRIOV_VF_OFFSET);
|
||||
uint16_t vf_stride =
|
||||
pci_get_word(dev->config + sriov_cap + PCI_SRIOV_VF_STRIDE);
|
||||
int32_t devfn = dev->devfn + vf_offset;
|
||||
|
||||
assert(sriov_cap > 0);
|
||||
num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
|
||||
|
@ -196,10 +195,18 @@ static void register_vfs(PCIDevice *dev)
|
|||
return;
|
||||
}
|
||||
|
||||
dev->exp.sriov_pf.vf = g_new(PCIDevice *, num_vfs);
|
||||
|
||||
trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn),
|
||||
PCI_FUNC(dev->devfn), num_vfs);
|
||||
for (i = 0; i < num_vfs; i++) {
|
||||
pci_set_enabled(dev->exp.sriov_pf.vf[i], true);
|
||||
dev->exp.sriov_pf.vf[i] = register_vf(dev, devfn,
|
||||
dev->exp.sriov_pf.vfname, i);
|
||||
if (!dev->exp.sriov_pf.vf[i]) {
|
||||
num_vfs = i;
|
||||
break;
|
||||
}
|
||||
devfn += vf_stride;
|
||||
}
|
||||
dev->exp.sriov_pf.num_vfs = num_vfs;
|
||||
}
|
||||
|
@ -212,8 +219,12 @@ static void unregister_vfs(PCIDevice *dev)
|
|||
trace_sriov_unregister_vfs(dev->name, PCI_SLOT(dev->devfn),
|
||||
PCI_FUNC(dev->devfn), num_vfs);
|
||||
for (i = 0; i < num_vfs; i++) {
|
||||
pci_set_enabled(dev->exp.sriov_pf.vf[i], false);
|
||||
PCIDevice *vf = dev->exp.sriov_pf.vf[i];
|
||||
object_unparent(OBJECT(vf));
|
||||
object_unref(OBJECT(vf));
|
||||
}
|
||||
g_free(dev->exp.sriov_pf.vf);
|
||||
dev->exp.sriov_pf.vf = NULL;
|
||||
dev->exp.sriov_pf.num_vfs = 0;
|
||||
}
|
||||
|
||||
|
@ -235,10 +246,14 @@ void pcie_sriov_config_write(PCIDevice *dev, uint32_t address,
|
|||
PCI_FUNC(dev->devfn), off, val, len);
|
||||
|
||||
if (range_covers_byte(off, len, PCI_SRIOV_CTRL)) {
|
||||
if (val & PCI_SRIOV_CTRL_VFE) {
|
||||
register_vfs(dev);
|
||||
if (dev->exp.sriov_pf.num_vfs) {
|
||||
if (!(val & PCI_SRIOV_CTRL_VFE)) {
|
||||
unregister_vfs(dev);
|
||||
}
|
||||
} else {
|
||||
unregister_vfs(dev);
|
||||
if (val & PCI_SRIOV_CTRL_VFE) {
|
||||
register_vfs(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue