diff mbox series

thermal: armada: fix legacy resource fixup

Message ID E1gLA9Z-0005uY-8Q@rmk-PC.armlinux.org.uk (mailing list archive)
State Accepted
Delegated to: Eduardo Valentin
Headers show
Series thermal: armada: fix legacy resource fixup | expand

Commit Message

Russell King (Oracle) Nov. 9, 2018, 5:01 p.m. UTC
When the armada thermal module is inserted, removed and then reinserted,
the system panics as per the messages below.  The reason is that "edit"
a live resource in the resource tree twice, and end up with it pointing
to some other hardware.

Editing live resources (resources that are part of the registered
resource tree) is not permissible - the resource tree is an ordered
set of resources, sorted by start address, and when a new resource is
inserted, it is validated that it (a) fits within its parent resource
and (b) does not overlap a neighbouring resource.

Get rid of this resource editing.  We can instead adjust the return
value from ioremap() as ioremap() deals with the creation of page-
based mappings - provided the adjustment does not cross a page
boundary.

SError Interrupt on CPU1, code 0xbf000000 -- SError
CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
pstate: 20400085 (nzCv daIf +PAN -UAO)
pc : regmap_mmio_read+0x3c/0x60
lr : regmap_mmio_read+0x3c/0x60
sp : ffffff800d453900
x29: ffffff800d453900 x28: ffffff800096a1d0
x27: 0000000000000100 x26: ffffff80009696d8
x25: ffffff8000969000 x24: ffffffc13a588918
x23: ffffffc13a9a28a8 x22: ffffff800d4539dc
x21: 0000000000000084 x20: ffffff800d4539dc
x19: ffffffc13a5d5480 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000
x15: 0000000000000000 x14: 0000000000000000
x13: 0000000000000000 x12: 0000000000000030
x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
x9 : 0000000000000000 x8 : ffffffc13a5d5a80
x7 : 0000000000000000 x6 : 000000000000003f
x5 : 0000000000000000 x4 : 0000000000000000
x3 : ffffff800851be70 x2 : ffffff800851bd60
x1 : ffffff800d492ff8 x0 : 0000000000000000
Kernel panic - not syncing: Asynchronous SError Interrupt
CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
Call trace:
 dump_backtrace+0x0/0x158
 show_stack+0x14/0x1c
 dump_stack+0x90/0xb0
 panic+0x128/0x298
 print_tainted+0x0/0xa8
 arm64_serror_panic+0x74/0x80
 do_serror+0x5c/0xb8
 el1_error+0xb4/0x144
 regmap_mmio_read+0x3c/0x60
 _regmap_bus_reg_read+0x18/0x20
 _regmap_read+0x64/0x180
 regmap_read+0x44/0x6c
 armada_ap806_init+0x24/0x5c [armada_thermal]
 armada_thermal_probe+0x2c8/0x37c [armada_thermal]
 platform_drv_probe+0x4c/0xb0
 really_probe+0x21c/0x2b4
 driver_probe_device+0x58/0xfc
 __driver_attach+0xd4/0xd8
 bus_for_each_dev+0x50/0xa0
 driver_attach+0x20/0x28
 bus_add_driver+0x1c4/0x228
 driver_register+0x6c/0x124
 __platform_driver_register+0x4c/0x54
 armada_thermal_driver_init+0x20/0x1000 [armada_thermal]
 do_one_initcall+0x30/0x204
 do_init_module+0x5c/0x1d4
 load_module+0x1a88/0x212c
 __se_sys_finit_module+0xa0/0xac
 __arm64_sys_finit_module+0x1c/0x24
 el0_svc_common+0x94/0xf0
 el0_svc_handler+0x24/0x80
 el0_svc+0x8/0x3c0
SMP: stopping secondary CPUs
Kernel Offset: disabled
CPU features: 0x0,21806000
Memory Limit: none

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/thermal/armada_thermal.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

Comments

