Mark Wielaard 5aafd9
commit a53adb79711ccfc76a4ee32b20253045cdab55c7
Mark Wielaard 5aafd9
Author: Mark Wielaard <mark@klomp.org>
Mark Wielaard 5aafd9
Date:   Mon Jul 27 16:36:17 2020 +0200
Mark Wielaard 5aafd9
Mark Wielaard 5aafd9
    Handle linux syscalls sched_getattr and sched_setattr
Mark Wielaard 5aafd9
    
Mark Wielaard 5aafd9
    The only "special" thing about these syscalls is that the given
Mark Wielaard 5aafd9
    struct sched_attr determines its own size for future expansion.
Mark Wielaard 5aafd9
    
Mark Wielaard 5aafd9
    Original fix by "ISHIKAWA,chiaki" <ishikawa@yk.rim.or.jp>
Mark Wielaard 5aafd9
    
Mark Wielaard 5aafd9
    https://bugs.kde.org/show_bug.cgi?id=369029
Mark Wielaard 5aafd9
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h
Mark Wielaard 5aafd9
index cdc73c1e6..eb0b320ca 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/priv_syswrap-linux.h
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/priv_syswrap-linux.h
Mark Wielaard 5aafd9
@@ -227,6 +227,8 @@ DECL_TEMPLATE(linux, sys_fremovexattr);
Mark Wielaard 5aafd9
 // syscalls.
Mark Wielaard 5aafd9
 DECL_TEMPLATE(linux, sys_sched_setparam);
Mark Wielaard 5aafd9
 DECL_TEMPLATE(linux, sys_sched_getparam);
Mark Wielaard 5aafd9
+DECL_TEMPLATE(linux, sys_sched_setattr);
Mark Wielaard 5aafd9
+DECL_TEMPLATE(linux, sys_sched_getattr);
Mark Wielaard 5aafd9
 DECL_TEMPLATE(linux, sys_sched_setscheduler);
Mark Wielaard 5aafd9
 DECL_TEMPLATE(linux, sys_sched_getscheduler);
