aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-01-03 15:12:39 -0500
committerArnd Bergmann <arnd@arndb.de>2019-02-06 18:13:27 -0500
commit1a596398a3d75f966b75f428e992cf1f242f9a5b (patch)
tree41f323cd7eceec2b40df53cb805586c4df05d9b8 /arch/sparc
parent50b93f30f6d8672f9ec80e90af94d733f11a20e0 (diff)
sparc64: add custom adjtimex/clock_adjtime functions
sparc64 is the only architecture on Linux that has a 'timeval' definition with a 32-bit tv_usec but a 64-bit tv_sec. This causes problems for sparc32 compat mode when we convert it to use the new __kernel_timex type that has the same layout as all other 64-bit architectures. To avoid adding sparc64 specific code into the generic adjtimex implementation, this adds a wrapper in the sparc64 system call handling that converts the sparc64 'timex' into the new '__kernel_timex'. At this point, the two structures are defined to be identical, but that will change in the next step once we convert sparc32. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c59
-rw-r--r--arch/sparc/kernel/syscalls/syscall.tbl6
2 files changed, 62 insertions, 3 deletions
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 1c079e7bab09..37de18a11207 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -28,8 +28,9 @@
28#include <linux/random.h> 28#include <linux/random.h>
29#include <linux/export.h> 29#include <linux/export.h>
30#include <linux/context_tracking.h> 30#include <linux/context_tracking.h>
31 31#include <linux/timex.h>
32#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33
33#include <asm/utrap.h> 34#include <asm/utrap.h>
34#include <asm/unistd.h> 35#include <asm/unistd.h>
35 36
@@ -544,6 +545,62 @@ out_unlock:
544 return err; 545 return err;
545} 546}
546 547
548SYSCALL_DEFINE1(sparc_adjtimex, struct timex __user *, txc_p)
549{
550 struct timex txc; /* Local copy of parameter */
551 struct timex *kt = (void *)&txc;
552 int ret;
553
554 /* Copy the user data space into the kernel copy
555 * structure. But bear in mind that the structures
556 * may change
557 */
558 if (copy_from_user(&txc, txc_p, sizeof(struct timex)))
559 return -EFAULT;
560
561 /*
562 * override for sparc64 specific timeval type: tv_usec
563 * is 32 bit wide instead of 64-bit in __kernel_timex
564 */
565 kt->time.tv_usec = txc.time.tv_usec;
566 ret = do_adjtimex(kt);
567 txc.time.tv_usec = kt->time.tv_usec;
568
569 return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
570}
571
572SYSCALL_DEFINE2(sparc_clock_adjtime, const clockid_t, which_clock,struct timex __user *, txc_p)
573{
574 struct timex txc; /* Local copy of parameter */
575 struct timex *kt = (void *)&txc;
576 int ret;
577
578 if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) {
579 pr_err_once("process %d (%s) attempted a POSIX timer syscall "
580 "while CONFIG_POSIX_TIMERS is not set\n",
581 current->pid, current->comm);
582
583 return -ENOSYS;
584 }
585
586 /* Copy the user data space into the kernel copy
587 * structure. But bear in mind that the structures
588 * may change
589 */
590 if (copy_from_user(&txc, txc_p, sizeof(struct timex)))
591 return -EFAULT;
592
593 /*
594 * override for sparc64 specific timeval type: tv_usec
595 * is 32 bit wide instead of 64-bit in __kernel_timex
596 */
597 kt->time.tv_usec = txc.time.tv_usec;
598 ret = do_clock_adjtime(which_clock, kt);
599 txc.time.tv_usec = kt->time.tv_usec;
600
601 return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
602}
603
547SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, 604SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type,
548 utrap_handler_t, new_p, utrap_handler_t, new_d, 605 utrap_handler_t, new_p, utrap_handler_t, new_d,
549 utrap_handler_t __user *, old_p, 606 utrap_handler_t __user *, old_p,
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 6992d17cce37..e63cd013cc77 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -258,7 +258,8 @@
258216 64 sigreturn sys_nis_syscall 258216 64 sigreturn sys_nis_syscall
259217 common clone sys_clone 259217 common clone sys_clone
260218 common ioprio_get sys_ioprio_get 260218 common ioprio_get sys_ioprio_get
261219 common adjtimex sys_adjtimex compat_sys_adjtimex 261219 32 adjtimex sys_adjtimex compat_sys_adjtimex
262219 64 adjtimex sys_sparc_adjtimex
262220 32 sigprocmask sys_sigprocmask compat_sys_sigprocmask 263220 32 sigprocmask sys_sigprocmask compat_sys_sigprocmask
263220 64 sigprocmask sys_nis_syscall 264220 64 sigprocmask sys_nis_syscall
264221 common create_module sys_ni_syscall 265221 common create_module sys_ni_syscall
@@ -377,7 +378,8 @@
377331 common prlimit64 sys_prlimit64 378331 common prlimit64 sys_prlimit64
378332 common name_to_handle_at sys_name_to_handle_at 379332 common name_to_handle_at sys_name_to_handle_at
379333 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at 380333 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at
380334 common clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime 381334 32 clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime
382334 64 clock_adjtime sys_sparc_clock_adjtime
381335 common syncfs sys_syncfs 383335 common syncfs sys_syncfs
382336 common sendmmsg sys_sendmmsg compat_sys_sendmmsg 384336 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
383337 common setns sys_setns 385337 common setns sys_setns