Skip to content

Commit f3dc0e8

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 345eea9 commit f3dc0e8

5 files changed

Lines changed: 94 additions & 36 deletions

File tree

src/include/ipc4/notification.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,18 @@ 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+
#if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
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+
#include <zephyr/syscalls/notification.h>
305+
306+
#else
307+
308+
bool z_impl_send_resource_notif(uint32_t resource_id, uint32_t event_type,
309+
uint32_t resource_type, void *data, uint32_t data_size);
310+
#define send_resource_notif z_impl_send_resource_notif
311+
312+
#endif
313+
300314
#endif /* __IPC4_NOTIFICATION_H__ */

src/ipc/ipc4/CMakeLists.txt

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

1213
# The DAI interface is not implemented in library builds and

src/ipc/ipc4/notification-user.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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, 0);
24+
}
25+
26+
bool send_gateway_xrun_notif_msg(uint32_t resource_id, enum sof_ipc_stream_direction dir)
27+
{
28+
return send_resource_notif(resource_id, dir_to_xrun_event(dir), SOF_IPC4_GATEWAY, NULL, 0);
29+
}
30+
31+
void send_mixer_underrun_notif_msg(uint32_t resource_id, uint32_t eos_flag, uint32_t data_mixed,
32+
uint32_t expected_data_mixed)
33+
{
34+
struct ipc4_mixer_underrun_event_data mixer_underrun_data;
35+
36+
mixer_underrun_data.eos_flag = eos_flag;
37+
mixer_underrun_data.data_mixed = data_mixed;
38+
mixer_underrun_data.expected_data_mixed = expected_data_mixed;
39+
40+
send_resource_notif(resource_id, SOF_IPC4_MIXER_UNDERRUN_DETECTED, SOF_IPC4_PIPELINE,
41+
&mixer_underrun_data, sizeof(mixer_underrun_data));
42+
}
43+
EXPORT_SYMBOL(send_mixer_underrun_notif_msg);
44+
45+
void send_process_data_error_notif_msg(uint32_t resource_id, uint32_t error_code)
46+
{
47+
struct ipc4_process_data_error_event_data error_data;
48+
49+
error_data.error_code = error_code;
50+
51+
send_resource_notif(resource_id, SOF_IPC4_PROCESS_DATA_ERROR, SOF_IPC4_MODULE_INSTANCE,
52+
&error_data, sizeof(error_data));
53+
}

src/ipc/ipc4/notification.c

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

15-
#include <rtos/symbol.h>
15+
#ifdef __ZEPHYR__
16+
#include <zephyr/kernel.h>
17+
#include <zephyr/internal/syscall_handler.h>
18+
#endif
1619

1720
static uint32_t notification_mask = 0xFFFFFFFF;
1821

@@ -37,8 +40,8 @@ static bool is_notif_filtered_out(uint32_t event_type)
3740
return (notification_mask & BIT(notif_idx)) == 0;
3841
}
3942

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)
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)
4245
{
4346
struct ipc_msg *msg;
4447

@@ -80,49 +83,34 @@ static bool send_resource_notif(uint32_t resource_id, uint32_t event_type, uint3
8083
return true;
8184
}
8285

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-
8986
void ipc4_update_notification_mask(uint32_t ntfy_mask, uint32_t enabled_mask)
9087
{
9188
notification_mask &= enabled_mask | (~ntfy_mask);
9289
notification_mask |= enabled_mask & ntfy_mask;
9390
}
9491

95-
bool send_copier_gateway_xrun_notif_msg(uint32_t pipeline_id, enum sof_ipc_stream_direction dir)
92+
#if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
93+
static inline bool z_vrfy_send_resource_notif(uint32_t resource_id, uint32_t event_type,
94+
uint32_t resource_type, void *data,
95+
uint32_t data_size)
9696
{
97-
return send_resource_notif(pipeline_id, dir_to_xrun_event(dir), SOF_IPC4_PIPELINE, NULL,
98-
0);
99-
}
97+
/* Validate event_type is a known resource event */
98+
K_OOPS(K_SYSCALL_VERIFY(event_type < SOF_IPC4_INVALID_RESOURCE_EVENT_TYPE));
10099

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-
}
100+
/* Validate resource_type is a known resource type */
101+
K_OOPS(K_SYSCALL_VERIFY(resource_type < SOF_IPC4_INVALID_RESOURCE_TYPE));
105102

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;
103+
/* data and data_size must be consistent */
104+
K_OOPS(K_SYSCALL_VERIFY((!data && !data_size) || (data && data_size)));
114105

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;
106+
/* Payload must fit in the event_data union and the IPC message */
107+
K_OOPS(K_SYSCALL_VERIFY(data_size <= sizeof(union ipc4_resource_event_data)));
108+
K_OOPS(K_SYSCALL_VERIFY(data_size <= SOF_IPC_MSG_MAX_SIZE));
123109

124-
error_data.error_code = error_code;
110+
if (data && data_size)
111+
K_OOPS(K_SYSCALL_MEMORY_READ(data, data_size));
125112

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

zephyr/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,8 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE syscall/dai.c)
633633

634634
zephyr_syscall_header(${SOF_SRC_PATH}/include/user/debug_stream_slot.h)
635635

636+
zephyr_syscall_header(${SOF_SRC_PATH}/include/ipc4/notification.h)
637+
636638
zephyr_library_link_libraries(SOF)
637639
target_link_libraries(SOF INTERFACE zephyr_interface)
638640

0 commit comments

Comments
 (0)