From: kernel test robot <lkp@intel.com>
To: kbuild@lists.01.org
Subject: [avpatel:riscv_aia_v1 16/18] drivers/irqchip/irq-riscv-imsic.c:851 imsic_init() warn: possible memory leak of 'priv'
Date: Thu, 08 Jul 2021 10:48:53 +0800 [thread overview]
Message-ID: <202107081051.Rool3tJA-lkp@intel.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 22201 bytes --]
CC: kbuild-all(a)lists.01.org
CC: linux-kernel(a)vger.kernel.org
TO: Anup Patel <anup.patel@wdc.com>
tree: https://github.com/avpatel/linux.git riscv_aia_v1
head: e4b6f153340e5471c82603f7b08226ba6e2c6249
commit: d180bb1147b8790d605daf66388a2a827806b2ed [16/18] irqchip: Add RISC-V incoming MSI controller driver
:::::: branch date: 23 hours ago
:::::: commit date: 23 hours ago
config: riscv-randconfig-m031-20210707 (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
drivers/irqchip/irq-riscv-imsic.c:851 imsic_init() warn: possible memory leak of 'priv'
vim +/priv +851 drivers/irqchip/irq-riscv-imsic.c
d180bb1147b879 Anup Patel 2021-04-26 826
d180bb1147b879 Anup Patel 2021-04-26 827 static int __init imsic_init(struct device_node *node,
d180bb1147b879 Anup Patel 2021-04-26 828 struct device_node *parent)
d180bb1147b879 Anup Patel 2021-04-26 829 {
d180bb1147b879 Anup Patel 2021-04-26 830 struct resource res;
d180bb1147b879 Anup Patel 2021-04-26 831 phys_addr_t base_addr;
d180bb1147b879 Anup Patel 2021-04-26 832 int rc, nr_parent_irqs;
d180bb1147b879 Anup Patel 2021-04-26 833 struct imsic_mmio *mmio;
d180bb1147b879 Anup Patel 2021-04-26 834 struct imsic_priv *priv;
d180bb1147b879 Anup Patel 2021-04-26 835 struct imsic_handler *handler;
d180bb1147b879 Anup Patel 2021-04-26 836 u32 i, tmp, nr_handlers = 0;
d180bb1147b879 Anup Patel 2021-04-26 837
d180bb1147b879 Anup Patel 2021-04-26 838 if (imsic_init_done) {
d180bb1147b879 Anup Patel 2021-04-26 839 pr_err("%pOFP: already initialized hence ignoring\n", node);
d180bb1147b879 Anup Patel 2021-04-26 840 return -ENODEV;
d180bb1147b879 Anup Patel 2021-04-26 841 }
d180bb1147b879 Anup Patel 2021-04-26 842
d180bb1147b879 Anup Patel 2021-04-26 843 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
d180bb1147b879 Anup Patel 2021-04-26 844 if (!priv)
d180bb1147b879 Anup Patel 2021-04-26 845 return -ENOMEM;
d180bb1147b879 Anup Patel 2021-04-26 846
d180bb1147b879 Anup Patel 2021-04-26 847 /* Find number of parent interrupts */
d180bb1147b879 Anup Patel 2021-04-26 848 nr_parent_irqs = of_irq_count(node);
d180bb1147b879 Anup Patel 2021-04-26 849 if (!nr_parent_irqs) {
d180bb1147b879 Anup Patel 2021-04-26 850 pr_err("%pOFP: no parent irqs available\n", node);
d180bb1147b879 Anup Patel 2021-04-26 @851 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 852 }
d180bb1147b879 Anup Patel 2021-04-26 853
d180bb1147b879 Anup Patel 2021-04-26 854 /* Find number of guest index bits in MSI address */
d180bb1147b879 Anup Patel 2021-04-26 855 rc = of_property_read_u32(node, "imsic,guest-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 856 &priv->guest_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 857 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 858 priv->guest_index_bits = 0;
d180bb1147b879 Anup Patel 2021-04-26 859 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
d180bb1147b879 Anup Patel 2021-04-26 860 if (tmp < priv->guest_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 861 pr_err("%pOFP: guest index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 862 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 863 }
d180bb1147b879 Anup Patel 2021-04-26 864
d180bb1147b879 Anup Patel 2021-04-26 865 /* Find number of HART index bits */
d180bb1147b879 Anup Patel 2021-04-26 866 rc = of_property_read_u32(node, "imsic,hart-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 867 &priv->hart_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 868 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 869 /* Assume default value */
d180bb1147b879 Anup Patel 2021-04-26 870 priv->hart_index_bits = __fls(nr_parent_irqs);
d180bb1147b879 Anup Patel 2021-04-26 871 if (BIT(priv->hart_index_bits) < nr_parent_irqs)
d180bb1147b879 Anup Patel 2021-04-26 872 priv->hart_index_bits++;
d180bb1147b879 Anup Patel 2021-04-26 873 }
d180bb1147b879 Anup Patel 2021-04-26 874 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
d180bb1147b879 Anup Patel 2021-04-26 875 priv->guest_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 876 if (tmp < priv->hart_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 877 pr_err("%pOFP: HART index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 878 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 879 }
d180bb1147b879 Anup Patel 2021-04-26 880
d180bb1147b879 Anup Patel 2021-04-26 881 /* Find number of group index bits */
d180bb1147b879 Anup Patel 2021-04-26 882 rc = of_property_read_u32(node, "imsic,group-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 883 &priv->group_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 884 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 885 priv->group_index_bits = 0;
d180bb1147b879 Anup Patel 2021-04-26 886 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
d180bb1147b879 Anup Patel 2021-04-26 887 priv->guest_index_bits - priv->hart_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 888 if (tmp < priv->group_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 889 pr_err("%pOFP: group index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 890 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 891 }
d180bb1147b879 Anup Patel 2021-04-26 892
d180bb1147b879 Anup Patel 2021-04-26 893 /* Find first bit position of group index */
d180bb1147b879 Anup Patel 2021-04-26 894 tmp = IMSIC_MMIO_PAGE_SHIFT + priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 895 priv->hart_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 896 rc = of_property_read_u32(node, "imsic,group-index-shift",
d180bb1147b879 Anup Patel 2021-04-26 897 &priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 898 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 899 priv->group_index_shift = tmp;
d180bb1147b879 Anup Patel 2021-04-26 900 if (priv->group_index_shift < tmp) {
d180bb1147b879 Anup Patel 2021-04-26 901 pr_err("%pOFP: group index shift too small\n", node);
d180bb1147b879 Anup Patel 2021-04-26 902 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 903 }
d180bb1147b879 Anup Patel 2021-04-26 904 tmp = priv->group_index_bits + priv->group_index_shift - 1;
d180bb1147b879 Anup Patel 2021-04-26 905 if (tmp >= BITS_PER_LONG) {
d180bb1147b879 Anup Patel 2021-04-26 906 pr_err("%pOFP: group index shift too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 907 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 908 }
d180bb1147b879 Anup Patel 2021-04-26 909
d180bb1147b879 Anup Patel 2021-04-26 910 /* Find number of interrupt identities */
d180bb1147b879 Anup Patel 2021-04-26 911 rc = of_property_read_u32(node, "imsic,num-ids", &priv->nr_ids);
d180bb1147b879 Anup Patel 2021-04-26 912 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 913 pr_err("%pOFP: number of interrupt identities not found\n",
d180bb1147b879 Anup Patel 2021-04-26 914 node);
d180bb1147b879 Anup Patel 2021-04-26 915 return rc;
d180bb1147b879 Anup Patel 2021-04-26 916 }
d180bb1147b879 Anup Patel 2021-04-26 917 if ((priv->nr_ids < IMSIC_MIN_ID) ||
d180bb1147b879 Anup Patel 2021-04-26 918 (priv->nr_ids >= IMSIC_MAX_ID) ||
d180bb1147b879 Anup Patel 2021-04-26 919 ((priv->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
d180bb1147b879 Anup Patel 2021-04-26 920 pr_err("%pOFP: invalid number of interrupt identities\n",
d180bb1147b879 Anup Patel 2021-04-26 921 node);
d180bb1147b879 Anup Patel 2021-04-26 922 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 923 }
d180bb1147b879 Anup Patel 2021-04-26 924
d180bb1147b879 Anup Patel 2021-04-26 925 /* Compute base address */
d180bb1147b879 Anup Patel 2021-04-26 926 rc = of_address_to_resource(node, 0, &res);
d180bb1147b879 Anup Patel 2021-04-26 927 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 928 pr_err("%pOFP: first MMIO resource not found\n", node);
d180bb1147b879 Anup Patel 2021-04-26 929 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 930 }
d180bb1147b879 Anup Patel 2021-04-26 931 priv->base_addr = res.start;
d180bb1147b879 Anup Patel 2021-04-26 932 priv->base_addr &= ~(BIT(priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 933 priv->hart_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 934 IMSIC_MMIO_PAGE_SHIFT) - 1);
d180bb1147b879 Anup Patel 2021-04-26 935 priv->base_addr &= ~((BIT(priv->group_index_bits) - 1) <<
d180bb1147b879 Anup Patel 2021-04-26 936 priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 937
d180bb1147b879 Anup Patel 2021-04-26 938 /* Find number of MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 939 while (!of_address_to_resource(node, priv->num_mmios, &res))
d180bb1147b879 Anup Patel 2021-04-26 940 priv->num_mmios++;
d180bb1147b879 Anup Patel 2021-04-26 941
d180bb1147b879 Anup Patel 2021-04-26 942 /* Allocate MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 943 priv->mmios = kcalloc(priv->num_mmios, sizeof(*mmio), GFP_KERNEL);
d180bb1147b879 Anup Patel 2021-04-26 944 if (!priv->mmios) {
d180bb1147b879 Anup Patel 2021-04-26 945 rc = -ENOMEM;
d180bb1147b879 Anup Patel 2021-04-26 946 goto out_free_priv;
d180bb1147b879 Anup Patel 2021-04-26 947 }
d180bb1147b879 Anup Patel 2021-04-26 948
d180bb1147b879 Anup Patel 2021-04-26 949 /* Parse and map MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 950 for (i = 0; i < priv->num_mmios; i++) {
d180bb1147b879 Anup Patel 2021-04-26 951 mmio = &priv->mmios[i];
d180bb1147b879 Anup Patel 2021-04-26 952 rc = of_address_to_resource(node, i, &res);
d180bb1147b879 Anup Patel 2021-04-26 953 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 954 pr_err("%pOFP: unable to parse MMIO regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 955 node, i);
d180bb1147b879 Anup Patel 2021-04-26 956 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 957 }
d180bb1147b879 Anup Patel 2021-04-26 958 mmio->pa = res.start;
d180bb1147b879 Anup Patel 2021-04-26 959 mmio->size = res.end - res.start + 1;
d180bb1147b879 Anup Patel 2021-04-26 960
d180bb1147b879 Anup Patel 2021-04-26 961 base_addr = mmio->pa;
d180bb1147b879 Anup Patel 2021-04-26 962 base_addr &= ~(BIT(priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 963 priv->hart_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 964 IMSIC_MMIO_PAGE_SHIFT) - 1);
d180bb1147b879 Anup Patel 2021-04-26 965 base_addr &= ~((BIT(priv->group_index_bits) - 1) <<
d180bb1147b879 Anup Patel 2021-04-26 966 priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 967 if (base_addr != priv->base_addr) {
d180bb1147b879 Anup Patel 2021-04-26 968 rc = -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 969 pr_err("%pOFP: address mismatch for regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 970 node, i);
d180bb1147b879 Anup Patel 2021-04-26 971 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 972 }
d180bb1147b879 Anup Patel 2021-04-26 973
d180bb1147b879 Anup Patel 2021-04-26 974 tmp = BIT(priv->guest_index_bits) - 1;
d180bb1147b879 Anup Patel 2021-04-26 975 if ((mmio->size / IMSIC_MMIO_PAGE_SZ) & tmp) {
d180bb1147b879 Anup Patel 2021-04-26 976 rc = -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 977 pr_err("%pOFP: size mismatch for regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 978 node, i);
d180bb1147b879 Anup Patel 2021-04-26 979 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 980 }
d180bb1147b879 Anup Patel 2021-04-26 981
d180bb1147b879 Anup Patel 2021-04-26 982 mmio->va = of_iomap(node, i);
d180bb1147b879 Anup Patel 2021-04-26 983 if (!mmio->va) {
d180bb1147b879 Anup Patel 2021-04-26 984 rc = -EIO;
d180bb1147b879 Anup Patel 2021-04-26 985 pr_err("%pOFP: unable to map MMIO regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 986 node, i);
d180bb1147b879 Anup Patel 2021-04-26 987 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 988 }
d180bb1147b879 Anup Patel 2021-04-26 989 }
d180bb1147b879 Anup Patel 2021-04-26 990
d180bb1147b879 Anup Patel 2021-04-26 991 /* Initialize interrupt identity management */
d180bb1147b879 Anup Patel 2021-04-26 992 rc = imsic_ids_init(priv);
d180bb1147b879 Anup Patel 2021-04-26 993 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 994 pr_err("%pOFP: failed to initialize interrupt management\n",
d180bb1147b879 Anup Patel 2021-04-26 995 node);
d180bb1147b879 Anup Patel 2021-04-26 996 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 997 }
d180bb1147b879 Anup Patel 2021-04-26 998
d180bb1147b879 Anup Patel 2021-04-26 999 /* Configure handlers for target CPUs */
d180bb1147b879 Anup Patel 2021-04-26 1000 for (i = 0; i < nr_parent_irqs; i++) {
d180bb1147b879 Anup Patel 2021-04-26 1001 struct of_phandle_args parent;
d180bb1147b879 Anup Patel 2021-04-26 1002 unsigned long reloff;
d180bb1147b879 Anup Patel 2021-04-26 1003 int j, cpu, hartid;
d180bb1147b879 Anup Patel 2021-04-26 1004
d180bb1147b879 Anup Patel 2021-04-26 1005 if (of_irq_parse_one(node, i, &parent)) {
d180bb1147b879 Anup Patel 2021-04-26 1006 pr_warn("%pOFP: failed to parse parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1007 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1008 continue;
d180bb1147b879 Anup Patel 2021-04-26 1009 }
d180bb1147b879 Anup Patel 2021-04-26 1010
d180bb1147b879 Anup Patel 2021-04-26 1011 /*
d180bb1147b879 Anup Patel 2021-04-26 1012 * Skip interrupt pages other than external interrupts for
d180bb1147b879 Anup Patel 2021-04-26 1013 * out privilege level.
d180bb1147b879 Anup Patel 2021-04-26 1014 */
d180bb1147b879 Anup Patel 2021-04-26 1015 if (parent.args[0] != RV_IRQ_EXT) {
d180bb1147b879 Anup Patel 2021-04-26 1016 pr_warn("%pOFP: invalid hwirq for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1017 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1018 continue;
d180bb1147b879 Anup Patel 2021-04-26 1019 }
d180bb1147b879 Anup Patel 2021-04-26 1020
d180bb1147b879 Anup Patel 2021-04-26 1021 hartid = riscv_of_parent_hartid(parent.np);
d180bb1147b879 Anup Patel 2021-04-26 1022 if (hartid < 0) {
d180bb1147b879 Anup Patel 2021-04-26 1023 pr_warn("%pOFP: hart ID for parent irq%d not found\n",
d180bb1147b879 Anup Patel 2021-04-26 1024 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1025 continue;
d180bb1147b879 Anup Patel 2021-04-26 1026 }
d180bb1147b879 Anup Patel 2021-04-26 1027
d180bb1147b879 Anup Patel 2021-04-26 1028 cpu = riscv_hartid_to_cpuid(hartid);
d180bb1147b879 Anup Patel 2021-04-26 1029 if (cpu < 0) {
d180bb1147b879 Anup Patel 2021-04-26 1030 pr_warn("%pOFP: invalid cpuid for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1031 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1032 continue;
d180bb1147b879 Anup Patel 2021-04-26 1033 }
d180bb1147b879 Anup Patel 2021-04-26 1034
d180bb1147b879 Anup Patel 2021-04-26 1035 /* Find parent domain and register chained handler */
d180bb1147b879 Anup Patel 2021-04-26 1036 if (!imsic_parent_irq && irq_find_host(parent.np)) {
d180bb1147b879 Anup Patel 2021-04-26 1037 imsic_parent_irq = irq_of_parse_and_map(node, i);
d180bb1147b879 Anup Patel 2021-04-26 1038 if (imsic_parent_irq)
d180bb1147b879 Anup Patel 2021-04-26 1039 irq_set_chained_handler(imsic_parent_irq,
d180bb1147b879 Anup Patel 2021-04-26 1040 imsic_handle_irq);
d180bb1147b879 Anup Patel 2021-04-26 1041 }
d180bb1147b879 Anup Patel 2021-04-26 1042
d180bb1147b879 Anup Patel 2021-04-26 1043 /* Find MMIO location of MSI page */
d180bb1147b879 Anup Patel 2021-04-26 1044 mmio = NULL;
d180bb1147b879 Anup Patel 2021-04-26 1045 reloff = i * BIT(priv->guest_index_bits) *
d180bb1147b879 Anup Patel 2021-04-26 1046 IMSIC_MMIO_PAGE_SZ;
d180bb1147b879 Anup Patel 2021-04-26 1047 for (j = 0; priv->num_mmios; j++) {
d180bb1147b879 Anup Patel 2021-04-26 1048 if (reloff < priv->mmios[j].size) {
d180bb1147b879 Anup Patel 2021-04-26 1049 mmio = &priv->mmios[j];
d180bb1147b879 Anup Patel 2021-04-26 1050 break;
d180bb1147b879 Anup Patel 2021-04-26 1051 }
d180bb1147b879 Anup Patel 2021-04-26 1052
d180bb1147b879 Anup Patel 2021-04-26 1053 reloff -= priv->mmios[j].size;
d180bb1147b879 Anup Patel 2021-04-26 1054 }
d180bb1147b879 Anup Patel 2021-04-26 1055 if (!mmio) {
d180bb1147b879 Anup Patel 2021-04-26 1056 pr_warn("%pOFP: MMIO not found for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1057 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1058 continue;
d180bb1147b879 Anup Patel 2021-04-26 1059 }
d180bb1147b879 Anup Patel 2021-04-26 1060
d180bb1147b879 Anup Patel 2021-04-26 1061 handler = per_cpu_ptr(&imsic_handlers, cpu);
d180bb1147b879 Anup Patel 2021-04-26 1062 if (handler->priv) {
d180bb1147b879 Anup Patel 2021-04-26 1063 pr_warn("%pOFP: CPU%d handler already configured.\n",
d180bb1147b879 Anup Patel 2021-04-26 1064 node, cpu);
d180bb1147b879 Anup Patel 2021-04-26 1065 goto done;
d180bb1147b879 Anup Patel 2021-04-26 1066 }
d180bb1147b879 Anup Patel 2021-04-26 1067
d180bb1147b879 Anup Patel 2021-04-26 1068 cpumask_set_cpu(cpu, &priv->lmask);
d180bb1147b879 Anup Patel 2021-04-26 1069 handler->msi_pa = mmio->pa + reloff;
d180bb1147b879 Anup Patel 2021-04-26 1070 handler->msi_va = mmio->va + reloff;
d180bb1147b879 Anup Patel 2021-04-26 1071 handler->priv = priv;
d180bb1147b879 Anup Patel 2021-04-26 1072
d180bb1147b879 Anup Patel 2021-04-26 1073 done:
d180bb1147b879 Anup Patel 2021-04-26 1074 nr_handlers++;
d180bb1147b879 Anup Patel 2021-04-26 1075 }
d180bb1147b879 Anup Patel 2021-04-26 1076
d180bb1147b879 Anup Patel 2021-04-26 1077 /* Initialize IPI domain */
d180bb1147b879 Anup Patel 2021-04-26 1078 rc = imsic_ipi_domain_init(priv, node);
d180bb1147b879 Anup Patel 2021-04-26 1079 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 1080 pr_err("%pOFP: Failed to initialize IPI domain\n", node);
d180bb1147b879 Anup Patel 2021-04-26 1081 goto out_ids_cleanup;
d180bb1147b879 Anup Patel 2021-04-26 1082 }
d180bb1147b879 Anup Patel 2021-04-26 1083
d180bb1147b879 Anup Patel 2021-04-26 1084 /* Initialize IRQ and MSI domains */
d180bb1147b879 Anup Patel 2021-04-26 1085 rc = imsic_irq_domains_init(priv, node);
d180bb1147b879 Anup Patel 2021-04-26 1086 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 1087 pr_err("%pOFP: Failed to initialize IRQ and MSI domains\n",
d180bb1147b879 Anup Patel 2021-04-26 1088 node);
d180bb1147b879 Anup Patel 2021-04-26 1089 goto out_ipi_domain_cleanup;
d180bb1147b879 Anup Patel 2021-04-26 1090 }
d180bb1147b879 Anup Patel 2021-04-26 1091
d180bb1147b879 Anup Patel 2021-04-26 1092 /* Setup cpuhp state */
d180bb1147b879 Anup Patel 2021-04-26 1093 cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
d180bb1147b879 Anup Patel 2021-04-26 1094 "irqchip/riscv/imsic:starting",
d180bb1147b879 Anup Patel 2021-04-26 1095 imsic_starting_cpu, imsic_dying_cpu);
d180bb1147b879 Anup Patel 2021-04-26 1096
d180bb1147b879 Anup Patel 2021-04-26 1097 /*
d180bb1147b879 Anup Patel 2021-04-26 1098 * Only one IMSIC instance allowed in a platform for clean
d180bb1147b879 Anup Patel 2021-04-26 1099 * implementation of SMP IRQ affinity and per-CPU IPIs.
d180bb1147b879 Anup Patel 2021-04-26 1100 *
d180bb1147b879 Anup Patel 2021-04-26 1101 * This means on a multi-socket (or multi-die) platform we
d180bb1147b879 Anup Patel 2021-04-26 1102 * will have multiple MMIO regions for one IMSIC instance.
d180bb1147b879 Anup Patel 2021-04-26 1103 */
d180bb1147b879 Anup Patel 2021-04-26 1104 imsic_init_done = true;
d180bb1147b879 Anup Patel 2021-04-26 1105
d180bb1147b879 Anup Patel 2021-04-26 1106 pr_info("%pOFP: mapped %d interrupts using %d handlers\n",
d180bb1147b879 Anup Patel 2021-04-26 1107 node, priv->nr_ids, nr_handlers);
d180bb1147b879 Anup Patel 2021-04-26 1108
d180bb1147b879 Anup Patel 2021-04-26 1109 return 0;
d180bb1147b879 Anup Patel 2021-04-26 1110
d180bb1147b879 Anup Patel 2021-04-26 1111 out_ipi_domain_cleanup:
d180bb1147b879 Anup Patel 2021-04-26 1112 imsic_ipi_domain_cleanup(priv);
d180bb1147b879 Anup Patel 2021-04-26 1113 out_ids_cleanup:
d180bb1147b879 Anup Patel 2021-04-26 1114 imsic_ids_cleanup(priv);
d180bb1147b879 Anup Patel 2021-04-26 1115 out_iounmap:
d180bb1147b879 Anup Patel 2021-04-26 1116 for (i = 0; i < priv->num_mmios; i++) {
d180bb1147b879 Anup Patel 2021-04-26 1117 if (priv->mmios[i].va)
d180bb1147b879 Anup Patel 2021-04-26 1118 iounmap(priv->mmios[i].va);
d180bb1147b879 Anup Patel 2021-04-26 1119 }
d180bb1147b879 Anup Patel 2021-04-26 1120 kfree(priv->mmios);
d180bb1147b879 Anup Patel 2021-04-26 1121 out_free_priv:
d180bb1147b879 Anup Patel 2021-04-26 1122 kfree(priv);
d180bb1147b879 Anup Patel 2021-04-26 1123 return rc;
d180bb1147b879 Anup Patel 2021-04-26 1124 }
d180bb1147b879 Anup Patel 2021-04-26 1125
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 24952 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kbuild-all@lists.01.org
Subject: [avpatel:riscv_aia_v1 16/18] drivers/irqchip/irq-riscv-imsic.c:851 imsic_init() warn: possible memory leak of 'priv'
Date: Thu, 08 Jul 2021 15:18:23 +0300 [thread overview]
Message-ID: <202107081051.Rool3tJA-lkp@intel.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 22008 bytes --]
tree: https://github.com/avpatel/linux.git riscv_aia_v1
head: e4b6f153340e5471c82603f7b08226ba6e2c6249
commit: d180bb1147b8790d605daf66388a2a827806b2ed [16/18] irqchip: Add RISC-V incoming MSI controller driver
config: riscv-randconfig-m031-20210707 (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
drivers/irqchip/irq-riscv-imsic.c:851 imsic_init() warn: possible memory leak of 'priv'
vim +/priv +851 drivers/irqchip/irq-riscv-imsic.c
d180bb1147b879 Anup Patel 2021-04-26 827 static int __init imsic_init(struct device_node *node,
d180bb1147b879 Anup Patel 2021-04-26 828 struct device_node *parent)
d180bb1147b879 Anup Patel 2021-04-26 829 {
d180bb1147b879 Anup Patel 2021-04-26 830 struct resource res;
d180bb1147b879 Anup Patel 2021-04-26 831 phys_addr_t base_addr;
d180bb1147b879 Anup Patel 2021-04-26 832 int rc, nr_parent_irqs;
d180bb1147b879 Anup Patel 2021-04-26 833 struct imsic_mmio *mmio;
d180bb1147b879 Anup Patel 2021-04-26 834 struct imsic_priv *priv;
d180bb1147b879 Anup Patel 2021-04-26 835 struct imsic_handler *handler;
d180bb1147b879 Anup Patel 2021-04-26 836 u32 i, tmp, nr_handlers = 0;
d180bb1147b879 Anup Patel 2021-04-26 837
d180bb1147b879 Anup Patel 2021-04-26 838 if (imsic_init_done) {
d180bb1147b879 Anup Patel 2021-04-26 839 pr_err("%pOFP: already initialized hence ignoring\n", node);
d180bb1147b879 Anup Patel 2021-04-26 840 return -ENODEV;
d180bb1147b879 Anup Patel 2021-04-26 841 }
d180bb1147b879 Anup Patel 2021-04-26 842
d180bb1147b879 Anup Patel 2021-04-26 843 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
d180bb1147b879 Anup Patel 2021-04-26 844 if (!priv)
d180bb1147b879 Anup Patel 2021-04-26 845 return -ENOMEM;
d180bb1147b879 Anup Patel 2021-04-26 846
d180bb1147b879 Anup Patel 2021-04-26 847 /* Find number of parent interrupts */
d180bb1147b879 Anup Patel 2021-04-26 848 nr_parent_irqs = of_irq_count(node);
d180bb1147b879 Anup Patel 2021-04-26 849 if (!nr_parent_irqs) {
d180bb1147b879 Anup Patel 2021-04-26 850 pr_err("%pOFP: no parent irqs available\n", node);
d180bb1147b879 Anup Patel 2021-04-26 @851 return -EINVAL;
goto out_free_priv? Same for a bunch of other error paths as well.
d180bb1147b879 Anup Patel 2021-04-26 852 }
d180bb1147b879 Anup Patel 2021-04-26 853
d180bb1147b879 Anup Patel 2021-04-26 854 /* Find number of guest index bits in MSI address */
d180bb1147b879 Anup Patel 2021-04-26 855 rc = of_property_read_u32(node, "imsic,guest-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 856 &priv->guest_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 857 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 858 priv->guest_index_bits = 0;
d180bb1147b879 Anup Patel 2021-04-26 859 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
d180bb1147b879 Anup Patel 2021-04-26 860 if (tmp < priv->guest_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 861 pr_err("%pOFP: guest index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 862 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 863 }
d180bb1147b879 Anup Patel 2021-04-26 864
d180bb1147b879 Anup Patel 2021-04-26 865 /* Find number of HART index bits */
d180bb1147b879 Anup Patel 2021-04-26 866 rc = of_property_read_u32(node, "imsic,hart-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 867 &priv->hart_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 868 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 869 /* Assume default value */
d180bb1147b879 Anup Patel 2021-04-26 870 priv->hart_index_bits = __fls(nr_parent_irqs);
d180bb1147b879 Anup Patel 2021-04-26 871 if (BIT(priv->hart_index_bits) < nr_parent_irqs)
d180bb1147b879 Anup Patel 2021-04-26 872 priv->hart_index_bits++;
d180bb1147b879 Anup Patel 2021-04-26 873 }
d180bb1147b879 Anup Patel 2021-04-26 874 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
d180bb1147b879 Anup Patel 2021-04-26 875 priv->guest_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 876 if (tmp < priv->hart_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 877 pr_err("%pOFP: HART index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 878 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 879 }
d180bb1147b879 Anup Patel 2021-04-26 880
d180bb1147b879 Anup Patel 2021-04-26 881 /* Find number of group index bits */
d180bb1147b879 Anup Patel 2021-04-26 882 rc = of_property_read_u32(node, "imsic,group-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 883 &priv->group_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 884 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 885 priv->group_index_bits = 0;
d180bb1147b879 Anup Patel 2021-04-26 886 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
d180bb1147b879 Anup Patel 2021-04-26 887 priv->guest_index_bits - priv->hart_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 888 if (tmp < priv->group_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 889 pr_err("%pOFP: group index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 890 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 891 }
d180bb1147b879 Anup Patel 2021-04-26 892
d180bb1147b879 Anup Patel 2021-04-26 893 /* Find first bit position of group index */
d180bb1147b879 Anup Patel 2021-04-26 894 tmp = IMSIC_MMIO_PAGE_SHIFT + priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 895 priv->hart_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 896 rc = of_property_read_u32(node, "imsic,group-index-shift",
d180bb1147b879 Anup Patel 2021-04-26 897 &priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 898 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 899 priv->group_index_shift = tmp;
d180bb1147b879 Anup Patel 2021-04-26 900 if (priv->group_index_shift < tmp) {
d180bb1147b879 Anup Patel 2021-04-26 901 pr_err("%pOFP: group index shift too small\n", node);
d180bb1147b879 Anup Patel 2021-04-26 902 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 903 }
d180bb1147b879 Anup Patel 2021-04-26 904 tmp = priv->group_index_bits + priv->group_index_shift - 1;
d180bb1147b879 Anup Patel 2021-04-26 905 if (tmp >= BITS_PER_LONG) {
d180bb1147b879 Anup Patel 2021-04-26 906 pr_err("%pOFP: group index shift too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 907 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 908 }
d180bb1147b879 Anup Patel 2021-04-26 909
d180bb1147b879 Anup Patel 2021-04-26 910 /* Find number of interrupt identities */
d180bb1147b879 Anup Patel 2021-04-26 911 rc = of_property_read_u32(node, "imsic,num-ids", &priv->nr_ids);
d180bb1147b879 Anup Patel 2021-04-26 912 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 913 pr_err("%pOFP: number of interrupt identities not found\n",
d180bb1147b879 Anup Patel 2021-04-26 914 node);
d180bb1147b879 Anup Patel 2021-04-26 915 return rc;
d180bb1147b879 Anup Patel 2021-04-26 916 }
d180bb1147b879 Anup Patel 2021-04-26 917 if ((priv->nr_ids < IMSIC_MIN_ID) ||
d180bb1147b879 Anup Patel 2021-04-26 918 (priv->nr_ids >= IMSIC_MAX_ID) ||
d180bb1147b879 Anup Patel 2021-04-26 919 ((priv->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
d180bb1147b879 Anup Patel 2021-04-26 920 pr_err("%pOFP: invalid number of interrupt identities\n",
d180bb1147b879 Anup Patel 2021-04-26 921 node);
d180bb1147b879 Anup Patel 2021-04-26 922 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 923 }
d180bb1147b879 Anup Patel 2021-04-26 924
d180bb1147b879 Anup Patel 2021-04-26 925 /* Compute base address */
d180bb1147b879 Anup Patel 2021-04-26 926 rc = of_address_to_resource(node, 0, &res);
d180bb1147b879 Anup Patel 2021-04-26 927 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 928 pr_err("%pOFP: first MMIO resource not found\n", node);
d180bb1147b879 Anup Patel 2021-04-26 929 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 930 }
d180bb1147b879 Anup Patel 2021-04-26 931 priv->base_addr = res.start;
d180bb1147b879 Anup Patel 2021-04-26 932 priv->base_addr &= ~(BIT(priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 933 priv->hart_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 934 IMSIC_MMIO_PAGE_SHIFT) - 1);
d180bb1147b879 Anup Patel 2021-04-26 935 priv->base_addr &= ~((BIT(priv->group_index_bits) - 1) <<
d180bb1147b879 Anup Patel 2021-04-26 936 priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 937
d180bb1147b879 Anup Patel 2021-04-26 938 /* Find number of MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 939 while (!of_address_to_resource(node, priv->num_mmios, &res))
d180bb1147b879 Anup Patel 2021-04-26 940 priv->num_mmios++;
d180bb1147b879 Anup Patel 2021-04-26 941
d180bb1147b879 Anup Patel 2021-04-26 942 /* Allocate MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 943 priv->mmios = kcalloc(priv->num_mmios, sizeof(*mmio), GFP_KERNEL);
d180bb1147b879 Anup Patel 2021-04-26 944 if (!priv->mmios) {
d180bb1147b879 Anup Patel 2021-04-26 945 rc = -ENOMEM;
d180bb1147b879 Anup Patel 2021-04-26 946 goto out_free_priv;
d180bb1147b879 Anup Patel 2021-04-26 947 }
d180bb1147b879 Anup Patel 2021-04-26 948
d180bb1147b879 Anup Patel 2021-04-26 949 /* Parse and map MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 950 for (i = 0; i < priv->num_mmios; i++) {
d180bb1147b879 Anup Patel 2021-04-26 951 mmio = &priv->mmios[i];
d180bb1147b879 Anup Patel 2021-04-26 952 rc = of_address_to_resource(node, i, &res);
d180bb1147b879 Anup Patel 2021-04-26 953 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 954 pr_err("%pOFP: unable to parse MMIO regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 955 node, i);
d180bb1147b879 Anup Patel 2021-04-26 956 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 957 }
d180bb1147b879 Anup Patel 2021-04-26 958 mmio->pa = res.start;
d180bb1147b879 Anup Patel 2021-04-26 959 mmio->size = res.end - res.start + 1;
d180bb1147b879 Anup Patel 2021-04-26 960
d180bb1147b879 Anup Patel 2021-04-26 961 base_addr = mmio->pa;
d180bb1147b879 Anup Patel 2021-04-26 962 base_addr &= ~(BIT(priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 963 priv->hart_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 964 IMSIC_MMIO_PAGE_SHIFT) - 1);
d180bb1147b879 Anup Patel 2021-04-26 965 base_addr &= ~((BIT(priv->group_index_bits) - 1) <<
d180bb1147b879 Anup Patel 2021-04-26 966 priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 967 if (base_addr != priv->base_addr) {
d180bb1147b879 Anup Patel 2021-04-26 968 rc = -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 969 pr_err("%pOFP: address mismatch for regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 970 node, i);
d180bb1147b879 Anup Patel 2021-04-26 971 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 972 }
d180bb1147b879 Anup Patel 2021-04-26 973
d180bb1147b879 Anup Patel 2021-04-26 974 tmp = BIT(priv->guest_index_bits) - 1;
d180bb1147b879 Anup Patel 2021-04-26 975 if ((mmio->size / IMSIC_MMIO_PAGE_SZ) & tmp) {
d180bb1147b879 Anup Patel 2021-04-26 976 rc = -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 977 pr_err("%pOFP: size mismatch for regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 978 node, i);
d180bb1147b879 Anup Patel 2021-04-26 979 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 980 }
d180bb1147b879 Anup Patel 2021-04-26 981
d180bb1147b879 Anup Patel 2021-04-26 982 mmio->va = of_iomap(node, i);
d180bb1147b879 Anup Patel 2021-04-26 983 if (!mmio->va) {
d180bb1147b879 Anup Patel 2021-04-26 984 rc = -EIO;
d180bb1147b879 Anup Patel 2021-04-26 985 pr_err("%pOFP: unable to map MMIO regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 986 node, i);
d180bb1147b879 Anup Patel 2021-04-26 987 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 988 }
d180bb1147b879 Anup Patel 2021-04-26 989 }
d180bb1147b879 Anup Patel 2021-04-26 990
d180bb1147b879 Anup Patel 2021-04-26 991 /* Initialize interrupt identity management */
d180bb1147b879 Anup Patel 2021-04-26 992 rc = imsic_ids_init(priv);
d180bb1147b879 Anup Patel 2021-04-26 993 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 994 pr_err("%pOFP: failed to initialize interrupt management\n",
d180bb1147b879 Anup Patel 2021-04-26 995 node);
d180bb1147b879 Anup Patel 2021-04-26 996 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 997 }
d180bb1147b879 Anup Patel 2021-04-26 998
d180bb1147b879 Anup Patel 2021-04-26 999 /* Configure handlers for target CPUs */
d180bb1147b879 Anup Patel 2021-04-26 1000 for (i = 0; i < nr_parent_irqs; i++) {
d180bb1147b879 Anup Patel 2021-04-26 1001 struct of_phandle_args parent;
d180bb1147b879 Anup Patel 2021-04-26 1002 unsigned long reloff;
d180bb1147b879 Anup Patel 2021-04-26 1003 int j, cpu, hartid;
d180bb1147b879 Anup Patel 2021-04-26 1004
d180bb1147b879 Anup Patel 2021-04-26 1005 if (of_irq_parse_one(node, i, &parent)) {
d180bb1147b879 Anup Patel 2021-04-26 1006 pr_warn("%pOFP: failed to parse parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1007 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1008 continue;
d180bb1147b879 Anup Patel 2021-04-26 1009 }
d180bb1147b879 Anup Patel 2021-04-26 1010
d180bb1147b879 Anup Patel 2021-04-26 1011 /*
d180bb1147b879 Anup Patel 2021-04-26 1012 * Skip interrupt pages other than external interrupts for
d180bb1147b879 Anup Patel 2021-04-26 1013 * out privilege level.
d180bb1147b879 Anup Patel 2021-04-26 1014 */
d180bb1147b879 Anup Patel 2021-04-26 1015 if (parent.args[0] != RV_IRQ_EXT) {
d180bb1147b879 Anup Patel 2021-04-26 1016 pr_warn("%pOFP: invalid hwirq for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1017 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1018 continue;
d180bb1147b879 Anup Patel 2021-04-26 1019 }
d180bb1147b879 Anup Patel 2021-04-26 1020
d180bb1147b879 Anup Patel 2021-04-26 1021 hartid = riscv_of_parent_hartid(parent.np);
d180bb1147b879 Anup Patel 2021-04-26 1022 if (hartid < 0) {
d180bb1147b879 Anup Patel 2021-04-26 1023 pr_warn("%pOFP: hart ID for parent irq%d not found\n",
d180bb1147b879 Anup Patel 2021-04-26 1024 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1025 continue;
d180bb1147b879 Anup Patel 2021-04-26 1026 }
d180bb1147b879 Anup Patel 2021-04-26 1027
d180bb1147b879 Anup Patel 2021-04-26 1028 cpu = riscv_hartid_to_cpuid(hartid);
d180bb1147b879 Anup Patel 2021-04-26 1029 if (cpu < 0) {
d180bb1147b879 Anup Patel 2021-04-26 1030 pr_warn("%pOFP: invalid cpuid for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1031 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1032 continue;
d180bb1147b879 Anup Patel 2021-04-26 1033 }
d180bb1147b879 Anup Patel 2021-04-26 1034
d180bb1147b879 Anup Patel 2021-04-26 1035 /* Find parent domain and register chained handler */
d180bb1147b879 Anup Patel 2021-04-26 1036 if (!imsic_parent_irq && irq_find_host(parent.np)) {
d180bb1147b879 Anup Patel 2021-04-26 1037 imsic_parent_irq = irq_of_parse_and_map(node, i);
d180bb1147b879 Anup Patel 2021-04-26 1038 if (imsic_parent_irq)
d180bb1147b879 Anup Patel 2021-04-26 1039 irq_set_chained_handler(imsic_parent_irq,
d180bb1147b879 Anup Patel 2021-04-26 1040 imsic_handle_irq);
d180bb1147b879 Anup Patel 2021-04-26 1041 }
d180bb1147b879 Anup Patel 2021-04-26 1042
d180bb1147b879 Anup Patel 2021-04-26 1043 /* Find MMIO location of MSI page */
d180bb1147b879 Anup Patel 2021-04-26 1044 mmio = NULL;
d180bb1147b879 Anup Patel 2021-04-26 1045 reloff = i * BIT(priv->guest_index_bits) *
d180bb1147b879 Anup Patel 2021-04-26 1046 IMSIC_MMIO_PAGE_SZ;
d180bb1147b879 Anup Patel 2021-04-26 1047 for (j = 0; priv->num_mmios; j++) {
d180bb1147b879 Anup Patel 2021-04-26 1048 if (reloff < priv->mmios[j].size) {
d180bb1147b879 Anup Patel 2021-04-26 1049 mmio = &priv->mmios[j];
d180bb1147b879 Anup Patel 2021-04-26 1050 break;
d180bb1147b879 Anup Patel 2021-04-26 1051 }
d180bb1147b879 Anup Patel 2021-04-26 1052
d180bb1147b879 Anup Patel 2021-04-26 1053 reloff -= priv->mmios[j].size;
d180bb1147b879 Anup Patel 2021-04-26 1054 }
d180bb1147b879 Anup Patel 2021-04-26 1055 if (!mmio) {
d180bb1147b879 Anup Patel 2021-04-26 1056 pr_warn("%pOFP: MMIO not found for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1057 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1058 continue;
d180bb1147b879 Anup Patel 2021-04-26 1059 }
d180bb1147b879 Anup Patel 2021-04-26 1060
d180bb1147b879 Anup Patel 2021-04-26 1061 handler = per_cpu_ptr(&imsic_handlers, cpu);
d180bb1147b879 Anup Patel 2021-04-26 1062 if (handler->priv) {
d180bb1147b879 Anup Patel 2021-04-26 1063 pr_warn("%pOFP: CPU%d handler already configured.\n",
d180bb1147b879 Anup Patel 2021-04-26 1064 node, cpu);
d180bb1147b879 Anup Patel 2021-04-26 1065 goto done;
d180bb1147b879 Anup Patel 2021-04-26 1066 }
d180bb1147b879 Anup Patel 2021-04-26 1067
d180bb1147b879 Anup Patel 2021-04-26 1068 cpumask_set_cpu(cpu, &priv->lmask);
d180bb1147b879 Anup Patel 2021-04-26 1069 handler->msi_pa = mmio->pa + reloff;
d180bb1147b879 Anup Patel 2021-04-26 1070 handler->msi_va = mmio->va + reloff;
d180bb1147b879 Anup Patel 2021-04-26 1071 handler->priv = priv;
d180bb1147b879 Anup Patel 2021-04-26 1072
d180bb1147b879 Anup Patel 2021-04-26 1073 done:
d180bb1147b879 Anup Patel 2021-04-26 1074 nr_handlers++;
d180bb1147b879 Anup Patel 2021-04-26 1075 }
d180bb1147b879 Anup Patel 2021-04-26 1076
d180bb1147b879 Anup Patel 2021-04-26 1077 /* Initialize IPI domain */
d180bb1147b879 Anup Patel 2021-04-26 1078 rc = imsic_ipi_domain_init(priv, node);
d180bb1147b879 Anup Patel 2021-04-26 1079 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 1080 pr_err("%pOFP: Failed to initialize IPI domain\n", node);
d180bb1147b879 Anup Patel 2021-04-26 1081 goto out_ids_cleanup;
d180bb1147b879 Anup Patel 2021-04-26 1082 }
d180bb1147b879 Anup Patel 2021-04-26 1083
d180bb1147b879 Anup Patel 2021-04-26 1084 /* Initialize IRQ and MSI domains */
d180bb1147b879 Anup Patel 2021-04-26 1085 rc = imsic_irq_domains_init(priv, node);
d180bb1147b879 Anup Patel 2021-04-26 1086 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 1087 pr_err("%pOFP: Failed to initialize IRQ and MSI domains\n",
d180bb1147b879 Anup Patel 2021-04-26 1088 node);
d180bb1147b879 Anup Patel 2021-04-26 1089 goto out_ipi_domain_cleanup;
d180bb1147b879 Anup Patel 2021-04-26 1090 }
d180bb1147b879 Anup Patel 2021-04-26 1091
d180bb1147b879 Anup Patel 2021-04-26 1092 /* Setup cpuhp state */
d180bb1147b879 Anup Patel 2021-04-26 1093 cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
d180bb1147b879 Anup Patel 2021-04-26 1094 "irqchip/riscv/imsic:starting",
d180bb1147b879 Anup Patel 2021-04-26 1095 imsic_starting_cpu, imsic_dying_cpu);
d180bb1147b879 Anup Patel 2021-04-26 1096
d180bb1147b879 Anup Patel 2021-04-26 1097 /*
d180bb1147b879 Anup Patel 2021-04-26 1098 * Only one IMSIC instance allowed in a platform for clean
d180bb1147b879 Anup Patel 2021-04-26 1099 * implementation of SMP IRQ affinity and per-CPU IPIs.
d180bb1147b879 Anup Patel 2021-04-26 1100 *
d180bb1147b879 Anup Patel 2021-04-26 1101 * This means on a multi-socket (or multi-die) platform we
d180bb1147b879 Anup Patel 2021-04-26 1102 * will have multiple MMIO regions for one IMSIC instance.
d180bb1147b879 Anup Patel 2021-04-26 1103 */
d180bb1147b879 Anup Patel 2021-04-26 1104 imsic_init_done = true;
d180bb1147b879 Anup Patel 2021-04-26 1105
d180bb1147b879 Anup Patel 2021-04-26 1106 pr_info("%pOFP: mapped %d interrupts using %d handlers\n",
d180bb1147b879 Anup Patel 2021-04-26 1107 node, priv->nr_ids, nr_handlers);
d180bb1147b879 Anup Patel 2021-04-26 1108
d180bb1147b879 Anup Patel 2021-04-26 1109 return 0;
d180bb1147b879 Anup Patel 2021-04-26 1110
d180bb1147b879 Anup Patel 2021-04-26 1111 out_ipi_domain_cleanup:
d180bb1147b879 Anup Patel 2021-04-26 1112 imsic_ipi_domain_cleanup(priv);
d180bb1147b879 Anup Patel 2021-04-26 1113 out_ids_cleanup:
d180bb1147b879 Anup Patel 2021-04-26 1114 imsic_ids_cleanup(priv);
d180bb1147b879 Anup Patel 2021-04-26 1115 out_iounmap:
d180bb1147b879 Anup Patel 2021-04-26 1116 for (i = 0; i < priv->num_mmios; i++) {
d180bb1147b879 Anup Patel 2021-04-26 1117 if (priv->mmios[i].va)
d180bb1147b879 Anup Patel 2021-04-26 1118 iounmap(priv->mmios[i].va);
d180bb1147b879 Anup Patel 2021-04-26 1119 }
d180bb1147b879 Anup Patel 2021-04-26 1120 kfree(priv->mmios);
d180bb1147b879 Anup Patel 2021-04-26 1121 out_free_priv:
d180bb1147b879 Anup Patel 2021-04-26 1122 kfree(priv);
d180bb1147b879 Anup Patel 2021-04-26 1123 return rc;
d180bb1147b879 Anup Patel 2021-04-26 1124 }
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kbuild@lists.01.org, Anup Patel <anup.patel@wdc.com>
Cc: lkp@intel.com, kbuild-all@lists.01.org, linux-kernel@vger.kernel.org
Subject: [avpatel:riscv_aia_v1 16/18] drivers/irqchip/irq-riscv-imsic.c:851 imsic_init() warn: possible memory leak of 'priv'
Date: Thu, 8 Jul 2021 15:18:23 +0300 [thread overview]
Message-ID: <202107081051.Rool3tJA-lkp@intel.com> (raw)
tree: https://github.com/avpatel/linux.git riscv_aia_v1
head: e4b6f153340e5471c82603f7b08226ba6e2c6249
commit: d180bb1147b8790d605daf66388a2a827806b2ed [16/18] irqchip: Add RISC-V incoming MSI controller driver
config: riscv-randconfig-m031-20210707 (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
drivers/irqchip/irq-riscv-imsic.c:851 imsic_init() warn: possible memory leak of 'priv'
vim +/priv +851 drivers/irqchip/irq-riscv-imsic.c
d180bb1147b879 Anup Patel 2021-04-26 827 static int __init imsic_init(struct device_node *node,
d180bb1147b879 Anup Patel 2021-04-26 828 struct device_node *parent)
d180bb1147b879 Anup Patel 2021-04-26 829 {
d180bb1147b879 Anup Patel 2021-04-26 830 struct resource res;
d180bb1147b879 Anup Patel 2021-04-26 831 phys_addr_t base_addr;
d180bb1147b879 Anup Patel 2021-04-26 832 int rc, nr_parent_irqs;
d180bb1147b879 Anup Patel 2021-04-26 833 struct imsic_mmio *mmio;
d180bb1147b879 Anup Patel 2021-04-26 834 struct imsic_priv *priv;
d180bb1147b879 Anup Patel 2021-04-26 835 struct imsic_handler *handler;
d180bb1147b879 Anup Patel 2021-04-26 836 u32 i, tmp, nr_handlers = 0;
d180bb1147b879 Anup Patel 2021-04-26 837
d180bb1147b879 Anup Patel 2021-04-26 838 if (imsic_init_done) {
d180bb1147b879 Anup Patel 2021-04-26 839 pr_err("%pOFP: already initialized hence ignoring\n", node);
d180bb1147b879 Anup Patel 2021-04-26 840 return -ENODEV;
d180bb1147b879 Anup Patel 2021-04-26 841 }
d180bb1147b879 Anup Patel 2021-04-26 842
d180bb1147b879 Anup Patel 2021-04-26 843 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
d180bb1147b879 Anup Patel 2021-04-26 844 if (!priv)
d180bb1147b879 Anup Patel 2021-04-26 845 return -ENOMEM;
d180bb1147b879 Anup Patel 2021-04-26 846
d180bb1147b879 Anup Patel 2021-04-26 847 /* Find number of parent interrupts */
d180bb1147b879 Anup Patel 2021-04-26 848 nr_parent_irqs = of_irq_count(node);
d180bb1147b879 Anup Patel 2021-04-26 849 if (!nr_parent_irqs) {
d180bb1147b879 Anup Patel 2021-04-26 850 pr_err("%pOFP: no parent irqs available\n", node);
d180bb1147b879 Anup Patel 2021-04-26 @851 return -EINVAL;
goto out_free_priv? Same for a bunch of other error paths as well.
d180bb1147b879 Anup Patel 2021-04-26 852 }
d180bb1147b879 Anup Patel 2021-04-26 853
d180bb1147b879 Anup Patel 2021-04-26 854 /* Find number of guest index bits in MSI address */
d180bb1147b879 Anup Patel 2021-04-26 855 rc = of_property_read_u32(node, "imsic,guest-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 856 &priv->guest_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 857 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 858 priv->guest_index_bits = 0;
d180bb1147b879 Anup Patel 2021-04-26 859 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT;
d180bb1147b879 Anup Patel 2021-04-26 860 if (tmp < priv->guest_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 861 pr_err("%pOFP: guest index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 862 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 863 }
d180bb1147b879 Anup Patel 2021-04-26 864
d180bb1147b879 Anup Patel 2021-04-26 865 /* Find number of HART index bits */
d180bb1147b879 Anup Patel 2021-04-26 866 rc = of_property_read_u32(node, "imsic,hart-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 867 &priv->hart_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 868 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 869 /* Assume default value */
d180bb1147b879 Anup Patel 2021-04-26 870 priv->hart_index_bits = __fls(nr_parent_irqs);
d180bb1147b879 Anup Patel 2021-04-26 871 if (BIT(priv->hart_index_bits) < nr_parent_irqs)
d180bb1147b879 Anup Patel 2021-04-26 872 priv->hart_index_bits++;
d180bb1147b879 Anup Patel 2021-04-26 873 }
d180bb1147b879 Anup Patel 2021-04-26 874 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
d180bb1147b879 Anup Patel 2021-04-26 875 priv->guest_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 876 if (tmp < priv->hart_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 877 pr_err("%pOFP: HART index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 878 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 879 }
d180bb1147b879 Anup Patel 2021-04-26 880
d180bb1147b879 Anup Patel 2021-04-26 881 /* Find number of group index bits */
d180bb1147b879 Anup Patel 2021-04-26 882 rc = of_property_read_u32(node, "imsic,group-index-bits",
d180bb1147b879 Anup Patel 2021-04-26 883 &priv->group_index_bits);
d180bb1147b879 Anup Patel 2021-04-26 884 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 885 priv->group_index_bits = 0;
d180bb1147b879 Anup Patel 2021-04-26 886 tmp = BITS_PER_LONG - IMSIC_MMIO_PAGE_SHIFT -
d180bb1147b879 Anup Patel 2021-04-26 887 priv->guest_index_bits - priv->hart_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 888 if (tmp < priv->group_index_bits) {
d180bb1147b879 Anup Patel 2021-04-26 889 pr_err("%pOFP: group index bits too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 890 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 891 }
d180bb1147b879 Anup Patel 2021-04-26 892
d180bb1147b879 Anup Patel 2021-04-26 893 /* Find first bit position of group index */
d180bb1147b879 Anup Patel 2021-04-26 894 tmp = IMSIC_MMIO_PAGE_SHIFT + priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 895 priv->hart_index_bits;
d180bb1147b879 Anup Patel 2021-04-26 896 rc = of_property_read_u32(node, "imsic,group-index-shift",
d180bb1147b879 Anup Patel 2021-04-26 897 &priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 898 if (rc)
d180bb1147b879 Anup Patel 2021-04-26 899 priv->group_index_shift = tmp;
d180bb1147b879 Anup Patel 2021-04-26 900 if (priv->group_index_shift < tmp) {
d180bb1147b879 Anup Patel 2021-04-26 901 pr_err("%pOFP: group index shift too small\n", node);
d180bb1147b879 Anup Patel 2021-04-26 902 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 903 }
d180bb1147b879 Anup Patel 2021-04-26 904 tmp = priv->group_index_bits + priv->group_index_shift - 1;
d180bb1147b879 Anup Patel 2021-04-26 905 if (tmp >= BITS_PER_LONG) {
d180bb1147b879 Anup Patel 2021-04-26 906 pr_err("%pOFP: group index shift too big\n", node);
d180bb1147b879 Anup Patel 2021-04-26 907 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 908 }
d180bb1147b879 Anup Patel 2021-04-26 909
d180bb1147b879 Anup Patel 2021-04-26 910 /* Find number of interrupt identities */
d180bb1147b879 Anup Patel 2021-04-26 911 rc = of_property_read_u32(node, "imsic,num-ids", &priv->nr_ids);
d180bb1147b879 Anup Patel 2021-04-26 912 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 913 pr_err("%pOFP: number of interrupt identities not found\n",
d180bb1147b879 Anup Patel 2021-04-26 914 node);
d180bb1147b879 Anup Patel 2021-04-26 915 return rc;
d180bb1147b879 Anup Patel 2021-04-26 916 }
d180bb1147b879 Anup Patel 2021-04-26 917 if ((priv->nr_ids < IMSIC_MIN_ID) ||
d180bb1147b879 Anup Patel 2021-04-26 918 (priv->nr_ids >= IMSIC_MAX_ID) ||
d180bb1147b879 Anup Patel 2021-04-26 919 ((priv->nr_ids & IMSIC_MIN_ID) != IMSIC_MIN_ID)) {
d180bb1147b879 Anup Patel 2021-04-26 920 pr_err("%pOFP: invalid number of interrupt identities\n",
d180bb1147b879 Anup Patel 2021-04-26 921 node);
d180bb1147b879 Anup Patel 2021-04-26 922 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 923 }
d180bb1147b879 Anup Patel 2021-04-26 924
d180bb1147b879 Anup Patel 2021-04-26 925 /* Compute base address */
d180bb1147b879 Anup Patel 2021-04-26 926 rc = of_address_to_resource(node, 0, &res);
d180bb1147b879 Anup Patel 2021-04-26 927 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 928 pr_err("%pOFP: first MMIO resource not found\n", node);
d180bb1147b879 Anup Patel 2021-04-26 929 return -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 930 }
d180bb1147b879 Anup Patel 2021-04-26 931 priv->base_addr = res.start;
d180bb1147b879 Anup Patel 2021-04-26 932 priv->base_addr &= ~(BIT(priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 933 priv->hart_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 934 IMSIC_MMIO_PAGE_SHIFT) - 1);
d180bb1147b879 Anup Patel 2021-04-26 935 priv->base_addr &= ~((BIT(priv->group_index_bits) - 1) <<
d180bb1147b879 Anup Patel 2021-04-26 936 priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 937
d180bb1147b879 Anup Patel 2021-04-26 938 /* Find number of MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 939 while (!of_address_to_resource(node, priv->num_mmios, &res))
d180bb1147b879 Anup Patel 2021-04-26 940 priv->num_mmios++;
d180bb1147b879 Anup Patel 2021-04-26 941
d180bb1147b879 Anup Patel 2021-04-26 942 /* Allocate MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 943 priv->mmios = kcalloc(priv->num_mmios, sizeof(*mmio), GFP_KERNEL);
d180bb1147b879 Anup Patel 2021-04-26 944 if (!priv->mmios) {
d180bb1147b879 Anup Patel 2021-04-26 945 rc = -ENOMEM;
d180bb1147b879 Anup Patel 2021-04-26 946 goto out_free_priv;
d180bb1147b879 Anup Patel 2021-04-26 947 }
d180bb1147b879 Anup Patel 2021-04-26 948
d180bb1147b879 Anup Patel 2021-04-26 949 /* Parse and map MMIO register sets */
d180bb1147b879 Anup Patel 2021-04-26 950 for (i = 0; i < priv->num_mmios; i++) {
d180bb1147b879 Anup Patel 2021-04-26 951 mmio = &priv->mmios[i];
d180bb1147b879 Anup Patel 2021-04-26 952 rc = of_address_to_resource(node, i, &res);
d180bb1147b879 Anup Patel 2021-04-26 953 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 954 pr_err("%pOFP: unable to parse MMIO regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 955 node, i);
d180bb1147b879 Anup Patel 2021-04-26 956 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 957 }
d180bb1147b879 Anup Patel 2021-04-26 958 mmio->pa = res.start;
d180bb1147b879 Anup Patel 2021-04-26 959 mmio->size = res.end - res.start + 1;
d180bb1147b879 Anup Patel 2021-04-26 960
d180bb1147b879 Anup Patel 2021-04-26 961 base_addr = mmio->pa;
d180bb1147b879 Anup Patel 2021-04-26 962 base_addr &= ~(BIT(priv->guest_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 963 priv->hart_index_bits +
d180bb1147b879 Anup Patel 2021-04-26 964 IMSIC_MMIO_PAGE_SHIFT) - 1);
d180bb1147b879 Anup Patel 2021-04-26 965 base_addr &= ~((BIT(priv->group_index_bits) - 1) <<
d180bb1147b879 Anup Patel 2021-04-26 966 priv->group_index_shift);
d180bb1147b879 Anup Patel 2021-04-26 967 if (base_addr != priv->base_addr) {
d180bb1147b879 Anup Patel 2021-04-26 968 rc = -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 969 pr_err("%pOFP: address mismatch for regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 970 node, i);
d180bb1147b879 Anup Patel 2021-04-26 971 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 972 }
d180bb1147b879 Anup Patel 2021-04-26 973
d180bb1147b879 Anup Patel 2021-04-26 974 tmp = BIT(priv->guest_index_bits) - 1;
d180bb1147b879 Anup Patel 2021-04-26 975 if ((mmio->size / IMSIC_MMIO_PAGE_SZ) & tmp) {
d180bb1147b879 Anup Patel 2021-04-26 976 rc = -EINVAL;
d180bb1147b879 Anup Patel 2021-04-26 977 pr_err("%pOFP: size mismatch for regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 978 node, i);
d180bb1147b879 Anup Patel 2021-04-26 979 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 980 }
d180bb1147b879 Anup Patel 2021-04-26 981
d180bb1147b879 Anup Patel 2021-04-26 982 mmio->va = of_iomap(node, i);
d180bb1147b879 Anup Patel 2021-04-26 983 if (!mmio->va) {
d180bb1147b879 Anup Patel 2021-04-26 984 rc = -EIO;
d180bb1147b879 Anup Patel 2021-04-26 985 pr_err("%pOFP: unable to map MMIO regset %d\n",
d180bb1147b879 Anup Patel 2021-04-26 986 node, i);
d180bb1147b879 Anup Patel 2021-04-26 987 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 988 }
d180bb1147b879 Anup Patel 2021-04-26 989 }
d180bb1147b879 Anup Patel 2021-04-26 990
d180bb1147b879 Anup Patel 2021-04-26 991 /* Initialize interrupt identity management */
d180bb1147b879 Anup Patel 2021-04-26 992 rc = imsic_ids_init(priv);
d180bb1147b879 Anup Patel 2021-04-26 993 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 994 pr_err("%pOFP: failed to initialize interrupt management\n",
d180bb1147b879 Anup Patel 2021-04-26 995 node);
d180bb1147b879 Anup Patel 2021-04-26 996 goto out_iounmap;
d180bb1147b879 Anup Patel 2021-04-26 997 }
d180bb1147b879 Anup Patel 2021-04-26 998
d180bb1147b879 Anup Patel 2021-04-26 999 /* Configure handlers for target CPUs */
d180bb1147b879 Anup Patel 2021-04-26 1000 for (i = 0; i < nr_parent_irqs; i++) {
d180bb1147b879 Anup Patel 2021-04-26 1001 struct of_phandle_args parent;
d180bb1147b879 Anup Patel 2021-04-26 1002 unsigned long reloff;
d180bb1147b879 Anup Patel 2021-04-26 1003 int j, cpu, hartid;
d180bb1147b879 Anup Patel 2021-04-26 1004
d180bb1147b879 Anup Patel 2021-04-26 1005 if (of_irq_parse_one(node, i, &parent)) {
d180bb1147b879 Anup Patel 2021-04-26 1006 pr_warn("%pOFP: failed to parse parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1007 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1008 continue;
d180bb1147b879 Anup Patel 2021-04-26 1009 }
d180bb1147b879 Anup Patel 2021-04-26 1010
d180bb1147b879 Anup Patel 2021-04-26 1011 /*
d180bb1147b879 Anup Patel 2021-04-26 1012 * Skip interrupt pages other than external interrupts for
d180bb1147b879 Anup Patel 2021-04-26 1013 * out privilege level.
d180bb1147b879 Anup Patel 2021-04-26 1014 */
d180bb1147b879 Anup Patel 2021-04-26 1015 if (parent.args[0] != RV_IRQ_EXT) {
d180bb1147b879 Anup Patel 2021-04-26 1016 pr_warn("%pOFP: invalid hwirq for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1017 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1018 continue;
d180bb1147b879 Anup Patel 2021-04-26 1019 }
d180bb1147b879 Anup Patel 2021-04-26 1020
d180bb1147b879 Anup Patel 2021-04-26 1021 hartid = riscv_of_parent_hartid(parent.np);
d180bb1147b879 Anup Patel 2021-04-26 1022 if (hartid < 0) {
d180bb1147b879 Anup Patel 2021-04-26 1023 pr_warn("%pOFP: hart ID for parent irq%d not found\n",
d180bb1147b879 Anup Patel 2021-04-26 1024 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1025 continue;
d180bb1147b879 Anup Patel 2021-04-26 1026 }
d180bb1147b879 Anup Patel 2021-04-26 1027
d180bb1147b879 Anup Patel 2021-04-26 1028 cpu = riscv_hartid_to_cpuid(hartid);
d180bb1147b879 Anup Patel 2021-04-26 1029 if (cpu < 0) {
d180bb1147b879 Anup Patel 2021-04-26 1030 pr_warn("%pOFP: invalid cpuid for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1031 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1032 continue;
d180bb1147b879 Anup Patel 2021-04-26 1033 }
d180bb1147b879 Anup Patel 2021-04-26 1034
d180bb1147b879 Anup Patel 2021-04-26 1035 /* Find parent domain and register chained handler */
d180bb1147b879 Anup Patel 2021-04-26 1036 if (!imsic_parent_irq && irq_find_host(parent.np)) {
d180bb1147b879 Anup Patel 2021-04-26 1037 imsic_parent_irq = irq_of_parse_and_map(node, i);
d180bb1147b879 Anup Patel 2021-04-26 1038 if (imsic_parent_irq)
d180bb1147b879 Anup Patel 2021-04-26 1039 irq_set_chained_handler(imsic_parent_irq,
d180bb1147b879 Anup Patel 2021-04-26 1040 imsic_handle_irq);
d180bb1147b879 Anup Patel 2021-04-26 1041 }
d180bb1147b879 Anup Patel 2021-04-26 1042
d180bb1147b879 Anup Patel 2021-04-26 1043 /* Find MMIO location of MSI page */
d180bb1147b879 Anup Patel 2021-04-26 1044 mmio = NULL;
d180bb1147b879 Anup Patel 2021-04-26 1045 reloff = i * BIT(priv->guest_index_bits) *
d180bb1147b879 Anup Patel 2021-04-26 1046 IMSIC_MMIO_PAGE_SZ;
d180bb1147b879 Anup Patel 2021-04-26 1047 for (j = 0; priv->num_mmios; j++) {
d180bb1147b879 Anup Patel 2021-04-26 1048 if (reloff < priv->mmios[j].size) {
d180bb1147b879 Anup Patel 2021-04-26 1049 mmio = &priv->mmios[j];
d180bb1147b879 Anup Patel 2021-04-26 1050 break;
d180bb1147b879 Anup Patel 2021-04-26 1051 }
d180bb1147b879 Anup Patel 2021-04-26 1052
d180bb1147b879 Anup Patel 2021-04-26 1053 reloff -= priv->mmios[j].size;
d180bb1147b879 Anup Patel 2021-04-26 1054 }
d180bb1147b879 Anup Patel 2021-04-26 1055 if (!mmio) {
d180bb1147b879 Anup Patel 2021-04-26 1056 pr_warn("%pOFP: MMIO not found for parent irq%d\n",
d180bb1147b879 Anup Patel 2021-04-26 1057 node, i);
d180bb1147b879 Anup Patel 2021-04-26 1058 continue;
d180bb1147b879 Anup Patel 2021-04-26 1059 }
d180bb1147b879 Anup Patel 2021-04-26 1060
d180bb1147b879 Anup Patel 2021-04-26 1061 handler = per_cpu_ptr(&imsic_handlers, cpu);
d180bb1147b879 Anup Patel 2021-04-26 1062 if (handler->priv) {
d180bb1147b879 Anup Patel 2021-04-26 1063 pr_warn("%pOFP: CPU%d handler already configured.\n",
d180bb1147b879 Anup Patel 2021-04-26 1064 node, cpu);
d180bb1147b879 Anup Patel 2021-04-26 1065 goto done;
d180bb1147b879 Anup Patel 2021-04-26 1066 }
d180bb1147b879 Anup Patel 2021-04-26 1067
d180bb1147b879 Anup Patel 2021-04-26 1068 cpumask_set_cpu(cpu, &priv->lmask);
d180bb1147b879 Anup Patel 2021-04-26 1069 handler->msi_pa = mmio->pa + reloff;
d180bb1147b879 Anup Patel 2021-04-26 1070 handler->msi_va = mmio->va + reloff;
d180bb1147b879 Anup Patel 2021-04-26 1071 handler->priv = priv;
d180bb1147b879 Anup Patel 2021-04-26 1072
d180bb1147b879 Anup Patel 2021-04-26 1073 done:
d180bb1147b879 Anup Patel 2021-04-26 1074 nr_handlers++;
d180bb1147b879 Anup Patel 2021-04-26 1075 }
d180bb1147b879 Anup Patel 2021-04-26 1076
d180bb1147b879 Anup Patel 2021-04-26 1077 /* Initialize IPI domain */
d180bb1147b879 Anup Patel 2021-04-26 1078 rc = imsic_ipi_domain_init(priv, node);
d180bb1147b879 Anup Patel 2021-04-26 1079 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 1080 pr_err("%pOFP: Failed to initialize IPI domain\n", node);
d180bb1147b879 Anup Patel 2021-04-26 1081 goto out_ids_cleanup;
d180bb1147b879 Anup Patel 2021-04-26 1082 }
d180bb1147b879 Anup Patel 2021-04-26 1083
d180bb1147b879 Anup Patel 2021-04-26 1084 /* Initialize IRQ and MSI domains */
d180bb1147b879 Anup Patel 2021-04-26 1085 rc = imsic_irq_domains_init(priv, node);
d180bb1147b879 Anup Patel 2021-04-26 1086 if (rc) {
d180bb1147b879 Anup Patel 2021-04-26 1087 pr_err("%pOFP: Failed to initialize IRQ and MSI domains\n",
d180bb1147b879 Anup Patel 2021-04-26 1088 node);
d180bb1147b879 Anup Patel 2021-04-26 1089 goto out_ipi_domain_cleanup;
d180bb1147b879 Anup Patel 2021-04-26 1090 }
d180bb1147b879 Anup Patel 2021-04-26 1091
d180bb1147b879 Anup Patel 2021-04-26 1092 /* Setup cpuhp state */
d180bb1147b879 Anup Patel 2021-04-26 1093 cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
d180bb1147b879 Anup Patel 2021-04-26 1094 "irqchip/riscv/imsic:starting",
d180bb1147b879 Anup Patel 2021-04-26 1095 imsic_starting_cpu, imsic_dying_cpu);
d180bb1147b879 Anup Patel 2021-04-26 1096
d180bb1147b879 Anup Patel 2021-04-26 1097 /*
d180bb1147b879 Anup Patel 2021-04-26 1098 * Only one IMSIC instance allowed in a platform for clean
d180bb1147b879 Anup Patel 2021-04-26 1099 * implementation of SMP IRQ affinity and per-CPU IPIs.
d180bb1147b879 Anup Patel 2021-04-26 1100 *
d180bb1147b879 Anup Patel 2021-04-26 1101 * This means on a multi-socket (or multi-die) platform we
d180bb1147b879 Anup Patel 2021-04-26 1102 * will have multiple MMIO regions for one IMSIC instance.
d180bb1147b879 Anup Patel 2021-04-26 1103 */
d180bb1147b879 Anup Patel 2021-04-26 1104 imsic_init_done = true;
d180bb1147b879 Anup Patel 2021-04-26 1105
d180bb1147b879 Anup Patel 2021-04-26 1106 pr_info("%pOFP: mapped %d interrupts using %d handlers\n",
d180bb1147b879 Anup Patel 2021-04-26 1107 node, priv->nr_ids, nr_handlers);
d180bb1147b879 Anup Patel 2021-04-26 1108
d180bb1147b879 Anup Patel 2021-04-26 1109 return 0;
d180bb1147b879 Anup Patel 2021-04-26 1110
d180bb1147b879 Anup Patel 2021-04-26 1111 out_ipi_domain_cleanup:
d180bb1147b879 Anup Patel 2021-04-26 1112 imsic_ipi_domain_cleanup(priv);
d180bb1147b879 Anup Patel 2021-04-26 1113 out_ids_cleanup:
d180bb1147b879 Anup Patel 2021-04-26 1114 imsic_ids_cleanup(priv);
d180bb1147b879 Anup Patel 2021-04-26 1115 out_iounmap:
d180bb1147b879 Anup Patel 2021-04-26 1116 for (i = 0; i < priv->num_mmios; i++) {
d180bb1147b879 Anup Patel 2021-04-26 1117 if (priv->mmios[i].va)
d180bb1147b879 Anup Patel 2021-04-26 1118 iounmap(priv->mmios[i].va);
d180bb1147b879 Anup Patel 2021-04-26 1119 }
d180bb1147b879 Anup Patel 2021-04-26 1120 kfree(priv->mmios);
d180bb1147b879 Anup Patel 2021-04-26 1121 out_free_priv:
d180bb1147b879 Anup Patel 2021-04-26 1122 kfree(priv);
d180bb1147b879 Anup Patel 2021-04-26 1123 return rc;
d180bb1147b879 Anup Patel 2021-04-26 1124 }
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
next reply other threads:[~2021-07-08 2:48 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-08 2:48 kernel test robot [this message]
2021-07-08 12:18 ` [avpatel:riscv_aia_v1 16/18] drivers/irqchip/irq-riscv-imsic.c:851 imsic_init() warn: possible memory leak of 'priv' Dan Carpenter
2021-07-08 12:18 ` Dan Carpenter
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=202107081051.Rool3tJA-lkp@intel.com \
--to=lkp@intel.com \
--cc=kbuild@lists.01.org \
/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.