lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250811103942.4144-1-christian.bruel@foss.st.com>
Date: Mon, 11 Aug 2025 12:39:42 +0200
From: Christian Bruel <christian.bruel@...s.st.com>
To: <maz@...nel.org>, <tglx@...utronix.de>
CC: <linux-arm-kernel@...ts.infradead.org>, <linux-kernel@...r.kernel.org>,
        <fabrice.gasnier@...s.st.com>, <mani@...nel.org>,
        Christian Bruel
	<christian.bruel@...s.st.com>
Subject: [PATCH v1] irqchip: gic-v2m: Handle Multiple MSI base IRQ Alignment

The PCI Local Bus Specification (section 6.8.3.4 in Rev 3) permits
modifying the low-order bits of the DATA register to encode the interrupt
number. These bits must be reserved, but the base SPI may not be aligned to
the requested number of SPIs.

For example, with an initial MSI_TYPER base SPI of 0x16A and allocating a
multiple MSI of size 8, the offset returned is 8, resulting in an MSI DATA
base of 0x172.
This causes the endpoint device to send interrupt 3 wrong interrupt number:

1st MSI = 0x172 | 0x0 = 0x172
2nd MSI = 0x172 | 0x1 = 0x173
3rd MSI = 0x172 | 0x2 = 0x172 wrongly triggers the 1st MSI
...

To fix this, use bitmap_find_next_zero_area_off() instead of
bitmap_find_free_region() applying an initial offset of
base_spi - rounded(base_spi, nr_irqs) to accommodate the required alignment
for the first MSI.

With the above case, the returned bitmap offset is 6 which results in the
correct interrupts number encoding:

1st MSI = 0x170 | 0x0 = 0x170
2nd MSI = 0x170 | 0x1 = 0x171
3rd MSI = 0x170 | 0x2 = 0x172
...

Signed-off-by: Christian Bruel <christian.bruel@...s.st.com>
---
Changes in v1:
   (Marc Zyngier)
 - Replace the incorrect usage of msi_attrib.multiple with nr_irqs
 - Reworked changelog
---
 drivers/irqchip/irq-gic-v2m.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 24ef5af569fe..2d5cf36340b1 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -153,14 +153,18 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 {
 	msi_alloc_info_t *info = args;
 	struct v2m_data *v2m = NULL, *tmp;
-	int hwirq, offset, i, err = 0;
+	int hwirq, i, err = 0;
+	unsigned long align_off, offset;
+	unsigned long align_mask = nr_irqs - 1;
 
 	spin_lock(&v2m_lock);
 	list_for_each_entry(tmp, &v2m_nodes, entry) {
-		offset = bitmap_find_free_region(tmp->bm, tmp->nr_spis,
-						 get_count_order(nr_irqs));
-		if (offset >= 0) {
+		align_off = tmp->spi_start - (tmp->spi_start & ~align_mask);
+		offset = bitmap_find_next_zero_area_off(tmp->bm, tmp->nr_spis, 0,
+							nr_irqs, align_mask, align_off);
+		if (offset < tmp->nr_spis) {
 			v2m = tmp;
+			bitmap_set(v2m->bm, offset, nr_irqs);
 			break;
 		}
 	}
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