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>] [thread-next>] [day] [month] [year] [list]
Message-ID: <ZtUuYXSq8g2Mphuq@den-build>
Date: Mon, 2 Sep 2024 11:17:53 +0800
From: Richard Clark <richard.xnu.clark@...il.com>
To: tglx@...utronix.de
Cc: linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
	torvalds@...ux-foundation.org, richard.xnu.clark@...il.com
Subject: [PATCH] irq: fix the interrupt trigger type override issue

In current implementation, the trigger type in 'flags' when calling request_irq
will override the type value get from the firmware(dt/acpi node) if they are
not consistent, and the overrided trigger type value will be retained by irq_data,
consequently the type value get from the firmware will not match the retained one
next time in case the virq is available.

Thus below error message will be observed by the __2nd__ 'insmod' within the
'insmod - rmmod - insmod' operation sequence for the same device driver kernel
module, in which request_irq(..., IRQ_TYPE_LEVEL_HIGH, ...) is used:

	irq: type mismatch, failed to map hwirq-182 for interrupt-controller!

The corresponding 'interrupts' property of that device node is:
	interrupts = <0 150 1>;

This commit fixes the above issue by adding a new checker - irqd_trigger_type_was_set:
the irq_create_fwspec_mapping(...) will return the interrupt number directly if the
trigger type has been set previously.

Signed-off-by: Richard Clark <richard.xnu.clark@...il.com>
---
 kernel/irq/irqdomain.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index cea8f6874b1f..fb0be8e73c5b 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -895,25 +895,25 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
 	 */
 	virq = irq_find_mapping(domain, hwirq);
 	if (virq) {
+		irq_data = irq_get_irq_data(virq);
+		if (!irq_data) {
+			virq = 0;
+			goto out;
+		}
+
 		/*
 		 * If the trigger type is not specified or matches the
-		 * current trigger type then we are done so return the
-		 * interrupt number.
+		 * current trigger type or has been set previously then we are done so
+		 * return the interrupt number.
 		 */
-		if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq))
+		if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq) ||
+		    irqd_trigger_type_was_set(irq_data))
 			goto out;
-
 		/*
 		 * If the trigger type has not been set yet, then set
 		 * it now and return the interrupt number.
 		 */
 		if (irq_get_trigger_type(virq) == IRQ_TYPE_NONE) {
-			irq_data = irq_get_irq_data(virq);
-			if (!irq_data) {
-				virq = 0;
-				goto out;
-			}
-
 			irqd_set_trigger_type(irq_data, type);
 			goto out;
 		}
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