From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Paul Burton <paul.burton@imgtec.com>,
linux-mips@linux-mips.org, Jason Cooper <jason@lakedaemon.net>,
Qais Yousef <qsyousef@gmail.com>,
Marc Zyngier <marc.zyngier@arm.com>,
Thomas Gleixner <tglx@linutronix.de>
Subject: [PATCH 4.7 40/69] irqchip/mips-gic: Fix local interrupts
Date: Wed, 28 Sep 2016 11:05:22 +0200 [thread overview]
Message-ID: <20160928090446.748458443@linuxfoundation.org> (raw)
In-Reply-To: <20160928090445.054716307@linuxfoundation.org>
4.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Burton <paul.burton@imgtec.com>
commit e875bd66dfb68f4e898e9a43ef42858c504a7f23 upstream.
Since the device hierarchy domain was added by commit c98c1822ee13
("irqchip/mips-gic: Add device hierarchy domain"), GIC local interrupts
have been broken.
Users attempting to setup a per-cpu local IRQ, for example the GIC timer
clock events code in drivers/clocksource/mips-gic-timer.c, the
setup_percpu_irq function would refuse with -EINVAL because the GIC
irqchip driver never called irq_set_percpu_devid so the
IRQ_PER_CPU_DEVID flag was never set for the IRQ. This happens because
irq_set_percpu_devid was being called from the gic_irq_domain_map
function which is no longer called.
Doing only that runs into further problems because gic_dev_domain_alloc
set the struct irq_chip for all interrupts, local or shared, to
gic_level_irq_controller despite that only being suitable for shared
interrupts. The typical outcome of this is that gic_level_irq_controller
callback functions are called for local interrupts, and then hwirq
number calculations overflow & the driver ends up attempting to access
some invalid register with an address calculated from an invalid hwirq
number. Best case scenario is that this then leads to a bus error. This
is fixed by abstracting the setup of the hwirq & chip to a new function
gic_setup_dev_chip which is used by both the root GIC IRQ domain & the
device domain.
Finally, decoding local interrupts failed because gic_dev_domain_alloc
only called irq_domain_alloc_irqs_parent for shared interrupts. Local
ones were therefore never associated with hwirqs in the root GIC IRQ
domain and the virq in gic_handle_local_int would always be 0. This is
fixed by calling irq_domain_alloc_irqs_parent unconditionally & having
gic_irq_domain_alloc handle both local & shared interrupts, which is
easy due to the aforementioned abstraction of chip setup into
gic_setup_dev_chip.
This fixes use of the MIPS GIC timer for clock events, which has been
broken since c98c1822ee13 ("irqchip/mips-gic: Add device hierarchy
domain") but hadn't been noticed due to a silent fallback to the MIPS
coprocessor 0 count/compare clock events device.
Fixes: c98c1822ee13 ("irqchip/mips-gic: Add device hierarchy domain")
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Qais Yousef <qsyousef@gmail.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Link: http://lkml.kernel.org/r/20160913165335.31389-1-paul.burton@imgtec.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/irqchip/irq-mips-gic.c | 105 +++++++++++++++++++----------------------
1 file changed, 50 insertions(+), 55 deletions(-)
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -638,27 +638,6 @@ static int gic_local_irq_domain_map(stru
if (!gic_local_irq_is_routable(intr))
return -EPERM;
- /*
- * HACK: These are all really percpu interrupts, but the rest
- * of the MIPS kernel code does not use the percpu IRQ API for
- * the CP0 timer and performance counter interrupts.
- */
- switch (intr) {
- case GIC_LOCAL_INT_TIMER:
- case GIC_LOCAL_INT_PERFCTR:
- case GIC_LOCAL_INT_FDC:
- irq_set_chip_and_handler(virq,
- &gic_all_vpes_local_irq_controller,
- handle_percpu_irq);
- break;
- default:
- irq_set_chip_and_handler(virq,
- &gic_local_irq_controller,
- handle_percpu_devid_irq);
- irq_set_percpu_devid(virq);
- break;
- }
-
spin_lock_irqsave(&gic_lock, flags);
for (i = 0; i < gic_vpes; i++) {
u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin;
@@ -724,16 +703,42 @@ static int gic_shared_irq_domain_map(str
return 0;
}
-static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
- irq_hw_number_t hw)
+static int gic_setup_dev_chip(struct irq_domain *d, unsigned int virq,
+ unsigned int hwirq)
{
- if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS)
- return gic_local_irq_domain_map(d, virq, hw);
+ struct irq_chip *chip;
+ int err;
- irq_set_chip_and_handler(virq, &gic_level_irq_controller,
- handle_level_irq);
+ if (hwirq >= GIC_SHARED_HWIRQ_BASE) {
+ err = irq_domain_set_hwirq_and_chip(d, virq, hwirq,
+ &gic_level_irq_controller,
+ NULL);
+ } else {
+ switch (GIC_HWIRQ_TO_LOCAL(hwirq)) {
+ case GIC_LOCAL_INT_TIMER:
+ case GIC_LOCAL_INT_PERFCTR:
+ case GIC_LOCAL_INT_FDC:
+ /*
+ * HACK: These are all really percpu interrupts, but
+ * the rest of the MIPS kernel code does not use the
+ * percpu IRQ API for them.
+ */
+ chip = &gic_all_vpes_local_irq_controller;
+ irq_set_handler(virq, handle_percpu_irq);
+ break;
+
+ default:
+ chip = &gic_local_irq_controller;
+ irq_set_handler(virq, handle_percpu_devid_irq);
+ irq_set_percpu_devid(virq);
+ break;
+ }
- return gic_shared_irq_domain_map(d, virq, hw, 0);
+ err = irq_domain_set_hwirq_and_chip(d, virq, hwirq,
+ chip, NULL);
+ }
+
+ return err;
}
static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
@@ -744,15 +749,12 @@ static int gic_irq_domain_alloc(struct i
int cpu, ret, i;
if (spec->type == GIC_DEVICE) {
- /* verify that it doesn't conflict with an IPI irq */
- if (test_bit(spec->hwirq, ipi_resrv))
+ /* verify that shared irqs don't conflict with an IPI irq */
+ if ((spec->hwirq >= GIC_SHARED_HWIRQ_BASE) &&
+ test_bit(GIC_HWIRQ_TO_SHARED(spec->hwirq), ipi_resrv))
return -EBUSY;
- hwirq = GIC_SHARED_TO_HWIRQ(spec->hwirq);
-
- return irq_domain_set_hwirq_and_chip(d, virq, hwirq,
- &gic_level_irq_controller,
- NULL);
+ return gic_setup_dev_chip(d, virq, spec->hwirq);
} else {
base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs);
if (base_hwirq == gic_shared_intrs) {
@@ -821,7 +823,6 @@ int gic_irq_domain_match(struct irq_doma
}
static const struct irq_domain_ops gic_irq_domain_ops = {
- .map = gic_irq_domain_map,
.alloc = gic_irq_domain_alloc,
.free = gic_irq_domain_free,
.match = gic_irq_domain_match,
@@ -852,29 +853,20 @@ static int gic_dev_domain_alloc(struct i
struct irq_fwspec *fwspec = arg;
struct gic_irq_spec spec = {
.type = GIC_DEVICE,
- .hwirq = fwspec->param[1],
};
int i, ret;
- bool is_shared = fwspec->param[0] == GIC_SHARED;
-
- if (is_shared) {
- ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec);
- if (ret)
- return ret;
- }
- for (i = 0; i < nr_irqs; i++) {
- irq_hw_number_t hwirq;
+ if (fwspec->param[0] == GIC_SHARED)
+ spec.hwirq = GIC_SHARED_TO_HWIRQ(fwspec->param[1]);
+ else
+ spec.hwirq = GIC_LOCAL_TO_HWIRQ(fwspec->param[1]);
- if (is_shared)
- hwirq = GIC_SHARED_TO_HWIRQ(spec.hwirq + i);
- else
- hwirq = GIC_LOCAL_TO_HWIRQ(spec.hwirq + i);
+ ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, &spec);
+ if (ret)
+ return ret;
- ret = irq_domain_set_hwirq_and_chip(d, virq + i,
- hwirq,
- &gic_level_irq_controller,
- NULL);
+ for (i = 0; i < nr_irqs; i++) {
+ ret = gic_setup_dev_chip(d, virq + i, spec.hwirq + i);
if (ret)
goto error;
}
@@ -896,7 +888,10 @@ void gic_dev_domain_free(struct irq_doma
static void gic_dev_domain_activate(struct irq_domain *domain,
struct irq_data *d)
{
- gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0);
+ if (GIC_HWIRQ_TO_LOCAL(d->hwirq) < GIC_NUM_LOCAL_INTRS)
+ gic_local_irq_domain_map(domain, d->irq, d->hwirq);
+ else
+ gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0);
}
static struct irq_domain_ops gic_dev_domain_ops = {
next prev parent reply other threads:[~2016-09-28 9:14 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20160928090645uscas1p25d8333ed85efe1cdd54dcaecedfc3b84@uscas1p2.samsung.com>
2016-09-28 9:04 ` [PATCH 4.7 00/69] 4.7.6-stable review Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 01/69] reiserfs: fix "new_insert_key may be used uninitialized ..." Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 02/69] crypto: arm64/aes-ctr - fix NULL dereference in tail processing Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 03/69] crypto: arm/aes-ctr " Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 04/69] crypto: skcipher - Fix blkcipher walk OOM crash Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 05/69] crypto: echainiv - Replace chaining with multiplication Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 06/69] ocfs2/dlm: fix race between convert and migration Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 07/69] ocfs2: fix start offset to ocfs2_zero_range_for_truncate() Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 08/69] Revert "ocfs2: bump up o2cb network protocol version" Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 09/69] autofs: use dentry flags to block walks during expire Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 10/69] Disable "maybe-uninitialized" warning globally Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 12/69] Makefile: Mute warning for __builtin_return_address(>0) for tracing only Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 13/69] xfs: prevent dropping ioend completions during buftarg wait Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 14/69] mm: fix the page_swap_info() BUG_ON check Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 15/69] fsnotify: add a way to stop queueing events on group shutdown Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 16/69] fanotify: fix list corruption in fanotify_get_response() Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.7 17/69] mm: memcontrol: make per-cpu charge cache IRQ-safe for socket accounting Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 18/69] cgroup: duplicate cgroup reference when cloning sockets Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 19/69] fix fault_in_multipages_...() on architectures with no-op access_ok() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 20/69] KEYS: Fix skcipher IV clobbering Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 21/69] arm64: Call numa_store_cpu_info() earlier Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 22/69] configfs: Return -EFBIG from configfs_write_bin_file Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 24/69] mtd: maps: sa1100-flash: potential NULL dereference Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 25/69] mtd: pmcmsp-flash: Allocating too much in init_msp_flash() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 26/69] mtd: spi-nor: fix wrong "fully unlocked" test Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 27/69] reset: Return -ENOTSUPP when not configured Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 28/69] rtc: ds1307: Fix relying on reset value for weekday Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 29/69] power: reset: hisi-reboot: Unmap region obtained by of_iomap Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 30/69] mac80211: reject TSPEC TIDs (TSIDs) for aggregation Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 31/69] fix memory leaks in tracing_buffers_splice_read() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 32/69] tracing: Move mutex to protect against resetting of seq data Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 33/69] mm: delete unnecessary and unsafe init_tlb_ubc() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 34/69] can: flexcan: fix resume function Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 35/69] net: can: ifi: Configure transmitter delay Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 36/69] iwlwifi: mvm: update TX queue before making a copy of the skb Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 37/69] nl80211: validate number of probe response CSA counters Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 38/69] btrfs: ensure that file descriptor used with subvol ioctls is a dir Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 39/69] x86/efi: Only map RAM into EFI page tables if in mixed-mode Greg Kroah-Hartman
2016-09-28 9:05 ` Greg Kroah-Hartman [this message]
2016-09-28 9:05 ` [PATCH 4.7 41/69] i2c-eg20t: fix race between i2c init and interrupt enable Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 42/69] i2c: mux: pca954x: retry updating the mux selection on failure Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 43/69] i2c: qup: skip qup_i2c_suspend if the device is already runtime suspended Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 44/69] MIPS: Fix pre-r6 emulation FPU initialisation Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 45/69] MIPS: SMP: Fix possibility of deadlock when bringing CPUs online Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 46/69] MIPS: vDSO: Fix Malta EVA mapping to vDSO page structs Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 47/69] MIPS: Remove compact branch policy Kconfig entries Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 48/69] MIPS: Avoid a BUG warning during prctl(PR_SET_FP_MODE, ...) Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 49/69] MIPS: Add a missing ".set pop" in an early commit Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 50/69] MIPS: paravirt: Fix undefined reference to smp_bootstrap Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 51/69] x86/mm/pat: Prevent hang during boot when mapping pages Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 52/69] libceph: add an ONSTACK initializer for oids Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 53/69] ceph: fix symbol versioning for ceph_monc_do_statfs Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 54/69] ceph: Correctly return NXIO errors from ceph_llseek Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 55/69] libceph: fix return value check in alloc_msg_with_page_vector() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 56/69] PM / hibernate: Restore processor state before using per-CPU variables Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 57/69] PM / hibernate: Fix rtree_next_node() to avoid walking off list ends Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 58/69] power_supply: tps65217-charger: fix missing platform_set_drvdata() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 59/69] power: supply: max17042_battery: fix model download bug Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 60/69] ixgbe: Force VLNCTRL.VFE to be set in all VMDq paths Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 61/69] ixgbe: Re-enable ability to toggle VLAN filtering Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 62/69] igb: fix adjusting PTP timestamps for Tx/Rx latency Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 63/69] soc/tegra: pmc: Dont probe PMC if early initialisation fails Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 64/69] qxl: check for kmap failures Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 65/69] hostfs: Freeing an ERR_PTR in hostfs_fill_sb_common() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 66/69] kasan: avoid overflowing quarantine size on low memory systems Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 67/69] mm/kasan: dont reduce quarantine in atomic contexts Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.7 68/69] iw_cxgb4: stop MPA_REPLY timer when disconnecting Greg Kroah-Hartman
2016-09-28 16:46 ` [PATCH 4.7 00/69] 4.7.6-stable review Shuah Khan
2016-09-29 9:00 ` Greg Kroah-Hartman
2016-09-28 22:44 ` Guenter Roeck
2016-09-29 9:00 ` Greg Kroah-Hartman
[not found] ` <57ec0654.4756c20a.c7ddf.48d1@mx.google.com>
[not found] ` <7ha8erru8h.fsf@baylibre.com>
2016-09-29 8:33 ` Greg Kroah-Hartman
2016-09-29 14:46 ` Kevin Hilman
2016-09-29 15:26 ` Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160928090446.748458443@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=jason@lakedaemon.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@linux-mips.org \
--cc=marc.zyngier@arm.com \
--cc=paul.burton@imgtec.com \
--cc=qsyousef@gmail.com \
--cc=stable@vger.kernel.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.