Mark Wielaard 5aafd9
 DECL_TEMPLATE(linux, sys_sched_yield);
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
Mark Wielaard 5aafd9
index 28d90135a..d6f3eb910 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
Mark Wielaard 5aafd9
@@ -846,9 +846,8 @@ static SyscallTableEntry syscall_table[] = {
Mark Wielaard 5aafd9
    LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 311
Mark Wielaard 5aafd9
    LINX_(__NR_kcmp,              sys_kcmp),             // 312
Mark Wielaard 5aafd9
    LINX_(__NR_finit_module,      sys_finit_module),     // 313
Mark Wielaard 5aafd9
-//   LIN__(__NR_sched_setattr,     sys_ni_syscall),       // 314
Mark Wielaard 5aafd9
-
Mark Wielaard 5aafd9
-//   LIN__(__NR_sched_getattr,     sys_ni_syscall),       // 315
Mark Wielaard 5aafd9
+   LINX_(__NR_sched_setattr,     sys_sched_setattr),    // 314
Mark Wielaard 5aafd9
+   LINXY(__NR_sched_getattr,     sys_sched_getattr),    // 315
Mark Wielaard 5aafd9
    LINX_(__NR_renameat2,         sys_renameat2),        // 316
Mark Wielaard 5aafd9
 //   LIN__(__NR_seccomp,           sys_ni_syscall),       // 317
Mark Wielaard 5aafd9
    LINXY(__NR_getrandom,         sys_getrandom),        // 318
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c
Mark Wielaard 5aafd9
index 579542785..70700e53f 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-arm-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-arm-linux.c
Mark Wielaard 5aafd9
@@ -1009,6 +1009,8 @@ static SyscallTableEntry syscall_main_table[] = {
Mark Wielaard 5aafd9
    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 376
Mark Wielaard 5aafd9
    LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 377
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
+   LINX_(__NR_sched_setattr,     sys_sched_setattr),    // 380
Mark Wielaard 5aafd9
+   LINXY(__NR_sched_getattr,     sys_sched_getattr),    // 381
Mark Wielaard 5aafd9
    LINX_(__NR_renameat2,         sys_renameat2),        // 382
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
    LINXY(__NR_getrandom,         sys_getrandom),        // 384
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c
Mark Wielaard 5aafd9
index 81e01456f..acca02442 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-arm64-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-arm64-linux.c
Mark Wielaard 5aafd9
@@ -806,8 +806,8 @@ static SyscallTableEntry syscall_main_table[] = {
Mark Wielaard 5aafd9
    LINX_(__NR_process_vm_writev, sys_process_vm_writev), // 271
Mark Wielaard 5aafd9
    LINX_(__NR_kcmp,              sys_kcmp),              // 272
Mark Wielaard 5aafd9
    LINX_(__NR_finit_module,      sys_finit_module),      // 273
Mark Wielaard 5aafd9
-   //   (__NR_sched_setattr,     sys_ni_syscall),        // 274
Mark Wielaard 5aafd9
-   //   (__NR_sched_getattr,     sys_ni_syscall),        // 275
Mark Wielaard 5aafd9
+   LINX_(__NR_sched_setattr,     sys_sched_setattr),     // 274
Mark Wielaard 5aafd9
+   LINXY(__NR_sched_getattr,     sys_sched_getattr),     // 275
Mark Wielaard 5aafd9
    LINX_(__NR_renameat2,         sys_renameat2),         // 276
Mark Wielaard 5aafd9
    //   (__NR_seccomp,           sys_ni_syscall),        // 277
Mark Wielaard 5aafd9
    LINXY(__NR_getrandom,         sys_getrandom),         // 278
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 5aafd9
index 5b5b7eee6..56be3032d 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 5aafd9
@@ -3677,6 +3677,41 @@ POST(sys_sched_getparam)
Mark Wielaard 5aafd9
    POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
Mark Wielaard 5aafd9
 }
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
+PRE(sys_sched_setattr)
Mark Wielaard 5aafd9
+{
Mark Wielaard 5aafd9
+   struct vki_sched_attr *attr;
Mark Wielaard 5aafd9
+   PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#"
Mark Wielaard 5aafd9
+         FMT_REGWORD "x )", SARG1, ARG2, ARG3 );
Mark Wielaard 5aafd9
+   PRE_REG_READ3(long, "sched_setattr",
Mark Wielaard 5aafd9
+                 vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags);
Mark Wielaard 5aafd9
+   /* We need to be able to read at least the size field.  */
Mark Wielaard 5aafd9
+   PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
Mark Wielaard 5aafd9
+   attr = (struct vki_sched_attr *)(Addr)ARG2;
Mark Wielaard 5aafd9
+   if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
Mark Wielaard 5aafd9
+      PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size);
Mark Wielaard 5aafd9
+}
Mark Wielaard 5aafd9
+
Mark Wielaard 5aafd9
+PRE(sys_sched_getattr)
Mark Wielaard 5aafd9
+{
Mark Wielaard 5aafd9
+   struct vki_sched_attr *attr;
Mark Wielaard 5aafd9
+   PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %ld, %#"
Mark Wielaard 5aafd9
+         FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 );
Mark Wielaard 5aafd9
+   PRE_REG_READ4(long, "sched_getattr",
Mark Wielaard 5aafd9
+                 vki_pid_t, pid, struct sched_attr *, p,
Mark Wielaard 5aafd9
+                 unsigned int, size, unsigned int, flags);
Mark Wielaard 5aafd9
+   /* We need to be able to read at least the size field.  */
Mark Wielaard 5aafd9
+   PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
Mark Wielaard 5aafd9
+   /* And the kernel needs to be able to write to the whole struct size. */
Mark Wielaard 5aafd9
+   attr = (struct vki_sched_attr *)(Addr)ARG2;
Mark Wielaard 5aafd9
+   if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
Mark Wielaard 5aafd9
+      PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size);
Mark Wielaard 5aafd9
+}
Mark Wielaard 5aafd9
+POST(sys_sched_getattr)
Mark Wielaard 5aafd9
+{
Mark Wielaard 5aafd9
+   struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2;
Mark Wielaard 5aafd9
+   POST_MEM_WRITE( (Addr)attr, attr->size );
Mark Wielaard 5aafd9
+}
Mark Wielaard 5aafd9
+
Mark Wielaard 5aafd9
 PRE(sys_sched_getscheduler)