Russell King (Oracle) Nov. 9, 2018, 5:04 p.m. UTC | #1
On Fri, Nov 09, 2018 at 05:01:05PM +0000, Russell King wrote:
> When the armada thermal module is inserted, removed and then reinserted,
> the system panics as per the messages below.  The reason is that "edit"
> a live resource in the resource tree twice, and end up with it pointing
> to some other hardware.
> 
> Editing live resources (resources that are part of the registered
> resource tree) is not permissible - the resource tree is an ordered
> set of resources, sorted by start address, and when a new resource is
> inserted, it is validated that it (a) fits within its parent resource
> and (b) does not overlap a neighbouring resource.
> 
> Get rid of this resource editing.  We can instead adjust the return
> value from ioremap() as ioremap() deals with the creation of page-
> based mappings - provided the adjustment does not cross a page
> boundary.
> 
> SError Interrupt on CPU1, code 0xbf000000 -- SError
> CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> pstate: 20400085 (nzCv daIf +PAN -UAO)
> pc : regmap_mmio_read+0x3c/0x60
> lr : regmap_mmio_read+0x3c/0x60
> sp : ffffff800d453900
> x29: ffffff800d453900 x28: ffffff800096a1d0
> x27: 0000000000000100 x26: ffffff80009696d8
> x25: ffffff8000969000 x24: ffffffc13a588918
> x23: ffffffc13a9a28a8 x22: ffffff800d4539dc
> x21: 0000000000000084 x20: ffffff800d4539dc
> x19: ffffffc13a5d5480 x18: 0000000000000000
> x17: 0000000000000000 x16: 0000000000000000
> x15: 0000000000000000 x14: 0000000000000000
> x13: 0000000000000000 x12: 0000000000000030
> x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> x9 : 0000000000000000 x8 : ffffffc13a5d5a80
> x7 : 0000000000000000 x6 : 000000000000003f
> x5 : 0000000000000000 x4 : 0000000000000000
> x3 : ffffff800851be70 x2 : ffffff800851bd60
> x1 : ffffff800d492ff8 x0 : 0000000000000000
> Kernel panic - not syncing: Asynchronous SError Interrupt
> CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> Call trace:
>  dump_backtrace+0x0/0x158
>  show_stack+0x14/0x1c
>  dump_stack+0x90/0xb0
>  panic+0x128/0x298
>  print_tainted+0x0/0xa8
>  arm64_serror_panic+0x74/0x80
>  do_serror+0x5c/0xb8
>  el1_error+0xb4/0x144
>  regmap_mmio_read+0x3c/0x60
>  _regmap_bus_reg_read+0x18/0x20
>  _regmap_read+0x64/0x180
>  regmap_read+0x44/0x6c
>  armada_ap806_init+0x24/0x5c [armada_thermal]
>  armada_thermal_probe+0x2c8/0x37c [armada_thermal]
>  platform_drv_probe+0x4c/0xb0
>  really_probe+0x21c/0x2b4
>  driver_probe_device+0x58/0xfc
>  __driver_attach+0xd4/0xd8
>  bus_for_each_dev+0x50/0xa0
>  driver_attach+0x20/0x28
>  bus_add_driver+0x1c4/0x228
>  driver_register+0x6c/0x124
>  __platform_driver_register+0x4c/0x54
>  armada_thermal_driver_init+0x20/0x1000 [armada_thermal]
>  do_one_initcall+0x30/0x204
>  do_init_module+0x5c/0x1d4
>  load_module+0x1a88/0x212c
>  __se_sys_finit_module+0xa0/0xac
>  __arm64_sys_finit_module+0x1c/0x24
>  el0_svc_common+0x94/0xf0
>  el0_svc_handler+0x24/0x80
>  el0_svc+0x8/0x3c0
> SMP: stopping secondary CPUs
> Kernel Offset: disabled
> CPU features: 0x0,21806000
> Memory Limit: none
> 

Sorry, I missed the fixes tag:

Fixes: 3d4e51844a4e ("thermal: armada: convert driver to syscon register accesses")

> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/thermal/armada_thermal.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
> index e16b3cb1808c..a6d3ee6077f8 100644
> --- a/drivers/thermal/armada_thermal.c
> +++ b/drivers/thermal/armada_thermal.c
> @@ -526,23 +526,21 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
>  
>  	/* First memory region points towards the status register */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (IS_ERR(res))
> -		return PTR_ERR(res);
> -
> -	/*
> -	 * Edit the resource start address and length to map over all the
> -	 * registers, instead of pointing at them one by one.
> -	 */
> -	res->start -= data->syscon_status_off;
> -	res->end = res->start + max(data->syscon_status_off,
> -				    max(data->syscon_control0_off,
> -					data->syscon_control1_off)) +
> -		   sizeof(unsigned int) - 1;
> -
>  	base = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(base))
>  		return PTR_ERR(base);
>  
> +	/*
> +	 * Fix up from the old individual DT register specification to
> +	 * cover all the registers.  We do this by adjusting the ioremap()
> +	 * result, which should be fine as ioremap() deals with pages.
> +	 * However, validate that we do not cross a page boundary while
> +	 * making this adjustment.
> +	 */
> +	if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off)
> +		return -EINVAL;
> +	base -= data->syscon_status_off;
> +
>  	priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
>  					     &armada_thermal_regmap_config);
>  	if (IS_ERR(priv->syscon))
> -- 
> 2.7.4
>
Miquel Raynal Nov. 9, 2018, 5:07 p.m. UTC | #2
Hi Russell,

