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-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200117001706.40620-1-jiaxun.yang@flygoat.com>
Date:   Fri, 17 Jan 2020 08:17:05 +0800
From:   Jiaxun Yang <jiaxun.yang@...goat.com>
To:     linux-mips@...r.kernel.org
Cc:     chenhc@...ote.com, paul.burton@...s.com,
        linux-kernel@...r.kernel.org, maz@...nel.org, tglx@...utronix.de,
        Jiaxun Yang <jiaxun.yang@...goat.com>
Subject: [PATCH v1 1/2] genirq: Check for level based percpu irq

MIPS processors implemented their IPI IRQ and CPU interrupt line
as level triggered IRQ. However, our current percpu_irq flow is trying
do it in a level triggered manner.

Thus we attempt to determine whether it is or not level triggered type by
checking if both ack and eoi operation not exist. And handle it in
mask/unmask way.

Signed-off-by: Jiaxun Yang <jiaxun.yang@...goat.com>
---
 kernel/irq/chip.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index b3fa2d87d2f3..4fafe572d022 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -893,6 +893,7 @@ void handle_edge_eoi_irq(struct irq_desc *desc)
 void handle_percpu_irq(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
+	bool is_level = !chip->irq_ack && !chip->irq_eoi;
 
 	/*
 	 * PER CPU interrupts are not serialized. Do not touch
@@ -900,12 +901,16 @@ void handle_percpu_irq(struct irq_desc *desc)
 	 */
 	__kstat_incr_irqs_this_cpu(desc);
 
-	if (chip->irq_ack)
+	if (is_level)
+		chip->irq_mask(&desc->irq_data);
+	else if (chip->irq_ack)
 		chip->irq_ack(&desc->irq_data);
 
 	handle_irq_event_percpu(desc);
 
-	if (chip->irq_eoi)
+	if (is_level)
+		chip->irq_unmask(&desc->irq_data);
+	else if (chip->irq_eoi)
 		chip->irq_eoi(&desc->irq_data);
 }
 
@@ -925,6 +930,7 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct irqaction *action = desc->action;
 	unsigned int irq = irq_desc_get_irq(desc);
+	bool is_level = !chip->irq_ack && !chip->irq_eoi;
 	irqreturn_t res;
 
 	/*
@@ -933,7 +939,9 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
 	 */
 	__kstat_incr_irqs_this_cpu(desc);
 
-	if (chip->irq_ack)
+	if (is_level)
+		chip->irq_mask(&desc->irq_data);
+	else if (chip->irq_ack)
 		chip->irq_ack(&desc->irq_data);
 
 	if (likely(action)) {
@@ -951,7 +959,9 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
 			    enabled ? " and unmasked" : "", irq, cpu);
 	}
 
-	if (chip->irq_eoi)
+	if (is_level)
+		chip->irq_unmask(&desc->irq_data);
+	else if (chip->irq_eoi)
 		chip->irq_eoi(&desc->irq_data);
 }
 
-- 
2.24.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