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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Tue,  6 Mar 2018 14:30:15 +0000
From:   Ard Biesheuvel <ard.biesheuvel@...aro.org>
To:     linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org
Cc:     marc.zyngier@....com, jason@...edaemon.net, tglx@...utronix.de,
        Ard Biesheuvel <ard.biesheuvel@...aro.org>
Subject: [PATCH] irqchip: gic-v3-its: fail IRQ allocation if nr_ites is exceeded

Normally, ITS device IDs are not shared between different PCIe
devices, and ITS MSIs are allocated from the range that was
reserved when the device's struct its_device was created.

When a duplicate device ID is seen by its_msi_prepare(), it skips
the call to its_create_device(), since it assumes it is dealing
with an alias of what is essentially the same device.

In exceptional cases, such as on the Socionext SynQuacer SoC that
maps all PCIe RIDs to ITS device ID #0, we may end up in the
situation where its_alloc_device_irq() calls succeed erroneously,
due to the fact that the first its_create_device() call allocated
a LPI map of sufficient size to cover the newly allocated MSI,
while the size of the ITT mapping (which is based on nr_ites) has
already been programmed to a value that does not cover this MSI.

The result is that the additional devices that share device ID #0
get MSIs assigned to them, but asserting them doesn't actually
work, and the device doesn't function.

Instead, let's fail the its_alloc_device_irq() in this case, and
allow the device to fall back to legacy INTx interrupts instead.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...aro.org>
---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 1d3056f53747..b5a1e4f83297 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2186,7 +2186,7 @@ static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq)
 
 	idx = find_first_zero_bit(dev->event_map.lpi_map,
 				  dev->event_map.nr_lpis);
-	if (idx == dev->event_map.nr_lpis)
+	if (idx == dev->event_map.nr_lpis || idx == dev->nr_ites)
 		return -ENOSPC;
 
 	*hwirq = dev->event_map.lpi_base + idx;
-- 
2.11.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