Russell King - ARM Linux <linux@armlinux.org.uk> wrote on Fri, 9 Nov
2018 17:04:42 +0000:

> On Fri, Nov 09, 2018 at 05:01:05PM +0000, Russell King wrote:
> > When the armada thermal module is inserted, removed and then reinserted,
> > the system panics as per the messages below.  The reason is that "edit"
> > a live resource in the resource tree twice, and end up with it pointing
> > to some other hardware.
> > 
> > Editing live resources (resources that are part of the registered
> > resource tree) is not permissible - the resource tree is an ordered
> > set of resources, sorted by start address, and when a new resource is
> > inserted, it is validated that it (a) fits within its parent resource
> > and (b) does not overlap a neighbouring resource.
> > 
> > Get rid of this resource editing.  We can instead adjust the return
> > value from ioremap() as ioremap() deals with the creation of page-
> > based mappings - provided the adjustment does not cross a page
> > boundary.
> > 
> > SError Interrupt on CPU1, code 0xbf000000 -- SError
> > CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> > Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> > pstate: 20400085 (nzCv daIf +PAN -UAO)
> > pc : regmap_mmio_read+0x3c/0x60
> > lr : regmap_mmio_read+0x3c/0x60
> > sp : ffffff800d453900
> > x29: ffffff800d453900 x28: ffffff800096a1d0
> > x27: 0000000000000100 x26: ffffff80009696d8
> > x25: ffffff8000969000 x24: ffffffc13a588918
> > x23: ffffffc13a9a28a8 x22: ffffff800d4539dc
> > x21: 0000000000000084 x20: ffffff800d4539dc
> > x19: ffffffc13a5d5480 x18: 0000000000000000
> > x17: 0000000000000000 x16: 0000000000000000
> > x15: 0000000000000000 x14: 0000000000000000
> > x13: 0000000000000000 x12: 0000000000000030
> > x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> > x9 : 0000000000000000 x8 : ffffffc13a5d5a80
> > x7 : 0000000000000000 x6 : 000000000000003f
> > x5 : 0000000000000000 x4 : 0000000000000000
> > x3 : ffffff800851be70 x2 : ffffff800851bd60
> > x1 : ffffff800d492ff8 x0 : 0000000000000000
> > Kernel panic - not syncing: Asynchronous SError Interrupt
> > CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> > Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> > Call trace:
> >  dump_backtrace+0x0/0x158
> >  show_stack+0x14/0x1c
> >  dump_stack+0x90/0xb0
> >  panic+0x128/0x298
> >  print_tainted+0x0/0xa8
> >  arm64_serror_panic+0x74/0x80
> >  do_serror+0x5c/0xb8
> >  el1_error+0xb4/0x144
> >  regmap_mmio_read+0x3c/0x60
> >  _regmap_bus_reg_read+0x18/0x20
> >  _regmap_read+0x64/0x180
> >  regmap_read+0x44/0x6c
> >  armada_ap806_init+0x24/0x5c [armada_thermal]
> >  armada_thermal_probe+0x2c8/0x37c [armada_thermal]
> >  platform_drv_probe+0x4c/0xb0
> >  really_probe+0x21c/0x2b4
> >  driver_probe_device+0x58/0xfc
> >  __driver_attach+0xd4/0xd8
> >  bus_for_each_dev+0x50/0xa0
> >  driver_attach+0x20/0x28
> >  bus_add_driver+0x1c4/0x228
> >  driver_register+0x6c/0x124
> >  __platform_driver_register+0x4c/0x54
> >  armada_thermal_driver_init+0x20/0x1000 [armada_thermal]
> >  do_one_initcall+0x30/0x204
> >  do_init_module+0x5c/0x1d4
> >  load_module+0x1a88/0x212c
> >  __se_sys_finit_module+0xa0/0xac
> >  __arm64_sys_finit_module+0x1c/0x24
> >  el0_svc_common+0x94/0xf0
> >  el0_svc_handler+0x24/0x80
> >  el0_svc+0x8/0x3c0
> > SMP: stopping secondary CPUs
> > Kernel Offset: disabled
> > CPU features: 0x0,21806000
> > Memory Limit: none
> >   
> 
> Sorry, I missed the fixes tag:
> 
> Fixes: 3d4e51844a4e ("thermal: armada: convert driver to syscon register accesses")
> 
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---

