Skip to content

Commit ec72578

Browse files
committed
Merge tag 'scmi-updates-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers
Arm SCMI updates for v6.13 Just couple of main additions: 1. Support for variable I/O width within ARM SCMI shared memory area. Some shared memory areas might only support a certain access width, such as 32-bit, which memcpy_{from,to}_io() does not adhere to at least on ARM64 by making both 8-bit and 64-bit accesses to such memory. This support updates the shmem layer to support reading from and writing to such shared memory area using the specified I/O width in the Device Tree. The various transport layers making use of the shmem.c code are updated accordingly to pass the I/O accessors that they store. The device tree bindings are also updated for the same. 2. Extension of SCMI transport bindings to add more properties SCMI transports are characterized by a number of properties. The values assumed by some of them tightly depend on the choices taken at design time and on the overall archiecture of the specific platform: things like timeouts, maximum message size and number of in-flight messages are closely tied to the architecture of the platform like number of SCMI agents on the system, physical memory available to the SCMI platform and so on. Such details are not discoverable as they are outside the scope of the SCMI protocol specification. Currently such properties are simple default values defined at build time, but the increasing number and variety of platforms using SCMI with a wide range of designs has increased the need to have a way to describe such properties across all these platforms. Apart from the above two, there is one NULL pointer dereference fix for very age old SCPI protocol driver which seems to be still in use on few platforms. * tag 'scmi-updates-6.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scpi: Check the DVFS OPP count returned by the firmware firmware: arm_scmi: Relocate atomic_threshold to scmi_desc firmware: arm_scmi: Use max_msg and max_msg_size devicetree properties dt-bindings: firmware: arm,scmi: Introduce more transport properties firmware: arm_scmi: Calculate virtio PDU max size dynamically firmware: arm_scmi: Account for SHMEM memory overhead firmware: arm_scmi: Support 'reg-io-width' property for shared memory dt-bindings: sram: Document reg-io-width property firmware: arm_scmi: Use vendor string in max-rx-timeout-ms dt-bindings: firmware: arm,scmi: Add missing vendor string firmware: arm_scmi: Reject clear channel request on A2P firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier() Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents 1fac9f8 + 109aa65 commit ec72578

File tree

11 files changed

+219
-60
lines changed

11 files changed

+219
-60
lines changed

Documentation/devicetree/bindings/firmware/arm,scmi.yaml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,28 @@ properties:
124124
atomic mode of operation, even if requested.
125125
default: 0
126126

127-
max-rx-timeout-ms:
127+
arm,max-rx-timeout-ms:
128128
description:
129129
An optional time value, expressed in milliseconds, representing the
130130
transport maximum timeout value for the receive channel. The value should
131131
be a non-zero value if set.
132132
minimum: 1
133133

134+
arm,max-msg-size:
135+
$ref: /schemas/types.yaml#/definitions/uint32
136+
description:
137+
An optional value, expressed in bytes, representing the maximum size
138+
allowed for the payload of messages transmitted on this transport.
139+
140+
arm,max-msg:
141+
$ref: /schemas/types.yaml#/definitions/uint32
142+
description:
143+
An optional value representing the maximum number of concurrent in-flight
144+
messages allowed by this transport; this number represents the maximum
145+
number of concurrently outstanding messages that the server can handle on
146+
this platform. If set, the value should be non-zero.
147+
minimum: 1
148+
134149
arm,smc-id:
135150
$ref: /schemas/types.yaml#/definitions/uint32
136151
description:

Documentation/devicetree/bindings/sram/sram.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ patternProperties:
101101
IO mem address range, relative to the SRAM range.
102102
maxItems: 1
103103

104+
reg-io-width:
105+
description:
106+
The size (in bytes) of the IO accesses that should be performed on the
107+
SRAM.
108+
enum: [1, 2, 4, 8]
109+
104110
pool:
105111
description:
106112
Indicates that the particular reserved SRAM area is addressable

