From: Thomas Huth <thuth@redhat.com>
To: Laurent Vivier <lvivier@redhat.com>, qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Jens Freimann <jfreimann@redhat.com>,
Juan Quintela <quintela@redhat.com>
Subject: Re: [PATCH v6 1/6] qtest/libqos: add a function to initialize secondary PCI buses
Date: Tue, 7 Dec 2021 09:09:05 +0100 [thread overview]
Message-ID: <d754cc02-c4a7-17df-83c5-9120ba44a85d@redhat.com> (raw)
In-Reply-To: <20211206222040.3872253-2-lvivier@redhat.com>
On 06/12/2021 23.20, Laurent Vivier wrote:
> Scan the PCI devices to find bridge and set PCI_SECONDARY_BUS and
> PCI_SUBORDINATE_BUS (algorithm from seabios)
>
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
> include/hw/pci/pci_bridge.h | 8 +++
> tests/qtest/libqos/pci.c | 118 ++++++++++++++++++++++++++++++++++++
> tests/qtest/libqos/pci.h | 1 +
> 3 files changed, 127 insertions(+)
>
> diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
> index a94d350034bf..30691a6e5728 100644
> --- a/include/hw/pci/pci_bridge.h
> +++ b/include/hw/pci/pci_bridge.h
> @@ -138,6 +138,7 @@ typedef struct PCIBridgeQemuCap {
> uint64_t mem_pref_64; /* Prefetchable memory to reserve (64-bit MMIO) */
> } PCIBridgeQemuCap;
>
> +#define REDHAT_PCI_CAP_TYPE_OFFSET 3
> #define REDHAT_PCI_CAP_RESOURCE_RESERVE 1
>
> /*
> @@ -152,6 +153,13 @@ typedef struct PCIResReserve {
> uint64_t mem_pref_64;
> } PCIResReserve;
>
> +#define REDHAT_PCI_CAP_RES_RESERVE_BUS_RES 4
> +#define REDHAT_PCI_CAP_RES_RESERVE_IO 8
> +#define REDHAT_PCI_CAP_RES_RESERVE_MEM 16
> +#define REDHAT_PCI_CAP_RES_RESERVE_PREF_MEM_32 20
> +#define REDHAT_PCI_CAP_RES_RESERVE_PREF_MEM_64 24
> +#define REDHAT_PCI_CAP_RES_RESERVE_CAP_SIZE 32
> +
> int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset,
> PCIResReserve res_reserve, Error **errp);
>
> diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c
> index e1e96189c821..3f0b18f4750b 100644
> --- a/tests/qtest/libqos/pci.c
> +++ b/tests/qtest/libqos/pci.c
> @@ -13,6 +13,8 @@
> #include "qemu/osdep.h"
> #include "pci.h"
>
> +#include "hw/pci/pci.h"
> +#include "hw/pci/pci_bridge.h"
> #include "hw/pci/pci_regs.h"
> #include "qemu/host-utils.h"
> #include "qgraph.h"
> @@ -99,6 +101,122 @@ void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr)
> g_assert(!addr->device_id || device_id == addr->device_id);
> }
>
> +static uint8_t qpci_find_resource_reserve_capability(QPCIDevice *dev)
> +{
> + uint16_t device_id;
> + uint8_t cap = 0;
> +
> + if (qpci_config_readw(dev, PCI_VENDOR_ID) != PCI_VENDOR_ID_REDHAT) {
> + return 0;
> + }
> +
> + device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
> +
> + if (device_id != PCI_DEVICE_ID_REDHAT_PCIE_RP &&
> + device_id != PCI_DEVICE_ID_REDHAT_BRIDGE) {
> + return 0;
> + }
> +
> + do {
> + cap = qpci_find_capability(dev, PCI_CAP_ID_VNDR, cap);
> + } while (cap &&
> + qpci_config_readb(dev, cap + REDHAT_PCI_CAP_TYPE_OFFSET) !=
> + REDHAT_PCI_CAP_RESOURCE_RESERVE);
> + if (cap) {
> + uint8_t cap_len = qpci_config_readb(dev, cap + PCI_CAP_FLAGS);
> + if (cap_len < REDHAT_PCI_CAP_RES_RESERVE_CAP_SIZE) {
> + return 0;
> + }
> + }
> + return cap;
> +}
> +
> +static void qpci_secondary_buses_rec(QPCIBus *qbus, int bus, int *pci_bus)
> +{
> + QPCIDevice *dev;
> + uint16_t class;
> + uint8_t pribus, secbus, subbus;
> + int i;
<nit>I'd maybe use a better name instead of "i" here.</nit>
> + for (i = 0; i < 32; i++) {
> + dev = qpci_device_find(qbus, QPCI_DEVFN(bus + i, 0));
> + if (dev == NULL) {
> + continue;
> + }
> + class = qpci_config_readw(dev, PCI_CLASS_DEVICE);
> + if (class == PCI_CLASS_BRIDGE_PCI) {
> + qpci_config_writeb(dev, PCI_SECONDARY_BUS, 255);
> + qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, 0);
> + }
> + g_free(dev);
> + }
> +
> + for (i = 0; i < 32; i++) {
> + dev = qpci_device_find(qbus, QPCI_DEVFN(bus + i, 0));
> + if (dev == NULL) {
> + continue;
> + }
> + class = qpci_config_readw(dev, PCI_CLASS_DEVICE);
> + if (class != PCI_CLASS_BRIDGE_PCI) {
> + continue;
> + }
> +
> + pribus = qpci_config_readb(dev, PCI_PRIMARY_BUS);
> + if (pribus != bus) {
> + qpci_config_writeb(dev, PCI_PRIMARY_BUS, bus);
> + }
> +
> + secbus = qpci_config_readb(dev, PCI_SECONDARY_BUS);
> + (*pci_bus)++;
> + if (*pci_bus != secbus) {
> + secbus = *pci_bus;
> + qpci_config_writeb(dev, PCI_SECONDARY_BUS, secbus);
> + }
> +
> + subbus = qpci_config_readb(dev, PCI_SUBORDINATE_BUS);
> + qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, 255);
> +
> + qpci_secondary_buses_rec(qbus, secbus << 5, pci_bus);
> +
> + if (subbus != *pci_bus) {
> + uint8_t res_bus = *pci_bus;
> + uint8_t cap = qpci_find_resource_reserve_capability(dev);
> +
> + if (cap) {
> + uint32_t tmp_res_bus;
> +
> + tmp_res_bus = qpci_config_readl(dev, cap +
> + REDHAT_PCI_CAP_RES_RESERVE_BUS_RES);
> + if (tmp_res_bus != (uint32_t)-1) {
> + res_bus = tmp_res_bus & 0xFF;
> + if ((uint8_t)(res_bus + secbus) < secbus ||
> + (uint8_t)(res_bus + secbus) < res_bus) {
> + res_bus = 0;
> + }
> + if (secbus + res_bus > *pci_bus) {
> + res_bus = secbus + res_bus;
> + }
> + }
> + }
> + subbus = res_bus;
> + *pci_bus = res_bus;
> + }
> +
> + qpci_config_writeb(dev, PCI_SUBORDINATE_BUS, subbus);
> + g_free(dev);
> + }
> +}
> +
> +int qpci_secondary_buses_init(QPCIBus *bus)
> +{
> + int last_bus = 0;
> +
> + qpci_secondary_buses_rec(bus, 0, &last_bus);
> +
> + return last_bus;
> +}
> +
> +
> void qpci_device_enable(QPCIDevice *dev)
> {
> uint16_t cmd;
> diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
> index ee64fdecbda8..becb800f9e6a 100644
> --- a/tests/qtest/libqos/pci.h
> +++ b/tests/qtest/libqos/pci.h
> @@ -81,6 +81,7 @@ void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
> void *data);
> QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn);
> void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr);
> +int qpci_secondary_buses_init(QPCIBus *bus);
>
> bool qpci_has_buggy_msi(QPCIDevice *dev);
> bool qpci_check_buggy_msi(QPCIDevice *dev);
>
Acked-by: Thomas Huth <thuth@redhat.com>
next prev parent reply other threads:[~2021-12-07 8:10 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-06 22:20 [PATCH v6 0/6] tests/qtest: add some tests for virtio-net failover Laurent Vivier
2021-12-06 22:20 ` [PATCH v6 1/6] qtest/libqos: add a function to initialize secondary PCI buses Laurent Vivier
2021-12-07 8:09 ` Thomas Huth [this message]
2021-12-06 22:20 ` [PATCH v6 2/6] tests/qtest: add some tests for virtio-net failover Laurent Vivier
2021-12-07 8:29 ` Thomas Huth
2021-12-06 22:20 ` [PATCH v6 3/6] failover: fix unplug pending detection Laurent Vivier
2021-12-07 4:13 ` Ani Sinha
2021-12-07 7:31 ` Laurent Vivier
2021-12-06 22:20 ` [PATCH v6 4/6] tests/libqtest: update virtio-net failover test Laurent Vivier
2021-12-07 8:33 ` Thomas Huth
2021-12-06 22:20 ` [PATCH v6 5/6] test/libqtest: add some virtio-net failover migration cancelling tests Laurent Vivier
2021-12-07 8:35 ` Thomas Huth
2021-12-08 7:44 ` Michael S. Tsirkin
2021-12-08 7:48 ` Thomas Huth
2021-12-08 7:53 ` Thomas Huth
2021-12-06 22:20 ` [PATCH v6 6/6] tests/libqtest: add a migration test with two couples of failover devices Laurent Vivier
2021-12-07 8:39 ` Thomas Huth
2021-12-08 7:44 ` [PATCH v6 0/6] tests/qtest: add some tests for virtio-net failover Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d754cc02-c4a7-17df-83c5-9120ba44a85d@redhat.com \
--to=thuth@redhat.com \
--cc=jfreimann@redhat.com \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).