Tested-by: Miquel Raynal <miquel.raynal@bootlin.com>


Thanks again,
Miquèl
Russell King (Oracle) Dec. 3, 2018, 4:51 p.m. UTC | #3
*ping*

On Fri, Nov 09, 2018 at 05:01:05PM +0000, Russell King wrote:
> When the armada thermal module is inserted, removed and then reinserted,
> the system panics as per the messages below.  The reason is that "edit"
> a live resource in the resource tree twice, and end up with it pointing
> to some other hardware.
> 
> Editing live resources (resources that are part of the registered
> resource tree) is not permissible - the resource tree is an ordered
> set of resources, sorted by start address, and when a new resource is
> inserted, it is validated that it (a) fits within its parent resource
> and (b) does not overlap a neighbouring resource.
> 
> Get rid of this resource editing.  We can instead adjust the return
> value from ioremap() as ioremap() deals with the creation of page-
> based mappings - provided the adjustment does not cross a page
> boundary.
> 
> SError Interrupt on CPU1, code 0xbf000000 -- SError
> CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> pstate: 20400085 (nzCv daIf +PAN -UAO)
> pc : regmap_mmio_read+0x3c/0x60
> lr : regmap_mmio_read+0x3c/0x60
> sp : ffffff800d453900
> x29: ffffff800d453900 x28: ffffff800096a1d0
> x27: 0000000000000100 x26: ffffff80009696d8
> x25: ffffff8000969000 x24: ffffffc13a588918
> x23: ffffffc13a9a28a8 x22: ffffff800d4539dc
> x21: 0000000000000084 x20: ffffff800d4539dc
> x19: ffffffc13a5d5480 x18: 0000000000000000
> x17: 0000000000000000 x16: 0000000000000000
> x15: 0000000000000000 x14: 0000000000000000
> x13: 0000000000000000 x12: 0000000000000030
> x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> x9 : 0000000000000000 x8 : ffffffc13a5d5a80
> x7 : 0000000000000000 x6 : 000000000000003f
> x5 : 0000000000000000 x4 : 0000000000000000
> x3 : ffffff800851be70 x2 : ffffff800851bd60
> x1 : ffffff800d492ff8 x0 : 0000000000000000
> Kernel panic - not syncing: Asynchronous SError Interrupt
> CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> Call trace:
>  dump_backtrace+0x0/0x158
>  show_stack+0x14/0x1c
>  dump_stack+0x90/0xb0
>  panic+0x128/0x298
>  print_tainted+0x0/0xa8
>  arm64_serror_panic+0x74/0x80
>  do_serror+0x5c/0xb8
>  el1_error+0xb4/0x144
>  regmap_mmio_read+0x3c/0x60
>  _regmap_bus_reg_read+0x18/0x20
>  _regmap_read+0x64/0x180
>  regmap_read+0x44/0x6c
>  armada_ap806_init+0x24/0x5c [armada_thermal]
>  armada_thermal_probe+0x2c8/0x37c [armada_thermal]
>  platform_drv_probe+0x4c/0xb0
>  really_probe+0x21c/0x2b4
>  driver_probe_device+0x58/0xfc
>  __driver_attach+0xd4/0xd8
>  bus_for_each_dev+0x50/0xa0
>  driver_attach+0x20/0x28
>  bus_add_driver+0x1c4/0x228
>  driver_register+0x6c/0x124
>  __platform_driver_register+0x4c/0x54
>  armada_thermal_driver_init+0x20/0x1000 [armada_thermal]
>  do_one_initcall+0x30/0x204
>  do_init_module+0x5c/0x1d4
>  load_module+0x1a88/0x212c
>  __se_sys_finit_module+0xa0/0xac
>  __arm64_sys_finit_module+0x1c/0x24
>  el0_svc_common+0x94/0xf0
>  el0_svc_handler+0x24/0x80
>  el0_svc+0x8/0x3c0
> SMP: stopping secondary CPUs
> Kernel Offset: disabled
> CPU features: 0x0,21806000
> Memory Limit: none
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/thermal/armada_thermal.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
> index e16b3cb1808c..a6d3ee6077f8 100644
> --- a/drivers/thermal/armada_thermal.c
> +++ b/drivers/thermal/armada_thermal.c
> @@ -526,23 +526,21 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
>  
>  	/* First memory region points towards the status register */
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (IS_ERR(res))
> -		return PTR_ERR(res);
> -
> -	/*
> -	 * Edit the resource start address and length to map over all the
> -	 * registers, instead of pointing at them one by one.
> -	 */
> -	res->start -= data->syscon_status_off;
> -	res->end = res->start + max(data->syscon_status_off,
> -				    max(data->syscon_control0_off,
> -					data->syscon_control1_off)) +
> -		   sizeof(unsigned int) - 1;
> -
>  	base = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(base))
>  		return PTR_ERR(base);
>  
> +	/*
> +	 * Fix up from the old individual DT register specification to
> +	 * cover all the registers.  We do this by adjusting the ioremap()
> +	 * result, which should be fine as ioremap() deals with pages.
> +	 * However, validate that we do not cross a page boundary while
> +	 * making this adjustment.
> +	 */
> +	if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off)
> +		return -EINVAL;
> +	base -= data->syscon_status_off;
> +
>  	priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
>  					     &armada_thermal_regmap_config);
>  	if (IS_ERR(priv->syscon))
> -- 
> 2.7.4
>
Eduardo Valentin Dec. 5, 2018, 5:32 a.m. UTC | #4
On Mon, Dec 03, 2018 at 04:51:28PM +0000, Russell King - ARM Linux wrote:
> *ping*

