diff mbox

[v5,05/24] posix-timers: Introduce {get,put}_timespec and {get,put}_itimerspec

Message ID 647dcc7ede88d9d95a6f9a2878487d46c233fb2a.1434079262.git.baolin.wang@linaro.org
State New
Headers show

Commit Message

(Exiting) Baolin Wang June 12, 2015, 7:48 a.m. UTC
These are new helper macros that convert between a user timespec/
itimerspec and a kernel timespec64/itimerspec64 structure.

When converting syscall functions, it need to deal with these conversions:
  user timespec (32 bit), kernel timespec (32 bit)
  user timespec (64 bit), kernel timespec (64 bit)
  user timespec (32 bit), kernel timespec64 (64 bit)
  user timespec (64 bit), kernel timespec64 (64 bit)
  user itimerspec (32 bit), kernel itimerspec (32 bit)
  user itimerspec (64 bit), kernel itimerspec (64 bit)
  user itimerspec (32 bit), kernel itimerspec64 (64 bit)
  user itimerspec (64 bit), kernel itimerspec64 (64 bit)

In order to handle all these conversions, and ensure that it can change
over all callers at the same time with the structure type above, and
introduce the get/put macros based on __put_user() and __get_user().

Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
 kernel/time/posix-timers.c |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
diff mbox

Patch

diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 31d11ac..5ddd912 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -147,6 +147,35 @@  static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags);
 	__timr;								   \
 })
 
+#define __get_timespec(kts, uts) \
+	(__get_user((kts)->tv_sec, &(uts)->tv_sec) || \
+	__get_user((kts)->tv_nsec, &(uts)->tv_nsec))
+
+#define __put_timespec(kts, uts) \
+	(__put_user((kts)->tv_sec, &(uts)->tv_sec) || \
+	__put_user((kts)->tv_nsec, &(uts)->tv_nsec))
+
+#define get_timespec(kts, uts) \
+	((access_ok(VERIFY_READ, (uts), sizeof(*(uts))) || \
+	__get_timespec((kts), (uts))) ? \
+	-EFAULT : 0)
+
+#define put_timespec(kts, uts) \
+	((access_ok(VERIFY_WRITE, (uts), sizeof(*(uts))) || \
+	__put_timespec((kts), (uts))) ? \
+	-EFAULT : 0)
+
+#define get_itimerspec(kit, uit) \
+	((access_ok(VERIFY_READ, (uit), sizeof(*(uit))) || \
+	__get_timespec(&(kit)->it_interval, &(uit)->it_interval) || \
+	__get_timespec(&(kit)->it_value, &(uit)->it_value)))
+
+#define put_itimerspec(kit, uit) \
+	((access_ok(VERIFY_WRITE, (uit), sizeof(*(uit))) || \
+	__put_timespec(&(kit)->it_interval, &(uit)->it_interval) || \
+	__put_timespec(&(kit)->it_value, &(uit)->it_value)) ? \
+	-EFAULT : 0)
+
 static int hash(struct signal_struct *sig, unsigned int nr)
 {
 	return hash_32(hash32_ptr(sig) ^ nr, HASH_BITS(posix_timers_hashtable));