drivers/firmware/arm_scmi/bus.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,10 @@ EXPORT_SYMBOL_GPL(scmi_driver_unregister);
325325

326326
static void scmi_device_release(struct device *dev)
327327
{
328-
kfree(to_scmi_dev(dev));
328+
struct scmi_device *scmi_dev = to_scmi_dev(dev);
329+
330+
kfree_const(scmi_dev->name);
331+
kfree(scmi_dev);
329332
}
330333

331334
static void __scmi_device_destroy(struct scmi_device *scmi_dev)
@@ -338,7 +341,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
338341
if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
339342
atomic_set(&scmi_syspower_registered, 0);
340343

341-
kfree_const(scmi_dev->name);
342344
ida_free(&scmi_bus_id, scmi_dev->id);
343345
device_unregister(&scmi_dev->dev);
344346
}
@@ -410,7 +412,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,
410412

411413
return scmi_dev;
412414
put_dev:
413-
kfree_const(scmi_dev->name);
414415
put_device(&scmi_dev->dev);
415416
ida_free(&scmi_bus_id, id);
416417
return NULL;

drivers/firmware/arm_scmi/common.h

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC)
3333

34+
#define SCMI_SHMEM_MAX_PAYLOAD_SIZE 104
35+
3436
enum scmi_error_codes {
3537
SCMI_SUCCESS = 0, /* Success */
3638
SCMI_ERR_SUPPORT = -1, /* Not supported */
@@ -163,7 +165,9 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
163165
* used to initialize this channel
164166
* @dev: Reference to device in the SCMI hierarchy corresponding to this
165167
* channel
168+
* @is_p2a: A flag to identify a channel as P2A (RX)
166169
* @rx_timeout_ms: The configured RX timeout in milliseconds.
170+
* @max_msg_size: Maximum size of message payload.
167171
* @handle: Pointer to SCMI entity handle
168172
* @no_completion_irq: Flag to indicate that this channel has no completion
169173
* interrupt mechanism for synchronous commands.
@@ -174,7 +178,9 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
174178
struct scmi_chan_info {
175179
int id;
176180
struct device *dev;
181+
bool is_p2a;
177182
unsigned int rx_timeout_ms;
183+
unsigned int max_msg_size;
178184
struct scmi_handle *handle;
179185
bool no_completion_irq;
180186
void *transport_info;
@@ -222,7 +228,13 @@ struct scmi_transport_ops {
222228
* @max_msg: Maximum number of messages for a channel type (tx or rx) that can
223229
* be pending simultaneously in the system. May be overridden by the
224230
* get_max_msg op.
225-
* @max_msg_size: Maximum size of data per message that can be handled.
231+
* @max_msg_size: Maximum size of data payload per message that can be handled.
232+
* @atomic_threshold: Optional system wide DT-configured threshold, expressed
233+
* in microseconds, for atomic operations.
234+
* Only SCMI synchronous commands reported by the platform
235+
* to have an execution latency lesser-equal to the threshold
236+
* should be considered for atomic mode operation: such
237+
* decision is finally left up to the SCMI drivers.
226238
* @force_polling: Flag to force this whole transport to use SCMI core polling
227239
* mechanism instead of completion interrupts even if available.
228240
* @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
@@ -241,6 +253,7 @@ struct scmi_desc {
241253
int max_rx_timeout_ms;
242254
int max_msg;
243255
int max_msg_size;
256+
unsigned int atomic_threshold;
244257
const bool force_polling;
245258
const bool sync_cmds_completed_on_ret;
246259
const bool atomic_enabled;
@@ -309,6 +322,26 @@ enum scmi_bad_msg {
309322
MSG_MBOX_SPURIOUS = -5,
310323
};
311324

325+
/* Used for compactness and signature validation of the function pointers being
326+
* passed.
327+
*/
328+
typedef void (*shmem_copy_toio_t)(void __iomem *to, const void *from,
329+
size_t count);
330+
typedef void (*shmem_copy_fromio_t)(void *to, const void __iomem *from,
331+
size_t count);
332+
333+
/**
334+
* struct scmi_shmem_io_ops - I/O operations to read from/write to
335+
* Shared Memory
336+
*
337+
* @toio: Copy data to the shared memory area
338+
* @fromio: Copy data from the shared memory area
339+
*/
340+
struct scmi_shmem_io_ops {
341+
shmem_copy_fromio_t fromio;
342+
shmem_copy_toio_t toio;
343+
};
344+
312345
/* shmem related declarations */
313346
struct scmi_shared_mem;
314347

@@ -329,21 +362,25 @@ struct scmi_shared_mem;
329362
struct scmi_shared_mem_operations {
330363
void (*tx_prepare)(struct scmi_shared_mem __iomem *shmem,
331364
struct scmi_xfer *xfer,
332-
struct scmi_chan_info *cinfo);
365+
struct scmi_chan_info *cinfo,
366+
shmem_copy_toio_t toio);
333367
u32 (*read_header)(struct scmi_shared_mem __iomem *shmem);
334368

335369
void (*fetch_response)(struct scmi_shared_mem __iomem *shmem,
336-
struct scmi_xfer *xfer);
370+
struct scmi_xfer *xfer,
371+
shmem_copy_fromio_t fromio);
337372
void (*fetch_notification)(struct scmi_shared_mem __iomem *shmem,
338-
size_t max_len, struct scmi_xfer *xfer);
373+
size_t max_len, struct scmi_xfer *xfer,
374+
shmem_copy_fromio_t fromio);
339375
void (*clear_channel)(struct scmi_shared_mem __iomem *shmem);
340376
bool (*poll_done)(struct scmi_shared_mem __iomem *shmem,
341377
struct scmi_xfer *xfer);
342378
bool (*channel_free)(struct scmi_shared_mem __iomem *shmem);
343379
bool (*channel_intr_enabled)(struct scmi_shared_mem __iomem *shmem);
344380
void __iomem *(*setup_iomap)(struct scmi_chan_info *cinfo,
345381
struct device *dev,
346-
bool tx, struct resource *res);
382+
bool tx, struct resource *res,
383+
struct scmi_shmem_io_ops **ops);
347384
};
348385

