Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

of: unittest: Add a case to test if API of_irq_parse_raw() leaks refcount

To test if of_irq_parse_raw(), invoked by of_irq_parse_one(), will leak
refcount of interrupt combo node consisting of controller and nexus.

Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
Link: https://lore.kernel.org/r/20250209-of_irq_fix-v2-3-93e3a2659aa7@quicinc.com
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>

authored by

Zijun Hu and committed by
Rob Herring (Arm)
f8647991 0cb58d6c

+36 -1
+13
drivers/of/unittest-data/tests-interrupts.dtsi
··· 50 50 interrupt-map = <0x5000 1 2 &test_intc0 15>; 51 51 }; 52 52 53 + test_intc_intmap0: intc-intmap0 { 54 + #interrupt-cells = <1>; 55 + #address-cells = <1>; 56 + interrupt-controller; 57 + interrupt-map = <0x6000 1 &test_intc_intmap0 0x7000 2>; 58 + }; 59 + 53 60 interrupts0 { 54 61 interrupt-parent = <&test_intc0>; 55 62 interrupts = <1>, <2>, <3>, <4>; ··· 65 58 interrupts1 { 66 59 interrupt-parent = <&test_intmap0>; 67 60 interrupts = <1>, <2>, <3>, <4>; 61 + }; 62 + 63 + interrupts2 { 64 + reg = <0x6000 0x100>; 65 + interrupt-parent = <&test_intc_intmap0>; 66 + interrupts = <1>; 68 67 }; 69 68 70 69 interrupts-extended0 {
+23 -1
drivers/of/unittest.c
··· 1659 1659 { 1660 1660 struct of_phandle_args args; 1661 1661 struct device_node *intc0, *int_ext0; 1662 + struct device_node *int2, *intc_intmap0; 1662 1663 unsigned int ref_c0, ref_c1, ref_c2; 1663 1664 int rc; 1664 1665 bool passed; ··· 1669 1668 1670 1669 intc0 = of_find_node_by_path("/testcase-data/interrupts/intc0"); 1671 1670 int_ext0 = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); 1672 - if (!intc0 || !int_ext0) { 1671 + intc_intmap0 = of_find_node_by_path("/testcase-data/interrupts/intc-intmap0"); 1672 + int2 = of_find_node_by_path("/testcase-data/interrupts/interrupts2"); 1673 + if (!intc0 || !int_ext0 || !intc_intmap0 || !int2) { 1673 1674 pr_err("missing testcase data\n"); 1674 1675 goto out; 1675 1676 } ··· 1693 1690 unittest(passed, "IRQ refcount case #1 failed, original(%u) expected(%u) got(%u)\n", 1694 1691 ref_c0, ref_c1, ref_c2); 1695 1692 1693 + /* Test refcount for API of_irq_parse_raw() */ 1694 + passed = true; 1695 + ref_c0 = OF_KREF_READ(intc_intmap0); 1696 + ref_c1 = ref_c0 + 1; 1697 + memset(&args, 0, sizeof(args)); 1698 + rc = of_irq_parse_one(int2, 0, &args); 1699 + ref_c2 = OF_KREF_READ(intc_intmap0); 1700 + of_node_put(args.np); 1701 + 1702 + passed &= !rc; 1703 + passed &= (args.np == intc_intmap0); 1704 + passed &= (args.args_count == 1); 1705 + passed &= (args.args[0] == 2); 1706 + passed &= (ref_c1 == ref_c2); 1707 + unittest(passed, "IRQ refcount case #2 failed, original(%u) expected(%u) got(%u)\n", 1708 + ref_c0, ref_c1, ref_c2); 1709 + 1696 1710 out: 1711 + of_node_put(int2); 1712 + of_node_put(intc_intmap0); 1697 1713 of_node_put(int_ext0); 1698 1714 of_node_put(intc0); 1699 1715 }