Skip to content

Commit e385f10

Browse files
author
Jyri Sarha
committed
ipc4: notification: make send_resource_notif() a syscall
Move user-facing notification functions (send_copier_gateway_xrun_notif_msg, send_gateway_xrun_notif_msg, send_mixer_underrun_notif_msg, send_process_data_error_notif_msg) to a new notification-user.c file so they can run in userspace. The send_resource_notif() function, which depends on the kernel-side notification pool and IPC message infrastructure, is converted to a Zephyr syscall. The implementation is renamed to z_impl_send_resource_notif() and remains in notification.c alongside is_notif_filtered_out() and ipc4_update_notification_mask(). The send_resource_notif() is converted to a system call only if CONFIG_SOF_USERSPACE_LL=y, without it the behaviour is same as befofe. A z_vrfy_send_resource_notif() handler is added to validate the user-provided data buffer and other parameters before forwarding to the kernel implementation. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent 11a17d5 commit e385f10

5 files changed

Lines changed: 102 additions & 36 deletions

File tree

src/include/ipc4/notification.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,21 @@ void send_mixer_underrun_notif_msg(uint32_t resource_id, uint32_t eos_flag, uint
297297
uint32_t expected_data_mixed);
298298
void ipc4_update_notification_mask(uint32_t ntfy_mask, uint32_t enabled_mask);
299299

300+
#ifdef CONFIG_SOF_USERSPACE_LL
301+
302+
__syscall bool send_resource_notif(uint32_t resource_id, uint32_t event_type,
303+
uint32_t resource_type, void *data, uint32_t data_size);
304+
305+
bool z_impl_send_resource_notif(uint32_t resource_id, uint32_t event_type,
306+
uint32_t resource_type, void *data, uint32_t data_size);
307+
308+
#include <zephyr/syscalls/notification.h>
309+
310+
#else
311+
312+
bool send_resource_notif(uint32_t resource_id, uint32_t event_type,
313+
uint32_t resource_type, void *data, uint32_t data_size);
314+
315+
#endif /* CONFIG_SOF_USERSPACE_LL */
316+
300317
#endif /* __IPC4_NOTIFICATION_H__ */

src/ipc/ipc4/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_local_sources(sof
88
helper.c
99
logging.c
1010
notification.c
11+
notification-user.c
1112
)
1213

1314
is_zephyr(zephyr)

src/ipc/ipc4/notification-user.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
/*
3+
* Copyright(c) 2023 Intel Corporation. All rights reserved.
4+
*
5+
* Author: Piotr Makaruk <piotr.makaruk@intel.com>
6+
* Adrian Warecki <adrian.warecki@intel.com>
7+
*/
8+
9+
#include <sof/common.h>
10+
#include <stdbool.h>
11+
#include <ipc4/notification.h>
12+
13+
#include <rtos/symbol.h>
14+
15+
static enum sof_ipc4_resource_event_type dir_to_xrun_event(enum sof_ipc_stream_direction dir)
16+
{
17+
return (dir == SOF_IPC_STREAM_PLAYBACK) ? SOF_IPC4_GATEWAY_UNDERRUN_DETECTED :
18+
SOF_IPC4_GATEWAY_OVERRUN_DETECTED;
19+
}
20+
21+
bool send_copier_gateway_xrun_notif_msg(uint32_t pipeline_id, enum sof_ipc_stream_direction dir)
22+
{
23+
return send_resource_notif(pipeline_id, dir_to_xrun_event(dir), SOF_IPC4_PIPELINE, NULL,
24+
0);
25+
}
26+
27+
bool send_gateway_xrun_notif_msg(uint32_t resource_id, enum sof_ipc_stream_direction dir)
28+
{
29+
return send_resource_notif(resource_id, dir_to_xrun_event(dir), SOF_IPC4_GATEWAY, NULL, 0);
30+
}
31+
32+
void send_mixer_underrun_notif_msg(uint32_t resource_id, uint32_t eos_flag, uint32_t data_mixed,
33+
uint32_t expected_data_mixed)
34+
{
35+
struct ipc4_mixer_underrun_event_data mixer_underrun_data;
36+
37+
mixer_underrun_data.eos_flag = eos_flag;
38+
mixer_underrun_data.data_mixed = data_mixed;
39+
mixer_underrun_data.expected_data_mixed = expected_data_mixed;
40+
41+
send_resource_notif(resource_id, SOF_IPC4_MIXER_UNDERRUN_DETECTED, SOF_IPC4_PIPELINE,
42+
&mixer_underrun_data, sizeof(mixer_underrun_data));
43+
}
44+
EXPORT_SYMBOL(send_mixer_underrun_notif_msg);
45+
46+
void send_process_data_error_notif_msg(uint32_t resource_id, uint32_t error_code)
47+
{
48+
struct ipc4_process_data_error_event_data error_data;
49+
50+
error_data.error_code = error_code;
51+
52+
send_resource_notif(resource_id, SOF_IPC4_PROCESS_DATA_ERROR, SOF_IPC4_MODULE_INSTANCE,
53+
&error_data, sizeof(error_data));
54+
}

src/ipc/ipc4/notification.c

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
#include <ipc4/notification.h>
1313
#include <sof/ipc/notification_pool.h>
1414

15-
#include <rtos/symbol.h>
15+
#ifdef CONFIG_SOF_USERSPACE_LL
16+
#include <zephyr/internal/syscall_handler.h>
17+
#endif
1618

