On Wed, 23 Oct 2019 10:27:02 +0200 Jens Freimann <jfreim...@redhat.com> wrote:
> This patch adds a net_failover_pair_id property to PCIDev which is > used to link the primary device in a failover pair (the PCI dev) to > a standby (a virtio-net-pci) device. > > It only supports ethernet devices. Also currently it only supports > PCIe devices. QEMU will exit with an error message otherwise. > > Signed-off-by: Jens Freimann <jfreim...@redhat.com> > --- > hw/pci/pci.c | 17 +++++++++++++++++ > include/hw/pci/pci.h | 3 +++ > 2 files changed, 20 insertions(+) > > diff --git a/hw/pci/pci.c b/hw/pci/pci.c > index aa05c2b9b2..fa9b5219f8 100644 > --- a/hw/pci/pci.c > +++ b/hw/pci/pci.c > @@ -75,6 +75,8 @@ static Property pci_props[] = { > QEMU_PCIE_LNKSTA_DLLLA_BITNR, true), > DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present, > QEMU_PCIE_EXTCAP_INIT_BITNR, true), > + DEFINE_PROP_STRING("net_failover_pair_id", PCIDevice, > + net_failover_pair_id), Nit, white space appears broken here. > DEFINE_PROP_END_OF_LIST() > }; > > @@ -2077,6 +2079,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error > **errp) > ObjectClass *klass = OBJECT_CLASS(pc); > Error *local_err = NULL; > bool is_default_rom; > + uint16_t class_id; > > /* initialize cap_present for pci_is_express() and pci_config_size(), > * Note that hybrid PCIs are not set automatically and need to manage > @@ -2101,6 +2104,20 @@ static void pci_qdev_realize(DeviceState *qdev, Error > **errp) > } > } > > + if (pci_dev->net_failover_pair_id) { > + if (!pci_is_express(pci_dev)) { > + error_setg(errp, "failover device is not a PCIExpress device"); > + error_propagate(errp, local_err); > + return; > + } Did we decide we don't need to test that the device is also in a hotpluggable slot? Are there also multi-function considerations that should be prevented or documented? For example, if a user tries to configure both the primary and failover NICs in the same slot, I assume bad things will happen. > + class_id = pci_get_word(pci_dev->config + PCI_CLASS_DEVICE); > + if (class_id != PCI_CLASS_NETWORK_ETHERNET) { > + error_setg(errp, "failover device is not an Ethernet device"); > + error_propagate(errp, local_err); > + return; > + } > + } Looks like cleanup is missing both both error cases, the option rom error path below this does a pci_qdev_unrealize() before returning so I'd assume we want the same here. Thanks, Alex > + > /* rom loading */ > is_default_rom = false; > if (pci_dev->romfile == NULL && pc->romfile != NULL) { > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h > index f3f0ffd5fb..def5435685 100644 > --- a/include/hw/pci/pci.h > +++ b/include/hw/pci/pci.h > @@ -352,6 +352,9 @@ struct PCIDevice { > MSIVectorUseNotifier msix_vector_use_notifier; > MSIVectorReleaseNotifier msix_vector_release_notifier; > MSIVectorPollNotifier msix_vector_poll_notifier; > + > + /* ID of standby device in net_failover pair */ > + char *net_failover_pair_id; > }; > > void pci_register_bar(PCIDevice *pci_dev, int region_num,