2018-05-09 21:06:04 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright ( c ) 2012 , The Linux Foundation . All rights reserved .
2014-11-03 21:07:35 +03:00
*/
2019-06-19 22:53:06 +03:00
# include <linux/acpi.h>
2014-11-03 21:07:35 +03:00
# include <linux/types.h>
# include <linux/err.h>
# include <linux/slab.h>
# include <linux/clk.h>
# include <linux/of.h>
# include <linux/of_address.h>
# include <linux/of_graph.h>
# include <linux/of_platform.h>
# include <linux/platform_device.h>
# include <linux/amba/bus.h>
# include <linux/coresight.h>
2015-03-30 23:13:34 +03:00
# include <linux/cpumask.h>
2014-11-03 21:07:35 +03:00
# include <asm/smp_plat.h>
2019-06-19 22:53:01 +03:00
# include "coresight-priv.h"
2019-06-19 22:52:52 +03:00
/*
* coresight_alloc_conns : Allocate connections record for each output
* port from the device .
*/
static int coresight_alloc_conns ( struct device * dev ,
struct coresight_platform_data * pdata )
{
if ( pdata - > nr_outport ) {
2020-07-16 20:57:36 +03:00
pdata - > conns = devm_kcalloc ( dev , pdata - > nr_outport ,
sizeof ( * pdata - > conns ) , GFP_KERNEL ) ;
2019-06-19 22:52:52 +03:00
if ( ! pdata - > conns )
return - ENOMEM ;
}
return 0 ;
}
2014-11-03 21:07:35 +03:00
static struct device *
2019-06-19 22:53:02 +03:00
coresight_find_device_by_fwnode ( struct fwnode_handle * fwnode )
2014-11-03 21:07:35 +03:00
{
struct device * dev = NULL ;
/*
2015-05-19 19:55:20 +03:00
* If we have a non - configurable replicator , it will be found on the
2014-11-03 21:07:35 +03:00
* platform bus .
*/
2019-07-24 01:18:34 +03:00
dev = bus_find_device_by_fwnode ( & platform_bus_type , fwnode ) ;
2014-11-03 21:07:35 +03:00
if ( dev )
return dev ;
/*
* We have a configurable component - circle through the AMBA bus
* looking for the device that matches the endpoint node .
*/
2019-07-24 01:18:34 +03:00
return bus_find_device_by_fwnode ( & amba_bustype , fwnode ) ;
2014-11-03 21:07:35 +03:00
}
2020-03-20 19:52:57 +03:00
/*
* Find a registered coresight device from a device fwnode .
* The node info is associated with the AMBA parent , but the
* csdev keeps a copy so iterate round the coresight bus to
* find the device .
*/
struct coresight_device *
coresight_find_csdev_by_fwnode ( struct fwnode_handle * r_fwnode )
{
struct device * dev ;
struct coresight_device * csdev = NULL ;
dev = bus_find_device_by_fwnode ( & coresight_bustype , r_fwnode ) ;
if ( dev ) {
csdev = to_coresight_device ( dev ) ;
put_device ( dev ) ;
}
return csdev ;
}
2020-09-28 19:35:09 +03:00
EXPORT_SYMBOL_GPL ( coresight_find_csdev_by_fwnode ) ;
2020-03-20 19:52:57 +03:00
2019-06-19 22:53:02 +03:00
# ifdef CONFIG_OF
2018-09-20 22:17:43 +03:00
static inline bool of_coresight_legacy_ep_is_input ( struct device_node * ep )
2018-09-20 22:17:41 +03:00
{
return of_property_read_bool ( ep , " slave-mode " ) ;
}
2018-09-20 22:17:43 +03:00
static void of_coresight_get_ports_legacy ( const struct device_node * node ,
int * nr_inport , int * nr_outport )
2014-11-03 21:07:35 +03:00
{
struct device_node * ep = NULL ;
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
struct of_endpoint endpoint ;
2014-11-03 21:07:35 +03:00
int in = 0 , out = 0 ;
do {
2014-12-01 15:32:32 +03:00
ep = of_graph_get_next_endpoint ( node , ep ) ;
2014-11-03 21:07:35 +03:00
if ( ! ep )
break ;
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
if ( of_graph_parse_endpoint ( ep , & endpoint ) )
continue ;
if ( of_coresight_legacy_ep_is_input ( ep ) ) {
in = ( endpoint . port + 1 > in ) ?
endpoint . port + 1 : in ;
} else {
out = ( endpoint . port + 1 ) > out ?
endpoint . port + 1 : out ;
}
2014-11-03 21:07:35 +03:00
} while ( ep ) ;
* nr_inport = in ;
* nr_outport = out ;
}
2018-09-20 22:17:43 +03:00
static struct device_node * of_coresight_get_port_parent ( struct device_node * ep )
{
struct device_node * parent = of_graph_get_port_parent ( ep ) ;
/*
* Skip one - level up to the real device node , if we
* are using the new bindings .
*/
2019-02-06 02:24:55 +03:00
if ( of_node_name_eq ( parent , " in-ports " ) | |
of_node_name_eq ( parent , " out-ports " ) )
2018-09-20 22:17:43 +03:00
parent = of_get_next_parent ( parent ) ;
return parent ;
}
static inline struct device_node *
of_coresight_get_input_ports_node ( const struct device_node * node )
{
return of_get_child_by_name ( node , " in-ports " ) ;
}
static inline struct device_node *
of_coresight_get_output_ports_node ( const struct device_node * node )
{
return of_get_child_by_name ( node , " out-ports " ) ;
}
static inline int
of_coresight_count_ports ( struct device_node * port_parent )
{
int i = 0 ;
struct device_node * ep = NULL ;
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
struct of_endpoint endpoint ;
while ( ( ep = of_graph_get_next_endpoint ( port_parent , ep ) ) ) {
/* Defer error handling to parsing */
if ( of_graph_parse_endpoint ( ep , & endpoint ) )
continue ;
if ( endpoint . port + 1 > i )
i = endpoint . port + 1 ;
}
2018-09-20 22:17:43 +03:00
return i ;
}
static void of_coresight_get_ports ( const struct device_node * node ,
int * nr_inport , int * nr_outport )
{
struct device_node * input_ports = NULL , * output_ports = NULL ;
input_ports = of_coresight_get_input_ports_node ( node ) ;
output_ports = of_coresight_get_output_ports_node ( node ) ;
if ( input_ports | | output_ports ) {
if ( input_ports ) {
* nr_inport = of_coresight_count_ports ( input_ports ) ;
of_node_put ( input_ports ) ;
}
if ( output_ports ) {
* nr_outport = of_coresight_count_ports ( output_ports ) ;
of_node_put ( output_ports ) ;
}
} else {
/* Fall back to legacy DT bindings parsing */
of_coresight_get_ports_legacy ( node , nr_inport , nr_outport ) ;
}
}
2019-06-19 22:52:55 +03:00
static int of_coresight_get_cpu ( struct device * dev )
2017-06-05 23:15:15 +03:00
{
int cpu ;
2018-01-02 14:25:28 +03:00
struct device_node * dn ;
2017-06-05 23:15:15 +03:00
2019-06-19 22:52:55 +03:00
if ( ! dev - > of_node )
2019-07-04 12:53:05 +03:00
return - ENODEV ;
2019-06-19 22:52:55 +03:00
dn = of_parse_phandle ( dev - > of_node , " cpu " , 0 ) ;
2017-06-05 23:15:15 +03:00
if ( ! dn )
2019-07-04 12:53:05 +03:00
return - ENODEV ;
2018-01-02 14:25:28 +03:00
cpu = of_cpu_node_to_id ( dn ) ;
2017-06-05 23:15:15 +03:00
of_node_put ( dn ) ;
2019-07-04 12:53:05 +03:00
return cpu ;
2017-06-05 23:15:15 +03:00
}
2018-09-20 22:17:37 +03:00
/*
* of_coresight_parse_endpoint : Parse the given output endpoint @ ep
2018-09-20 22:17:42 +03:00
* and fill the connection information in @ conn
2018-09-20 22:17:37 +03:00
*
* Parses the local port , remote device name and the remote port .
*
* Returns :
* 0 - If the parsing completed without any fatal errors .
* - Errno - Fatal error , abort the scanning .
*/
static int of_coresight_parse_endpoint ( struct device * dev ,
struct device_node * ep ,
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
struct coresight_platform_data * pdata )
2018-09-20 22:17:37 +03:00
{
int ret = 0 ;
struct of_endpoint endpoint , rendpoint ;
struct device_node * rparent = NULL ;
2018-09-20 22:17:40 +03:00
struct device_node * rep = NULL ;
2018-09-20 22:17:37 +03:00
struct device * rdev = NULL ;
2019-06-19 22:53:02 +03:00
struct fwnode_handle * rdev_fwnode ;
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
struct coresight_connection * conn ;
2018-09-20 22:17:37 +03:00
do {
/* Parse the local port details */
if ( of_graph_parse_endpoint ( ep , & endpoint ) )
break ;
/*
2018-09-20 22:17:40 +03:00
* Get a handle on the remote endpoint and the device it is
* attached to .
2018-09-20 22:17:37 +03:00
*/
2018-09-20 22:17:40 +03:00
rep = of_graph_get_remote_endpoint ( ep ) ;
if ( ! rep )
2018-09-20 22:17:37 +03:00
break ;
2018-09-20 22:17:43 +03:00
rparent = of_coresight_get_port_parent ( rep ) ;
2018-09-20 22:17:40 +03:00
if ( ! rparent )
2018-09-20 22:17:37 +03:00
break ;
2018-09-20 22:17:40 +03:00
if ( of_graph_parse_endpoint ( rep , & rendpoint ) )
2018-09-20 22:17:37 +03:00
break ;
2019-06-19 22:53:02 +03:00
rdev_fwnode = of_fwnode_handle ( rparent ) ;
2018-09-20 22:17:37 +03:00
/* If the remote device is not available, defer probing */
2019-06-19 22:53:02 +03:00
rdev = coresight_find_device_by_fwnode ( rdev_fwnode ) ;
2018-09-20 22:17:37 +03:00
if ( ! rdev ) {
ret = - EPROBE_DEFER ;
break ;
}
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
conn = & pdata - > conns [ endpoint . port ] ;
if ( conn - > child_fwnode ) {
dev_warn ( dev , " Duplicate output port %d \n " ,
endpoint . port ) ;
ret = - EINVAL ;
break ;
}
2018-09-20 22:17:42 +03:00
conn - > outport = endpoint . port ;
2019-06-19 22:53:03 +03:00
/*
* Hold the refcount to the target device . This could be
* released via :
* 1 ) coresight_release_platform_data ( ) if the probe fails or
* this device is unregistered .
* 2 ) While removing the target device via
* coresight_remove_match ( )
*/
conn - > child_fwnode = fwnode_handle_get ( rdev_fwnode ) ;
2018-09-20 22:17:42 +03:00
conn - > child_port = rendpoint . port ;
2018-09-20 22:17:37 +03:00
/* Connection record updated */
} while ( 0 ) ;
2018-09-20 22:18:19 +03:00
of_node_put ( rparent ) ;
of_node_put ( rep ) ;
put_device ( rdev ) ;
2018-09-20 22:17:38 +03:00
2018-09-20 22:17:37 +03:00
return ret ;
}
2019-06-19 22:52:54 +03:00
static int of_get_coresight_platform_data ( struct device * dev ,
struct coresight_platform_data * pdata )
2014-11-03 21:07:35 +03:00
{
2018-09-20 22:17:42 +03:00
int ret = 0 ;
2014-11-03 21:07:35 +03:00
struct device_node * ep = NULL ;
2018-09-20 22:17:43 +03:00
const struct device_node * parent = NULL ;
bool legacy_binding = false ;
2019-06-19 22:52:54 +03:00
struct device_node * node = dev - > of_node ;
2014-11-03 21:07:35 +03:00
/* Get the number of input and output port for this component */
of_coresight_get_ports ( node , & pdata - > nr_inport , & pdata - > nr_outport ) ;
2018-09-20 22:17:37 +03:00
/* If there are no output connections, we are done */
if ( ! pdata - > nr_outport )
2019-06-19 22:52:54 +03:00
return 0 ;
2018-09-20 22:17:37 +03:00
2019-06-19 22:52:52 +03:00
ret = coresight_alloc_conns ( dev , pdata ) ;
2018-09-20 22:17:37 +03:00
if ( ret )
2019-06-19 22:52:54 +03:00
return ret ;
2018-09-20 22:17:37 +03:00
2018-09-20 22:17:43 +03:00
parent = of_coresight_get_output_ports_node ( node ) ;
/*
* If the DT uses obsoleted bindings , the ports are listed
* under the device and we need to filter out the input
* ports .
*/
if ( ! parent ) {
legacy_binding = true ;
parent = node ;
dev_warn_once ( dev , " Uses obsolete Coresight DT bindings \n " ) ;
}
/* Iterate through each output port to discover topology */
while ( ( ep = of_graph_get_next_endpoint ( parent , ep ) ) ) {
2018-09-20 22:17:37 +03:00
/*
2018-09-20 22:17:43 +03:00
* Legacy binding mixes input / output ports under the
* same parent . So , skip the input ports if we are dealing
* with legacy binding , as they processed with their
* connected output ports .
2018-09-20 22:17:37 +03:00
*/
2018-09-20 22:17:43 +03:00
if ( legacy_binding & & of_coresight_legacy_ep_is_input ( ep ) )
2018-09-20 22:17:37 +03:00
continue ;
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
ret = of_coresight_parse_endpoint ( dev , ep , pdata ) ;
if ( ret )
2019-06-19 22:52:54 +03:00
return ret ;
2014-11-03 21:07:35 +03:00
}
2019-06-19 22:52:54 +03:00
return 0 ;
}
# else
static inline int
of_get_coresight_platform_data ( struct device * dev ,
struct coresight_platform_data * pdata )
{
return - ENOENT ;
2014-11-03 21:07:35 +03:00
}
2019-06-19 22:53:09 +03:00
static inline int of_coresight_get_cpu ( struct device * dev )
{
2019-07-04 12:53:05 +03:00
return - ENODEV ;
2019-06-19 22:53:09 +03:00
}
2019-06-19 22:52:51 +03:00
# endif
2019-06-19 22:52:54 +03:00
2019-06-19 22:53:06 +03:00
# ifdef CONFIG_ACPI
# include <acpi/actypes.h>
# include <acpi/processor.h>
/* ACPI Graph _DSD UUID : "ab02a46b-74c7-45a2-bd68-f7d344ef2153" */
static const guid_t acpi_graph_uuid = GUID_INIT ( 0xab02a46b , 0x74c7 , 0x45a2 ,
0xbd , 0x68 , 0xf7 , 0xd3 ,
0x44 , 0xef , 0x21 , 0x53 ) ;
/* Coresight ACPI Graph UUID : "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd" */
static const guid_t coresight_graph_uuid = GUID_INIT ( 0x3ecbc8b6 , 0x1d0e , 0x4fb3 ,
0x81 , 0x07 , 0xe6 , 0x27 ,
0xf8 , 0x05 , 0xc6 , 0xcd ) ;
# define ACPI_CORESIGHT_LINK_SLAVE 0
# define ACPI_CORESIGHT_LINK_MASTER 1
static inline bool is_acpi_guid ( const union acpi_object * obj )
{
return ( obj - > type = = ACPI_TYPE_BUFFER ) & & ( obj - > buffer . length = = 16 ) ;
}
/*
* acpi_guid_matches - Checks if the given object is a GUID object and
* that it matches the supplied the GUID .
*/
static inline bool acpi_guid_matches ( const union acpi_object * obj ,
const guid_t * guid )
{
return is_acpi_guid ( obj ) & &
guid_equal ( ( guid_t * ) obj - > buffer . pointer , guid ) ;
}
static inline bool is_acpi_dsd_graph_guid ( const union acpi_object * obj )
{
return acpi_guid_matches ( obj , & acpi_graph_uuid ) ;
}
static inline bool is_acpi_coresight_graph_guid ( const union acpi_object * obj )
{
return acpi_guid_matches ( obj , & coresight_graph_uuid ) ;
}
static inline bool is_acpi_coresight_graph ( const union acpi_object * obj )
{
const union acpi_object * graphid , * guid , * links ;
if ( obj - > type ! = ACPI_TYPE_PACKAGE | |
obj - > package . count < 3 )
return false ;
graphid = & obj - > package . elements [ 0 ] ;
guid = & obj - > package . elements [ 1 ] ;
links = & obj - > package . elements [ 2 ] ;
if ( graphid - > type ! = ACPI_TYPE_INTEGER | |
links - > type ! = ACPI_TYPE_INTEGER )
return false ;
return is_acpi_coresight_graph_guid ( guid ) ;
}
/*
* acpi_validate_dsd_graph - Make sure the given _DSD graph conforms
* to the ACPI _DSD Graph specification .
*
* ACPI Devices Graph property has the following format :
* {
* Revision - Integer , must be 0
* NumberOfGraphs - Integer , N indicating the following list .
* Graph [ 1 ] ,
* . . .
* Graph [ N ]
* }
*
* And each Graph entry has the following format :
* {
* GraphID - Integer , identifying a graph the device belongs to .
* UUID - UUID identifying the specification that governs
* this graph . ( e . g , see is_acpi_coresight_graph ( ) )
* NumberOfLinks - Number " N " of connections on this node of the graph .
* Links [ 1 ]
* . . .
* Links [ N ]
* }
*
* Where each " Links " entry has the following format :
*
* {
* SourcePortAddress - Integer
* DestinationPortAddress - Integer
* DestinationDeviceName - Reference to another device
* ( - - - CoreSight specific extensions below - - - )
* DirectionOfFlow - Integer 1 for output ( master )
* 0 for input ( slave )
* }
*
* e . g :
* For a Funnel device
*
* Device ( MFUN ) {
* . . .
*
* Name ( _DSD , Package ( ) {
* // DSD Package contains tuples of { Proeprty_Type_UUID, Package() }
* ToUUID ( " daffd814-6eba-4d8c-8a91-bc9bbf4aa301 " ) , //Std. Property UUID
* Package ( ) {
* Package ( 2 ) { " property-name " , < property - value > }
* } ,
*
* ToUUID ( " ab02a46b-74c7-45a2-bd68-f7d344ef2153 " ) , // ACPI Graph UUID
* Package ( ) {
* 0 , // Revision
* 1 , // NumberOfGraphs.
* Package ( ) { // Graph[0] Package
* 1 , // GraphID
* // Coresight Graph UUID
* ToUUID ( " 3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd " ) ,
* 3 , // NumberOfLinks aka ports
* // Link[0]: Output_0 -> Replicator:Input_0
* Package ( ) { 0 , 0 , \ _SB_ . RPL0 , 1 } ,
* // Link[1]: Input_0 <- Cluster0_Funnel0:Output_0
* Package ( ) { 0 , 0 , \ _SB_ . CLU0 . FUN0 , 0 } ,
* // Link[2]: Input_1 <- Cluster1_Funnel0:Output_0
* Package ( ) { 1 , 0 , \ _SB_ . CLU1 . FUN0 , 0 } ,
* } // End of Graph[0] Package
*
* } , // End of ACPI Graph Property
* } )
*/
static inline bool acpi_validate_dsd_graph ( const union acpi_object * graph )
{
int i , n ;
const union acpi_object * rev , * nr_graphs ;
/* The graph must contain at least the Revision and Number of Graphs */
if ( graph - > package . count < 2 )
return false ;
rev = & graph - > package . elements [ 0 ] ;
nr_graphs = & graph - > package . elements [ 1 ] ;
if ( rev - > type ! = ACPI_TYPE_INTEGER | |
nr_graphs - > type ! = ACPI_TYPE_INTEGER )
return false ;
/* We only support revision 0 */
if ( rev - > integer . value ! = 0 )
return false ;
n = nr_graphs - > integer . value ;
/* CoreSight devices are only part of a single Graph */
if ( n ! = 1 )
return false ;
/* Make sure the ACPI graph package has right number of elements */
if ( graph - > package . count ! = ( n + 2 ) )
return false ;
/*
* Each entry must be a graph package with at least 3 members :
* { GraphID , UUID , NumberOfLinks ( n ) , Links [ . ] , . . . }
*/
for ( i = 2 ; i < n + 2 ; i + + ) {
const union acpi_object * obj = & graph - > package . elements [ i ] ;
if ( obj - > type ! = ACPI_TYPE_PACKAGE | |
obj - > package . count < 3 )
return false ;
}
return true ;
}
/* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */
2020-05-18 21:02:35 +03:00
static const union acpi_object *
2019-06-19 22:53:06 +03:00
acpi_get_dsd_graph ( struct acpi_device * adev )
{
int i ;
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER } ;
acpi_status status ;
const union acpi_object * dsd ;
status = acpi_evaluate_object_typed ( adev - > handle , " _DSD " , NULL ,
& buf , ACPI_TYPE_PACKAGE ) ;
if ( ACPI_FAILURE ( status ) )
return NULL ;
dsd = buf . pointer ;
/*
* _DSD property consists tuples { Prop_UUID , Package ( ) }
* Iterate through all the packages and find the Graph .
*/
for ( i = 0 ; i + 1 < dsd - > package . count ; i + = 2 ) {
const union acpi_object * guid , * package ;
guid = & dsd - > package . elements [ i ] ;
package = & dsd - > package . elements [ i + 1 ] ;
/* All _DSD elements must have a UUID and a Package */
if ( ! is_acpi_guid ( guid ) | | package - > type ! = ACPI_TYPE_PACKAGE )
break ;
/* Skip the non-Graph _DSD packages */
if ( ! is_acpi_dsd_graph_guid ( guid ) )
continue ;
if ( acpi_validate_dsd_graph ( package ) )
return package ;
/* Invalid graph format, continue */
dev_warn ( & adev - > dev , " Invalid Graph _DSD property \n " ) ;
}
return NULL ;
}
static inline bool
acpi_validate_coresight_graph ( const union acpi_object * cs_graph )
{
int nlinks ;
nlinks = cs_graph - > package . elements [ 2 ] . integer . value ;
/*
* Graph must have the following fields :
* { GraphID , GraphUUID , NumberOfLinks , Links . . . }
*/
if ( cs_graph - > package . count ! = ( nlinks + 3 ) )
return false ;
/* The links are validated in acpi_coresight_parse_link() */
return true ;
}
/*
* acpi_get_coresight_graph - Parse the device _DSD tables and find
* the Graph property matching the CoreSight Graphs .
*
* Returns the pointer to the CoreSight Graph Package when found . Otherwise
* returns NULL .
*/
2020-05-18 21:02:35 +03:00
static const union acpi_object *
2019-06-19 22:53:06 +03:00
acpi_get_coresight_graph ( struct acpi_device * adev )
{
const union acpi_object * graph_list , * graph ;
int i , nr_graphs ;
graph_list = acpi_get_dsd_graph ( adev ) ;
if ( ! graph_list )
return graph_list ;
nr_graphs = graph_list - > package . elements [ 1 ] . integer . value ;
for ( i = 2 ; i < nr_graphs + 2 ; i + + ) {
graph = & graph_list - > package . elements [ i ] ;
if ( ! is_acpi_coresight_graph ( graph ) )
continue ;
if ( acpi_validate_coresight_graph ( graph ) )
return graph ;
/* Invalid graph format */
break ;
}
return NULL ;
}
/*
* acpi_coresight_parse_link - Parse the given Graph connection
* of the device and populate the coresight_connection for an output
* connection .
*
* CoreSight Graph specification mandates that the direction of the data
* flow must be specified in the link . i . e ,
*
* SourcePortAddress , // Integer
* DestinationPortAddress , // Integer
* DestinationDeviceName , // Reference to another device
* DirectionOfFlow , // 1 for output(master), 0 for input(slave)
*
* Returns the direction of the data flow [ Input ( slave ) or Output ( master ) ]
* upon success .
* Returns an negative error number otherwise .
*/
static int acpi_coresight_parse_link ( struct acpi_device * adev ,
const union acpi_object * link ,
struct coresight_connection * conn )
{
int rc , dir ;
const union acpi_object * fields ;
struct acpi_device * r_adev ;
struct device * rdev ;
if ( link - > type ! = ACPI_TYPE_PACKAGE | |
link - > package . count ! = 4 )
return - EINVAL ;
fields = link - > package . elements ;
if ( fields [ 0 ] . type ! = ACPI_TYPE_INTEGER | |
fields [ 1 ] . type ! = ACPI_TYPE_INTEGER | |
fields [ 2 ] . type ! = ACPI_TYPE_LOCAL_REFERENCE | |
fields [ 3 ] . type ! = ACPI_TYPE_INTEGER )
return - EINVAL ;
rc = acpi_bus_get_device ( fields [ 2 ] . reference . handle , & r_adev ) ;
if ( rc )
return rc ;
dir = fields [ 3 ] . integer . value ;
if ( dir = = ACPI_CORESIGHT_LINK_MASTER ) {
conn - > outport = fields [ 0 ] . integer . value ;
conn - > child_port = fields [ 1 ] . integer . value ;
rdev = coresight_find_device_by_fwnode ( & r_adev - > fwnode ) ;
if ( ! rdev )
return - EPROBE_DEFER ;
/*
* Hold the refcount to the target device . This could be
* released via :
* 1 ) coresight_release_platform_data ( ) if the probe fails or
* this device is unregistered .
* 2 ) While removing the target device via
* coresight_remove_match ( ) .
*/
conn - > child_fwnode = fwnode_handle_get ( & r_adev - > fwnode ) ;
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
} else if ( dir = = ACPI_CORESIGHT_LINK_SLAVE ) {
/*
* We are only interested in the port number
* for the input ports at this component .
* Store the port number in child_port .
*/
conn - > child_port = fields [ 0 ] . integer . value ;
} else {
/* Invalid direction */
return - EINVAL ;
2019-06-19 22:53:06 +03:00
}
return dir ;
}
/*
* acpi_coresight_parse_graph - Parse the _DSD CoreSight graph
* connection information and populate the supplied coresight_platform_data
* instance .
*/
static int acpi_coresight_parse_graph ( struct acpi_device * adev ,
struct coresight_platform_data * pdata )
{
int rc , i , nlinks ;
const union acpi_object * graph ;
struct coresight_connection * conns , * ptr ;
pdata - > nr_inport = pdata - > nr_outport = 0 ;
graph = acpi_get_coresight_graph ( adev ) ;
if ( ! graph )
return - ENOENT ;
nlinks = graph - > package . elements [ 2 ] . integer . value ;
if ( ! nlinks )
return 0 ;
/*
* To avoid scanning the table twice ( once for finding the number of
* output links and then later for parsing the output links ) ,
* cache the links information in one go and then later copy
* it to the pdata .
*/
conns = devm_kcalloc ( & adev - > dev , nlinks , sizeof ( * conns ) , GFP_KERNEL ) ;
if ( ! conns )
return - ENOMEM ;
ptr = conns ;
for ( i = 0 ; i < nlinks ; i + + ) {
const union acpi_object * link = & graph - > package . elements [ 3 + i ] ;
int dir ;
dir = acpi_coresight_parse_link ( adev , link , ptr ) ;
if ( dir < 0 )
return dir ;
if ( dir = = ACPI_CORESIGHT_LINK_MASTER ) {
2020-09-16 22:17:24 +03:00
if ( ptr - > outport > = pdata - > nr_outport )
pdata - > nr_outport = ptr - > outport + 1 ;
2019-06-19 22:53:06 +03:00
ptr + + ;
} else {
2020-09-16 22:17:24 +03:00
WARN_ON ( pdata - > nr_inport = = ptr - > child_port + 1 ) ;
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
/*
* We do not track input port connections for a device .
* However we need the highest port number described ,
* which can be recorded now and reuse this connection
* record for an output connection . Hence , do not move
* the ptr for input connections
*/
2020-09-16 22:17:24 +03:00
if ( ptr - > child_port > = pdata - > nr_inport )
pdata - > nr_inport = ptr - > child_port + 1 ;
2019-06-19 22:53:06 +03:00
}
}
rc = coresight_alloc_conns ( & adev - > dev , pdata ) ;
if ( rc )
return rc ;
/* Copy the connection information to the final location */
coresight: Fix support for sparsely populated ports
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Mike Leach <mike.leach@linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20200518180242.7916-13-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-18 21:02:31 +03:00
for ( i = 0 ; conns + i < ptr ; i + + ) {
int port = conns [ i ] . outport ;
/* Duplicate output port */
WARN_ON ( pdata - > conns [ port ] . child_fwnode ) ;
pdata - > conns [ port ] = conns [ i ] ;
}
2019-06-19 22:53:06 +03:00
devm_kfree ( & adev - > dev , conns ) ;
return 0 ;
}
/*
* acpi_handle_to_logical_cpuid - Map a given acpi_handle to the
* logical CPU id of the corresponding CPU device .
*
* Returns the logical CPU id when found . Otherwise returns > = nr_cpus_id .
*/
static int
acpi_handle_to_logical_cpuid ( acpi_handle handle )
{
int i ;
struct acpi_processor * pr ;
for_each_possible_cpu ( i ) {
pr = per_cpu ( processors , i ) ;
if ( pr & & pr - > handle = = handle )
break ;
}
return i ;
}
/*
* acpi_coresigh_get_cpu - Find the logical CPU id of the CPU associated
* with this coresight device . With ACPI bindings , the CoreSight components
* are listed as child device of the associated CPU .
*
* Returns the logical CPU id when found . Otherwise returns 0.
*/
static int acpi_coresight_get_cpu ( struct device * dev )
{
int cpu ;
acpi_handle cpu_handle ;
acpi_status status ;
struct acpi_device * adev = ACPI_COMPANION ( dev ) ;
if ( ! adev )
2019-07-04 12:53:05 +03:00
return - ENODEV ;
2019-06-19 22:53:06 +03:00
status = acpi_get_parent ( adev - > handle , & cpu_handle ) ;
if ( ACPI_FAILURE ( status ) )
2019-07-04 12:53:05 +03:00
return - ENODEV ;
2019-06-19 22:53:06 +03:00
cpu = acpi_handle_to_logical_cpuid ( cpu_handle ) ;
if ( cpu > = nr_cpu_ids )
2019-07-04 12:53:05 +03:00
return - ENODEV ;
2019-06-19 22:53:06 +03:00
return cpu ;
}
static int
acpi_get_coresight_platform_data ( struct device * dev ,
struct coresight_platform_data * pdata )
{
struct acpi_device * adev ;
adev = ACPI_COMPANION ( dev ) ;
if ( ! adev )
return - EINVAL ;
return acpi_coresight_parse_graph ( adev , pdata ) ;
}
# else
static inline int
acpi_get_coresight_platform_data ( struct device * dev ,
struct coresight_platform_data * pdata )
{
return - ENOENT ;
}
static inline int acpi_coresight_get_cpu ( struct device * dev )
{
2019-07-04 12:53:05 +03:00
return - ENODEV ;
2019-06-19 22:53:06 +03:00
}
# endif
2019-06-19 22:52:55 +03:00
int coresight_get_cpu ( struct device * dev )
{
if ( is_of_node ( dev - > fwnode ) )
return of_coresight_get_cpu ( dev ) ;
2019-06-19 22:53:06 +03:00
else if ( is_acpi_device_node ( dev - > fwnode ) )
return acpi_coresight_get_cpu ( dev ) ;
2019-06-19 22:52:55 +03:00
return 0 ;
}
EXPORT_SYMBOL_GPL ( coresight_get_cpu ) ;
2019-06-19 22:52:54 +03:00
struct coresight_platform_data *
coresight_get_platform_data ( struct device * dev )
{
int ret = - ENOENT ;
2019-06-19 22:53:01 +03:00
struct coresight_platform_data * pdata = NULL ;
2019-06-19 22:52:54 +03:00
struct fwnode_handle * fwnode = dev_fwnode ( dev ) ;
if ( IS_ERR_OR_NULL ( fwnode ) )
goto error ;
pdata = devm_kzalloc ( dev , sizeof ( * pdata ) , GFP_KERNEL ) ;
if ( ! pdata ) {
ret = - ENOMEM ;
goto error ;
}
if ( is_of_node ( fwnode ) )
ret = of_get_coresight_platform_data ( dev , pdata ) ;
2019-06-19 22:53:06 +03:00
else if ( is_acpi_device_node ( fwnode ) )
ret = acpi_get_coresight_platform_data ( dev , pdata ) ;
2019-06-19 22:52:54 +03:00
if ( ! ret )
return pdata ;
error :
2019-06-19 22:53:01 +03:00
if ( ! IS_ERR_OR_NULL ( pdata ) )
/* Cleanup the connection information */
2020-05-18 21:02:20 +03:00
coresight_release_platform_data ( NULL , pdata ) ;
2019-06-19 22:52:54 +03:00
return ERR_PTR ( ret ) ;
}
EXPORT_SYMBOL_GPL ( coresight_get_platform_data ) ;