1719
static uint32_t notification_mask = 0xFFFFFFFF;
1820

@@ -37,8 +39,13 @@ static bool is_notif_filtered_out(uint32_t event_type)
3739
return (notification_mask & BIT(notif_idx)) == 0;
3840
}
3941

40-
static bool send_resource_notif(uint32_t resource_id, uint32_t event_type, uint32_t resource_type,
41-
void *data, uint32_t data_size)
42+
#ifdef CONFIG_SOF_USERSPACE_LL
43+
bool z_impl_send_resource_notif(uint32_t resource_id, uint32_t event_type,
44+
uint32_t resource_type, void *data, uint32_t data_size)
45+
#else
46+
bool send_resource_notif(uint32_t resource_id, uint32_t event_type,
47+
uint32_t resource_type, void *data, uint32_t data_size)
48+
#endif
4249
{
4350
struct ipc_msg *msg;
4451

@@ -80,49 +87,34 @@ static bool send_resource_notif(uint32_t resource_id, uint32_t event_type, uint3
8087
return true;
8188
}
8289

83-
static enum sof_ipc4_resource_event_type dir_to_xrun_event(enum sof_ipc_stream_direction dir)
84-
{
85-
return (dir == SOF_IPC_STREAM_PLAYBACK) ? SOF_IPC4_GATEWAY_UNDERRUN_DETECTED :
86-
SOF_IPC4_GATEWAY_OVERRUN_DETECTED;
87-
}
88-
8990
void ipc4_update_notification_mask(uint32_t ntfy_mask, uint32_t enabled_mask)
9091
{
9192
notification_mask &= enabled_mask | (~ntfy_mask);
9293
notification_mask |= enabled_mask & ntfy_mask;
9394
}
9495

95-
bool send_copier_gateway_xrun_notif_msg(uint32_t pipeline_id, enum sof_ipc_stream_direction dir)
96+
#ifdef CONFIG_SOF_USERSPACE_LL
97+
static inline bool z_vrfy_send_resource_notif(uint32_t resource_id, uint32_t event_type,
98+
uint32_t resource_type, void *data,
99+
uint32_t data_size)
96100
{
97-
return send_resource_notif(pipeline_id, dir_to_xrun_event(dir), SOF_IPC4_PIPELINE, NULL,
98-
0);
99-
}
101+
/* Validate event_type is a known resource event */
102+
K_OOPS(K_SYSCALL_VERIFY(event_type < SOF_IPC4_INVALID_RESORUCE_EVENT_TYPE));
100103

101-
bool send_gateway_xrun_notif_msg(uint32_t resource_id, enum sof_ipc_stream_direction dir)
102-
{
103-
return send_resource_notif(resource_id, dir_to_xrun_event(dir), SOF_IPC4_GATEWAY, NULL, 0);
104-
}
104+
/* Validate resource_type is a known resource type */
105+
K_OOPS(K_SYSCALL_VERIFY(resource_type < SOF_IPC4_INVALID_RESOURCE_TYPE));
105106

106-
void send_mixer_underrun_notif_msg(uint32_t resource_id, uint32_t eos_flag, uint32_t data_mixed,
107-
uint32_t expected_data_mixed)
108-
{
109-
struct ipc4_mixer_underrun_event_data mixer_underrun_data;
110-
111-
mixer_underrun_data.eos_flag = eos_flag;
112-
mixer_underrun_data.data_mixed = data_mixed;
113-
mixer_underrun_data.expected_data_mixed = expected_data_mixed;
107+
/* data and data_size must be consistent */
108+
K_OOPS(K_SYSCALL_VERIFY((!data && !data_size) || (data && data_size)));
114109

115-
send_resource_notif(resource_id, SOF_IPC4_MIXER_UNDERRUN_DETECTED, SOF_IPC4_PIPELINE,
116-
&mixer_underrun_data, sizeof(mixer_underrun_data));
117-
}
118-
EXPORT_SYMBOL(send_mixer_underrun_notif_msg);
119-
120-
void send_process_data_error_notif_msg(uint32_t resource_id, uint32_t error_code)
121-
{
122-
struct ipc4_process_data_error_event_data error_data;
110+
/* Payload must fit in the event_data union and the IPC message */
111+
K_OOPS(K_SYSCALL_VERIFY(data_size <= sizeof(union ipc4_resource_event_data)));
112+
K_OOPS(K_SYSCALL_VERIFY(data_size <= SOF_IPC_MSG_MAX_SIZE));
123113

124-
error_data.error_code = error_code;
114+
if (data && data_size)
115+
K_OOPS(K_SYSCALL_MEMORY_READ(data, data_size));
125116

126-
send_resource_notif(resource_id, SOF_IPC4_PROCESS_DATA_ERROR, SOF_IPC4_MODULE_INSTANCE,
127-
&error_data, sizeof(error_data));
117+
return z_impl_send_resource_notif(resource_id, event_type, resource_type, data, data_size);
128118
}
119+
#include <zephyr/syscalls/send_resource_notif_mrsh.c>
120+
#endif

zephyr/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,8 @@ zephyr_library_sources(syscall/alloc.c)
557557
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/lib/dai-zephyr.h)
558558
zephyr_library_sources(syscall/dai.c)
559559

560+
zephyr_syscall_header(${SOF_SRC_PATH}/include/ipc4/notification.h)
561+
560562
zephyr_library_link_libraries(SOF)
561563
target_link_libraries(SOF INTERFACE zephyr_interface)
562564

0 commit comments

Comments
 (0)