* [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes
@ 2025-01-17 17:22 Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 1/4] qtest/libqos/pci: Do not write to PBA memory Nicholas Piggin
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Nicholas Piggin @ 2025-01-17 17:22 UTC (permalink / raw)
To: Fabiano Rosas
Cc: Nicholas Piggin, John Snow, Laurent Vivier, Paolo Bonzini,
Akihiko Odaki, Michael S . Tsirkin, Marcel Apfelbaum, qemu-block,
qemu-devel
Since v2:
The e1000e|igb series got decoupled from this one and split into
its own series.
Patch 4 was added.
Thanks,
Nick
Nicholas Piggin (4):
qtest/libqos/pci: Do not write to PBA memory
qtest/libqos/pci: Enforce balanced iomap/unmap
qtest/libqos/pci: Fix qpci_msix_enable sharing bar0
qtest/libqos/pci: Factor msix entry helpers into pci common code
tests/qtest/libqos/ahci.h | 1 +
tests/qtest/libqos/pci.h | 6 ++
tests/qtest/libqos/virtio-pci.h | 1 +
tests/qtest/ahci-test.c | 2 +
tests/qtest/libqos/ahci.c | 6 ++
tests/qtest/libqos/pci.c | 127 +++++++++++++++++++++++++++++---
tests/qtest/libqos/virtio-pci.c | 54 +++-----------
7 files changed, 144 insertions(+), 53 deletions(-)
--
2.45.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 1/4] qtest/libqos/pci: Do not write to PBA memory
2025-01-17 17:22 [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Nicholas Piggin
@ 2025-01-17 17:22 ` Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap Nicholas Piggin
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Nicholas Piggin @ 2025-01-17 17:22 UTC (permalink / raw)
To: Fabiano Rosas
Cc: Nicholas Piggin, John Snow, Laurent Vivier, Paolo Bonzini,
Akihiko Odaki, Michael S . Tsirkin, Marcel Apfelbaum, qemu-block,
qemu-devel
The PCI Local Bus Specification says the result of writes to MSI-X
PBA memory is undefined. QEMU implements them as no-ops, so remove
the pointless write from qpci_msix_pending().
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
tests/qtest/libqos/pci.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c
index b23d72346b6..a59197b9922 100644
--- a/tests/qtest/libqos/pci.c
+++ b/tests/qtest/libqos/pci.c
@@ -328,8 +328,6 @@ bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry)
g_assert(dev->msix_enabled);
pba_entry = qpci_io_readl(dev, dev->msix_pba_bar, dev->msix_pba_off + off);
- qpci_io_writel(dev, dev->msix_pba_bar, dev->msix_pba_off + off,
- pba_entry & ~(1 << bit_n));
return (pba_entry & (1 << bit_n)) != 0;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap
2025-01-17 17:22 [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 1/4] qtest/libqos/pci: Do not write to PBA memory Nicholas Piggin
@ 2025-01-17 17:22 ` Nicholas Piggin
2025-01-20 5:29 ` Philippe Mathieu-Daudé
2025-01-17 17:22 ` [PATCH v3 3/4] qtest/libqos/pci: Fix qpci_msix_enable sharing bar0 Nicholas Piggin
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Nicholas Piggin @ 2025-01-17 17:22 UTC (permalink / raw)
To: Fabiano Rosas
Cc: Nicholas Piggin, John Snow, Laurent Vivier, Paolo Bonzini,
Akihiko Odaki, Michael S . Tsirkin, Marcel Apfelbaum, qemu-block,
qemu-devel
Add assertions to ensure a BAR is not mapped twice, and only
previously mapped BARs are unmapped. This can help catch some
bugs.
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
tests/qtest/libqos/ahci.h | 1 +
tests/qtest/libqos/pci.h | 2 ++
tests/qtest/libqos/virtio-pci.h | 1 +
tests/qtest/ahci-test.c | 2 ++
tests/qtest/libqos/ahci.c | 6 ++++++
tests/qtest/libqos/pci.c | 32 +++++++++++++++++++++++++++++++-
tests/qtest/libqos/virtio-pci.c | 6 +++++-
7 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/tests/qtest/libqos/ahci.h b/tests/qtest/libqos/ahci.h
index a0487a1557d..5d7e26aee2a 100644
--- a/tests/qtest/libqos/ahci.h
+++ b/tests/qtest/libqos/ahci.h
@@ -575,6 +575,7 @@ QPCIDevice *get_ahci_device(QTestState *qts, uint32_t *fingerprint);
void free_ahci_device(QPCIDevice *dev);
void ahci_pci_enable(AHCIQState *ahci);
void start_ahci_device(AHCIQState *ahci);
+void stop_ahci_device(AHCIQState *ahci);
void ahci_hba_enable(AHCIQState *ahci);
/* Port Management */
diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
index 83896145235..9dc82ea723a 100644
--- a/tests/qtest/libqos/pci.h
+++ b/tests/qtest/libqos/pci.h
@@ -65,6 +65,8 @@ struct QPCIDevice
{
QPCIBus *bus;
int devfn;
+ bool bars_mapped[6];
+ QPCIBar bars[6];
bool msix_enabled;
QPCIBar msix_table_bar, msix_pba_bar;
uint64_t msix_table_off, msix_pba_off;
diff --git a/tests/qtest/libqos/virtio-pci.h b/tests/qtest/libqos/virtio-pci.h
index f5115cacba2..efdf904b254 100644
--- a/tests/qtest/libqos/virtio-pci.h
+++ b/tests/qtest/libqos/virtio-pci.h
@@ -26,6 +26,7 @@ typedef struct QVirtioPCIDevice {
uint64_t config_msix_addr;
uint32_t config_msix_data;
+ bool enabled;
int bar_idx;
/* VIRTIO 1.0 */
diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c
index 5a1923f721b..b3dae7a8ce4 100644
--- a/tests/qtest/ahci-test.c
+++ b/tests/qtest/ahci-test.c
@@ -1483,6 +1483,8 @@ static void test_reset_pending_callback(void)
/* Wait for throttled write to finish. */
sleep(1);
+ stop_ahci_device(ahci);
+
/* Start again. */
ahci_clean_mem(ahci);
ahci_pci_enable(ahci);
diff --git a/tests/qtest/libqos/ahci.c b/tests/qtest/libqos/ahci.c
index 34a75b7f43b..cfc435b6663 100644
--- a/tests/qtest/libqos/ahci.c
+++ b/tests/qtest/libqos/ahci.c
@@ -217,6 +217,12 @@ void start_ahci_device(AHCIQState *ahci)
qpci_device_enable(ahci->dev);
}
+void stop_ahci_device(AHCIQState *ahci)
+{
+ /* Map AHCI's ABAR (BAR5) */
+ qpci_iounmap(ahci->dev, ahci->hba_bar);
+}
+
/**
* Test and initialize the AHCI's HBA memory areas.
* Initialize and start any ports with devices attached.
diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c
index a59197b9922..05089a5f24f 100644
--- a/tests/qtest/libqos/pci.c
+++ b/tests/qtest/libqos/pci.c
@@ -93,12 +93,17 @@ QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn)
void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr)
{
uint16_t vendor_id, device_id;
+ int i;
qpci_device_set(dev, bus, addr->devfn);
vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID);
device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
g_assert(!addr->vendor_id || vendor_id == addr->vendor_id);
g_assert(!addr->device_id || device_id == addr->device_id);
+
+ for (i = 0; i < 6; i++) {
+ g_assert(!dev->bars_mapped[i]);
+ }
}
static uint8_t qpci_find_resource_reserve_capability(QPCIDevice *dev)
@@ -529,6 +534,8 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
uint64_t loc;
g_assert(barno >= 0 && barno <= 5);
+ g_assert(!dev->bars_mapped[barno]);
+
bar_reg = bar_reg_map[barno];
qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
@@ -572,12 +579,35 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
}
bar.addr = loc;
+
+ dev->bars_mapped[barno] = true;
+ dev->bars[barno] = bar;
+
return bar;
}
void qpci_iounmap(QPCIDevice *dev, QPCIBar bar)
{
- /* FIXME */
+ static const int bar_reg_map[] = {
+ PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
+ PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
+ };
+ int bar_reg;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ if (!dev->bars_mapped[i]) {
+ continue;
+ }
+ if (dev->bars[i].addr == bar.addr) {
+ dev->bars_mapped[i] = false;
+ bar_reg = bar_reg_map[i];
+ qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
+ /* FIXME: the address space is leaked */
+ return;
+ }
+ }
+ g_assert_not_reached();
}
QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
diff --git a/tests/qtest/libqos/virtio-pci.c b/tests/qtest/libqos/virtio-pci.c
index 485b8f6b7e0..2b59fb181c9 100644
--- a/tests/qtest/libqos/virtio-pci.c
+++ b/tests/qtest/libqos/virtio-pci.c
@@ -304,11 +304,15 @@ void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
{
qpci_device_enable(d->pdev);
d->bar = qpci_iomap(d->pdev, d->bar_idx, NULL);
+ d->enabled = true;
}
void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
{
- qpci_iounmap(d->pdev, d->bar);
+ if (d->enabled) {
+ qpci_iounmap(d->pdev, d->bar);
+ d->enabled = false;
+ }
}
void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
--
2.45.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 3/4] qtest/libqos/pci: Fix qpci_msix_enable sharing bar0
2025-01-17 17:22 [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 1/4] qtest/libqos/pci: Do not write to PBA memory Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap Nicholas Piggin
@ 2025-01-17 17:22 ` Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 4/4] qtest/libqos/pci: Factor msix entry helpers into pci common code Nicholas Piggin
2025-01-18 9:58 ` [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Akihiko Odaki
4 siblings, 0 replies; 9+ messages in thread
From: Nicholas Piggin @ 2025-01-17 17:22 UTC (permalink / raw)
To: Fabiano Rosas
Cc: Nicholas Piggin, John Snow, Laurent Vivier, Paolo Bonzini,
Akihiko Odaki, Michael S . Tsirkin, Marcel Apfelbaum, qemu-block,
qemu-devel
Devices where the MSI-X addresses are shared with other MMIO on BAR0
can not use msi_enable because it unmaps and remaps BAR0, which
interferes with device MMIO mappings. xhci-nec is one such device we
would like to test msix with.
Use the BAR iomap tracking structure introduced in the previous change
to have qpci_misx_enable() use existing iomaps if msix bars are
already mapped.
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
tests/qtest/libqos/pci.h | 1 +
tests/qtest/libqos/pci.c | 40 ++++++++++++++++++++++++++++++++++------
2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
index 9dc82ea723a..5a7b2454ad5 100644
--- a/tests/qtest/libqos/pci.h
+++ b/tests/qtest/libqos/pci.h
@@ -68,6 +68,7 @@ struct QPCIDevice
bool bars_mapped[6];
QPCIBar bars[6];
bool msix_enabled;
+ bool msix_table_bar_iomap, msix_pba_bar_iomap;
QPCIBar msix_table_bar, msix_pba_bar;
uint64_t msix_table_off, msix_pba_off;
};
diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c
index 05089a5f24f..a187349d30a 100644
--- a/tests/qtest/libqos/pci.c
+++ b/tests/qtest/libqos/pci.c
@@ -288,15 +288,21 @@ void qpci_msix_enable(QPCIDevice *dev)
table = qpci_config_readl(dev, addr + PCI_MSIX_TABLE);
bir_table = table & PCI_MSIX_FLAGS_BIRMASK;
- dev->msix_table_bar = qpci_iomap(dev, bir_table, NULL);
+ if (dev->bars_mapped[bir_table]) {
+ dev->msix_table_bar = dev->bars[bir_table];
+ } else {
+ dev->msix_table_bar_iomap = true;
+ dev->msix_table_bar = qpci_iomap(dev, bir_table, NULL);
+ }
dev->msix_table_off = table & ~PCI_MSIX_FLAGS_BIRMASK;
table = qpci_config_readl(dev, addr + PCI_MSIX_PBA);
bir_pba = table & PCI_MSIX_FLAGS_BIRMASK;
- if (bir_pba != bir_table) {
- dev->msix_pba_bar = qpci_iomap(dev, bir_pba, NULL);
+ if (dev->bars_mapped[bir_pba]) {
+ dev->msix_pba_bar = dev->bars[bir_pba];
} else {
- dev->msix_pba_bar = dev->msix_table_bar;
+ dev->msix_pba_bar_iomap = true;
+ dev->msix_pba_bar = qpci_iomap(dev, bir_pba, NULL);
}
dev->msix_pba_off = table & ~PCI_MSIX_FLAGS_BIRMASK;
@@ -307,6 +313,7 @@ void qpci_msix_disable(QPCIDevice *dev)
{
uint8_t addr;
uint16_t val;
+ uint32_t table;
g_assert(dev->msix_enabled);
addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
@@ -315,10 +322,31 @@ void qpci_msix_disable(QPCIDevice *dev)
qpci_config_writew(dev, addr + PCI_MSIX_FLAGS,
val & ~PCI_MSIX_FLAGS_ENABLE);
- if (dev->msix_pba_bar.addr != dev->msix_table_bar.addr) {
+ if (dev->msix_pba_bar_iomap) {
+ dev->msix_pba_bar_iomap = false;
qpci_iounmap(dev, dev->msix_pba_bar);
+ } else {
+ /*
+ * If we had reused an existing iomap, ensure it is still mapped
+ * otherwise it would be a bug if it were unmapped before msix is
+ * disabled. A refcounting iomap implementation could avoid this
+ * issue entirely, but let's wait until that's needed.
+ */
+ uint8_t bir_pba;
+ table = qpci_config_readl(dev, addr + PCI_MSIX_PBA);
+ bir_pba = table & PCI_MSIX_FLAGS_BIRMASK;
+ g_assert(dev->bars_mapped[bir_pba]);
+ }
+
+ if (dev->msix_table_bar_iomap) {
+ dev->msix_table_bar_iomap = false;
+ qpci_iounmap(dev, dev->msix_table_bar);
+ } else {
+ uint8_t bir_table;
+ table = qpci_config_readl(dev, addr + PCI_MSIX_TABLE);
+ bir_table = table & PCI_MSIX_FLAGS_BIRMASK;
+ g_assert(dev->bars_mapped[bir_table]);
}
- qpci_iounmap(dev, dev->msix_table_bar);
dev->msix_enabled = 0;
dev->msix_table_off = 0;
--
2.45.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 4/4] qtest/libqos/pci: Factor msix entry helpers into pci common code
2025-01-17 17:22 [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Nicholas Piggin
` (2 preceding siblings ...)
2025-01-17 17:22 ` [PATCH v3 3/4] qtest/libqos/pci: Fix qpci_msix_enable sharing bar0 Nicholas Piggin
@ 2025-01-17 17:22 ` Nicholas Piggin
2025-01-18 9:58 ` [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Akihiko Odaki
4 siblings, 0 replies; 9+ messages in thread
From: Nicholas Piggin @ 2025-01-17 17:22 UTC (permalink / raw)
To: Fabiano Rosas
Cc: Nicholas Piggin, John Snow, Laurent Vivier, Paolo Bonzini,
Akihiko Odaki, Michael S . Tsirkin, Marcel Apfelbaum, qemu-block,
qemu-devel
Setting msix entry address and data and masking is moved into
common code helpers from virtio tests.
For now that remains the only user, but there are changes under
development to enable msix vectors for msix, e1000e, and xhci
tests, which can make use of them.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
tests/qtest/libqos/pci.h | 3 ++
tests/qtest/libqos/pci.c | 53 +++++++++++++++++++++++++++++++++
tests/qtest/libqos/virtio-pci.c | 48 ++++-------------------------
3 files changed, 61 insertions(+), 43 deletions(-)
diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
index 5a7b2454ad5..d46ce4239f0 100644
--- a/tests/qtest/libqos/pci.h
+++ b/tests/qtest/libqos/pci.h
@@ -93,8 +93,11 @@ void qpci_device_enable(QPCIDevice *dev);
uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id, uint8_t start_addr);
void qpci_msix_enable(QPCIDevice *dev);
void qpci_msix_disable(QPCIDevice *dev);
+void qpci_msix_set_entry(QPCIDevice *dev, uint16_t entry,
+ uint64_t guest_addr, uint32_t data);
bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry);
bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry);
+void qpci_msix_set_masked(QPCIDevice *dev, uint16_t entry, bool masked);
uint16_t qpci_msix_table_size(QPCIDevice *dev);
uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset);
diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c
index a187349d30a..47632c4b403 100644
--- a/tests/qtest/libqos/pci.c
+++ b/tests/qtest/libqos/pci.c
@@ -353,6 +353,25 @@ void qpci_msix_disable(QPCIDevice *dev)
dev->msix_pba_off = 0;
}
+void qpci_msix_set_entry(QPCIDevice *dev, uint16_t entry,
+ uint64_t guest_addr, uint32_t data)
+{
+ uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE;
+
+ g_assert(dev->msix_enabled);
+ g_assert_cmpint(entry, >=, 0);
+ g_assert_cmpint(entry, <, qpci_msix_table_size(dev));
+
+ qpci_io_writel(dev, dev->msix_table_bar,
+ vector_off + PCI_MSIX_ENTRY_LOWER_ADDR, guest_addr & ~0UL);
+ qpci_io_writel(dev, dev->msix_table_bar,
+ vector_off + PCI_MSIX_ENTRY_UPPER_ADDR,
+ (guest_addr >> 32) & ~0UL);
+
+ qpci_io_writel(dev, dev->msix_table_bar,
+ vector_off + PCI_MSIX_ENTRY_DATA, data);
+}
+
bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry)
{
uint32_t pba_entry;
@@ -360,6 +379,9 @@ bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry)
uint64_t off = (entry / 32) * PCI_MSIX_ENTRY_SIZE / 4;
g_assert(dev->msix_enabled);
+ g_assert_cmpint(entry, >=, 0);
+ g_assert_cmpint(entry, <, qpci_msix_table_size(dev));
+
pba_entry = qpci_io_readl(dev, dev->msix_pba_bar, dev->msix_pba_off + off);
return (pba_entry & (1 << bit_n)) != 0;
}
@@ -371,6 +393,9 @@ bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE;
g_assert(dev->msix_enabled);
+ g_assert_cmpint(entry, >=, 0);
+ g_assert_cmpint(entry, <, qpci_msix_table_size(dev));
+
addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
g_assert_cmphex(addr, !=, 0);
val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
@@ -384,6 +409,34 @@ bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
}
}
+void qpci_msix_set_masked(QPCIDevice *dev, uint16_t entry, bool masked)
+{
+ uint8_t addr;
+ uint16_t val;
+ uint64_t vector_off = dev->msix_table_off + entry * PCI_MSIX_ENTRY_SIZE;
+
+ g_assert(dev->msix_enabled);
+ g_assert_cmpint(entry, >=, 0);
+ g_assert_cmpint(entry, <, qpci_msix_table_size(dev));
+
+ addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX, 0);
+ g_assert_cmphex(addr, !=, 0);
+ val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
+ g_assert(!(val & PCI_MSIX_FLAGS_MASKALL));
+
+ val = qpci_io_readl(dev, dev->msix_table_bar,
+ vector_off + PCI_MSIX_ENTRY_VECTOR_CTRL);
+ if (masked && !(val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
+ qpci_io_writel(dev, dev->msix_table_bar,
+ vector_off + PCI_MSIX_ENTRY_VECTOR_CTRL,
+ val | PCI_MSIX_ENTRY_CTRL_MASKBIT);
+ } else if (!masked && (val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
+ qpci_io_writel(dev, dev->msix_table_bar,
+ vector_off + PCI_MSIX_ENTRY_VECTOR_CTRL,
+ val & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
+ }
+}
+
uint16_t qpci_msix_table_size(QPCIDevice *dev)
{
uint8_t addr;
diff --git a/tests/qtest/libqos/virtio-pci.c b/tests/qtest/libqos/virtio-pci.c
index 2b59fb181c9..ed7f50e41a5 100644
--- a/tests/qtest/libqos/virtio-pci.c
+++ b/tests/qtest/libqos/virtio-pci.c
@@ -318,64 +318,26 @@ void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
QGuestAllocator *alloc, uint16_t entry)
{
- uint32_t control;
- uint64_t off;
-
g_assert(d->pdev->msix_enabled);
- off = d->pdev->msix_table_off + (entry * 16);
-
- g_assert_cmpint(entry, >=, 0);
- g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev));
vqpci->msix_entry = entry;
-
vqpci->msix_addr = guest_alloc(alloc, 4);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_LOWER_ADDR, vqpci->msix_addr & ~0UL);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_UPPER_ADDR,
- (vqpci->msix_addr >> 32) & ~0UL);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_DATA, vqpci->msix_data);
-
- control = qpci_io_readl(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_VECTOR_CTRL);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_VECTOR_CTRL,
- control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
+ qpci_msix_set_entry(d->pdev, entry, vqpci->msix_addr, vqpci->msix_data);
+ qpci_msix_set_masked(d->pdev, entry, false);
d->msix_ops->set_queue_vector(d, vqpci->vq.index, entry);
}
void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
QGuestAllocator *alloc, uint16_t entry)
{
- uint32_t control;
- uint64_t off;
-
g_assert(d->pdev->msix_enabled);
- off = d->pdev->msix_table_off + (entry * 16);
-
- g_assert_cmpint(entry, >=, 0);
- g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev));
d->config_msix_entry = entry;
-
d->config_msix_data = 0x12345678;
d->config_msix_addr = guest_alloc(alloc, 4);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_LOWER_ADDR, d->config_msix_addr & ~0UL);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_UPPER_ADDR,
- (d->config_msix_addr >> 32) & ~0UL);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_DATA, d->config_msix_data);
-
- control = qpci_io_readl(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_VECTOR_CTRL);
- qpci_io_writel(d->pdev, d->pdev->msix_table_bar,
- off + PCI_MSIX_ENTRY_VECTOR_CTRL,
- control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
-
+ qpci_msix_set_entry(d->pdev, entry, d->config_msix_addr,
+ d->config_msix_data);
+ qpci_msix_set_masked(d->pdev, entry, false);
d->msix_ops->set_config_vector(d, entry);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes
2025-01-17 17:22 [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Nicholas Piggin
` (3 preceding siblings ...)
2025-01-17 17:22 ` [PATCH v3 4/4] qtest/libqos/pci: Factor msix entry helpers into pci common code Nicholas Piggin
@ 2025-01-18 9:58 ` Akihiko Odaki
4 siblings, 0 replies; 9+ messages in thread
From: Akihiko Odaki @ 2025-01-18 9:58 UTC (permalink / raw)
To: Nicholas Piggin, Fabiano Rosas
Cc: John Snow, Laurent Vivier, Paolo Bonzini, Michael S . Tsirkin,
Marcel Apfelbaum, qemu-block, qemu-devel
On 2025/01/18 2:22, Nicholas Piggin wrote:
> Since v2:
>
> The e1000e|igb series got decoupled from this one and split into
> its own series.
Thank you for working on e1000e/igb. I appreciate fixes for interrupt
throttling you added with the new version.
>
> Patch 4 was added.
For this series,
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
>
> Thanks,
> Nick
>
> Nicholas Piggin (4):
> qtest/libqos/pci: Do not write to PBA memory
> qtest/libqos/pci: Enforce balanced iomap/unmap
> qtest/libqos/pci: Fix qpci_msix_enable sharing bar0
> qtest/libqos/pci: Factor msix entry helpers into pci common code
>
> tests/qtest/libqos/ahci.h | 1 +
> tests/qtest/libqos/pci.h | 6 ++
> tests/qtest/libqos/virtio-pci.h | 1 +
> tests/qtest/ahci-test.c | 2 +
> tests/qtest/libqos/ahci.c | 6 ++
> tests/qtest/libqos/pci.c | 127 +++++++++++++++++++++++++++++---
> tests/qtest/libqos/virtio-pci.c | 54 +++-----------
> 7 files changed, 144 insertions(+), 53 deletions(-)
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap
2025-01-17 17:22 ` [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap Nicholas Piggin
@ 2025-01-20 5:29 ` Philippe Mathieu-Daudé
2025-01-21 4:39 ` Nicholas Piggin
0 siblings, 1 reply; 9+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-01-20 5:29 UTC (permalink / raw)
To: Nicholas Piggin, Fabiano Rosas
Cc: John Snow, Laurent Vivier, Paolo Bonzini, Akihiko Odaki,
Michael S . Tsirkin, Marcel Apfelbaum, qemu-block, qemu-devel
Hi Nick,
Only nitpicking comments...
On 17/1/25 18:22, Nicholas Piggin wrote:
> Add assertions to ensure a BAR is not mapped twice, and only
> previously mapped BARs are unmapped. This can help catch some
> bugs.
>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> tests/qtest/libqos/ahci.h | 1 +
> tests/qtest/libqos/pci.h | 2 ++
> tests/qtest/libqos/virtio-pci.h | 1 +
> tests/qtest/ahci-test.c | 2 ++
> tests/qtest/libqos/ahci.c | 6 ++++++
> tests/qtest/libqos/pci.c | 32 +++++++++++++++++++++++++++++++-
> tests/qtest/libqos/virtio-pci.c | 6 +++++-
> 7 files changed, 48 insertions(+), 2 deletions(-)
Maybe put the AHCI fix in a preliminary patch?
> diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
> index 83896145235..9dc82ea723a 100644
> --- a/tests/qtest/libqos/pci.h
> +++ b/tests/qtest/libqos/pci.h
Consider using a definition rather than a magic value:
#define PCI_BAR_COUNT 6
> @@ -65,6 +65,8 @@ struct QPCIDevice
> {
> QPCIBus *bus;
> int devfn;
> + bool bars_mapped[6];
> + QPCIBar bars[6];
> diff --git a/tests/qtest/libqos/pci.c b/tests/qtest/libqos/pci.c
> index a59197b9922..05089a5f24f 100644
> --- a/tests/qtest/libqos/pci.c
> +++ b/tests/qtest/libqos/pci.c
> @@ -93,12 +93,17 @@ QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn)
> void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr)
> {
> uint16_t vendor_id, device_id;
> + int i;
>
> qpci_device_set(dev, bus, addr->devfn);
> vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID);
> device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
> g_assert(!addr->vendor_id || vendor_id == addr->vendor_id);
> g_assert(!addr->device_id || device_id == addr->device_id);
> +
> + for (i = 0; i < 6; i++) {
> + g_assert(!dev->bars_mapped[i]);
> + }
> }
> @@ -572,12 +579,35 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr)
> }
>
> bar.addr = loc;
> +
> + dev->bars_mapped[barno] = true;
> + dev->bars[barno] = bar;
> +
> return bar;
> }
>
> void qpci_iounmap(QPCIDevice *dev, QPCIBar bar)
> {
> - /* FIXME */
> + static const int bar_reg_map[] = {
> + PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
> + PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
> + };
> + int bar_reg;
> + int i;
> +
> + for (i = 0; i < 6; i++) {
> + if (!dev->bars_mapped[i]) {
> + continue;
> + }
> + if (dev->bars[i].addr == bar.addr) {
> + dev->bars_mapped[i] = false;
> + bar_reg = bar_reg_map[i];
> + qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
> + /* FIXME: the address space is leaked */
> + return;
> + }
> + }
> + g_assert_not_reached();
> }
Regards,
Phil.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap
2025-01-20 5:29 ` Philippe Mathieu-Daudé
@ 2025-01-21 4:39 ` Nicholas Piggin
2025-01-21 6:53 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 9+ messages in thread
From: Nicholas Piggin @ 2025-01-21 4:39 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, Fabiano Rosas
Cc: John Snow, Laurent Vivier, Paolo Bonzini, Akihiko Odaki,
Michael S . Tsirkin, Marcel Apfelbaum, qemu-block, qemu-devel
On Mon Jan 20, 2025 at 3:29 PM AEST, Philippe Mathieu-Daudé wrote:
> Hi Nick,
>
> Only nitpicking comments...
Hey, no they're good comments actually.
>
> On 17/1/25 18:22, Nicholas Piggin wrote:
>> Add assertions to ensure a BAR is not mapped twice, and only
>> previously mapped BARs are unmapped. This can help catch some
>> bugs.
>>
>> Reviewed-by: Fabiano Rosas <farosas@suse.de>
>> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
>> ---
>> tests/qtest/libqos/ahci.h | 1 +
>> tests/qtest/libqos/pci.h | 2 ++
>> tests/qtest/libqos/virtio-pci.h | 1 +
>> tests/qtest/ahci-test.c | 2 ++
>> tests/qtest/libqos/ahci.c | 6 ++++++
>> tests/qtest/libqos/pci.c | 32 +++++++++++++++++++++++++++++++-
>> tests/qtest/libqos/virtio-pci.c | 6 +++++-
>> 7 files changed, 48 insertions(+), 2 deletions(-)
>
> Maybe put the AHCI fix in a preliminary patch?
Yeah, this was just laziness. I will fix.
>
>> diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
>> index 83896145235..9dc82ea723a 100644
>> --- a/tests/qtest/libqos/pci.h
>> +++ b/tests/qtest/libqos/pci.h
>
> Consider using a definition rather than a magic value:
>
> #define PCI_BAR_COUNT 6
Now I look again at PCI code and it has PCI_NUM_REGIONS 7
where ROM slot is the last entry. qtests doesn't use it
AFAIKS but maybe it could(?) so should I just use that
existing define?
Thanks,
Nick
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap
2025-01-21 4:39 ` Nicholas Piggin
@ 2025-01-21 6:53 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 9+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-01-21 6:53 UTC (permalink / raw)
To: Nicholas Piggin, Fabiano Rosas
Cc: John Snow, Laurent Vivier, Paolo Bonzini, Akihiko Odaki,
Michael S . Tsirkin, Marcel Apfelbaum, qemu-block, qemu-devel
On 21/1/25 05:39, Nicholas Piggin wrote:
> On Mon Jan 20, 2025 at 3:29 PM AEST, Philippe Mathieu-Daudé wrote:
>> Hi Nick,
>>
>> Only nitpicking comments...
>
> Hey, no they're good comments actually.
>
>>
>> On 17/1/25 18:22, Nicholas Piggin wrote:
>>> Add assertions to ensure a BAR is not mapped twice, and only
>>> previously mapped BARs are unmapped. This can help catch some
>>> bugs.
>>>
>>> Reviewed-by: Fabiano Rosas <farosas@suse.de>
>>> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
>>> ---
>>> tests/qtest/libqos/ahci.h | 1 +
>>> tests/qtest/libqos/pci.h | 2 ++
>>> tests/qtest/libqos/virtio-pci.h | 1 +
>>> tests/qtest/ahci-test.c | 2 ++
>>> tests/qtest/libqos/ahci.c | 6 ++++++
>>> tests/qtest/libqos/pci.c | 32 +++++++++++++++++++++++++++++++-
>>> tests/qtest/libqos/virtio-pci.c | 6 +++++-
>>> 7 files changed, 48 insertions(+), 2 deletions(-)
>>
>> Maybe put the AHCI fix in a preliminary patch?
>
> Yeah, this was just laziness. I will fix.
>
>>
>>> diff --git a/tests/qtest/libqos/pci.h b/tests/qtest/libqos/pci.h
>>> index 83896145235..9dc82ea723a 100644
>>> --- a/tests/qtest/libqos/pci.h
>>> +++ b/tests/qtest/libqos/pci.h
>>
>> Consider using a definition rather than a magic value:
>>
>> #define PCI_BAR_COUNT 6
>
> Now I look again at PCI code and it has PCI_NUM_REGIONS 7
> where ROM slot is the last entry. qtests doesn't use it
> AFAIKS but maybe it could(?) so should I just use that
> existing define?
Even if qtests don't use it, using it makes the code clearer IMHO.
Thanks!
Phil.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-01-21 6:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-17 17:22 [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 1/4] qtest/libqos/pci: Do not write to PBA memory Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 2/4] qtest/libqos/pci: Enforce balanced iomap/unmap Nicholas Piggin
2025-01-20 5:29 ` Philippe Mathieu-Daudé
2025-01-21 4:39 ` Nicholas Piggin
2025-01-21 6:53 ` Philippe Mathieu-Daudé
2025-01-17 17:22 ` [PATCH v3 3/4] qtest/libqos/pci: Fix qpci_msix_enable sharing bar0 Nicholas Piggin
2025-01-17 17:22 ` [PATCH v3 4/4] qtest/libqos/pci: Factor msix entry helpers into pci common code Nicholas Piggin
2025-01-18 9:58 ` [PATCH v3 0/4] qtest/libqos/pci: pci and msix fixes Akihiko Odaki
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).