I applied this. But I had to refresh the patch to latest linus master.

> 
> On Fri, Nov 09, 2018 at 05:01:05PM +0000, Russell King wrote:
> > When the armada thermal module is inserted, removed and then reinserted,
> > the system panics as per the messages below.  The reason is that "edit"
> > a live resource in the resource tree twice, and end up with it pointing
> > to some other hardware.
> > 
> > Editing live resources (resources that are part of the registered
> > resource tree) is not permissible - the resource tree is an ordered
> > set of resources, sorted by start address, and when a new resource is
> > inserted, it is validated that it (a) fits within its parent resource
> > and (b) does not overlap a neighbouring resource.
> > 
> > Get rid of this resource editing.  We can instead adjust the return
> > value from ioremap() as ioremap() deals with the creation of page-
> > based mappings - provided the adjustment does not cross a page
> > boundary.
> > 
> > SError Interrupt on CPU1, code 0xbf000000 -- SError
> > CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> > Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> > pstate: 20400085 (nzCv daIf +PAN -UAO)
> > pc : regmap_mmio_read+0x3c/0x60
> > lr : regmap_mmio_read+0x3c/0x60
> > sp : ffffff800d453900
> > x29: ffffff800d453900 x28: ffffff800096a1d0
> > x27: 0000000000000100 x26: ffffff80009696d8
> > x25: ffffff8000969000 x24: ffffffc13a588918
> > x23: ffffffc13a9a28a8 x22: ffffff800d4539dc
> > x21: 0000000000000084 x20: ffffff800d4539dc
> > x19: ffffffc13a5d5480 x18: 0000000000000000
> > x17: 0000000000000000 x16: 0000000000000000
> > x15: 0000000000000000 x14: 0000000000000000
> > x13: 0000000000000000 x12: 0000000000000030
> > x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> > x9 : 0000000000000000 x8 : ffffffc13a5d5a80
> > x7 : 0000000000000000 x6 : 000000000000003f
> > x5 : 0000000000000000 x4 : 0000000000000000
> > x3 : ffffff800851be70 x2 : ffffff800851bd60
> > x1 : ffffff800d492ff8 x0 : 0000000000000000
> > Kernel panic - not syncing: Asynchronous SError Interrupt
> > CPU: 1 PID: 2749 Comm: modprobe Not tainted 4.19.0+ #175
> > Hardware name: Marvell 8040 MACCHIATOBin Double shot (DT)
> > Call trace:
> >  dump_backtrace+0x0/0x158
> >  show_stack+0x14/0x1c
> >  dump_stack+0x90/0xb0
> >  panic+0x128/0x298
> >  print_tainted+0x0/0xa8
> >  arm64_serror_panic+0x74/0x80
> >  do_serror+0x5c/0xb8
> >  el1_error+0xb4/0x144
> >  regmap_mmio_read+0x3c/0x60
> >  _regmap_bus_reg_read+0x18/0x20
> >  _regmap_read+0x64/0x180
> >  regmap_read+0x44/0x6c
> >  armada_ap806_init+0x24/0x5c [armada_thermal]
> >  armada_thermal_probe+0x2c8/0x37c [armada_thermal]
> >  platform_drv_probe+0x4c/0xb0
> >  really_probe+0x21c/0x2b4
> >  driver_probe_device+0x58/0xfc
> >  __driver_attach+0xd4/0xd8
> >  bus_for_each_dev+0x50/0xa0
> >  driver_attach+0x20/0x28
> >  bus_add_driver+0x1c4/0x228
> >  driver_register+0x6c/0x124
> >  __platform_driver_register+0x4c/0x54
> >  armada_thermal_driver_init+0x20/0x1000 [armada_thermal]
> >  do_one_initcall+0x30/0x204
> >  do_init_module+0x5c/0x1d4
> >  load_module+0x1a88/0x212c
> >  __se_sys_finit_module+0xa0/0xac
> >  __arm64_sys_finit_module+0x1c/0x24
> >  el0_svc_common+0x94/0xf0
> >  el0_svc_handler+0x24/0x80
> >  el0_svc+0x8/0x3c0
> > SMP: stopping secondary CPUs
> > Kernel Offset: disabled
> > CPU features: 0x0,21806000
> > Memory Limit: none
> > 
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> >  drivers/thermal/armada_thermal.c | 24 +++++++++++-------------
> >  1 file changed, 11 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
> > index e16b3cb1808c..a6d3ee6077f8 100644
> > --- a/drivers/thermal/armada_thermal.c
> > +++ b/drivers/thermal/armada_thermal.c
> > @@ -526,23 +526,21 @@ static int armada_thermal_probe_legacy(struct platform_device *pdev,
> >  
> >  	/* First memory region points towards the status register */
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > -	if (IS_ERR(res))
> > -		return PTR_ERR(res);
> > -
> > -	/*
> > -	 * Edit the resource start address and length to map over all the
> > -	 * registers, instead of pointing at them one by one.
> > -	 */
> > -	res->start -= data->syscon_status_off;
> > -	res->end = res->start + max(data->syscon_status_off,
> > -				    max(data->syscon_control0_off,
> > -					data->syscon_control1_off)) +
> > -		   sizeof(unsigned int) - 1;
> > -
> >  	base = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(base))
> >  		return PTR_ERR(base);
> >  
> > +	/*
> > +	 * Fix up from the old individual DT register specification to
> > +	 * cover all the registers.  We do this by adjusting the ioremap()
> > +	 * result, which should be fine as ioremap() deals with pages.
> > +	 * However, validate that we do not cross a page boundary while
> > +	 * making this adjustment.
> > +	 */
> > +	if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off)
> > +		return -EINVAL;
> > +	base -= data->syscon_status_off;
> > +
> >  	priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
> >  					     &armada_thermal_regmap_config);
> >  	if (IS_ERR(priv->syscon))
> > -- 
> > 2.7.4
> > 
> 
> -- 
> RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
> According to speedtest.net: 11.9Mbps down 500kbps up
diff mbox series

Patch

diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index e16b3cb1808c..a6d3ee6077f8 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -526,23 +526,21 @@  static int armada_thermal_probe_legacy(struct platform_device *pdev,
 
 	/* First memory region points towards the status register */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (IS_ERR(res))
-		return PTR_ERR(res);
-
-	/*
-	 * Edit the resource start address and length to map over all the
-	 * registers, instead of pointing at them one by one.
-	 */
-	res->start -= data->syscon_status_off;
-	res->end = res->start + max(data->syscon_status_off,
-				    max(data->syscon_control0_off,
-					data->syscon_control1_off)) +
-		   sizeof(unsigned int) - 1;
-
 	base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	/*
+	 * Fix up from the old individual DT register specification to
+	 * cover all the registers.  We do this by adjusting the ioremap()
+	 * result, which should be fine as ioremap() deals with pages.
+	 * However, validate that we do not cross a page boundary while
+	 * making this adjustment.
+	 */
+	if (((unsigned long)base & ~PAGE_MASK) < data->syscon_status_off)
+		return -EINVAL;
+	base -= data->syscon_status_off;
+
 	priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
 					     &armada_thermal_regmap_config);
 	if (IS_ERR(priv->syscon))