-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lkl: 32-bit timespec fixes #556
Conversation
ddiss
commented
Jan 31, 2025
•
edited
Loading
edited
Use the always-64-bit __lkl__kernel_timespec struct for lkl_sys_nanosleep calls and rewrite the lkl_sys_nanosleep_time32 wrapper to use __lkl__NR_clock_nanosleep_time64 on 32-bit builds. This fixes the following -Wincompatible-pointer-types errors: lib/fs.c:287:43: error: passing argument 1 of ‘lkl_sys_nanosleep_time32’ from incompatible pointer type [-Wincompatible-pointer-types] 287 | lkl_sys_nanosleep((struct __lkl__kernel_timespec *)&ts, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | struct __lkl__kernel_timespec * In file included from tools/lkl//include/lkl_host.h:9, from lib/fs.c:5: tools/lkl//include/lkl.h:68:65: note: expected ‘struct lkl_timespec *’ but argument is of type ‘struct __lkl__kernel_timespec *’ 68 | static inline int lkl_sys_nanosleep_time32(struct lkl_timespec *rqtp, | ~~~~~~~~~~~~~~~~~~~~~^~~~ make[1]: *** [tools/build/Makefile.build:98: tools/lkl/lib/fs.o] Error 1 Signed-off-by: David Disseldorp <[email protected]>
Explicitly cast between unsigned long and size_t for malloc, memcpy and memset. Signed-off-by: David Disseldorp <[email protected]>
Regarding the checkpatch warnings: two are from unwrapped compiler output in the commit messages and one is for a I have some more 32-bit time_t fixes which I'll push here soon. |
static inline int lkl_sys_nanosleep_time32(struct lkl_timespec *rqtp, | ||
struct lkl_timespec *rmtp) | ||
static inline int lkl_sys_nanosleep(struct __lkl__kernel_timespec *rqtp, | ||
struct __lkl__kernel_timespec *rmtp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should follow what Linux does and provide timespec for LKL APIs, even if for 32 bit machines it means that we loose range. Per timespec(3) man:
SYNOPSIS
#include <time.h>
struct timespec {
time_t tv_sec; /* Seconds */
/* ... */ tv_nsec; /* Nanoseconds [0, 999'999'999] */
};
DESCRIPTION
Describes times in seconds and nanoseconds.
tv_nsec is of an implementation-defined signed type capable of holding the specified range. Under glibc, this is usually long,
and long long on X32. It can be safely down-cast to any concrete 32-bit integer type for processing.
So basically use a local __lkl_kernel_timespec, copy the data from lkl_timespec argument, and pass the local to the system call.
Then we can remove __lkl_kernel_timespec
from LKL libs and apps which we introduced in 3d4047a. @thehajime does this sound reasonable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you just want this wrapper for nanosleep
, or should I also add lkl_timespec wrappers for lkl_sys_utimensat()
? I was hoping to avoid going too far down the generic-libc path and just stick to the modern kernel API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed a962b15 to this branch (with two extra changes) to show where other wrappers would be needed if we switch callers to lkl_timespec.
On the generic-libc side, I wonder whether lkl could hook into nolibc via e.g. tools/include/nolibc/arch-lkl.h
. It's already in-tree and relatively exhaustive in terms of syscalls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we can remove
__lkl_kernel_timespec
from LKL libs and apps which we introduced in 3d4047a. @thehajime does this sound reasonable?
sorry, I don't quite remember what/why my followup fixes (3d4047a) did.. my best guess is to silence warnings from compilation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you just want this wrapper for nanosleep, or should I also add lkl_timespec wrappers for lkl_sys_utimensat()? I was hoping to avoid going too far down the generic-libc path and just stick to the modern kernel API.
I thought more about this and I think you are right, we should stick with modern kernel APIs.
We should be able to override struct timespec
defined in include/uapi/linux/time.h
with a custom one arch/lkl/include/uapi/asm/types.h
. If you prefer to merge as is (use __lkl_kernel_timespec) for now we can cleanup later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...
We should be able to override
struct timespec
defined ininclude/uapi/linux/time.h
with a custom onearch/lkl/include/uapi/asm/types.h
. If you prefer to merge as is (use __lkl_kernel_timespec) for now we can cleanup later.
I'm not sure I follow; would you like some sort of helper macro to ease conversion from timespec
to __lkl_kernel_timespec
? Thanks a lot for the review btw
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets merge this as it is and I will followup with a proposal.
a962b15
to
31f9880
Compare
I've reworked the |
Don't bother parsing the results if the initial stat call failed. Signed-off-by: David Disseldorp <[email protected]>
max_time is incorrect for both 8-byte and 4-byte time_t sizes. It should be 0x7fffffffffffffff on 64-bit arches instead of 0x7fe. Given that we will (in the next commit) be casting from a (long x 2) lkl_timeval to a (long long x 2) __lkl__kernel_timespec, I think we can ignore overflow and match the nolibc conversion logic. Link: lkl#557 Fixes: 780bdc7 ("lkl: follow up fixes after 4.17 merge") Signed-off-by: David Disseldorp <[email protected]>
On 32-bit architectures, struct lkl_timespec is 2*sizeof(long) while __lkl__kernel_timespec is 2*sizeof(long long); casting these pointer types is unsafe. Fixes: 3d4047a ("lkl: follow up fixes after v5.1 merge (y2038)") Signed-off-by: David Disseldorp <[email protected]>
31f9880
to
0692c1e
Compare
Changes since previous version:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, great work @ddis, thank you!