> -Original Message-
> From: Yi Wang
> Sent: Friday, October 16, 2020 1:49 AM
> To: Roy Pledge ; Laurentiu Tudor
>
> Cc: Leo Li ; linux-ker...@vger.kernel.org; linuxppc-
> d...@lists.ozlabs.org; linux-arm-ker...@lists.infradead.org;
> xue.zhih...@zte.com.cn; wang.y...@zte.com.cn; jiang.xue...@zte.com.cn;
> Hao Si ; Lin Chen
> Subject: [PATCH v2] soc: fsl: dpio: Change 'cpumask_t mask' to the driver's
> private data
>
> From: Hao Si
>
> The local variable 'cpumask_t mask' is in the stack memory, and its address
> is assigned to 'desc->affinity' in 'irq_set_affinity_hint()'.
> But the memory area where this variable is located is at risk of being
> modified.
>
> During LTP testing, the following error was generated:
>
> Unable to handle kernel paging request at virtual address 12e9b790
> Mem abort info:
> ESR = 0x9607
> Exception class = DABT (current EL), IL = 32 bits
> SET = 0, FnV = 0
> EA = 0, S1PTW = 0
> Data abort info:
> ISV = 0, ISS = 0x0007
> CM = 0, WnR = 0
> swapper pgtable: 4k pages, 48-bit VAs, pgdp = 75ac5e07
> [12e9b790] pgd=0027dbffe003, pud=0027dbffd003,
> pmd=0027b6d61003, pte=
> Internal error: Oops: 9607 [#1] PREEMPT SMP
> Modules linked in: xt_conntrack
> Process read_all (pid: 20171, stack limit = 0x44ea4095)
> CPU: 14 PID: 20171 Comm: read_all Tainted: GB W
> Hardware name: NXP Layerscape LX2160ARDB (DT)
> pstate: 8085 (Nzcv daIf -PAN -UAO)
> pc : irq_affinity_hint_proc_show+0x54/0xb0
> lr : irq_affinity_hint_proc_show+0x4c/0xb0
> sp : 1138bc10
> x29: 1138bc10 x28: d131d1e0
> x27: 007000c0 x26: 8025b9480dc0
> x25: 8025b9480da8 x24: 03ff
> x23: 8027334f8300 x22: 80272e97d000
> x21: 80272e97d0b0 x20: 8025b9480d80
> x19: 09a49000 x18:
> x17: x16:
> x15: x14:
> x13: x12: 0040
> x11: x10: 802735b79b88
> x9 : x8 :
> x7 : 09a49848 x6 : 0003
> x5 : x4 : 08157d6c
> x3 : 1138bc10 x2 : 12e9b790
> x1 : x0 :
> Call trace:
> irq_affinity_hint_proc_show+0x54/0xb0
> seq_read+0x1b0/0x440
> proc_reg_read+0x80/0xd8
> __vfs_read+0x60/0x178
> vfs_read+0x94/0x150
> ksys_read+0x74/0xf0
> __arm64_sys_read+0x24/0x30
> el0_svc_common.constprop.0+0xd8/0x1a0
> el0_svc_handler+0x34/0x88
> el0_svc+0x10/0x14
> Code: f9001bbf 943e0732 f94066c2 b462 (f9400041)
> ---[ end trace b495bdcb0b3b732b ]---
> Kernel panic - not syncing: Fatal exception
> SMP: stopping secondary CPUs
> SMP: failed to stop secondary CPUs 0,2-4,6,8,11,13-15
> Kernel Offset: disabled
> CPU features: 0x0,21006008
> Memory Limit: none
> ---[ end Kernel panic - not syncing: Fatal exception ]---
>
> Fix it by changing 'cpumask_t mask' to the driver's private data.
Thanks for the patch. Sorry to chime in late.
Since we are only setting single bit in the cpumask, it is actually not
necessary to keep the cpumask in private data as we already kept the cpu number
in desc.cpu. The better and easier approach is to actually use
get_cpu_mask(cpu) API to get the pre-defined cpumask in the static
cpu_bit_bitmap array. We don't even need to declare the mask/cpu_mask in the
register_dpio_irq_handlers().
>
> Signed-off-by: Hao Si
> Signed-off-by: Lin Chen
> Signed-off-by: Yi Wang
> ---
> v2: Place 'cpumask_t mask' in the driver's private data and while at it,
> rename it to cpu_mask.
>
> drivers/soc/fsl/dpio/dpio-driver.c | 9 +
> include/linux/fsl/mc.h | 2 ++
> 2 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/soc/fsl/dpio/dpio-driver.c b/drivers/soc/fsl/dpio/dpio-
> driver.c
> index 7b642c3..e9d820d 100644
> --- a/drivers/soc/fsl/dpio/dpio-driver.c
> +++ b/drivers/soc/fsl/dpio/dpio-driver.c
> @@ -95,7 +95,7 @@ static int register_dpio_irq_handlers(struct
> fsl_mc_device *dpio_dev, int cpu)
> {
> int error;
> struct fsl_mc_device_irq *irq;
> - cpumask_t mask;
> + cpumask_t *cpu_mask;
>
> irq = dpio_dev->irqs[0];
> error = devm_request_irq(_dev->dev,
> @@ -112,9 +112,10 @@ static int register_dpio_irq_handlers(struct
> fsl_mc_device *dpio_dev, int cpu)
> }
>
> /* set the affinity hint */
> - cpumask_clear();
> - cpumask_set_cpu(cpu, );
> - if (irq_set_affinity_hint(irq->msi_desc->irq, ))
> + cpu_mask = _dev->mask;
> + cpumask_clear(cpu_mask);
> + cpumask_set_cpu(cpu, cpu_mask);
> + if (irq_set_affinity_hint(irq->msi_desc->irq, cpu_mask))
> dev_err(_dev->dev,
> "irq_set_affinity failed irq %d cpu %d\n",
> irq->msi_desc->irq, cpu);
> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
> index