* [PATCH 0/2] linux-user: fixes for sched_ syscalls
@ 2021-12-11 2:27 Tonis Tiigi
2021-12-11 2:27 ` [PATCH 1/2] linux-user: add sched_getattr support Tonis Tiigi
2021-12-11 2:27 ` [PATCH 2/2] linux-user: call set/getscheduler set/getparam directly Tonis Tiigi
0 siblings, 2 replies; 5+ messages in thread
From: Tonis Tiigi @ 2021-12-11 2:27 UTC (permalink / raw)
To: qemu-devel, Laurent Vivier; +Cc: Tonis Tiigi
This patchset improves support for sched_* syscalls under user emulation. The first commit adds support for sched_g/setattr that was previously not implemented. There is no equivalent for these syscalls in libc, so I needed to redefine the struct from kernel. It can't be included directly because of conflict with libc sched headers.
The second commit fixes sched_g/setscheduler and sched_g/setparam, when QEMU is built with musl. Musl does not implement these due to conflict between what these functions should do in syscalls and libc https://git.musl-libc.org/cgit/musl/commit/?id=1e21e78bf7a5c24c217446d8760be7b7188711c2 . I've changed it to call syscall directly what should always be the expected behavior for the user.
Via https://github.com/tonistiigi/binfmt/pull/70 with additional tests.
Tonis Tiigi (2):
linux-user: add sched_getattr support
linux-user: call set/getscheduler set/getparam directly
linux-user/syscall.c | 71 ++++++++++++++++++++++++++++++++++++---
linux-user/syscall_defs.h | 15 +++++++++
2 files changed, 82 insertions(+), 4 deletions(-)
--
2.30.1 (Apple Git-130)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] linux-user: add sched_getattr support
2021-12-11 2:27 [PATCH 0/2] linux-user: fixes for sched_ syscalls Tonis Tiigi
@ 2021-12-11 2:27 ` Tonis Tiigi
2021-12-19 17:09 ` Laurent Vivier
2021-12-11 2:27 ` [PATCH 2/2] linux-user: call set/getscheduler set/getparam directly Tonis Tiigi
1 sibling, 1 reply; 5+ messages in thread
From: Tonis Tiigi @ 2021-12-11 2:27 UTC (permalink / raw)
To: qemu-devel, Laurent Vivier; +Cc: Tonis Tiigi
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
---
linux-user/syscall.c | 55 +++++++++++++++++++++++++++++++++++++++
linux-user/syscall_defs.h | 15 +++++++++++
2 files changed, 70 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f1cfcc8104..670b61b2ef 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -339,6 +339,10 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
unsigned long *, user_mask_ptr);
+#define __NR_sys_sched_getattr __NR_sched_getattr
+_syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr, unsigned int, size, unsigned int, flags);
+#define __NR_sys_sched_setattr __NR_sched_setattr
+_syscall3(int, sys_sched_setattr, pid_t, pid, struct sched_attr *, attr, unsigned int, flags);
#define __NR_sys_getcpu __NR_getcpu
_syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
@@ -10593,6 +10597,57 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
}
case TARGET_NR_sched_getscheduler:
return get_errno(sched_getscheduler(arg1));
+ case TARGET_NR_sched_getattr:
+ {
+ struct target_sched_attr *target_scha;
+ struct target_sched_attr scha;
+ if (arg2 == 0) {
+ return -TARGET_EINVAL;
+ }
+ ret = get_errno(sys_sched_getattr(arg1, &scha, arg3, arg4));
+ if (!is_error(ret)) {
+ if (!lock_user_struct(VERIFY_WRITE, target_scha, arg2, 0))
+ return -TARGET_EFAULT;
+ target_scha->size = tswap32(scha.size);
+ target_scha->sched_policy = tswap32(scha.sched_policy);
+ target_scha->sched_flags = tswap64(scha.sched_policy);
+ target_scha->sched_nice = tswap32(scha.sched_nice);
+ target_scha->sched_priority = tswap32(scha.sched_priority);
+ target_scha->sched_runtime = tswap64(scha.sched_runtime);
+ target_scha->sched_deadline = tswap64(scha.sched_deadline);
+ target_scha->sched_period = tswap64(scha.sched_period);
+ if (scha.size >= 0x38) {
+ target_scha->sched_util_min = tswap32(scha.sched_util_min);
+ target_scha->sched_util_max = tswap32(scha.sched_util_max);
+ }
+ unlock_user_struct(target_scha, arg2, 1);
+ }
+ return ret;
+ }
+ case TARGET_NR_sched_setattr:
+ {
+ struct target_sched_attr *target_scha;
+ struct target_sched_attr scha;
+ if (arg2 == 0) {
+ return -TARGET_EINVAL;
+ }
+ if (!lock_user_struct(VERIFY_READ, target_scha, arg2, 1))
+ return -TARGET_EFAULT;
+ scha.size = tswap32(target_scha->size);
+ scha.sched_policy = tswap32(target_scha->sched_policy);
+ scha.sched_flags = tswap64(target_scha->sched_flags);
+ scha.sched_nice = tswap32(target_scha->sched_nice);
+ scha.sched_priority = tswap32(target_scha->sched_priority);
+ scha.sched_runtime = tswap64(target_scha->sched_runtime);
+ scha.sched_deadline = tswap64(target_scha->sched_deadline);
+ scha.sched_period = tswap64(target_scha->sched_period);
+ if (scha.size >= 0x38) {
+ scha.sched_util_min = tswap32(target_scha->sched_util_min);
+ scha.sched_util_max = tswap32(target_scha->sched_util_max);
+ }
+ unlock_user_struct(target_scha, arg2, 0);
+ return get_errno(sys_sched_setattr(arg1, &scha, arg3));
+ }
case TARGET_NR_sched_yield:
return get_errno(sched_yield());
case TARGET_NR_sched_get_priority_max:
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 0b13975937..715ec75462 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2914,4 +2914,19 @@ struct target_statx {
/* 0x100 */
};
+/* from kernel's include/linux/sched/types.h */
+struct target_sched_attr {
+ uint32_t size;
+ uint32_t sched_policy;
+ uint64_t sched_flags;
+ int32_t sched_nice;
+ uint32_t sched_priority;
+ uint64_t sched_runtime;
+ uint64_t sched_deadline;
+ uint64_t sched_period;
+ // 0x30
+ uint32_t sched_util_min;
+ uint32_t sched_util_max;
+};
+
#endif
--
2.30.1 (Apple Git-130)
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] linux-user: call set/getscheduler set/getparam directly
2021-12-11 2:27 [PATCH 0/2] linux-user: fixes for sched_ syscalls Tonis Tiigi
2021-12-11 2:27 ` [PATCH 1/2] linux-user: add sched_getattr support Tonis Tiigi
@ 2021-12-11 2:27 ` Tonis Tiigi
2021-12-19 17:19 ` Laurent Vivier
1 sibling, 1 reply; 5+ messages in thread
From: Tonis Tiigi @ 2021-12-11 2:27 UTC (permalink / raw)
To: qemu-devel, Laurent Vivier; +Cc: Tonis Tiigi
There seems to be difference in syscall and libc definition of these
methods and therefore musl does not implement them (1e21e78bf7). Call
syscall directly to ensure the behavior of the libc of user application,
not the libc that was used to build QEMU.
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
---
linux-user/syscall.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 670b61b2ef..263d7fac5e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -343,6 +343,14 @@ _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
_syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr, unsigned int, size, unsigned int, flags);
#define __NR_sys_sched_setattr __NR_sched_setattr
_syscall3(int, sys_sched_setattr, pid_t, pid, struct sched_attr *, attr, unsigned int, flags);
+#define __NR_sys_sched_getscheduler __NR_sched_getscheduler
+_syscall1(int, sys_sched_getscheduler, pid_t, pid);
+#define __NR_sys_sched_setscheduler __NR_sched_setscheduler
+_syscall3(int, sys_sched_setscheduler, pid_t, pid, int, policy, const struct sched_param *, param);
+#define __NR_sys_sched_getparam __NR_sched_getparam
+_syscall2(int, sys_sched_getparam, pid_t, pid, struct sched_param *, param);
+#define __NR_sys_sched_setparam __NR_sched_setparam
+_syscall2(int, sys_sched_setparam, pid_t, pid, const struct sched_param *, param);
#define __NR_sys_getcpu __NR_getcpu
_syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
@@ -10563,7 +10571,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return -TARGET_EFAULT;
schp.sched_priority = tswap32(target_schp->sched_priority);
unlock_user_struct(target_schp, arg2, 0);
- return get_errno(sched_setparam(arg1, &schp));
+ return get_errno(sys_sched_setparam(arg1, &schp));
}
case TARGET_NR_sched_getparam:
{
@@ -10573,7 +10581,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (arg2 == 0) {
return -TARGET_EINVAL;
}
- ret = get_errno(sched_getparam(arg1, &schp));
+ ret = get_errno(sys_sched_getparam(arg1, &schp));
if (!is_error(ret)) {
if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
return -TARGET_EFAULT;
@@ -10593,10 +10601,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return -TARGET_EFAULT;
schp.sched_priority = tswap32(target_schp->sched_priority);
unlock_user_struct(target_schp, arg3, 0);
- return get_errno(sched_setscheduler(arg1, arg2, &schp));
+ return get_errno(sys_sched_setscheduler(arg1, arg2, &schp));
}
case TARGET_NR_sched_getscheduler:
- return get_errno(sched_getscheduler(arg1));
+ return get_errno(sys_sched_getscheduler(arg1));
case TARGET_NR_sched_getattr:
{
struct target_sched_attr *target_scha;
--
2.30.1 (Apple Git-130)
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] linux-user: add sched_getattr support
2021-12-11 2:27 ` [PATCH 1/2] linux-user: add sched_getattr support Tonis Tiigi
@ 2021-12-19 17:09 ` Laurent Vivier
0 siblings, 0 replies; 5+ messages in thread
From: Laurent Vivier @ 2021-12-19 17:09 UTC (permalink / raw)
To: Tonis Tiigi, qemu-devel
Le 11/12/2021 à 03:27, Tonis Tiigi a écrit :
> Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
> ---
> linux-user/syscall.c | 55 +++++++++++++++++++++++++++++++++++++++
> linux-user/syscall_defs.h | 15 +++++++++++
> 2 files changed, 70 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index f1cfcc8104..670b61b2ef 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -339,6 +339,10 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
> #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
> _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
> unsigned long *, user_mask_ptr);
> +#define __NR_sys_sched_getattr __NR_sched_getattr
> +_syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr, unsigned int, size, unsigned int, flags);
> +#define __NR_sys_sched_setattr __NR_sched_setattr
> +_syscall3(int, sys_sched_setattr, pid_t, pid, struct sched_attr *, attr, unsigned int, flags);
> #define __NR_sys_getcpu __NR_getcpu
> _syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
> _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
> @@ -10593,6 +10597,57 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
> }
> case TARGET_NR_sched_getscheduler:
> return get_errno(sched_getscheduler(arg1));
> + case TARGET_NR_sched_getattr:
> + {
> + struct target_sched_attr *target_scha;
> + struct target_sched_attr scha;
> + if (arg2 == 0) {
> + return -TARGET_EINVAL;
> + }
> + ret = get_errno(sys_sched_getattr(arg1, &scha, arg3, arg4));
> + if (!is_error(ret)) {
> + if (!lock_user_struct(VERIFY_WRITE, target_scha, arg2, 0))
As sizeof(target_scha) can be greater than arg3, you should user lock_user() with arg3 as length.
> + return -TARGET_EFAULT;
QEMU style uses braces {} even for one line statement.
You can run scripts/checkpath.pl to check the style
> + target_scha->size = tswap32(scha.size);
> + target_scha->sched_policy = tswap32(scha.sched_policy);
> + target_scha->sched_flags = tswap64(scha.sched_policy);
> + target_scha->sched_nice = tswap32(scha.sched_nice);
> + target_scha->sched_priority = tswap32(scha.sched_priority);
> + target_scha->sched_runtime = tswap64(scha.sched_runtime);
> + target_scha->sched_deadline = tswap64(scha.sched_deadline);
> + target_scha->sched_period = tswap64(scha.sched_period);
> + if (scha.size >= 0x38) {
You should use offsetot(target_sched_attr, sched_util_min) rather than 0x38.
> + target_scha->sched_util_min = tswap32(scha.sched_util_min);
> + target_scha->sched_util_max = tswap32(scha.sched_util_max);
> + }
> + unlock_user_struct(target_scha, arg2, 1);
> + }
> + return ret;
> + }
> + case TARGET_NR_sched_setattr:
> + {
> + struct target_sched_attr *target_scha;
> + struct target_sched_attr scha;
> + if (arg2 == 0) {
> + return -TARGET_EINVAL;
> + }
> + if (!lock_user_struct(VERIFY_READ, target_scha, arg2, 1))
> + return -TARGET_EFAULT;
same comment
> + scha.size = tswap32(target_scha->size);
> + scha.sched_policy = tswap32(target_scha->sched_policy);
> + scha.sched_flags = tswap64(target_scha->sched_flags);
> + scha.sched_nice = tswap32(target_scha->sched_nice);
> + scha.sched_priority = tswap32(target_scha->sched_priority);
> + scha.sched_runtime = tswap64(target_scha->sched_runtime);
> + scha.sched_deadline = tswap64(target_scha->sched_deadline);
> + scha.sched_period = tswap64(target_scha->sched_period);
> + if (scha.size >= 0x38) {
same comment
> + scha.sched_util_min = tswap32(target_scha->sched_util_min);
> + scha.sched_util_max = tswap32(target_scha->sched_util_max);
> + }
> + unlock_user_struct(target_scha, arg2, 0);
> + return get_errno(sys_sched_setattr(arg1, &scha, arg3));
> + }
> case TARGET_NR_sched_yield:
> return get_errno(sched_yield());
> case TARGET_NR_sched_get_priority_max:
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 0b13975937..715ec75462 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -2914,4 +2914,19 @@ struct target_statx {
> /* 0x100 */
> };
>
> +/* from kernel's include/linux/sched/types.h */
> +struct target_sched_attr {
> + uint32_t size;
> + uint32_t sched_policy;
> + uint64_t sched_flags;
> + int32_t sched_nice;
> + uint32_t sched_priority;
> + uint64_t sched_runtime;
> + uint64_t sched_deadline;
> + uint64_t sched_period;
> + // 0x30
Remove this comment
> + uint32_t sched_util_min;
> + uint32_t sched_util_max;
> +};
> +
Please, use abi_uint, abit_int, abi_ullong rather than uint32_t, int32_t and uint64_t.
These types forces alignment according to the target type.
Thanks,
Laurent
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] linux-user: call set/getscheduler set/getparam directly
2021-12-11 2:27 ` [PATCH 2/2] linux-user: call set/getscheduler set/getparam directly Tonis Tiigi
@ 2021-12-19 17:19 ` Laurent Vivier
0 siblings, 0 replies; 5+ messages in thread
From: Laurent Vivier @ 2021-12-19 17:19 UTC (permalink / raw)
To: Tonis Tiigi, qemu-devel
Le 11/12/2021 à 03:27, Tonis Tiigi a écrit :
> There seems to be difference in syscall and libc definition of these
> methods and therefore musl does not implement them (1e21e78bf7). Call
> syscall directly to ensure the behavior of the libc of user application,
> not the libc that was used to build QEMU.
>
> Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
> ---
> linux-user/syscall.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 670b61b2ef..263d7fac5e 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -343,6 +343,14 @@ _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
> _syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr, unsigned int, size, unsigned int, flags);
> #define __NR_sys_sched_setattr __NR_sched_setattr
> _syscall3(int, sys_sched_setattr, pid_t, pid, struct sched_attr *, attr, unsigned int, flags);
> +#define __NR_sys_sched_getscheduler __NR_sched_getscheduler
> +_syscall1(int, sys_sched_getscheduler, pid_t, pid);
> +#define __NR_sys_sched_setscheduler __NR_sched_setscheduler
> +_syscall3(int, sys_sched_setscheduler, pid_t, pid, int, policy, const struct sched_param *, param);
> +#define __NR_sys_sched_getparam __NR_sched_getparam
> +_syscall2(int, sys_sched_getparam, pid_t, pid, struct sched_param *, param);
> +#define __NR_sys_sched_setparam __NR_sched_setparam
> +_syscall2(int, sys_sched_setparam, pid_t, pid, const struct sched_param *, param);
> #define __NR_sys_getcpu __NR_getcpu
> _syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
> _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
> @@ -10563,7 +10571,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
> return -TARGET_EFAULT;
> schp.sched_priority = tswap32(target_schp->sched_priority);
> unlock_user_struct(target_schp, arg2, 0);
> - return get_errno(sched_setparam(arg1, &schp));
> + return get_errno(sys_sched_setparam(arg1, &schp));
> }
> case TARGET_NR_sched_getparam:
> {
> @@ -10573,7 +10581,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
> if (arg2 == 0) {
> return -TARGET_EINVAL;
> }
> - ret = get_errno(sched_getparam(arg1, &schp));
> + ret = get_errno(sys_sched_getparam(arg1, &schp));
> if (!is_error(ret)) {
> if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
> return -TARGET_EFAULT;
> @@ -10593,10 +10601,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
> return -TARGET_EFAULT;
> schp.sched_priority = tswap32(target_schp->sched_priority);
> unlock_user_struct(target_schp, arg3, 0);
> - return get_errno(sched_setscheduler(arg1, arg2, &schp));
> + return get_errno(sys_sched_setscheduler(arg1, arg2, &schp));
> }
> case TARGET_NR_sched_getscheduler:
> - return get_errno(sched_getscheduler(arg1));
> + return get_errno(sys_sched_getscheduler(arg1));
> case TARGET_NR_sched_getattr:
> {
> struct target_sched_attr *target_scha;
>
It looks good, but you need to introduce also target_sched_param using abi_int.
Thanks,
Laurent
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-12-19 17:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-11 2:27 [PATCH 0/2] linux-user: fixes for sched_ syscalls Tonis Tiigi
2021-12-11 2:27 ` [PATCH 1/2] linux-user: add sched_getattr support Tonis Tiigi
2021-12-19 17:09 ` Laurent Vivier
2021-12-11 2:27 ` [PATCH 2/2] linux-user: call set/getscheduler set/getparam directly Tonis Tiigi
2021-12-19 17:19 ` Laurent Vivier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).