kernel: fix errno access for user mode
The errno "variable" is required to be thread-specific. It gets defined to a macro which dereferences a pointer returned by a kernel function. In user mode, we cannot simply read/write the thread struct. We do not have thread-local storage mechanism, so for now use the lowest address of the thread stack to store this value, since this is guaranteed to be read/writable by a user thread. The downside of this approach is potential stack corruption if the stack pointer goes down this far but does not exceed the location, since a fault won't be generated in this case. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
89f87ec56e
commit
7f4d006959
6 changed files with 69 additions and 5 deletions
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
|
||||
#include <kernel_structs.h>
|
||||
#include <syscall_handler.h>
|
||||
|
||||
/*
|
||||
* Define _k_neg_eagain for use in assembly files as errno.h is
|
||||
|
@ -22,8 +23,20 @@
|
|||
const int _k_neg_eagain = -EAGAIN;
|
||||
|
||||
#ifdef CONFIG_ERRNO
|
||||
int *__errno(void)
|
||||
#ifdef CONFIG_USERSPACE
|
||||
int *_impl_z_errno(void)
|
||||
{
|
||||
/* Initialized to the lowest address in the stack so the thread can
|
||||
* directly read/write it
|
||||
*/
|
||||
return _current->errno_location;
|
||||
}
|
||||
|
||||
Z_SYSCALL_HANDLER0_SIMPLE(z_errno);
|
||||
#else
|
||||
int *_impl_z_errno(void)
|
||||
{
|
||||
return &_current->errno_var;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
#endif /* CONFIG_ERRNO */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue