Using irq_domain_free_irqs_common() on the irqdomain free path will
leave the MSI descriptor unfreed when platform devices get removed.
Properly free it by MSI domain free function.
Fixes: 9650c60ebf ("irqchip/mbigen: Create irq domain for each mbigen device")
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20200408114352.1604-1-yuzenghui@huawei.com
The following crash can be seen for setting
CONFIG_DEBUG_TEST_DRIVER_REMOVE=y for DT FW (which some people still use):
Hisilicon MBIGEN-V2 60080000.interrupt-controller: Failed to create mbi-gen irqdomain
Hisilicon MBIGEN-V2: probe of 60080000.interrupt-controller failed with error -12
[...]
Unable to handle kernel paging request at virtual address 0000000000005008
Mem abort info:
ESR = 0x96000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=0000041fb9990000
[0000000000005008] pgd=0000000000000000
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 7 PID: 1 Comm: swapper/0 Not tainted 5.5.0-rc6-00002-g3fc42638a506-dirty #1622
Hardware name: Huawei Taishan 2280 /D05, BIOS Hisilicon D05 IT21 Nemo 2.0 RC0 04/18/2018
pstate: 40000085 (nZcv daIf -PAN -UAO)
pc : mbigen_set_type+0x38/0x60
lr : __irq_set_trigger+0x6c/0x188
sp : ffff800014b4b400
x29: ffff800014b4b400 x28: 0000000000000007
x27: 0000000000000000 x26: 0000000000000000
x25: ffff041fd83bd0d4 x24: ffff041fd83bd188
x23: 0000000000000000 x22: ffff80001193ce00
x21: 0000000000000004 x20: 0000000000000000
x19: ffff041fd83bd000 x18: ffffffffffffffff
x17: 0000000000000000 x16: 0000000000000000
x15: ffff8000119098c8 x14: ffff041fb94ec91c
x13: ffff041fb94ec1a1 x12: 0000000000000030
x11: 0101010101010101 x10: 0000000000000040
x9 : 0000000000000000 x8 : ffff041fb98c6680
x7 : ffff800014b4b380 x6 : ffff041fd81636c8
x5 : 0000000000000000 x4 : 000000000000025f
x3 : 0000000000005000 x2 : 0000000000005008
x1 : 0000000000000004 x0 : 0000000080000000
Call trace:
mbigen_set_type+0x38/0x60
__setup_irq+0x744/0x900
request_threaded_irq+0xe0/0x198
pcie_pme_probe+0x98/0x118
pcie_port_probe_service+0x38/0x78
really_probe+0xa0/0x3e0
driver_probe_device+0x58/0x100
__device_attach_driver+0x90/0xb0
bus_for_each_drv+0x64/0xc8
__device_attach+0xd8/0x138
device_initial_probe+0x10/0x18
bus_probe_device+0x90/0x98
device_add+0x4c4/0x770
device_register+0x1c/0x28
pcie_port_device_register+0x1e4/0x4f0
pcie_portdrv_probe+0x34/0xd8
local_pci_probe+0x3c/0xa0
pci_device_probe+0x128/0x1c0
really_probe+0xa0/0x3e0
driver_probe_device+0x58/0x100
__device_attach_driver+0x90/0xb0
bus_for_each_drv+0x64/0xc8
__device_attach+0xd8/0x138
device_attach+0x10/0x18
pci_bus_add_device+0x4c/0xb8
pci_bus_add_devices+0x38/0x88
pci_host_probe+0x3c/0xc0
pci_host_common_probe+0xf0/0x208
hisi_pcie_almost_ecam_probe+0x24/0x30
platform_drv_probe+0x50/0xa0
really_probe+0xa0/0x3e0
driver_probe_device+0x58/0x100
device_driver_attach+0x6c/0x90
__driver_attach+0x84/0xc8
bus_for_each_dev+0x74/0xc8
driver_attach+0x20/0x28
bus_add_driver+0x148/0x1f0
driver_register+0x60/0x110
__platform_driver_register+0x40/0x48
hisi_pcie_almost_ecam_driver_init+0x1c/0x24
The specific problem here is that the mbigen driver real probe has failed
as the mbigen_of_create_domain()->of_platform_device_create() call fails,
the reason for that being that we never destroyed the platform device
created during the remove test dry run and there is some conflict.
Since we generally would never want to unbind this driver, and to save
adding a driver tear down path for that, just set the driver
.suppress_bind_attrs member to avoid this possibility.
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Link: https://lore.kernel.org/r/1579196323-180137-1-git-send-email-john.garry@huawei.com
- Fix a couple of UAF on error paths (RZA1, GICv3 ITS)
- Fix iMX GPCv2 trigger setting
- Add missing of_node_put on error path in MBIGEN
- Add another bunch of /* fall-through */ to silence warnings
-----BEGIN PGP SIGNATURE-----
iQJDBAABCgAtFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAl1B0ysPHG1hekBrZXJu
ZWwub3JnAAoJECPQ0LrRPXpDEq0P/19TlvVhBzRBQ7xrZsh7RYGYddgHZeYxEwcJ
iZaZnEwYPqrQXS7UIOyMmpdhDOE89sntgCfQWWhPqZdVMAPPAanucbcIA9vNxy+U
OI9ue90Eeo5MAm7T2qp3MgEROQ21npYeTNGPHM6Rhh3twbsLX5S7rQCOZBeuY1zT
l9FGOUsUgYfUgdEGAv4wZLdIakfTbwAlk+9QaryEn7leu4s/vzHIdyMmJ/RDlt/i
YPWFD4XfDV8WSE0CE88oy1T4ppD8e71C6LjS+NfJsY5brUGPDvcbllCm3tFudy/9
D/4kM6yjpNIGZK23p5ux8dBTZB/9+z/PadFJc6J78cFH+IMf2Clv40GrZ50cG8MK
GIDBgwGmooUU+vsmTTPeqtEn30CIyVGb1AkoZnTR/vRltsg0zaLhuqIHnhLTo5av
dEeTv1sBOcPR3b4NkX4WAHd5UJrF/a3/fSdW9h95rF/xlP3fto5lhRmtI9UOqlra
1X+GJXRWoEbMvLP75PlSOQkDiG8zKko9/5JX/da5Q0Qztl/gZPFaGexL/c36DLoJ
kKuHut/1TXu3xfoGPotYm8mainSHkEF1OThCOWX6sjS4m9JMYZMejjg9l1pNXfKw
lZVKKygYOwOeBubsYqmVOEliFai2EggSWmq77csu5FP84M/8JNRX+69yQLO0Cwea
ukYEvrvA
=oXHS
-----END PGP SIGNATURE-----
Merge tag 'irqchip-fixes-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent
Pull irqchip fixes from Marc Zyngier:
A small bunch of fixes from the irqchip department:
- Fix a couple of UAF on error paths (RZA1, GICv3 ITS)
- Fix iMX GPCv2 trigger setting
- Add missing of_node_put on error path in MBIGEN
- Add another bunch of /* fall-through */ to silence warnings
Each iteration of for_each_child_of_node puts the previous node, but
in the case of a return from the middle of the loop, there is no put,
thus causing a memory leak. Add an of_node_put before the return in
three places.
Issue found with Coccinelle.
Signed-off-by: Nishka Dasgupta <nishkadg.linux@gmail.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Pull irq updates from Thomas Gleixner:
"The irq departement provides the usual mixed bag:
Core:
- Further improvements to the irq timings code which aims to predict
the next interrupt for power state selection to achieve better
latency/power balance
- Add interrupt statistics to the core NMI handlers
- The usual small fixes and cleanups
Drivers:
- Support for Renesas RZ/A1, Annapurna Labs FIC, Meson-G12A SoC and
Amazon Gravition AMR/GIC interrupt controllers.
- Rework of the Renesas INTC controller driver
- ACPI support for Socionext SoCs
- Enhancements to the CSKY interrupt controller
- The usual small fixes and cleanups"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (39 commits)
irq/irqdomain: Fix comment typo
genirq: Update irq stats from NMI handlers
irqchip/gic-pm: Remove PM_CLK dependency
irqchip/al-fic: Introduce Amazon's Annapurna Labs Fabric Interrupt Controller Driver
dt-bindings: interrupt-controller: Add Amazon's Annapurna Labs FIC
softirq: Use __this_cpu_write() in takeover_tasklets()
irqchip/mbigen: Stop printing kernel addresses
irqchip/gic: Add dependency for ARM_GIC_MAX_NR
genirq/affinity: Remove unused argument from [__]irq_build_affinity_masks()
genirq/timings: Add selftest for next event computation
genirq/timings: Add selftest for irqs circular buffer
genirq/timings: Add selftest for circular array
genirq/timings: Encapsulate storing function
genirq/timings: Encapsulate timings push
genirq/timings: Optimize the period detection speed
genirq/timings: Fix timings buffer inspection
genirq/timings: Fix next event index function
irqchip/qcom: Use struct_size() in devm_kzalloc()
irqchip/irq-csky-mpintc: Remove unnecessary loop in interrupt handler
dt-bindings: interrupt-controller: Update csky mpintc
...
Based on 1 normalized pattern(s):
this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license version 2 as
published by the free software foundation this program is
distributed in the hope that it will be useful but without any
warranty without even the implied warranty of merchantability or
fitness for a particular purpose see the gnu general public license
for more details you should have received a copy of the gnu general
public license along with this program if not see http www gnu org
licenses
extracted by the scancode license scanner the SPDX license identifier
GPL-2.0-only
has been chosen to replace the boilerplate/reference in 503 file(s).
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Alexios Zavras <alexios.zavras@intel.com>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Enrico Weigelt <info@metux.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190602204653.811534538@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
After commit ad67b74d24 ("printk: hash addresses printed with %p"),
it will print "____ptrval____" instead of actual addresses when mbigen
create domain fails,
Hisilicon MBIGEN-V2 HISI0152:00: Failed to create mbi-gen@(____ptrval____) irqdomain
Hisilicon MBIGEN-V2: probe of HISI0152:00 failed with error -12
dev_xxx() helper contains the device info, HISI0152:00, which stands for
mbigen ACPI HID and its UID, we can identify the failing probed mbigen,
so just remove the printing "mgn_chip->base", and also add missing "\n".
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
mbigen_write_msg clears eventid bits of a mbigen register
when free a interrupt, because msi_domain_deactivate memset
struct msg to zero. Then multiple mbigen pins with zero eventid
will report the same interrupt number.
The eventid clear call trace:
free_irq
__free_irq
irq_shutdown
irq_domain_deactivate_irq
__irq_domain_deactivate_irq
__irq_domain_deactivate_irq
msi_domain_deactivate
platform_msi_write_msg
mbigen_write_msg
Signed-off-by: Jianguo Chen <chenjianguo3@huawei.com>
[maz: massaged subject]
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
struct irq_domain_ops is not modified, so it can be made const.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
The register array offset for clearing an interrupt is calculated by:
offset = (hwirq - RESERVED_IRQ_PER_MBIGEN_CHIP) / 32;
This is wrong because the clear register array includes the reserved
interrupts. So the clear operation ends up in the wrong register.
This went unnoticed so far, because the hardware clears the real bit
through a timeout mechanism when the hardware is configured in debug
mode. That debug mode was enabled on early generations of the hardware, so
the problem was papered over.
On newer hardware with updated firmware the debug mode was disabled, so the
bits did not get cleared which causes the system to malfunction.
Remove the subtraction of RESERVED_IRQ_PER_MBIGEN_CHIP, so the correct
register is accessed.
[ tglx: Rewrote changelog ]
Fixes: a6c2f87b88 ("irqchip/mbigen: Implement the mbigen irq chip operation functions")
Signed-off-by: MaJun <majun258@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: linuxarm@huawei.com
Cc: Wei Yongjun <weiyongjun1@huawei.com>
Link: http://lkml.kernel.org/r/1494561328-39514-4-git-send-email-guohanjun@huawei.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Some mbigens share memory regions, and devm_ioremap_resource
does not allow to share resources which will break the probe
of mbigen, in opposition to devm_ioremap.
This patch restores back usage of devm_ioremap function, but
with proper error handling and logging.
Fixes: 216646e4d8 ("irqchip/mbigen: Fix return value check in mbigen_device_probe()")
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: linuxarm@huawei.com
Cc: Wei Yongjun <weiyongjun1@huawei.com>
Cc: MaJun <majun258@huawei.com>
Link: http://lkml.kernel.org/r/1494561328-39514-2-git-send-email-guohanjun@huawei.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
In case of error, the function devm_ioremap() returns NULL pointer
not ERR_PTR(). Use devm_ioremap_resource() instead of devm_ioremap()
to fix the IS_ERR() test issue.
Fixes: 76e1f77f9c ("irqchip/mbigen: Introduce mbigen_of_create_domain()")
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Link: http://lkml.kernel.org/r/20170427152113.31147-1-weiyj.lk@gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
With the preparation of platform msi support and interrupt producer
in commit d44fa3d460 ("ACPI: Add support for ResourceSource/IRQ
domain mapping"), we can add mbigen ACPI support now.
Now that the major framework changes are ready, we just need to add
the ACPI probe code which creates the irqdomain for devices connecting
to it.
In order to create the irqdomain, we need to know the number of hw
irqs as input which is provided by mbigen. In DT case, we are using
"num-pins" property to describe it, and we will take advantage of
that too using _DSD in ACPI as there is no standard way of describe
it in ACPI way, also according to the _DSD rule described in
Documentation/acpi/DSD-properties-rules.txt, it doesn't break
the rules.
The DSDT is represented as below:
For mbigen,
Device(MBI0) {
Name(_HID, "HISI0152")
Name(_UID, Zero)
Name(_CRS, ResourceTemplate() {
Memory32Fixed(ReadWrite, 0xa0080000, 0x10000)
})
Name(_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"num-pins", 378}
}
})
}
For devices,
Device(SAS0) {
Name(_HID, "HISIxxxx")
Name(_UID, Zero)
Name(_CRS, ResourceTemplate() {
Memory32Fixed(ReadWrite, 0xb0030000, 0x10000)
Interrupt(ResourceConsumer,..., "\_SB.MBI0") {12, ...}
})
}
So for the devices connected to the mbigen, as we clearly say that
it refers to a specific interrupt controller (mbigen), we can get
the virq from mbigen's irqdomain once it's created successfully.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: MaJun <majun258@huawei.com>
Cc: Al Stone <ahs3@redhat.com>
Cc: Darren Hart <dvhart@infradead.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Introduce mbigen_of_create_domain() to consolidate OF related
code and prepare for ACPI later, no funtional change.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Ma Jun <majun258@huawei.com>
Tested-by: Ming Lei <ming.lei@canonical.com>
Tested-by: Wei Xu <xuwei5@hisilicon.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Module owner will be set by driver core, so drop it.
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Ma Jun <majun258@huawei.com>
Tested-by: Ming Lei <ming.lei@canonical.com>
Tested-by: Wei Xu <xuwei5@hisilicon.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
of_platform_device_create() returns NULL on error, it never returns
error pointers.
Fixes: ed2a1002d2 ('irqchip/mbigen: Handle multiple device nodes in a mbigen module')
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Add the interrupt controller chip operation functions of mbigen chip.
Signed-off-by: Ma Jun <majun258@huawei.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
For peripheral devices which connect to mbigen,mbigen is a interrupt
controller. So, we create irq domain for each mbigen device and add
mbigen irq domain into irq hierarchy structure.
Signed-off-by: Ma Jun <majun258@huawei.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Mbigen means Message Based Interrupt Generator(MBIGEN).
Its a kind of interrupt controller that collects
the interrupts from external devices and generate msi interrupt.
Mbigen is applied to reduce the number of wire connected interrupts.
As the peripherals increasing, the interrupts lines needed is
increasing much, especially on the Arm64 server SOC.
Therefore, the interrupt pin in GIC is not enough to cover so
many peripherals.
Mbigen is designed to fix this problem.
Mbigen chip locates in ITS or outside of ITS.
Mbigen chip hardware structure shows as below:
mbigen chip
|---------------------|-------------------|
mgn_node0 mgn_node1 mgn_node2
| |-------| |-------|------|
dev1 dev1 dev2 dev1 dev3 dev4
Each mbigen chip contains several mbigen nodes.
External devices can connect to mbigen node through wire connecting way.
Because a mbigen node only can support 128 interrupt maximum, depends
on the interrupt lines number of devices, a device can connects to one
more mbigen nodes.
Also, several different devices can connect to a same mbigen node.
When devices triggered interrupt,mbigen chip detects and collects
the interrupts and generates the MBI interrupts by writing the ITS
Translator register.
To simplify mbigen driver,I used a new conception--mbigen device.
Each mbigen device is initialized as a platform device.
Mbigen device presents the parts(register, pin definition etc.) in
mbigen chip corresponding to a peripheral device.
So from software view, the structure likes below
mbigen chip
|---------------------|-----------------|
mbigen device1 mbigen device2 mbigen device3
| | |
dev1 dev2 dev3
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Ma Jun <majun258@huawei.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>