diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r-- | kernel/posix-cpu-timers.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 4c68edff900b..520f6c59948d 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
8 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
9 | 9 | ||
10 | static int check_clock(clockid_t which_clock) | 10 | static int check_clock(const clockid_t which_clock) |
11 | { | 11 | { |
12 | int error = 0; | 12 | int error = 0; |
13 | struct task_struct *p; | 13 | struct task_struct *p; |
@@ -31,7 +31,7 @@ static int check_clock(clockid_t which_clock) | |||
31 | } | 31 | } |
32 | 32 | ||
33 | static inline union cpu_time_count | 33 | static inline union cpu_time_count |
34 | timespec_to_sample(clockid_t which_clock, const struct timespec *tp) | 34 | timespec_to_sample(const clockid_t which_clock, const struct timespec *tp) |
35 | { | 35 | { |
36 | union cpu_time_count ret; | 36 | union cpu_time_count ret; |
37 | ret.sched = 0; /* high half always zero when .cpu used */ | 37 | ret.sched = 0; /* high half always zero when .cpu used */ |
@@ -43,7 +43,7 @@ timespec_to_sample(clockid_t which_clock, const struct timespec *tp) | |||
43 | return ret; | 43 | return ret; |
44 | } | 44 | } |
45 | 45 | ||
46 | static void sample_to_timespec(clockid_t which_clock, | 46 | static void sample_to_timespec(const clockid_t which_clock, |
47 | union cpu_time_count cpu, | 47 | union cpu_time_count cpu, |
48 | struct timespec *tp) | 48 | struct timespec *tp) |
49 | { | 49 | { |
@@ -55,7 +55,7 @@ static void sample_to_timespec(clockid_t which_clock, | |||
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline int cpu_time_before(clockid_t which_clock, | 58 | static inline int cpu_time_before(const clockid_t which_clock, |
59 | union cpu_time_count now, | 59 | union cpu_time_count now, |
60 | union cpu_time_count then) | 60 | union cpu_time_count then) |
61 | { | 61 | { |
@@ -65,7 +65,7 @@ static inline int cpu_time_before(clockid_t which_clock, | |||
65 | return cputime_lt(now.cpu, then.cpu); | 65 | return cputime_lt(now.cpu, then.cpu); |
66 | } | 66 | } |
67 | } | 67 | } |
68 | static inline void cpu_time_add(clockid_t which_clock, | 68 | static inline void cpu_time_add(const clockid_t which_clock, |
69 | union cpu_time_count *acc, | 69 | union cpu_time_count *acc, |
70 | union cpu_time_count val) | 70 | union cpu_time_count val) |
71 | { | 71 | { |
@@ -75,7 +75,7 @@ static inline void cpu_time_add(clockid_t which_clock, | |||
75 | acc->cpu = cputime_add(acc->cpu, val.cpu); | 75 | acc->cpu = cputime_add(acc->cpu, val.cpu); |
76 | } | 76 | } |
77 | } | 77 | } |
78 | static inline union cpu_time_count cpu_time_sub(clockid_t which_clock, | 78 | static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock, |
79 | union cpu_time_count a, | 79 | union cpu_time_count a, |
80 | union cpu_time_count b) | 80 | union cpu_time_count b) |
81 | { | 81 | { |
@@ -151,7 +151,7 @@ static inline unsigned long long sched_ns(struct task_struct *p) | |||
151 | return (p == current) ? current_sched_time(p) : p->sched_time; | 151 | return (p == current) ? current_sched_time(p) : p->sched_time; |
152 | } | 152 | } |
153 | 153 | ||
154 | int posix_cpu_clock_getres(clockid_t which_clock, struct timespec *tp) | 154 | int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) |
155 | { | 155 | { |
156 | int error = check_clock(which_clock); | 156 | int error = check_clock(which_clock); |
157 | if (!error) { | 157 | if (!error) { |
@@ -169,7 +169,7 @@ int posix_cpu_clock_getres(clockid_t which_clock, struct timespec *tp) | |||
169 | return error; | 169 | return error; |
170 | } | 170 | } |
171 | 171 | ||
172 | int posix_cpu_clock_set(clockid_t which_clock, const struct timespec *tp) | 172 | int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp) |
173 | { | 173 | { |
174 | /* | 174 | /* |
175 | * You can never reset a CPU clock, but we check for other errors | 175 | * You can never reset a CPU clock, but we check for other errors |
@@ -186,7 +186,7 @@ int posix_cpu_clock_set(clockid_t which_clock, const struct timespec *tp) | |||
186 | /* | 186 | /* |
187 | * Sample a per-thread clock for the given task. | 187 | * Sample a per-thread clock for the given task. |
188 | */ | 188 | */ |
189 | static int cpu_clock_sample(clockid_t which_clock, struct task_struct *p, | 189 | static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p, |
190 | union cpu_time_count *cpu) | 190 | union cpu_time_count *cpu) |
191 | { | 191 | { |
192 | switch (CPUCLOCK_WHICH(which_clock)) { | 192 | switch (CPUCLOCK_WHICH(which_clock)) { |
@@ -248,7 +248,7 @@ static int cpu_clock_sample_group_locked(unsigned int clock_idx, | |||
248 | * Sample a process (thread group) clock for the given group_leader task. | 248 | * Sample a process (thread group) clock for the given group_leader task. |
249 | * Must be called with tasklist_lock held for reading. | 249 | * Must be called with tasklist_lock held for reading. |
250 | */ | 250 | */ |
251 | static int cpu_clock_sample_group(clockid_t which_clock, | 251 | static int cpu_clock_sample_group(const clockid_t which_clock, |
252 | struct task_struct *p, | 252 | struct task_struct *p, |
253 | union cpu_time_count *cpu) | 253 | union cpu_time_count *cpu) |
254 | { | 254 | { |
@@ -262,7 +262,7 @@ static int cpu_clock_sample_group(clockid_t which_clock, | |||
262 | } | 262 | } |
263 | 263 | ||
264 | 264 | ||
265 | int posix_cpu_clock_get(clockid_t which_clock, struct timespec *tp) | 265 | int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) |
266 | { | 266 | { |
267 | const pid_t pid = CPUCLOCK_PID(which_clock); | 267 | const pid_t pid = CPUCLOCK_PID(which_clock); |
268 | int error = -EINVAL; | 268 | int error = -EINVAL; |
@@ -1399,8 +1399,8 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx, | |||
1399 | 1399 | ||
1400 | static long posix_cpu_clock_nanosleep_restart(struct restart_block *); | 1400 | static long posix_cpu_clock_nanosleep_restart(struct restart_block *); |
1401 | 1401 | ||
1402 | int posix_cpu_nsleep(clockid_t which_clock, int flags, | 1402 | int posix_cpu_nsleep(const clockid_t which_clock, int flags, |
1403 | struct timespec *rqtp) | 1403 | struct timespec *rqtp, struct timespec __user *rmtp) |
1404 | { | 1404 | { |
1405 | struct restart_block *restart_block = | 1405 | struct restart_block *restart_block = |
1406 | ¤t_thread_info()->restart_block; | 1406 | ¤t_thread_info()->restart_block; |
@@ -1425,7 +1425,6 @@ int posix_cpu_nsleep(clockid_t which_clock, int flags, | |||
1425 | error = posix_cpu_timer_create(&timer); | 1425 | error = posix_cpu_timer_create(&timer); |
1426 | timer.it_process = current; | 1426 | timer.it_process = current; |
1427 | if (!error) { | 1427 | if (!error) { |
1428 | struct timespec __user *rmtp; | ||
1429 | static struct itimerspec zero_it; | 1428 | static struct itimerspec zero_it; |
1430 | struct itimerspec it = { .it_value = *rqtp, | 1429 | struct itimerspec it = { .it_value = *rqtp, |
1431 | .it_interval = {} }; | 1430 | .it_interval = {} }; |
@@ -1472,7 +1471,6 @@ int posix_cpu_nsleep(clockid_t which_clock, int flags, | |||
1472 | /* | 1471 | /* |
1473 | * Report back to the user the time still remaining. | 1472 | * Report back to the user the time still remaining. |
1474 | */ | 1473 | */ |
1475 | rmtp = (struct timespec __user *) restart_block->arg1; | ||
1476 | if (rmtp != NULL && !(flags & TIMER_ABSTIME) && | 1474 | if (rmtp != NULL && !(flags & TIMER_ABSTIME) && |
1477 | copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) | 1475 | copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) |
1478 | return -EFAULT; | 1476 | return -EFAULT; |
@@ -1480,6 +1478,7 @@ int posix_cpu_nsleep(clockid_t which_clock, int flags, | |||
1480 | restart_block->fn = posix_cpu_clock_nanosleep_restart; | 1478 | restart_block->fn = posix_cpu_clock_nanosleep_restart; |
1481 | /* Caller already set restart_block->arg1 */ | 1479 | /* Caller already set restart_block->arg1 */ |
1482 | restart_block->arg0 = which_clock; | 1480 | restart_block->arg0 = which_clock; |
1481 | restart_block->arg1 = (unsigned long) rmtp; | ||
1483 | restart_block->arg2 = rqtp->tv_sec; | 1482 | restart_block->arg2 = rqtp->tv_sec; |
1484 | restart_block->arg3 = rqtp->tv_nsec; | 1483 | restart_block->arg3 = rqtp->tv_nsec; |
1485 | 1484 | ||
@@ -1493,21 +1492,28 @@ static long | |||
1493 | posix_cpu_clock_nanosleep_restart(struct restart_block *restart_block) | 1492 | posix_cpu_clock_nanosleep_restart(struct restart_block *restart_block) |
1494 | { | 1493 | { |
1495 | clockid_t which_clock = restart_block->arg0; | 1494 | clockid_t which_clock = restart_block->arg0; |
1496 | struct timespec t = { .tv_sec = restart_block->arg2, | 1495 | struct timespec __user *rmtp; |
1497 | .tv_nsec = restart_block->arg3 }; | 1496 | struct timespec t; |
1497 | |||
1498 | rmtp = (struct timespec __user *) restart_block->arg1; | ||
1499 | t.tv_sec = restart_block->arg2; | ||
1500 | t.tv_nsec = restart_block->arg3; | ||
1501 | |||
1498 | restart_block->fn = do_no_restart_syscall; | 1502 | restart_block->fn = do_no_restart_syscall; |
1499 | return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t); | 1503 | return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t, rmtp); |
1500 | } | 1504 | } |
1501 | 1505 | ||
1502 | 1506 | ||
1503 | #define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED) | 1507 | #define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED) |
1504 | #define THREAD_CLOCK MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED) | 1508 | #define THREAD_CLOCK MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED) |
1505 | 1509 | ||
1506 | static int process_cpu_clock_getres(clockid_t which_clock, struct timespec *tp) | 1510 | static int process_cpu_clock_getres(const clockid_t which_clock, |
1511 | struct timespec *tp) | ||
1507 | { | 1512 | { |
1508 | return posix_cpu_clock_getres(PROCESS_CLOCK, tp); | 1513 | return posix_cpu_clock_getres(PROCESS_CLOCK, tp); |
1509 | } | 1514 | } |
1510 | static int process_cpu_clock_get(clockid_t which_clock, struct timespec *tp) | 1515 | static int process_cpu_clock_get(const clockid_t which_clock, |
1516 | struct timespec *tp) | ||
1511 | { | 1517 | { |
1512 | return posix_cpu_clock_get(PROCESS_CLOCK, tp); | 1518 | return posix_cpu_clock_get(PROCESS_CLOCK, tp); |
1513 | } | 1519 | } |
@@ -1516,16 +1522,19 @@ static int process_cpu_timer_create(struct k_itimer *timer) | |||
1516 | timer->it_clock = PROCESS_CLOCK; | 1522 | timer->it_clock = PROCESS_CLOCK; |
1517 | return posix_cpu_timer_create(timer); | 1523 | return posix_cpu_timer_create(timer); |
1518 | } | 1524 | } |
1519 | static int process_cpu_nsleep(clockid_t which_clock, int flags, | 1525 | static int process_cpu_nsleep(const clockid_t which_clock, int flags, |
1520 | struct timespec *rqtp) | 1526 | struct timespec *rqtp, |
1527 | struct timespec __user *rmtp) | ||
1521 | { | 1528 | { |
1522 | return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp); | 1529 | return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp, rmtp); |
1523 | } | 1530 | } |
1524 | static int thread_cpu_clock_getres(clockid_t which_clock, struct timespec *tp) | 1531 | static int thread_cpu_clock_getres(const clockid_t which_clock, |
1532 | struct timespec *tp) | ||
1525 | { | 1533 | { |
1526 | return posix_cpu_clock_getres(THREAD_CLOCK, tp); | 1534 | return posix_cpu_clock_getres(THREAD_CLOCK, tp); |
1527 | } | 1535 | } |
1528 | static int thread_cpu_clock_get(clockid_t which_clock, struct timespec *tp) | 1536 | static int thread_cpu_clock_get(const clockid_t which_clock, |
1537 | struct timespec *tp) | ||
1529 | { | 1538 | { |
1530 | return posix_cpu_clock_get(THREAD_CLOCK, tp); | 1539 | return posix_cpu_clock_get(THREAD_CLOCK, tp); |
1531 | } | 1540 | } |
@@ -1534,8 +1543,8 @@ static int thread_cpu_timer_create(struct k_itimer *timer) | |||
1534 | timer->it_clock = THREAD_CLOCK; | 1543 | timer->it_clock = THREAD_CLOCK; |
1535 | return posix_cpu_timer_create(timer); | 1544 | return posix_cpu_timer_create(timer); |
1536 | } | 1545 | } |
1537 | static int thread_cpu_nsleep(clockid_t which_clock, int flags, | 1546 | static int thread_cpu_nsleep(const clockid_t which_clock, int flags, |
1538 | struct timespec *rqtp) | 1547 | struct timespec *rqtp, struct timespec __user *rmtp) |
1539 | { | 1548 | { |
1540 | return -EINVAL; | 1549 | return -EINVAL; |
1541 | } | 1550 | } |