diff options
author | Arnd Bergmann <arnd@arndb.de> | 2019-01-03 15:12:39 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2019-02-06 18:13:27 -0500 |
commit | 1a596398a3d75f966b75f428e992cf1f242f9a5b (patch) | |
tree | 41f323cd7eceec2b40df53cb805586c4df05d9b8 /arch/sparc | |
parent | 50b93f30f6d8672f9ec80e90af94d733f11a20e0 (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.c | 59 | ||||
-rw-r--r-- | arch/sparc/kernel/syscalls/syscall.tbl | 6 |
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 | ||
548 | SYSCALL_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 | |||
572 | SYSCALL_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 | |||
547 | SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, | 604 | SYSCALL_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 @@ | |||
258 | 216 64 sigreturn sys_nis_syscall | 258 | 216 64 sigreturn sys_nis_syscall |
259 | 217 common clone sys_clone | 259 | 217 common clone sys_clone |
260 | 218 common ioprio_get sys_ioprio_get | 260 | 218 common ioprio_get sys_ioprio_get |
261 | 219 common adjtimex sys_adjtimex compat_sys_adjtimex | 261 | 219 32 adjtimex sys_adjtimex compat_sys_adjtimex |
262 | 219 64 adjtimex sys_sparc_adjtimex | ||
262 | 220 32 sigprocmask sys_sigprocmask compat_sys_sigprocmask | 263 | 220 32 sigprocmask sys_sigprocmask compat_sys_sigprocmask |
263 | 220 64 sigprocmask sys_nis_syscall | 264 | 220 64 sigprocmask sys_nis_syscall |
264 | 221 common create_module sys_ni_syscall | 265 | 221 common create_module sys_ni_syscall |
@@ -377,7 +378,8 @@ | |||
377 | 331 common prlimit64 sys_prlimit64 | 378 | 331 common prlimit64 sys_prlimit64 |
378 | 332 common name_to_handle_at sys_name_to_handle_at | 379 | 332 common name_to_handle_at sys_name_to_handle_at |
379 | 333 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at | 380 | 333 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at |
380 | 334 common clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime | 381 | 334 32 clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime |
382 | 334 64 clock_adjtime sys_sparc_clock_adjtime | ||
381 | 335 common syncfs sys_syncfs | 383 | 335 common syncfs sys_syncfs |
382 | 336 common sendmmsg sys_sendmmsg compat_sys_sendmmsg | 384 | 336 common sendmmsg sys_sendmmsg compat_sys_sendmmsg |
383 | 337 common setns sys_setns | 385 | 337 common setns sys_setns |