349386
const struct scmi_shared_mem_operations *scmi_shared_mem_operations_get(void);

drivers/firmware/arm_scmi/driver.c

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,6 @@ struct scmi_debug_info {
149149
* base protocol
150150
* @active_protocols: IDR storing device_nodes for protocols actually defined
151151
* in the DT and confirmed as implemented by fw.
152-
* @atomic_threshold: Optional system wide DT-configured threshold, expressed
153-
* in microseconds, for atomic operations.
154-
* Only SCMI synchronous commands reported by the platform
155-
* to have an execution latency lesser-equal to the threshold
156-
* should be considered for atomic mode operation: such
157-
* decision is finally left up to the SCMI drivers.
158152
* @notify_priv: Pointer to private data structure specific to notifications.
159153
* @node: List head
160154
* @users: Number of users of this instance
@@ -180,7 +174,6 @@ struct scmi_info {
180174
struct mutex protocols_mtx;
181175
u8 *protocols_imp;
182176
struct idr active_protocols;
183-
unsigned int atomic_threshold;
184177
void *notify_priv;
185178
struct list_head node;
186179
int users;
@@ -1048,6 +1041,11 @@ static inline void scmi_xfer_command_release(struct scmi_info *info,
10481041
static inline void scmi_clear_channel(struct scmi_info *info,
10491042
struct scmi_chan_info *cinfo)
10501043
{
1044+
if (!cinfo->is_p2a) {
1045+
dev_warn(cinfo->dev, "Invalid clear on A2P channel !\n");
1046+
return;
1047+
}
1048+
10511049
if (info->desc->ops->clear_channel)
10521050
info->desc->ops->clear_channel(cinfo);
10531051
}
@@ -2440,7 +2438,7 @@ static bool scmi_is_transport_atomic(const struct scmi_handle *handle,
24402438
ret = info->desc->atomic_enabled &&
24412439
is_transport_polling_capable(info->desc);
24422440
if (ret && atomic_threshold)
2443-
*atomic_threshold = info->atomic_threshold;
2441+
*atomic_threshold = info->desc->atomic_threshold;
24442442

24452443
return ret;
24462444
}
@@ -2638,7 +2636,9 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
26382636
if (!cinfo)
26392637
return -ENOMEM;
26402638

2639+
cinfo->is_p2a = !tx;
26412640
cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
2641+
cinfo->max_msg_size = info->desc->max_msg_size;
26422642

26432643
/* Create a unique name for this transport device */
26442644
snprintf(name, 32, "__scmi_transport_device_%s_%02X",
@@ -2952,7 +2952,7 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info)
29522952
(char **)&dbg->name);
29532953

29542954
debugfs_create_u32("atomic_threshold_us", 0400, top_dentry,
2955-
&info->atomic_threshold);
2955+
(u32 *)&info->desc->atomic_threshold);
29562956

29572957
debugfs_create_str("type", 0400, trans, (char **)&dbg->type);
29582958

@@ -3042,13 +3042,32 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
30423042

30433043
dev_info(dev, "Using %s\n", dev_driver_string(trans->supplier));
30443044

3045-
ret = of_property_read_u32(dev->of_node, "max-rx-timeout-ms",
3045+
ret = of_property_read_u32(dev->of_node, "arm,max-rx-timeout-ms",
30463046
&trans->desc->max_rx_timeout_ms);
30473047
if (ret && ret != -EINVAL)
3048-
dev_err(dev, "Malformed max-rx-timeout-ms DT property.\n");
3048+
dev_err(dev, "Malformed arm,max-rx-timeout-ms DT property.\n");
3049+
3050+
ret = of_property_read_u32(dev->of_node, "arm,max-msg-size",
3051+
&trans->desc->max_msg_size);
3052+
if (ret && ret != -EINVAL)
3053+
dev_err(dev, "Malformed arm,max-msg-size DT property.\n");
3054+
3055+
ret = of_property_read_u32(dev->of_node, "arm,max-msg",
3056+
&trans->desc->max_msg);
3057+
if (ret && ret != -EINVAL)
3058+
dev_err(dev, "Malformed arm,max-msg DT property.\n");
30493059

3050-
dev_info(dev, "SCMI max-rx-timeout: %dms\n",
3051-
trans->desc->max_rx_timeout_ms);
3060+
dev_info(dev,
3061+
"SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n",
3062+
trans->desc->max_rx_timeout_ms, trans->desc->max_msg_size,
3063+
trans->desc->max_msg);
3064+
3065+
/* System wide atomic threshold for atomic ops .. if any */
3066+
if (!of_property_read_u32(dev->of_node, "atomic-threshold-us",
3067+
&trans->desc->atomic_threshold))
3068+
dev_info(dev,
3069+
"SCMI System wide atomic threshold set to %u us\n",
3070+
trans->desc->atomic_threshold);
30523071

30533072
return trans->desc;
30543073
}
@@ -3099,13 +3118,6 @@ static int scmi_probe(struct platform_device *pdev)
30993118
handle->devm_protocol_acquire = scmi_devm_protocol_acquire;
31003119
handle->devm_protocol_get = scmi_devm_protocol_get;
31013120
handle->devm_protocol_put = scmi_devm_protocol_put;
3102-
3103-
/* System wide atomic threshold for atomic ops .. if any */
3104-
if (!of_property_read_u32(np, "atomic-threshold-us",
3105-
&info->atomic_threshold))
3106-
dev_info(dev,
3107-
"SCMI System wide atomic threshold set to %d us\n",
3108-
info->atomic_threshold);
31093121
handle->is_transport_atomic = scmi_is_transport_atomic;
31103122

31113123
/* Setup all channels described in the DT at first */

0 commit comments

Comments
 (0)