Mark Wielaard 5aafd9
 {
Mark Wielaard 5aafd9
    PRINT("sys_sched_getscheduler ( %ld )", SARG1);
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c
Mark Wielaard 5aafd9
index eed12a1bc..c19cb9e0e 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-ppc32-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c
Mark Wielaard 5aafd9
@@ -1016,6 +1016,9 @@ static SyscallTableEntry syscall_table[] = {
Mark Wielaard 5aafd9
    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 351
Mark Wielaard 5aafd9
    LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
+   LINX_(__NR_sched_setattr,     sys_sched_setattr),    // 355
Mark Wielaard 5aafd9
+   LINXY(__NR_sched_getattr,     sys_sched_getattr),    // 356
Mark Wielaard 5aafd9
+
Mark Wielaard 5aafd9
    LINXY(__NR_getrandom,         sys_getrandom),        // 359
Mark Wielaard 5aafd9
    LINXY(__NR_memfd_create,      sys_memfd_create),     // 360
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
Mark Wielaard 5aafd9
index d58200b49..b6422a765 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-ppc64-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
Mark Wielaard 5aafd9
@@ -998,6 +998,8 @@ static SyscallTableEntry syscall_table[] = {
Mark Wielaard 5aafd9
    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 351
Mark Wielaard 5aafd9
    LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
+   LINX_(__NR_sched_setattr,     sys_sched_setattr),    // 355
Mark Wielaard 5aafd9
+   LINXY(__NR_sched_getattr,     sys_sched_getattr),    // 356
Mark Wielaard 5aafd9
    LINX_(__NR_renameat2,         sys_renameat2),        // 357
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
    LINXY(__NR_getrandom,         sys_getrandom),        // 359
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c
Mark Wielaard 5aafd9
index a0a330aa2..3427fee16 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-s390x-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-s390x-linux.c
Mark Wielaard 5aafd9
@@ -825,8 +825,8 @@ static SyscallTableEntry syscall_table[] = {
Mark Wielaard 5aafd9
    LINX_(__NR_kcmp, sys_kcmp),                                        // 343
Mark Wielaard 5aafd9
 // ?????(__NR_finit_module, ),                                        // 344
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
-// ?????(__NR_sched_setattr, ),                                       // 345
Mark Wielaard 5aafd9
-// ?????(__NR_sched_getattr, ),                                       // 346
Mark Wielaard 5aafd9
+   LINX_(__NR_sched_setattr, sys_sched_setattr),                      // 345
Mark Wielaard 5aafd9
+   LINXY(__NR_sched_getattr, sys_sched_getattr),                      // 346
Mark Wielaard 5aafd9
    LINX_(__NR_renameat2, sys_renameat2),                              // 347
Mark Wielaard 5aafd9
 // ?????(__NR_seccomp, ),                                             // 348
Mark Wielaard 5aafd9
    LINXY(__NR_getrandom, sys_getrandom),                              // 349
Mark Wielaard 5aafd9
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
Mark Wielaard 5aafd9
index 332ed0bf2..b59d96f37 100644
Mark Wielaard 5aafd9
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
Mark Wielaard 5aafd9
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
Mark Wielaard 5aafd9
@@ -1580,8 +1580,8 @@ static SyscallTableEntry syscall_table[] = {
Mark Wielaard 5aafd9
    LINX_(__NR_kcmp,              sys_kcmp),             // 349
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
 //   LIN__(__NR_finit_module,      sys_ni_syscall),       // 350
Mark Wielaard 5aafd9
-//   LIN__(__NR_sched_setattr,     sys_ni_syscall),       // 351
Mark Wielaard 5aafd9
-//   LIN__(__NR_sched_getattr,     sys_ni_syscall),       // 352
Mark Wielaard 5aafd9
+   LINX_(__NR_sched_setattr,     sys_sched_setattr),    // 351
Mark Wielaard 5aafd9
+   LINXY(__NR_sched_getattr,     sys_sched_getattr),    // 352
Mark Wielaard 5aafd9
    LINX_(__NR_renameat2,         sys_renameat2),        // 353
Mark Wielaard 5aafd9
 //   LIN__(__NR_seccomp,           sys_ni_syscall),       // 354
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h
Mark Wielaard 5aafd9
index 75b583165..ef93b9258 100644
Mark Wielaard 5aafd9
--- a/include/vki/vki-linux.h
Mark Wielaard 5aafd9
+++ b/include/vki/vki-linux.h
Mark Wielaard 5aafd9
@@ -410,6 +410,23 @@ struct vki_sched_param {
Mark Wielaard 5aafd9
 	int sched_priority;
Mark Wielaard 5aafd9
 };
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
+struct vki_sched_attr {
Mark Wielaard 5aafd9
+	vki_uint32_t size;
Mark Wielaard 5aafd9
+	vki_uint32_t sched_policy;
Mark Wielaard 5aafd9
+	vki_uint64_t sched_flags;
Mark Wielaard 5aafd9
+
Mark Wielaard 5aafd9
+	/* SCHED_NORMAL, SCHED_BATCH */
Mark Wielaard 5aafd9
+	vki_int32_t sched_nice;
Mark Wielaard 5aafd9
+
Mark Wielaard 5aafd9
+	/* SCHED_FIFO, SCHED_RR */
Mark Wielaard 5aafd9
+	vki_uint32_t sched_priority;
Mark Wielaard 5aafd9
+
Mark Wielaard 5aafd9
+	/* SCHED_DEADLINE */
Mark Wielaard 5aafd9
+	vki_uint64_t sched_runtime;
Mark Wielaard 5aafd9
+	vki_uint64_t sched_deadline;
Mark Wielaard 5aafd9
+	vki_uint64_t sched_period;
Mark Wielaard 5aafd9
+};
Mark Wielaard 5aafd9
+
Mark Wielaard 5aafd9
 #define VKI_TASK_COMM_LEN 16
Mark Wielaard 5aafd9
 
Mark Wielaard 5aafd9
 //----------------------------------------------------------------------