kernel: pipe: runtime error checking
Add runtime error checking to k_pipe_cleanup and k_pipe_get and remove asserts. Adapted test which was expecting a fault to handle errors instead. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
5076a83ef5
commit
361a84d07f
3 changed files with 22 additions and 23 deletions
|
@ -4155,9 +4155,11 @@ void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size);
|
||||||
* if the buffer wasn't dynamically allocated.
|
* if the buffer wasn't dynamically allocated.
|
||||||
*
|
*
|
||||||
* @param pipe Address of the pipe.
|
* @param pipe Address of the pipe.
|
||||||
|
* @retval 0 on success
|
||||||
|
* @retval -EAGAIN nothing to cleanup
|
||||||
* @req K-PIPE-002
|
* @req K-PIPE-002
|
||||||
*/
|
*/
|
||||||
void k_pipe_cleanup(struct k_pipe *pipe);
|
int k_pipe_cleanup(struct k_pipe *pipe);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize a pipe and allocate a buffer for it
|
* @brief Initialize a pipe and allocate a buffer for it
|
||||||
|
@ -4216,6 +4218,7 @@ __syscall int k_pipe_put(struct k_pipe *pipe, void *data,
|
||||||
* and K_FOREVER.
|
* and K_FOREVER.
|
||||||
*
|
*
|
||||||
* @retval 0 At least @a min_xfer bytes of data were read.
|
* @retval 0 At least @a min_xfer bytes of data were read.
|
||||||
|
* @retval -EINVAL invalid parameters supplied
|
||||||
* @retval -EIO Returned without waiting; zero data bytes were read.
|
* @retval -EIO Returned without waiting; zero data bytes were read.
|
||||||
* @retval -EAGAIN Waiting period timed out; between zero and @a min_xfer
|
* @retval -EAGAIN Waiting period timed out; between zero and @a min_xfer
|
||||||
* minus one data bytes were read.
|
* minus one data bytes were read.
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include <sys/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <syscall_handler.h>
|
#include <syscall_handler.h>
|
||||||
#include <sys/__assert.h>
|
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
|
#include <sys/check.h>
|
||||||
|
|
||||||
struct k_pipe_desc {
|
struct k_pipe_desc {
|
||||||
unsigned char *buffer; /* Position in src/dest buffer */
|
unsigned char *buffer; /* Position in src/dest buffer */
|
||||||
|
@ -174,16 +174,19 @@ static inline int z_vrfy_k_pipe_alloc_init(struct k_pipe *pipe, size_t size)
|
||||||
#include <syscalls/k_pipe_alloc_init_mrsh.c>
|
#include <syscalls/k_pipe_alloc_init_mrsh.c>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void k_pipe_cleanup(struct k_pipe *pipe)
|
int k_pipe_cleanup(struct k_pipe *pipe)
|
||||||
{
|
{
|
||||||
__ASSERT_NO_MSG(!z_waitq_head(&pipe->wait_q.readers));
|
CHECKIF(z_waitq_head(&pipe->wait_q.readers) != NULL ||
|
||||||
__ASSERT_NO_MSG(!z_waitq_head(&pipe->wait_q.writers));
|
z_waitq_head(&pipe->wait_q.writers) != NULL) {
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
if ((pipe->flags & K_PIPE_FLAG_ALLOC) != 0) {
|
if ((pipe->flags & K_PIPE_FLAG_ALLOC) != 0) {
|
||||||
k_free(pipe->buffer);
|
k_free(pipe->buffer);
|
||||||
pipe->buffer = NULL;
|
pipe->buffer = NULL;
|
||||||
pipe->flags &= ~K_PIPE_FLAG_ALLOC;
|
pipe->flags &= ~K_PIPE_FLAG_ALLOC;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -438,6 +441,10 @@ int z_pipe_put_internal(struct k_pipe *pipe, struct k_pipe_async *async_desc,
|
||||||
ARG_UNUSED(async_desc);
|
ARG_UNUSED(async_desc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CHECKIF((min_xfer > bytes_to_write) || bytes_written == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
k_spinlock_key_t key = k_spin_lock(&pipe->lock);
|
k_spinlock_key_t key = k_spin_lock(&pipe->lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -577,8 +584,9 @@ int z_impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
||||||
size_t num_bytes_read = 0;
|
size_t num_bytes_read = 0;
|
||||||
size_t bytes_copied;
|
size_t bytes_copied;
|
||||||
|
|
||||||
__ASSERT(min_xfer <= bytes_to_read, "");
|
CHECKIF((min_xfer > bytes_to_read) || bytes_read == NULL) {
|
||||||
__ASSERT(bytes_read != NULL, "");
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
k_spinlock_key_t key = k_spin_lock(&pipe->lock);
|
k_spinlock_key_t key = k_spin_lock(&pipe->lock);
|
||||||
|
|
||||||
|
@ -586,7 +594,6 @@ int z_impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
||||||
* Create a list of "working readers" into which the data will be
|
* Create a list of "working readers" into which the data will be
|
||||||
* directly copied.
|
* directly copied.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!pipe_xfer_prepare(&xfer_list, &writer, &pipe->wait_q.writers,
|
if (!pipe_xfer_prepare(&xfer_list, &writer, &pipe->wait_q.writers,
|
||||||
pipe->bytes_used, bytes_to_read,
|
pipe->bytes_used, bytes_to_read,
|
||||||
min_xfer, timeout)) {
|
min_xfer, timeout)) {
|
||||||
|
@ -718,7 +725,6 @@ int z_vrfy_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
||||||
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
||||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read)));
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read)));
|
||||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read));
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read));
|
||||||
Z_OOPS(Z_SYSCALL_VERIFY(min_xfer <= bytes_to_read));
|
|
||||||
|
|
||||||
return z_impl_k_pipe_get((struct k_pipe *)pipe, (void *)data,
|
return z_impl_k_pipe_get((struct k_pipe *)pipe, (void *)data,
|
||||||
bytes_to_read, bytes_read, min_xfer,
|
bytes_to_read, bytes_read, min_xfer,
|
||||||
|
@ -730,9 +736,6 @@ int z_vrfy_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
||||||
int z_impl_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
|
int z_impl_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
|
||||||
size_t *bytes_written, size_t min_xfer, s32_t timeout)
|
size_t *bytes_written, size_t min_xfer, s32_t timeout)
|
||||||
{
|
{
|
||||||
__ASSERT(min_xfer <= bytes_to_write, "");
|
|
||||||
__ASSERT(bytes_written != NULL, "");
|
|
||||||
|
|
||||||
return z_pipe_put_internal(pipe, NULL, data,
|
return z_pipe_put_internal(pipe, NULL, data,
|
||||||
bytes_to_write, bytes_written,
|
bytes_to_write, bytes_written,
|
||||||
min_xfer, timeout);
|
min_xfer, timeout);
|
||||||
|
@ -745,7 +748,6 @@ int z_vrfy_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
|
||||||
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
||||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written)));
|
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written)));
|
||||||
Z_OOPS(Z_SYSCALL_MEMORY_READ((void *)data, bytes_to_write));
|
Z_OOPS(Z_SYSCALL_MEMORY_READ((void *)data, bytes_to_write));
|
||||||
Z_OOPS(Z_SYSCALL_VERIFY(min_xfer <= bytes_to_write));
|
|
||||||
|
|
||||||
return z_impl_k_pipe_put((struct k_pipe *)pipe, (void *)data,
|
return z_impl_k_pipe_put((struct k_pipe *)pipe, (void *)data,
|
||||||
bytes_to_write, bytes_written, min_xfer,
|
bytes_to_write, bytes_written, min_xfer,
|
||||||
|
|
|
@ -813,22 +813,16 @@ void test_pipe_get_timeout(void)
|
||||||
* @ingroup kernel_pipe_tests
|
* @ingroup kernel_pipe_tests
|
||||||
* @see k_pipe_get()
|
* @see k_pipe_get()
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_USERSPACE
|
|
||||||
/* userspace invalid size */
|
|
||||||
void test_pipe_get_invalid_size(void)
|
void test_pipe_get_invalid_size(void)
|
||||||
{
|
{
|
||||||
size_t read;
|
size_t read;
|
||||||
|
int ret;
|
||||||
|
|
||||||
valid_fault = true;
|
valid_fault = true;
|
||||||
k_pipe_get(&test_pipe, &rx_buffer,
|
ret = k_pipe_get(&test_pipe, &rx_buffer,
|
||||||
0, &read,
|
0, &read,
|
||||||
1, TIMEOUT_200MSEC);
|
1, TIMEOUT_200MSEC);
|
||||||
|
|
||||||
zassert_unreachable("fault didn't occur for min_xfer <= bytes_to_read");
|
zassert_equal(ret, -EINVAL,
|
||||||
|
"fault didn't occur for min_xfer <= bytes_to_read");
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
void test_pipe_get_invalid_size(void)
|
|
||||||
{
|
|
||||||
ztest_test_skip();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue