ltp.lists.linux.it archive mirror
 help / color / mirror / Atom feed
* [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants
@ 2020-04-22  5:37 ` Viresh Kumar
  2020-04-22  5:37   ` [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests Viresh Kumar
                     ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Viresh Kumar @ 2020-04-22  5:37 UTC (permalink / raw)
  To: ltp

Hello,

Here is the fourth version of this series and here are the changes since
v3.

V3->V4:
- Dropped the first patch, it is already applied by Cyril.
- Update clock_gettime() patch (1/5), according to the changes Cyril
  made.
- Rest four patches (2-5/5) are posted for the first time here.

--
Viresh

Viresh Kumar (5):
  syscalls/clock_gettime: Add support for time64 tests
  syscalls/clock_settime: Add support for time64 tests
  syscalls/clock_getres: Add support for time64 tests
  syscalls/clock_nanosleep: Add support for time64 tests
  syscalls/clock_adjtime: Add support for time64 tests

 include/tst_timer.h                           | 122 +++++++++-
 runtest/syscalls                              |   2 +-
 .../syscalls/clock_adjtime/clock_adjtime.h    | 220 +++++++++++++++---
 .../syscalls/clock_adjtime/clock_adjtime01.c  | 124 ++++++----
 .../syscalls/clock_adjtime/clock_adjtime02.c  |  90 +++++--
 .../syscalls/clock_getres/clock_getres01.c    |  58 +++--
 .../syscalls/clock_gettime/clock_gettime01.c  | 116 +++++----
 .../syscalls/clock_gettime/clock_gettime02.c  |  72 +++---
 .../syscalls/clock_gettime/clock_gettime03.c  |  58 ++++-
 .../syscalls/clock_nanosleep/.gitignore       |   1 +
 .../clock_nanosleep/clock_nanosleep01.c       | 102 ++++++--
 .../clock_nanosleep/clock_nanosleep03.c       |  68 +++++-
 .../clock_nanosleep/clock_nanosleep04.c       |  90 +++++++
 .../syscalls/clock_nanosleep2/.gitignore      |   1 -
 .../kernel/syscalls/clock_nanosleep2/Makefile |  10 -
 .../clock_nanosleep2/clock_nanosleep2_01.c    |  45 ----
 .../syscalls/clock_settime/clock_settime01.c  |  87 +++++--
 .../syscalls/clock_settime/clock_settime02.c  |  95 +++++---
 18 files changed, 993 insertions(+), 368 deletions(-)
 create mode 100644 testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/.gitignore
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/Makefile
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c

-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests
  2020-04-22  5:37 ` [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants Viresh Kumar
@ 2020-04-22  5:37   ` Viresh Kumar
  2020-04-23 13:50     ` Cyril Hrubis
  2020-04-22  5:37   ` [LTP] [PATCH V4 2/5] syscalls/clock_settime: " Viresh Kumar
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2020-04-22  5:37 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_gettime()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 include/tst_timer.h                           |  65 +++++++++-
 .../syscalls/clock_gettime/clock_gettime01.c  | 116 ++++++++----------
 .../syscalls/clock_gettime/clock_gettime02.c  |  72 ++++++-----
 .../syscalls/clock_gettime/clock_gettime03.c  |  58 +++++++--
 4 files changed, 206 insertions(+), 105 deletions(-)

diff --git a/include/tst_timer.h b/include/tst_timer.h
index 4f97acd165b8..f40b93a624b3 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -15,6 +15,7 @@
 #include <sys/time.h>
 #include <time.h>
 #include "tst_test.h"
+#include "lapi/syscalls.h"
 
 /*
  * Converts timeval to microseconds.
@@ -116,7 +117,9 @@ struct __kernel_timespec {
 enum tst_ts_type {
 	TST_LIBC_TIMESPEC,
 	TST_KERN_OLD_TIMESPEC,
-	TST_KERN_TIMESPEC
+	TST_KERN_TIMESPEC,
+	/* Used for indicating failure test with bad address */
+	TST_KERN_BAD_ADDR
 };
 
 struct tst_ts {
@@ -128,6 +131,66 @@ struct tst_ts {
 	};
 };
 
+static inline void *tst_get_ts(struct tst_ts *t)
+{
+	switch (t->type) {
+	case TST_LIBC_TIMESPEC:
+		return &t->libc_ts;
+	case TST_KERN_OLD_TIMESPEC:
+		return &t->kern_old_ts;
+	case TST_KERN_TIMESPEC:
+		return &t->kern_ts;
+	case TST_KERN_BAD_ADDR:
+		return tst_get_bad_addr(NULL);
+	default:
+		tst_brk(TBROK, "Invalid type: %d", t->type);
+		return NULL;
+	}
+}
+
+static inline int libc_clock_gettime(clockid_t clk_id, struct tst_ts *t)
+{
+	return clock_gettime(clk_id, tst_get_ts(t));
+}
+
+static inline int sys_clock_gettime(clockid_t clk_id, struct tst_ts *t)
+{
+	return tst_syscall(__NR_clock_gettime, clk_id, tst_get_ts(t));
+}
+
+static inline int sys_clock_gettime64(clockid_t clk_id, struct tst_ts *t)
+{
+	return tst_syscall(__NR_clock_gettime64, clk_id, tst_get_ts(t));
+}
+
+/*
+ * tst_ts_nonzero return:
+ * 0: On success, i.e. timespec updated correctly.
+ * -1: Error, timespec not updated.
+ * -2: Error, tv_nsec is corrupted.
+ */
+static inline int tst_ts_nonzero(struct tst_ts *t)
+{
+	switch (t->type) {
+	case TST_LIBC_TIMESPEC:
+		return (t->libc_ts.tv_nsec == 0 && t->libc_ts.tv_sec == 0) ? -1 : 0;
+	case TST_KERN_OLD_TIMESPEC:
+		return (t->kern_old_ts.tv_nsec == 0 && t->kern_old_ts.tv_sec == 0) ? -1 : 0;
+	case TST_KERN_TIMESPEC:
+		if (t->kern_ts.tv_nsec == 0 && t->kern_ts.tv_sec == 0)
+			return -1;
+
+		/* Upper 32 bits of tv_nsec should be cleared */
+		if (t->kern_ts.tv_nsec >> 32)
+			return -2;
+		else
+			return 0;
+	default:
+		tst_brk(TBROK, "Invalid type: %d", t->type);
+		return -1;
+	}
+}
+
 /*
  * Returns tst_ts seconds.
  */
diff --git a/testcases/kernel/syscalls/clock_gettime/clock_gettime01.c b/testcases/kernel/syscalls/clock_gettime/clock_gettime01.c
index d365823b2f0f..ea87e4fb4e9a 100644
--- a/testcases/kernel/syscalls/clock_gettime/clock_gettime01.c
+++ b/testcases/kernel/syscalls/clock_gettime/clock_gettime01.c
@@ -19,20 +19,14 @@
 #include "config.h"
 #include "tst_timer.h"
 #include "tst_safe_clocks.h"
-#include "tst_test.h"
-#include "lapi/syscalls.h"
+#include "lapi/abisize.h"
 
 struct test_case {
 	clockid_t clktype;
 	int allow_inval;
 };
 
-struct tmpfunc {
-	int (*func)(clockid_t clk_id, struct timespec *tp);
-	char *desc;
-};
-
-struct test_case tc[] = {
+static struct test_case tc[] = {
 	{
 	 .clktype = CLOCK_REALTIME,
 	 },
@@ -63,73 +57,65 @@ struct test_case tc[] = {
 	 },
 };
 
-static int sys_clock_gettime(clockid_t clk_id, struct timespec *tp)
-{
-	return tst_syscall(__NR_clock_gettime, clk_id, tp);
-}
+static struct tst_ts spec;
 
-static int check_spec(struct timespec *spec)
+static struct test_variants {
+	int (*func)(clockid_t clk_id, struct tst_ts *spec);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = libc_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .func = sys_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .func = sys_clock_gettime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_gettime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_gettime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
+static void setup(void)
 {
-	return (spec->tv_nsec != 0 || spec->tv_sec != 0) ? 1 : 0;
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 }
 
 static void verify_clock_gettime(unsigned int i)
 {
-	size_t sz;
-	struct timespec spec;
-
-	/*
-	 * check clock_gettime() syscall AND libc (or vDSO) functions
-	 */
-	struct tmpfunc tf[] = {
-		{ .func = sys_clock_gettime, .desc = "syscall"      },
-		{ .func = clock_gettime, .desc = "vDSO or syscall"  },
-	};
-
-	for (sz = 0; sz < ARRAY_SIZE(tf); sz++) {
+	struct test_variants *tv = &variants[tst_variant];
+	int ret;
 
-		memset(&spec, 0, sizeof(struct timespec));
+	memset(&spec, 0, sizeof(spec));
+	spec.type = tv->type;
 
-		TEST(tf[sz].func(tc[i].clktype, &spec));
-
-		if (TST_RET == -1) {
-
-			/* errors: allow unsupported clock types */
-
-			if (tc[i].allow_inval && TST_ERR == EINVAL) {
-
-				tst_res(TPASS, "clock_gettime(2): unsupported "
-						"clock %s (%s) failed as "
-						"expected",
-						tst_clock_name(tc[i].clktype),
-						tf[sz].desc);
-
-			} else {
-
-				tst_res(TFAIL | TTERRNO, "clock_gettime(2): "
-						"clock %s (%s) failed "
-						"unexpectedly",
-						tst_clock_name(tc[i].clktype),
-						tf[sz].desc);
-			}
+	TEST(tv->func(tc[i].clktype, &spec));
 
+	if (TST_RET == -1) {
+		/* errors: allow unsupported clock types */
+		if (tc[i].allow_inval && TST_ERR == EINVAL) {
+			tst_res(TPASS, "clock_gettime(2): unsupported clock %s failed as expected",
+				tst_clock_name(tc[i].clktype));
 		} else {
+			tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s failed unexpectedly",
+				tst_clock_name(tc[i].clktype));
+		}
 
-			/* success: also check if timespec was changed */
-
-			if (check_spec(&spec)) {
-				tst_res(TPASS, "clock_gettime(2): clock %s "
-						"(%s) passed",
-						tst_clock_name(tc[i].clktype),
-						tf[sz].desc);
-			} else {
-
-				tst_res(TFAIL, "clock_gettime(2): clock %s "
-						"(%s) passed, unchanged "
-						"timespec",
-						tst_clock_name(tc[i].clktype),
-						tf[sz].desc);
-			}
+	} else {
+		/* success: also check if timespec was changed */
+		ret = tst_ts_nonzero(&spec);
+		if (!ret) {
+			tst_res(TPASS, "clock_gettime(2): clock %s passed",
+				tst_clock_name(tc[i].clktype));
+		} else if (ret == -1) {
+			tst_res(TFAIL, "clock_gettime(2): clock %s passed, unchanged timespec",
+				tst_clock_name(tc[i].clktype));
+		} else if (ret == -2) {
+			tst_res(TFAIL, "clock_gettime(2): clock %s passed, Corrupted timespec",
+				tst_clock_name(tc[i].clktype));
 		}
 	}
 }
@@ -137,5 +123,7 @@ static void verify_clock_gettime(unsigned int i)
 static struct tst_test test = {
 	.test = verify_clock_gettime,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
+	.setup = setup,
 	.needs_root = 1,
 };
diff --git a/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c b/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c
index b4bc6e2d55d4..42784ae42c62 100644
--- a/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c
+++ b/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c
@@ -19,10 +19,9 @@
  */
 
 #include "config.h"
-#include "tst_test.h"
-#include "lapi/syscalls.h"
 #include "tst_timer.h"
 #include "tst_safe_clocks.h"
+#include "lapi/abisize.h"
 
 struct test_case {
 	clockid_t clktype;
@@ -30,7 +29,7 @@ struct test_case {
 	int allow_inval;
 };
 
-struct test_case tc[] = {
+static struct test_case tc[] = {
 	{
 	 .clktype = MAX_CLOCKS,
 	 .exp_err = EINVAL,
@@ -81,52 +80,67 @@ struct test_case tc[] = {
 	 },
 };
 
+static struct tst_ts spec;
+
 /*
  * bad pointer w/ libc causes SIGSEGV signal, call syscall directly
  */
-static int sys_clock_gettime(clockid_t clk_id, struct timespec *tp)
+static struct test_variants {
+	int (*func)(clockid_t clk_id, struct tst_ts *t);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = sys_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .func = sys_clock_gettime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_gettime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_gettime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
+static void setup(void)
 {
-	return tst_syscall(__NR_clock_gettime, clk_id, tp);
+	tst_res(TINFO, "Testing variant: %d: %s", tst_variant, variants[tst_variant].desc);
 }
 
 static void verify_clock_gettime(unsigned int i)
 {
-	struct timespec spec, *specptr;
-
-	specptr = &spec;
+	struct test_variants *tv = &variants[tst_variant];
 
 	/* bad pointer cases */
 	if (tc[i].exp_err == EFAULT)
-		specptr = tst_get_bad_addr(NULL);
-
-	TEST(sys_clock_gettime(tc[i].clktype, specptr));
+		spec.type = TST_KERN_BAD_ADDR;
+	else
+		spec.type = tv->type;
 
-	if (TST_RET == -1) {
+	TEST(tv->func(tc[i].clktype, &spec));
 
-		if ((tc[i].exp_err == TST_ERR) ||
-			(tc[i].allow_inval && TST_ERR == EINVAL)) {
-
-			tst_res(TPASS | TTERRNO, "clock_gettime(2): "
-					"clock %s failed as expected",
-					tst_clock_name(tc[i].clktype));
-
-		} else {
-
-			tst_res(TFAIL | TTERRNO, "clock_gettime(2): "
-					"clock %s failed unexpectedly",
-					tst_clock_name(tc[i].clktype));
-		}
+	if (TST_RET != -1) {
+		tst_res(TFAIL, "clock_gettime(2): clock %s passed unexcpectedly",
+			tst_clock_name(tc[i].clktype));
+		return;
+	}
 
+	if ((tc[i].exp_err == TST_ERR) ||
+	    (tc[i].allow_inval && TST_ERR == EINVAL)) {
+		tst_res(TPASS | TTERRNO, "clock_gettime(2): clock %s failed as expected",
+			tst_clock_name(tc[i].clktype));
 	} else {
-
-		tst_res(TFAIL, "clock_gettime(2): clock %s passed"
-				" unexcpectedly",
-				tst_clock_name(tc[i].clktype));
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s failed unexpectedly",
+			tst_clock_name(tc[i].clktype));
 	}
 }
 
 static struct tst_test test = {
 	.test = verify_clock_gettime,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
+	.setup = setup,
 	.needs_root = 1,
 };
diff --git a/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c b/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
index cf4706fa0c30..ce536e566a46 100644
--- a/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
+++ b/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
@@ -21,7 +21,7 @@
 #include "tst_safe_clocks.h"
 #include "tst_timer.h"
 #include "lapi/namespaces_constants.h"
-#include "tst_test.h"
+#include "lapi/abisize.h"
 
 static struct tcase {
 	int clk_id;
@@ -38,22 +38,48 @@ static struct tcase {
 	{CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC, 100},
 };
 
-static struct timespec now;
+static struct tst_ts now, then, parent_then;
 static int parent_ns;
 
-static void child(struct tcase *tc)
+static struct test_variants {
+	int (*func)(clockid_t clk_id, struct tst_ts *spec);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = libc_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .func = sys_clock_gettime, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .func = sys_clock_gettime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_gettime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_gettime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
+static void child(struct test_variants *tv, struct tcase *tc)
 {
-	struct timespec then;
-	struct timespec parent_then;
 	long long diff;
 
-	SAFE_CLOCK_GETTIME(tc->clk_id, &then);
+	if (tv->func(tc->clk_id, &then)) {
+		tst_res(TFAIL | TERRNO, "clock_gettime(%s) failed",
+			tst_clock_name(tc->clk_id));
+		return;
+	}
 
 	SAFE_SETNS(parent_ns, CLONE_NEWTIME);
 
-	SAFE_CLOCK_GETTIME(tc->clk_id, &parent_then);
+	if (tv->func(tc->clk_id, &parent_then)) {
+		tst_res(TFAIL | TERRNO, "clock_gettime(%s) failed",
+			tst_clock_name(tc->clk_id));
+		return;
+	}
 
-	diff = tst_timespec_diff_ms(then, now);
+	diff = tst_ts_diff_ms(then, now);
 
 	if (diff/1000 != tc->off) {
 		tst_res(TFAIL, "Wrong offset (%s) read %llims",
@@ -63,7 +89,7 @@ static void child(struct tcase *tc)
 		        tst_clock_name(tc->clk_id), diff);
 	}
 
-	diff = tst_timespec_diff_ms(parent_then, now);
+	diff = tst_ts_diff_ms(parent_then, now);
 
 	if (diff/1000) {
 		tst_res(TFAIL, "Wrong offset (%s) read %llims",
@@ -76,6 +102,7 @@ static void child(struct tcase *tc)
 
 static void verify_ns_clock(unsigned int n)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	struct tcase *tc = &tcases[n];
 
 	SAFE_UNSHARE(CLONE_NEWTIME);
@@ -83,14 +110,22 @@ static void verify_ns_clock(unsigned int n)
 	SAFE_FILE_PRINTF("/proc/self/timens_offsets", "%d %d 0",
 	                 tc->clk_off, tc->off);
 
-	SAFE_CLOCK_GETTIME(tc->clk_id, &now);
+	if (tv->func(tc->clk_id, &now)) {
+		tst_res(TFAIL | TERRNO, "%d clock_gettime(%s) failed",
+			__LINE__, tst_clock_name(tc->clk_id));
+		return;
+	}
 
 	if (!SAFE_FORK())
-		child(tc);
+		child(tv, tc);
 }
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
+
+	now.type = then.type = parent_then.type = tv->type;
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 	parent_ns = SAFE_OPEN("/proc/self/ns/time_for_children", O_RDONLY);
 }
 
@@ -104,6 +139,7 @@ static struct tst_test test = {
 	.cleanup = cleanup,
 	.tcnt = ARRAY_SIZE(tcases),
 	.test = verify_ns_clock,
+	.test_variants = ARRAY_SIZE(variants),
 	.needs_root = 1,
 	.forks_child = 1,
 	.needs_kconfigs = (const char *[]) {
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 2/5] syscalls/clock_settime: Add support for time64 tests
  2020-04-22  5:37 ` [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants Viresh Kumar
  2020-04-22  5:37   ` [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests Viresh Kumar
@ 2020-04-22  5:37   ` Viresh Kumar
  2020-04-23 15:08     ` Cyril Hrubis
  2020-04-22  5:37   ` [LTP] [PATCH V4 3/5] syscalls/clock_getres: " Viresh Kumar
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2020-04-22  5:37 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_settime()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 include/tst_timer.h                           | 15 +++
 .../syscalls/clock_settime/clock_settime01.c  | 87 ++++++++++++++---
 .../syscalls/clock_settime/clock_settime02.c  | 95 ++++++++++++-------
 3 files changed, 146 insertions(+), 51 deletions(-)

diff --git a/include/tst_timer.h b/include/tst_timer.h
index f40b93a624b3..fef201ee04df 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -163,6 +163,21 @@ static inline int sys_clock_gettime64(clockid_t clk_id, struct tst_ts *t)
 	return tst_syscall(__NR_clock_gettime64, clk_id, tst_get_ts(t));
 }
 
+static inline int libc_clock_settime(clockid_t clk_id, struct tst_ts *t)
+{
+	return clock_settime(clk_id, tst_get_ts(t));
+}
+
+static inline int sys_clock_settime(clockid_t clk_id, struct tst_ts *t)
+{
+	return tst_syscall(__NR_clock_settime, clk_id, tst_get_ts(t));
+}
+
+static inline int sys_clock_settime64(clockid_t clk_id, struct tst_ts *t)
+{
+	return tst_syscall(__NR_clock_settime64, clk_id, tst_get_ts(t));
+}
+
 /*
  * tst_ts_nonzero return:
  * 0: On success, i.e. timespec updated correctly.
diff --git a/testcases/kernel/syscalls/clock_settime/clock_settime01.c b/testcases/kernel/syscalls/clock_settime/clock_settime01.c
index 62d3491544a6..199264974ed0 100644
--- a/testcases/kernel/syscalls/clock_settime/clock_settime01.c
+++ b/testcases/kernel/syscalls/clock_settime/clock_settime01.c
@@ -16,31 +16,72 @@
 #include "config.h"
 #include "tst_timer.h"
 #include "tst_safe_clocks.h"
-#include "tst_test.h"
-#include "lapi/syscalls.h"
+#include "lapi/abisize.h"
 
 #define DELTA_SEC 10
 #define DELTA_US (long long) (DELTA_SEC * 1000000)
 #define DELTA_EPS (long long) (DELTA_US * 0.1)
 
-static struct timespec *begin, *change, *end;
+static struct tst_ts *begin, *change, *end;
+
+static struct test_variants {
+	int (*gettime)(clockid_t clk_id, struct tst_ts *spec);
+	int (*settime)(clockid_t clk_id, struct tst_ts *spec);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .gettime = libc_clock_gettime, .settime = libc_clock_settime, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_settime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .gettime = sys_clock_gettime64, .settime = sys_clock_settime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
+static void setup(void)
+{
+	begin->type = change->type = end->type = variants[tst_variant].type;
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
+}
 
 static void verify_clock_settime(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	long long elapsed;
 
 	/* test 01: move forward */
 
-	SAFE_CLOCK_GETTIME(CLOCK_REALTIME, begin);
+	TEST(tv->gettime(CLOCK_REALTIME, begin));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_REALTIME));
+		return;
+	}
 
-	*change = tst_timespec_add_us(*begin, DELTA_US);
+	*change = tst_ts_add_us(*begin, DELTA_US);
 
-	if (clock_settime(CLOCK_REALTIME, change) != 0)
-		tst_brk(TBROK | TTERRNO, "could not set realtime change");
+	TEST(tv->settime(CLOCK_REALTIME, change));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_settime(2) failed for clock %s",
+			tst_clock_name(CLOCK_REALTIME));
+		return;
+	}
 
-	SAFE_CLOCK_GETTIME(CLOCK_REALTIME, end);
+	TEST(tv->gettime(CLOCK_REALTIME, end));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_REALTIME));
+		return;
+	}
 
-	elapsed = tst_timespec_diff_us(*end, *begin);
+	elapsed = tst_ts_diff_us(*end, *begin);
 
 	if (elapsed >= DELTA_US && elapsed < (DELTA_US + DELTA_EPS))
 		tst_res(TPASS, "clock_settime(2): was able to advance time");
@@ -49,16 +90,30 @@ static void verify_clock_settime(void)
 
 	/* test 02: move backward */
 
-	SAFE_CLOCK_GETTIME(CLOCK_REALTIME, begin);
+	TEST(tv->gettime(CLOCK_REALTIME, begin));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_REALTIME));
+		return;
+	}
 
-	*change = tst_timespec_sub_us(*begin, DELTA_US);
+	*change = tst_ts_sub_us(*begin, DELTA_US);
 
-	if (clock_settime(CLOCK_REALTIME, change) != 0)
-		tst_brk(TBROK | TTERRNO, "could not set realtime change");
+	TEST(tv->settime(CLOCK_REALTIME, change));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_settime(2) failed for clock %s",
+			tst_clock_name(CLOCK_REALTIME));
+		return;
+	}
 
-	SAFE_CLOCK_GETTIME(CLOCK_REALTIME, end);
+	TEST(tv->gettime(CLOCK_REALTIME, end));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_REALTIME));
+		return;
+	}
 
-	elapsed = tst_timespec_diff_us(*end, *begin);
+	elapsed = tst_ts_diff_us(*end, *begin);
 
 	if (~(elapsed) <= DELTA_US && ~(elapsed) > (DELTA_US - DELTA_EPS))
 		tst_res(TPASS, "clock_settime(2): was able to recede time");
@@ -68,6 +123,8 @@ static void verify_clock_settime(void)
 
 static struct tst_test test = {
 	.test_all = verify_clock_settime,
+	.test_variants = ARRAY_SIZE(variants),
+	.setup = setup,
 	.needs_root = 1,
 	.restore_wallclock = 1,
 	.bufs = (struct tst_buffers []) {
diff --git a/testcases/kernel/syscalls/clock_settime/clock_settime02.c b/testcases/kernel/syscalls/clock_settime/clock_settime02.c
index e16e9061a972..29548d5a4be2 100644
--- a/testcases/kernel/syscalls/clock_settime/clock_settime02.c
+++ b/testcases/kernel/syscalls/clock_settime/clock_settime02.c
@@ -9,19 +9,19 @@
  */
 
 #include "config.h"
-#include "tst_test.h"
-#include "lapi/syscalls.h"
 #include "tst_timer.h"
 #include "tst_safe_clocks.h"
+#include "lapi/abisize.h"
 
 #define DELTA_SEC 10
 #define NSEC_PER_SEC (1000000000L)
 
 struct test_case {
 	clockid_t type;
-	struct timespec newtime;
 	int exp_err;
 	int replace;
+	long tv_sec;
+	long tv_nsec;
 };
 
 struct test_case tc[] = {
@@ -29,24 +29,29 @@ struct test_case tc[] = {
 	 .type = CLOCK_REALTIME,
 	 .exp_err = EFAULT,
 	 .replace = 1,
+	 .tv_sec = 0,
+	 .tv_nsec = 0,
 	 },
 	{				/* case 02: REALTIME: tv_sec = -1     */
 	 .type = CLOCK_REALTIME,
-	 .newtime.tv_sec = -1,
 	 .exp_err = EINVAL,
 	 .replace = 1,
+	 .tv_sec = -1,
+	 .tv_nsec = 0,
 	 },
 	{				/* case 03: REALTIME: tv_nsec = -1    */
 	 .type = CLOCK_REALTIME,
-	 .newtime.tv_nsec = -1,
 	 .exp_err = EINVAL,
 	 .replace = 1,
+	 .tv_sec = 0,
+	 .tv_nsec = -1,
 	 },
 	{				/* case 04: REALTIME: tv_nsec = 1s+1  */
 	 .type = CLOCK_REALTIME,
-	 .newtime.tv_nsec = NSEC_PER_SEC + 1,
 	 .exp_err = EINVAL,
 	 .replace = 1,
+	 .tv_sec = 0,
+	 .tv_nsec = NSEC_PER_SEC + 1,
 	 },
 	{				/* case 05: MONOTONIC		      */
 	 .type = CLOCK_MONOTONIC,
@@ -83,64 +88,82 @@ struct test_case tc[] = {
 	 },
 };
 
-/*
- * Some tests may cause libc to segfault when passing bad arguments.
- */
-static int sys_clock_settime(clockid_t clk_id, struct timespec *tp)
+static struct tst_ts spec;
+
+static struct test_variants {
+	int (*gettime)(clockid_t clk_id, struct tst_ts *spec);
+	int (*settime)(clockid_t clk_id, struct tst_ts *spec);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .gettime = sys_clock_gettime, .settime = sys_clock_settime, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_settime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .gettime = sys_clock_gettime64, .settime = sys_clock_settime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
+static void setup(void)
 {
-	return tst_syscall(__NR_clock_settime, clk_id, tp);
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 }
 
 static void verify_clock_settime(unsigned int i)
 {
-	struct timespec spec, *specptr;
+	struct test_variants *tv = &variants[tst_variant];
 
-	specptr = &spec;
+	spec.type = tv->type;
 
 	if (tc[i].replace == 0) {
-
-		SAFE_CLOCK_GETTIME(CLOCK_REALTIME, specptr);
+		TEST(tv->gettime(CLOCK_REALTIME, &spec));
+		if (TST_RET == -1) {
+			tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+				tst_clock_name(CLOCK_REALTIME));
+			return;
+		}
 
 		/* add 1 sec to wall clock */
-		specptr->tv_sec += 1;
-
+		spec = tst_ts_add_us(spec, 1000000);
 	} else {
-
 		/* use given time spec */
-		*specptr = tc[i].newtime;
+		tst_ts_set_sec(&spec, tc[i].tv_sec);
+		tst_ts_set_nsec(&spec, tc[i].tv_nsec);
 	}
 
 	/* bad pointer case */
 	if (tc[i].exp_err == EFAULT)
-		specptr = tst_get_bad_addr(NULL);
-
-	TEST(sys_clock_settime(tc[i].type, specptr));
+		spec.type = TST_KERN_BAD_ADDR;
 
-	if (TST_RET == -1) {
+	TEST(tv->settime(tc[i].type, &spec));
 
-		if (tc[i].exp_err == TST_ERR) {
-			tst_res(TPASS | TTERRNO,
-				"clock_settime(%s): failed as expected",
-				tst_clock_name(tc[i].type));
-			return;
-		}
-
-		tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s "
-			"expected to fail with %s",
+	if (TST_RET != -1) {
+		tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s passed unexpectedly, expected %s",
 			tst_clock_name(tc[i].type),
 			tst_strerrno(tc[i].exp_err));
+		return;
+	}
 
+	if (tc[i].exp_err == TST_ERR) {
+		tst_res(TPASS | TTERRNO, "clock_settime(%s): failed as expected",
+			tst_clock_name(tc[i].type));
 		return;
 	}
 
-	tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s passed "
-				 "unexpectedly, expected %s",
-				 tst_clock_name(tc[i].type),
-				 tst_strerrno(tc[i].exp_err));
+	tst_res(TFAIL | TTERRNO, "clock_settime(2): clock %s " "expected to fail with %s",
+		tst_clock_name(tc[i].type), tst_strerrno(tc[i].exp_err));
 }
 
 static struct tst_test test = {
 	.test = verify_clock_settime,
+	.test_variants = ARRAY_SIZE(variants),
+	.setup = setup,
 	.tcnt = ARRAY_SIZE(tc),
 	.needs_root = 1,
 	.restore_wallclock = 1,
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 3/5] syscalls/clock_getres: Add support for time64 tests
  2020-04-22  5:37 ` [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants Viresh Kumar
  2020-04-22  5:37   ` [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests Viresh Kumar
  2020-04-22  5:37   ` [LTP] [PATCH V4 2/5] syscalls/clock_settime: " Viresh Kumar
@ 2020-04-22  5:37   ` Viresh Kumar
  2020-04-22  5:37   ` [LTP] [PATCH V4 4/5] syscalls/clock_nanosleep: " Viresh Kumar
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Viresh Kumar @ 2020-04-22  5:37 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_getres()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 include/tst_timer.h                           | 18 ++++++
 .../syscalls/clock_getres/clock_getres01.c    | 58 ++++++++++++-------
 2 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/include/tst_timer.h b/include/tst_timer.h
index fef201ee04df..df59c6aac0a5 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -133,6 +133,9 @@ struct tst_ts {
 
 static inline void *tst_get_ts(struct tst_ts *t)
 {
+	if (!t)
+		return NULL;
+
 	switch (t->type) {
 	case TST_LIBC_TIMESPEC:
 		return &t->libc_ts;
@@ -148,6 +151,21 @@ static inline void *tst_get_ts(struct tst_ts *t)
 	}
 }
 
+static inline int libc_clock_getres(clockid_t clk_id, struct tst_ts *t)
+{
+	return clock_getres(clk_id, tst_get_ts(t));
+}
+
+static inline int sys_clock_getres(clockid_t clk_id, struct tst_ts *t)
+{
+	return tst_syscall(__NR_clock_getres, clk_id, tst_get_ts(t));
+}
+
+static inline int sys_clock_getres64(clockid_t clk_id, struct tst_ts *t)
+{
+	return tst_syscall(__NR_clock_getres_time64, clk_id, tst_get_ts(t));
+}
+
 static inline int libc_clock_gettime(clockid_t clk_id, struct tst_ts *t)
 {
 	return clock_gettime(clk_id, tst_get_ts(t));
diff --git a/testcases/kernel/syscalls/clock_getres/clock_getres01.c b/testcases/kernel/syscalls/clock_getres/clock_getres01.c
index fcdf53b9cb79..1e961a3f8a25 100644
--- a/testcases/kernel/syscalls/clock_getres/clock_getres01.c
+++ b/testcases/kernel/syscalls/clock_getres/clock_getres01.c
@@ -12,11 +12,9 @@
 
 #include <errno.h>
 
-#include "tst_test.h"
-#include "lapi/syscalls.h"
+#include "tst_timer.h"
 #include "lapi/posix_clocks.h"
-
-static struct timespec *res;
+#include "lapi/abisize.h"
 
 static struct test_case {
 	char *name;
@@ -37,29 +35,45 @@ static struct test_case {
 	{"-1", -1, -1, EINVAL},
 };
 
-static const char *variant_desc[] = {
-	"default (vdso or syscall)",
-	"syscall",
-	"syscall with NULL res parameter" };
+static struct tst_ts *tspec, *nspec = NULL;
+
+static struct test_variants {
+	int (*func)(clockid_t clk_id, struct tst_ts *spec);
+	enum tst_ts_type type;
+	struct tst_ts **spec;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = libc_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &tspec, .desc = "vDSO or syscall with libc spec"},
+	{ .func = libc_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &nspec, .desc = "vDSO or syscall with libc spec with NULL res"},
+	{ .func = sys_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &tspec, .desc = "syscall with libc spec"},
+	{ .func = sys_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &nspec, .desc = "syscall with libc spec with NULL res"},
+	{ .func = sys_clock_getres, .type = TST_KERN_OLD_TIMESPEC, .spec = &tspec, .desc = "syscall with kernel spec32"},
+	{ .func = sys_clock_getres, .type = TST_KERN_OLD_TIMESPEC, .spec = &nspec, .desc = "syscall with kernel spec32 with NULL res"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_getres, .type = TST_KERN_TIMESPEC, .spec = &tspec, .desc = "syscall with kernel spec64"},
+	{ .func = sys_clock_getres, .type = TST_KERN_TIMESPEC, .spec = &nspec, .desc = "syscall with kernel spec64 with NULL res"},
+#endif
+
+#if (__NR_clock_getres_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_getres64, .type = TST_KERN_TIMESPEC, .spec = &tspec, .desc = "syscall time64 with kernel spec64"},
+	{ .func = sys_clock_getres64, .type = TST_KERN_TIMESPEC, .spec = &nspec, .desc = "syscall time64 with kernel spec64 with NULL res"},
+#endif
+};
 
 static void setup(void)
 {
-	tst_res(TINFO, "Testing variant: %s", variant_desc[tst_variant]);
+	tspec->type = variants[tst_variant].type;
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 }
 
 static void do_test(unsigned int i)
 {
-	switch (tst_variant) {
-	case 0:
-		TEST(clock_getres(tcase[i].clk_id, res));
-		break;
-	case 1:
-		TEST(tst_syscall(__NR_clock_getres, tcase[i].clk_id, res));
-		break;
-	case 2:
-		TEST(tst_syscall(__NR_clock_getres, tcase[i].clk_id, NULL));
-		break;
-	}
+	struct test_variants *tv = &variants[tst_variant];
+
+	TEST(tv->func(tcase[i].clk_id, *tv->spec));
 
 	if (TST_RET != tcase[i].ret) {
 		if (TST_ERR == EINVAL) {
@@ -84,10 +98,10 @@ static void do_test(unsigned int i)
 static struct tst_test test = {
 	.test = do_test,
 	.tcnt = ARRAY_SIZE(tcase),
-	.test_variants = 3,
+	.test_variants = ARRAY_SIZE(variants),
 	.setup = setup,
 	.bufs = (struct tst_buffers []) {
-		{&res, .size = sizeof(*res)},
+		{&tspec, .size = sizeof(*tspec)},
 		{},
 	}
 };
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 4/5] syscalls/clock_nanosleep: Add support for time64 tests
  2020-04-22  5:37 ` [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants Viresh Kumar
                     ` (2 preceding siblings ...)
  2020-04-22  5:37   ` [LTP] [PATCH V4 3/5] syscalls/clock_getres: " Viresh Kumar
@ 2020-04-22  5:37   ` Viresh Kumar
  2020-04-22  5:37   ` [LTP] [PATCH V4 5/5] syscalls/clock_adjtime: " Viresh Kumar
  2020-04-24  7:18   ` [LTP] [PATCH V5 3/5] syscalls/clock_getres: " Viresh Kumar
  5 siblings, 0 replies; 15+ messages in thread
From: Viresh Kumar @ 2020-04-22  5:37 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_nanosleep()
syscall tests.

This also moves the tests from clock_nanosleep2/ directory to
clock_nanosleep/ directory as it was added mistakenly there, as there is
no clock_nanosleep2() syscall.

Also note that this patch doesn't update clock_nanosleep02.c test as
that uses the sample test pattern and will result in many other changes
to core libraries of LTP test suite.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 include/tst_timer.h                           |  24 +++++
 runtest/syscalls                              |   2 +-
 .../syscalls/clock_nanosleep/.gitignore       |   1 +
 .../clock_nanosleep/clock_nanosleep01.c       | 102 +++++++++++++-----
 .../clock_nanosleep/clock_nanosleep03.c       |  68 ++++++++++--
 .../clock_nanosleep/clock_nanosleep04.c       |  90 ++++++++++++++++
 .../syscalls/clock_nanosleep2/.gitignore      |   1 -
 .../kernel/syscalls/clock_nanosleep2/Makefile |  10 --
 .../clock_nanosleep2/clock_nanosleep2_01.c    |  45 --------
 9 files changed, 253 insertions(+), 90 deletions(-)
 create mode 100644 testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/.gitignore
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/Makefile
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c

diff --git a/include/tst_timer.h b/include/tst_timer.h
index df59c6aac0a5..ab7d65f73b7b 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -196,6 +196,30 @@ static inline int sys_clock_settime64(clockid_t clk_id, struct tst_ts *t)
 	return tst_syscall(__NR_clock_settime64, clk_id, tst_get_ts(t));
 }
 
+static inline int libc_clock_nanosleep(clockid_t clk_id, int flags,
+				       struct tst_ts *request,
+				       struct tst_ts *remain)
+{
+	return clock_nanosleep(clk_id, flags, tst_get_ts(request),
+			       tst_get_ts(remain));
+}
+
+static inline int sys_clock_nanosleep(clockid_t clk_id, int flags,
+				      struct tst_ts *request,
+				      struct tst_ts *remain)
+{
+	return tst_syscall(__NR_clock_nanosleep, clk_id, flags,
+			   tst_get_ts(request), tst_get_ts(remain));
+}
+
+static inline int sys_clock_nanosleep64(clockid_t clk_id, int flags,
+				        struct tst_ts *request,
+					struct tst_ts *remain)
+{
+	return tst_syscall(__NR_clock_nanosleep_time64, clk_id, flags,
+			   tst_get_ts(request), tst_get_ts(remain));
+}
+
 /*
  * tst_ts_nonzero return:
  * 0: On success, i.e. timespec updated correctly.
diff --git a/runtest/syscalls b/runtest/syscalls
index 9bb72beb2287..bfd8d3dc32f2 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -90,8 +90,8 @@ clock_adjtime02 clock_adjtime02
 clock_getres01 clock_getres01
 clock_nanosleep01 clock_nanosleep01
 clock_nanosleep02 clock_nanosleep02
-clock_nanosleep2_01 clock_nanosleep2_01
 clock_nanosleep03 clock_nanosleep03
+clock_nanosleep04 clock_nanosleep04
 
 clock_gettime01 clock_gettime01
 clock_gettime02 clock_gettime02
diff --git a/testcases/kernel/syscalls/clock_nanosleep/.gitignore b/testcases/kernel/syscalls/clock_nanosleep/.gitignore
index 406897cded6d..1ab03a335f37 100644
--- a/testcases/kernel/syscalls/clock_nanosleep/.gitignore
+++ b/testcases/kernel/syscalls/clock_nanosleep/.gitignore
@@ -1,3 +1,4 @@
 /clock_nanosleep01
 /clock_nanosleep02
 /clock_nanosleep03
+/clock_nanosleep04
diff --git a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c
index d1fb0ee664c9..5add7226880a 100644
--- a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c
+++ b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c
@@ -9,10 +9,10 @@
 
 #include <limits.h>
 
-#include "lapi/syscalls.h"
+#include "tst_safe_clocks.h"
 #include "tst_sig_proc.h"
 #include "tst_timer.h"
-#include "tst_test.h"
+#include "lapi/abisize.h"
 
 static void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
 {
@@ -30,7 +30,8 @@ struct test_case {
 	int ttype;		   /* test type (enum) */
 	const char *desc;	   /* test description (name) */
 	int flags;		   /* clock_nanosleep flags parameter */
-	struct timespec rq;
+	long tv_sec;
+	long tv_nsec;
 	int exp_ret;
 	int exp_err;
 };
@@ -46,45 +47,76 @@ static struct test_case tcase[] = {
 		TYPE_NAME(NORMAL),
 		.clk_id = CLOCK_REALTIME,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 0, .tv_nsec = -1},
-		.exp_ret = EINVAL,
-		.exp_err = 0,
+		.tv_sec = 0,
+		.tv_nsec = -1,
+		.exp_ret = -1,
+		.exp_err = EINVAL,
 	},
 	{
 		TYPE_NAME(NORMAL),
 		.clk_id = CLOCK_REALTIME,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 0, .tv_nsec = 1000000000},
-		.exp_ret = EINVAL,
-		.exp_err = 0,
+		.tv_sec = 0,
+		.tv_nsec = 1000000000,
+		.exp_ret = -1,
+		.exp_err = EINVAL,
 	},
 	{
 		TYPE_NAME(NORMAL),
 		.clk_id = CLOCK_THREAD_CPUTIME_ID,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 0, .tv_nsec = 500000000},
-		.exp_ret = EINVAL,
-		.exp_err = 0,
+		.tv_sec = 0,
+		.tv_nsec = 500000000,
+		.exp_ret = -1,
+		.exp_err = ENOTSUP,
 	},
 	{
 		TYPE_NAME(SEND_SIGINT),
 		.clk_id = CLOCK_REALTIME,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 10, .tv_nsec = 0},
-		.exp_ret = EINTR,
-		.exp_err = 0,
+		.tv_sec = 10,
+		.tv_nsec = 0,
+		.exp_ret = -1,
+		.exp_err = EINTR,
 	},
 };
 
+static struct tst_ts rq;
+
+static struct test_variants {
+	int (*func)(clockid_t clock_id, int flags,
+		    struct tst_ts *request,
+		    struct tst_ts *remain);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = libc_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .func = sys_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .func = sys_clock_nanosleep, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_nanosleep, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_nanosleep_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_nanosleep64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 void setup(void)
 {
+	rq.type = variants[tst_variant].type;
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 	SAFE_SIGNAL(SIGINT, sighandler);
 }
 
 static void do_test(unsigned int i)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	struct test_case *tc = &tcase[i];
-	struct timespec rm = {0};
+	struct tst_ts rm = {.type = tv->type, };
 	pid_t pid = 0;
 
 	tst_res(TINFO, "case %s", tc->desc);
@@ -92,7 +124,29 @@ static void do_test(unsigned int i)
 	if (tc->ttype == SEND_SIGINT)
 		pid = create_sig_proc(SIGINT, 40, 500000);
 
-	TEST(clock_nanosleep(tc->clk_id, tc->flags, &tc->rq, &rm));
+	tst_ts_set_sec(&rq, tc->tv_sec);
+	tst_ts_set_nsec(&rq, tc->tv_nsec);
+
+	TEST(tv->func(tc->clk_id, tc->flags, &rq, &rm));
+
+	if (tv->func == libc_clock_nanosleep) {
+		/*
+		 * The return value and error number are differently set for
+		 * libc syscall as compared to kernel syscall.
+		 */
+		if (TST_RET) {
+			TST_ERR = TST_RET;
+			TST_RET = -1;
+		}
+
+		/*
+		 * nsleep isn't implemented by kernelf or
+		 * CLOCK_THREAD_CPUTIME_ID and it returns ENOTSUP, but libc
+		 * changes that error value to EINVAL.
+		 */
+		if (tc->clk_id == CLOCK_THREAD_CPUTIME_ID)
+			tc->exp_err = EINVAL;
+	}
 
 	if (pid) {
 		SAFE_KILL(pid, SIGTERM);
@@ -100,12 +154,10 @@ static void do_test(unsigned int i)
 	}
 
 	if (tc->ttype == SEND_SIGINT) {
-		long long expect_ms = tst_timespec_to_ms(tc->rq);
-		long long remain_ms = tst_timespec_to_ms(rm);
-
-		tst_res(TINFO, "remain time: %lds %ldns", rm.tv_sec, rm.tv_nsec);
+		long long expect_ms = tst_ts_to_ms(rq);
+		long long remain_ms = tst_ts_to_ms(rm);
 
-		if (!rm.tv_sec && !rm.tv_nsec) {
+		if (tst_ts_nonzero(&rm)) {
 			tst_res(TFAIL | TTERRNO,
 				"The clock_nanosleep() haven't updated"
 				" timestamp with remaining time");
@@ -120,20 +172,20 @@ static void do_test(unsigned int i)
 		}
 	}
 
-	if (TST_RET != tc->exp_ret) {
+	if ((TST_RET != tc->exp_ret) || (TST_ERR != tc->exp_err)) {
 		tst_res(TFAIL | TTERRNO, "returned %ld, expected %d,"
 			" expected errno: %s (%d)", TST_RET,
 			tc->exp_ret, tst_strerrno(tc->exp_err), tc->exp_err);
 		return;
 	}
 
-	tst_res(TPASS, "returned %s (%ld)",
-		tst_strerrno(TST_RET), TST_RET);
+	tst_res(TPASS, "returned %s (%d)", tst_strerrno(TST_ERR), TST_ERR);
 }
 
 static struct tst_test test = {
 	.tcnt = ARRAY_SIZE(tcase),
 	.test = do_test,
+	.test_variants = ARRAY_SIZE(variants),
 	.setup = setup,
 	.forks_child = 1,
 };
diff --git a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c
index 68773d59e346..4cd95f087889 100644
--- a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c
+++ b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c
@@ -19,33 +19,85 @@
 #include "tst_safe_clocks.h"
 #include "tst_timer.h"
 #include "lapi/namespaces_constants.h"
-#include "tst_test.h"
+#include "lapi/abisize.h"
 
 #define OFFSET_S 10
 #define SLEEP_US 100000
 
+static struct test_variants {
+	int (*gettime)(clockid_t clk_id, struct tst_ts *spec);
+	int (*func)(clockid_t clock_id, int flags,
+		    struct tst_ts *request,
+		    struct tst_ts *remain);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .gettime = libc_clock_gettime, .func = libc_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_nanosleep_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .gettime = sys_clock_gettime64, .func = sys_clock_nanosleep64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 static void verify_clock_nanosleep(void)
 {
-	struct timespec start, end, sleep_abs;
+	struct test_variants *tv = &variants[tst_variant];
+	struct tst_ts start, end, sleep_abs;
+
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+
+	start.type = end.type = sleep_abs.type = tv->type;
 
 	SAFE_UNSHARE(CLONE_NEWTIME);
 
 	SAFE_FILE_PRINTF("/proc/self/timens_offsets", "%d %d 0", CLOCK_MONOTONIC, OFFSET_S);
 
-	SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &start);
+	TEST(tv->gettime(CLOCK_MONOTONIC, &start));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_MONOTONIC));
+		return;
+	}
 
-	sleep_abs = tst_timespec_add_us(start, 1000000 * OFFSET_S + SLEEP_US);
+	sleep_abs = tst_ts_add_us(start, 1000000 * OFFSET_S + SLEEP_US);
 
 	if (!SAFE_FORK()) {
-		clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleep_abs, NULL);
+		TEST(tv->func(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleep_abs, NULL));
+		/*
+		 * The return value and error number are differently set for
+		 * libc syscall as compared to kernel syscall.
+		 */
+		if ((tv->func == libc_clock_nanosleep) && TST_RET) {
+			TST_ERR = TST_RET;
+			TST_RET = -1;
+		}
+
+		if (TST_RET == -1) {
+			tst_res(TFAIL | TTERRNO, "clock_nanosleep(2) failed for clock %s",
+				tst_clock_name(CLOCK_MONOTONIC));
+		}
+
 		exit(0);
 	}
 
 	SAFE_WAIT(NULL);
 
-	SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &end);
+	TEST(tv->gettime(CLOCK_MONOTONIC, &end));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_MONOTONIC));
+		return;
+	}
 
-	long long diff = tst_timespec_diff_us(end, start);
+	long long diff = tst_ts_diff_us(end, start);
 
 	if (diff > 5 * SLEEP_US) {
 		tst_res(TFAIL, "clock_nanosleep() slept too long %lli", diff);
@@ -62,11 +114,11 @@ static void verify_clock_nanosleep(void)
 
 static struct tst_test test = {
 	.test_all = verify_clock_nanosleep,
+	.test_variants = ARRAY_SIZE(variants),
 	.needs_root = 1,
 	.forks_child = 1,
 	.needs_kconfigs = (const char *[]) {
 		"CONFIG_TIME_NS=y",
 		NULL
 	}
-
 };
diff --git a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c
new file mode 100644
index 000000000000..9d69773d65f7
--- /dev/null
+++ b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) M. Koehrer <mathias_koehrer@arcor.de>, 2009
+ * Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include "tst_safe_clocks.h"
+#include "tst_timer.h"
+#include "lapi/abisize.h"
+
+#define NSEC_IN_SEC 1000000000
+
+static clockid_t tcase[] = {
+	CLOCK_MONOTONIC,
+	CLOCK_REALTIME,
+};
+
+static struct test_variants {
+	int (*gettime)(clockid_t clk_id, struct tst_ts *spec);
+	int (*func)(clockid_t clock_id, int flags,
+		    struct tst_ts *request,
+		    struct tst_ts *remain);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .gettime = libc_clock_gettime, .func = libc_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_nanosleep_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .gettime = sys_clock_gettime64, .func = sys_clock_nanosleep64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
+void setup(void)
+{
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
+}
+
+static void do_test(unsigned int i)
+{
+	struct test_variants *tv = &variants[tst_variant];
+	struct tst_ts ts = {.type = tv->type};
+	long long sec, nsec;
+
+	TEST(tv->gettime(tcase[i], &ts));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(tcase[i]));
+		return;
+	}
+
+	sec = tst_ts_get_sec(ts);
+	nsec = tst_ts_get_nsec(ts);
+
+	nsec += NSEC_IN_SEC/10;
+	if (nsec >= NSEC_IN_SEC) {
+		sec += 1;
+		nsec %= NSEC_IN_SEC;
+	}
+
+	tst_ts_set_sec(&ts, sec);
+	tst_ts_set_nsec(&ts, nsec);
+
+	TEST(tv->func(tcase[i], TIMER_ABSTIME, &ts, NULL));
+
+	if (TST_RET) {
+		tst_res(TFAIL | TTERRNO, "clock_nanosleep(2) failed for clock %s",
+			tst_clock_name(tcase[i]));
+	}
+
+	tst_res(TPASS, "clock_nanosleep(2) passed for clock %s",
+		tst_clock_name(tcase[i]));
+}
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcase),
+	.test = do_test,
+	.test_variants = ARRAY_SIZE(variants),
+	.setup = setup,
+};
diff --git a/testcases/kernel/syscalls/clock_nanosleep2/.gitignore b/testcases/kernel/syscalls/clock_nanosleep2/.gitignore
deleted file mode 100644
index 5be9cd0e8a8d..000000000000
--- a/testcases/kernel/syscalls/clock_nanosleep2/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/clock_nanosleep2_01
diff --git a/testcases/kernel/syscalls/clock_nanosleep2/Makefile b/testcases/kernel/syscalls/clock_nanosleep2/Makefile
deleted file mode 100644
index 262eef71b02b..000000000000
--- a/testcases/kernel/syscalls/clock_nanosleep2/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (c) International Business Machines  Corp., 2009
-
-top_srcdir		?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-LDLIBS			+= -lpthread -lrt
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c b/testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c
deleted file mode 100644
index d82d74d2d9fa..000000000000
--- a/testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) M. Koehrer <mathias_koehrer@arcor.de>, 2009
- * Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz>
- */
-
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-#include "tst_test.h"
-#include "lapi/syscalls.h"
-
-#define NSEC_IN_SEC 1000000000
-
-const clockid_t CLOCK_TO_USE = CLOCK_MONOTONIC;
-static int clock_nanosleep2(clockid_t clock_id, int flags,
-			    const struct timespec *req, struct timespec *rem)
-{
-	return tst_syscall(__NR_clock_nanosleep, clock_id, flags, req, rem);
-}
-
-static void verify_clock_nanosleep2(void)
-{
-	struct timespec ts;
-
-	clock_gettime(CLOCK_TO_USE, &ts);
-	ts.tv_nsec += NSEC_IN_SEC/10;
-	if (ts.tv_nsec >= NSEC_IN_SEC) {
-		ts.tv_sec += 1;
-		ts.tv_nsec %= NSEC_IN_SEC;
-	}
-
-	TEST(clock_nanosleep2(CLOCK_TO_USE, TIMER_ABSTIME, &ts, NULL));
-
-	if (TST_RET)
-		tst_res(TFAIL | TTERRNO, "clock_nanosleep2() failed");
-	else
-		tst_res(TPASS, "clock_nanosleep2() passed");
-}
-
-static struct tst_test test = {
-	.test_all = verify_clock_nanosleep2,
-};
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 5/5] syscalls/clock_adjtime: Add support for time64 tests
  2020-04-22  5:37 ` [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants Viresh Kumar
                     ` (3 preceding siblings ...)
  2020-04-22  5:37   ` [LTP] [PATCH V4 4/5] syscalls/clock_nanosleep: " Viresh Kumar
@ 2020-04-22  5:37   ` Viresh Kumar
  2020-04-24  7:18   ` [LTP] [PATCH V5 3/5] syscalls/clock_getres: " Viresh Kumar
  5 siblings, 0 replies; 15+ messages in thread
From: Viresh Kumar @ 2020-04-22  5:37 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_adjtime()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 .../syscalls/clock_adjtime/clock_adjtime.h    | 220 +++++++++++++++---
 .../syscalls/clock_adjtime/clock_adjtime01.c  | 124 ++++++----
 .../syscalls/clock_adjtime/clock_adjtime02.c  |  90 +++++--
 3 files changed, 334 insertions(+), 100 deletions(-)

diff --git a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
index d7f553a3a04b..4f65307be0ab 100644
--- a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
+++ b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
@@ -16,43 +16,195 @@
 #include <sys/types.h>
 #include "lapi/timex.h"
 
-static int sys_clock_adjtime(clockid_t, struct timex *);
-static void timex_show(char *, struct timex);
+#ifndef __kernel_timex
+struct __kernel_timex_timeval {
+	__kernel_time64_t       tv_sec;
+	long long		tv_usec;
+};
 
-/*
- * bad pointer w/ libc causes SIGSEGV signal, call syscall directly
- */
-static int sys_clock_adjtime(clockid_t clk_id, struct timex *txc)
+struct __kernel_timex {
+	unsigned int modes;	/* mode selector */
+	int :32;            /* pad */
+	long long offset;	/* time offset (usec) */
+	long long freq;	/* frequency offset (scaled ppm) */
+	long long maxerror;/* maximum error (usec) */
+	long long esterror;/* estimated error (usec) */
+	int status;		/* clock command/status */
+	int :32;            /* pad */
+	long long constant;/* pll time constant */
+	long long precision;/* clock precision (usec) (read only) */
+	long long tolerance;/* clock frequency tolerance (ppm)
+				   * (read only)
+				   */
+	struct __kernel_timex_timeval time;	/* (read only, except for ADJ_SETOFFSET) */
+	long long tick;	/* (modified) usecs between clock ticks */
+
+	long long ppsfreq;/* pps frequency (scaled ppm) (ro) */
+	long long jitter; /* pps jitter (us) (ro) */
+	int shift;              /* interval duration (s) (shift) (ro) */
+	int :32;            /* pad */
+	long long stabil;            /* pps stability (scaled ppm) (ro) */
+	long long jitcnt; /* jitter limit exceeded (ro) */
+	long long calcnt; /* calibration intervals (ro) */
+	long long errcnt; /* calibration errors (ro) */
+	long long stbcnt; /* stability limit exceeded (ro) */
+
+	int tai;		/* TAI offset (ro) */
+
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32;
+};
+#endif
+
+enum tst_timex_type {
+	TST_LIBC_TIMEX,
+	TST_KERN_TIMEX,
+	/* Used for indicating failure test with bad address */
+	TST_KERN_TIMEX_BAD_ADDR
+};
+
+struct tst_timex {
+	enum tst_timex_type type;
+	union {
+		struct timex libc_timex;
+		struct __kernel_timex kern_timex;
+	};
+};
+
+static inline void *tst_get_timex(struct tst_timex *t)
+{
+	switch (t->type) {
+	case TST_LIBC_TIMEX:
+		return &t->libc_timex;
+	case TST_KERN_TIMEX:
+		return &t->kern_timex;
+	case TST_KERN_TIMEX_BAD_ADDR:
+		return tst_get_bad_addr(NULL);
+	default:
+		tst_brk(TBROK, "Invalid type: %d", t->type);
+		return NULL;
+	}
+}
+
+static inline int sys_clock_adjtime(clockid_t clk_id, struct tst_timex *t)
 {
-	return tst_syscall(__NR_clock_adjtime, clk_id, txc);
+	return tst_syscall(__NR_clock_adjtime, clk_id, tst_get_timex(t));
 }
 
-static void timex_show(char *given, struct timex txc)
+static inline int sys_clock_adjtime64(clockid_t clk_id, struct tst_timex *t)
 {
-	tst_res(TINFO,  "%s\n"
-			"             mode: %d\n"
-			"           offset: %ld\n"
-			"        frequency: %ld\n"
-			"         maxerror: %ld\n"
-			"         esterror: %ld\n"
-			"           status: %d (0x%x)\n"
-			"    time_constant: %ld\n"
-			"        precision: %ld\n"
-			"        tolerance: %ld\n"
-			"             tick: %ld\n"
-			"         raw time: %d(s) %d(us)",
-			given,
-			txc.modes,
-			txc.offset,
-			txc.freq,
-			txc.maxerror,
-			txc.esterror,
-			txc.status,
-			txc.status,
-			txc.constant,
-			txc.precision,
-			txc.tolerance,
-			txc.tick,
-			(int)txc.time.tv_sec,
-			(int)txc.time.tv_usec);
+	return tst_syscall(__NR_clock_adjtime64, clk_id, tst_get_timex(t));
+}
+
+#define _timex_show(_timex, _desc)					\
+	tst_res(TINFO,  "%s\n"						\
+			"             mode: %u\n"			\
+			"           offset: "#_desc"\n"			\
+			"        frequency: "#_desc"\n"			\
+			"         maxerror: "#_desc"\n"			\
+			"         esterror: "#_desc"\n"			\
+			"           status: %d (0x%x)\n"		\
+			"    time_constant: "#_desc"\n"			\
+			"        precision: "#_desc"\n"			\
+			"        tolerance: "#_desc"\n"			\
+			"             tick: "#_desc"\n"			\
+			"         raw time: "#_desc"(s) "#_desc"(us)",	\
+			given,						\
+			_timex.modes,					\
+			_timex.offset,					\
+			_timex.freq,					\
+			_timex.maxerror,				\
+			_timex.esterror,				\
+			_timex.status,					\
+			_timex.status,					\
+			_timex.constant,				\
+			_timex.precision,				\
+			_timex.tolerance,				\
+			_timex.tick,					\
+			_timex.time.tv_sec,				\
+			_timex.time.tv_usec)
+
+static inline void timex_show(char *given, struct tst_timex *timex)
+{
+	switch (timex->type) {
+	case TST_LIBC_TIMEX:
+		_timex_show(timex->libc_timex, %ld);
+		return;
+	case TST_KERN_TIMEX:
+		_timex_show(timex->kern_timex, %lld);
+		return;
+	default:
+		tst_res(TFAIL, "Invalid type: %d", timex->type);
+	}
+}
+
+#define ADJ_MODES	0
+
+#define _select_field(_timex, _field)					\
+{									\
+	if (_field == ADJ_MODES)					\
+		return &_timex.modes;					\
+	if (_field == ADJ_OFFSET)					\
+		return &_timex.offset;					\
+	if (_field == ADJ_FREQUENCY)					\
+		return &_timex.freq;					\
+	if (_field == ADJ_MAXERROR)					\
+		return &_timex.maxerror;				\
+	if (_field == ADJ_ESTERROR)					\
+		return &_timex.esterror;				\
+	if (_field == ADJ_TIMECONST)					\
+		return &_timex.constant;				\
+	if (_field == ADJ_TICK)						\
+		return &_timex.tick;					\
+	if (_field == ADJ_STATUS)					\
+		return &_timex.status;					\
+	tst_res(TFAIL, "Invalid type: %d", timex->type);		\
+	return NULL;							\
+}
+
+static inline void *_get_field(struct tst_timex *timex, unsigned int field)
+{
+	switch (timex->type) {
+	case TST_LIBC_TIMEX:
+		_select_field(timex->libc_timex, field);
+	case TST_KERN_TIMEX:
+		_select_field(timex->kern_timex, field);
+	default:
+		tst_res(TFAIL, "Invalid type: %d", timex->type);
+		return NULL;
+	}
+}
+
+#define timex_get_set_field_type(_type_libc, _type_kern)		\
+static inline _type_kern						\
+timex_get_field_##_type_libc(struct tst_timex *timex, unsigned int field) \
+{									\
+	switch (timex->type) {						\
+	case TST_LIBC_TIMEX:						\
+		return *((_type_libc*)_get_field(timex, field));	\
+	case TST_KERN_TIMEX:						\
+		return *((_type_kern*)_get_field(timex, field));	\
+	default:							\
+		tst_res(TFAIL, "Invalid type: %d", timex->type);	\
+		return 0;						\
+	}								\
+}									\
+									\
+static inline void							\
+timex_set_field_##_type_libc(struct tst_timex *timex, unsigned int field, \
+			    _type_kern value)				\
+{									\
+	switch (timex->type) {						\
+	case TST_LIBC_TIMEX:						\
+		*((_type_libc*)_get_field(timex, field)) = value;	\
+		return;							\
+	case TST_KERN_TIMEX:						\
+		*((_type_kern*)_get_field(timex, field)) = value;	\
+		return;							\
+	default:							\
+		tst_res(TFAIL, "Invalid type: %d", timex->type);	\
+	}								\
 }
+timex_get_set_field_type(uint, uint);
+timex_get_set_field_type(long, long long);
diff --git a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c
index 1262d34fa0d6..b3e74c776f2b 100644
--- a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c
+++ b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c
@@ -55,15 +55,15 @@
  */
 
 #include "clock_adjtime.h"
+#include "lapi/abisize.h"
 
 static long hz;
-static struct timex saved, ttxc;
+static struct tst_timex saved, ttxc;
 static int supported;
 
 struct test_case {
 	unsigned int modes;
 	long highlimit;
-	long *ptr;
 	long delta;
 };
 
@@ -80,79 +80,103 @@ struct test_case tc[] = {
 	{
 	 .modes = ADJ_OFFSET,
 	 .highlimit = 500000,
-	 .ptr = &ttxc.offset,
 	 .delta = 10000,
 	},
 	{
 	 .modes = ADJ_FREQUENCY,
-	 .ptr = &ttxc.freq,
 	 .delta = 100,
 	},
 	{
 	 .modes = ADJ_MAXERROR,
-	 .ptr = &ttxc.maxerror,
 	 .delta = 100,
 	},
 	{
 	 .modes = ADJ_ESTERROR,
-	 .ptr = &ttxc.esterror,
 	 .delta = 100,
 	},
 	{
 	 .modes = ADJ_TIMECONST,
-	 .ptr = &ttxc.constant,
 	 .delta = 1,
 	},
 	{
 	 .modes = ADJ_TICK,
 	 .highlimit = 1100000,
-	 .ptr = &ttxc.tick,
 	 .delta = 1000,
 	},
 };
 
+static struct test_variants {
+	int (*func)(clockid_t clk_id, struct tst_timex *timex);
+	enum tst_timex_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = sys_clock_adjtime, .type = TST_LIBC_TIMEX, .desc = "syscall with libc spec"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_adjtime, .type = TST_KERN_TIMEX, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_adjtime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_adjtime64, .type = TST_KERN_TIMEX, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 static void verify_clock_adjtime(unsigned int i)
 {
-	long ptroff, *ptr = NULL;
-	struct timex verify;
+	struct test_variants *tv = &variants[tst_variant];
+	struct tst_timex verify;
+	long long val;
+	int rval;
 
-	memset(&ttxc, 0, sizeof(struct timex));
-	memset(&verify, 0, sizeof(struct timex));
+	memset(&ttxc, 0, sizeof(ttxc));
+	memset(&verify, 0, sizeof(verify));
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &ttxc);
-	timex_show("GET", ttxc);
+	ttxc.type = verify.type = tv->type;
+
+	rval = tv->func(CLOCK_REALTIME, &ttxc);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 
-	ttxc.modes = tc[i].modes;
+	timex_show("GET", &ttxc);
 
-	if (tc[i].ptr && tc[i].delta) {
+	timex_set_field_uint(&ttxc, ADJ_MODES, tc[i].modes);
 
-		*tc[i].ptr += tc[i].delta;
+	if (tc[i].delta) {
+		val = timex_get_field_long(&ttxc, tc[i].modes);
+		val += tc[i].delta;
 
 		/* fix limits, if existent, so no errors occur */
+		if (tc[i].highlimit && val >= tc[i].highlimit)
+			val = tc[i].highlimit;
 
-		if (tc[i].highlimit) {
-			if (*tc[i].ptr >= tc[i].highlimit)
-				*tc[i].ptr = tc[i].highlimit;
-		}
+		timex_set_field_long(&ttxc, tc[i].modes, val);
 	}
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &ttxc);
-	timex_show("SET", ttxc);
-
-	if (tc[i].ptr) {
+	rval = tv->func(CLOCK_REALTIME, &ttxc);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 
-		/* adjtimex field being tested so we can verify later */
+	timex_show("SET", &ttxc);
 
-		ptroff = (long) tc[i].ptr - (long) &ttxc;
-		ptr = (void *) &verify + ptroff;
+	rval = tv->func(CLOCK_REALTIME, &verify);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
 	}
 
-	TEST(sys_clock_adjtime(CLOCK_REALTIME, &verify));
-	timex_show("VERIFY", verify);
+	timex_show("VERIFY", &verify);
 
-	if (tc[i].ptr && *tc[i].ptr != *ptr) {
+	if (tc[i].delta &&
+	    timex_get_field_long(&ttxc, tc[i].modes) !=
+	    timex_get_field_long(&verify, tc[i].modes)) {
 		tst_res(TFAIL, "clock_adjtime(): could not set value (mode=%x)",
-				tc[i].modes);
+			tc[i].modes);
 	}
 
 	if (TST_RET < 0) {
@@ -165,14 +189,23 @@ static void verify_clock_adjtime(unsigned int i)
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	size_t i;
 	int rval;
 
-	rval = SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+
+	saved.type = tv->type;
+	rval = tv->func(CLOCK_REALTIME, &saved);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
+
 	supported = 1;
 
 	if (rval != TIME_OK && rval != TIME_ERROR) {
-		timex_show("SAVE_STATUS", saved);
+		timex_show("SAVE_STATUS", &saved);
 		tst_brk(TBROK | TTERRNO, "clock has on-going leap changes, "
 				"returned: %i", rval);
 	}
@@ -188,7 +221,7 @@ static void setup(void)
 
 		/* fix usec as being test default resolution */
 
-		if (saved.modes & ADJ_NANO) {
+		if (timex_get_field_uint(&saved, ADJ_MODES) & ADJ_NANO) {
 			if (tc[i].modes == ADJ_OFFSET) {
 				tc[i].highlimit *= 1000;
 				tc[i].delta *= 1000;
@@ -199,21 +232,29 @@ static void setup(void)
 
 static void cleanup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
+	unsigned int modes = ADJ_ALL;
+	int rval;
+
 	if (supported == 0)
 		return;
 
-	saved.modes = ADJ_ALL;
-
 	/* restore clock resolution based on original status flag */
 
-	if (saved.status & STA_NANO)
-		saved.modes |= ADJ_NANO;
+	if (timex_get_field_uint(&saved, ADJ_STATUS) & STA_NANO)
+		modes |= ADJ_NANO;
 	else
-		saved.modes |= ADJ_MICRO;
+		modes |= ADJ_MICRO;
+
+	timex_set_field_uint(&saved, ADJ_MODES, modes);
 
 	/* restore original clock flags */
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	rval = tv->func(CLOCK_REALTIME, &saved);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 }
 
 static struct tst_test test = {
@@ -221,6 +262,7 @@ static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
 	.needs_root = 1,
 	.restore_wallclock = 1,
 };
diff --git a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c
index ba8eae54f5ed..858a598eb9bb 100644
--- a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c
+++ b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c
@@ -56,9 +56,10 @@
  */
 
 #include "clock_adjtime.h"
+#include "lapi/abisize.h"
 
 static long hz;
-static struct timex saved, ttxc;
+static struct tst_timex saved, ttxc;
 static int supported;
 
 static void cleanup(void);
@@ -68,7 +69,6 @@ struct test_case {
 	unsigned int modes;
 	long lowlimit;
 	long highlimit;
-	long *ptr;
 	long delta;
 	int exp_err;
 	int droproot;
@@ -92,7 +92,6 @@ struct test_case tc[] = {
 	 .clktype = CLOCK_REALTIME,
 	 .modes = ADJ_TICK,
 	 .lowlimit = 900000,
-	 .ptr = &ttxc.tick,
 	 .delta = 1,
 	 .exp_err = EINVAL,
 	},
@@ -100,7 +99,6 @@ struct test_case tc[] = {
 	 .clktype = CLOCK_REALTIME,
 	 .modes = ADJ_TICK,
 	 .highlimit = 1100000,
-	 .ptr = &ttxc.tick,
 	 .delta = 1,
 	 .exp_err = EINVAL,
 	},
@@ -112,19 +110,43 @@ struct test_case tc[] = {
 	},
 };
 
+static struct test_variants {
+	int (*func)(clockid_t clk_id, struct tst_timex *timex);
+	enum tst_timex_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = sys_clock_adjtime, .type = TST_LIBC_TIMEX, .desc = "syscall with libc spec"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_adjtime, .type = TST_KERN_TIMEX, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_adjtime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_adjtime64, .type = TST_KERN_TIMEX, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 static void verify_clock_adjtime(unsigned int i)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	uid_t whoami = 0;
-	struct timex *txcptr;
+	struct tst_timex *txcptr = &ttxc;
 	struct passwd *nobody;
 	static const char name[] = "nobody";
+	int rval;
 
-	txcptr = &ttxc;
+	memset(txcptr, 0, sizeof(*txcptr));
 
-	memset(txcptr, 0, sizeof(struct timex));
+	txcptr->type = tv->type;
+	rval = tv->func(CLOCK_REALTIME, txcptr);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, txcptr);
-	timex_show("GET", *txcptr);
+	timex_show("GET", txcptr);
 
 	if (tc[i].droproot) {
 		nobody = SAFE_GETPWNAM(name);
@@ -132,24 +154,24 @@ static void verify_clock_adjtime(unsigned int i)
 		SAFE_SETEUID(whoami);
 	}
 
-	txcptr->modes = tc[i].modes;
-
-	if (tc[i].ptr) {
+	timex_set_field_uint(txcptr, ADJ_MODES, tc[i].modes);
 
+	if (tc[i].delta) {
 		if (tc[i].lowlimit)
-			*tc[i].ptr = tc[i].lowlimit - tc[i].delta;
+			timex_set_field_long(&ttxc, tc[i].modes, tc[i].lowlimit - tc[i].delta);
 
 		if (tc[i].highlimit)
-			*tc[i].ptr = tc[i].highlimit + tc[i].delta;
+			timex_set_field_long(&ttxc, tc[i].modes, tc[i].highlimit + tc[i].delta);
 	}
 
 	/* special case: EFAULT for bad addresses */
 	if (tc[i].exp_err == EFAULT)
-		txcptr = tst_get_bad_addr(cleanup);
+		txcptr->type = TST_KERN_TIMEX_BAD_ADDR;
+
+	TEST(tv->func(tc[i].clktype, txcptr));
 
-	TEST(sys_clock_adjtime(tc[i].clktype, txcptr));
 	if (txcptr && tc[i].exp_err != EFAULT)
-		timex_show("TEST", *txcptr);
+		timex_show("TEST", txcptr);
 
 	if (TST_RET >= 0) {
 		tst_res(TFAIL, "clock_adjtime(): passed unexpectedly (mode=%x, "
@@ -173,14 +195,23 @@ static void verify_clock_adjtime(unsigned int i)
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	size_t i;
 	int rval;
 
-	rval = SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+
+	saved.type = tv->type;
+	rval = tv->func(CLOCK_REALTIME, &saved);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
+
 	supported = 1;
 
 	if (rval != TIME_OK && rval != TIME_ERROR) {
-		timex_show("SAVE_STATUS", saved);
+		timex_show("SAVE_STATUS", &saved);
 		tst_brk(TBROK | TTERRNO, "clock has on-going leap changes, "
 				"returned: %i", rval);
 	}
@@ -199,21 +230,29 @@ static void setup(void)
 
 static void cleanup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
+	unsigned int modes = ADJ_ALL;
+	int rval;
+
 	if (supported == 0)
 		return;
 
-	saved.modes = ADJ_ALL;
-
 	/* restore clock resolution based on original status flag */
 
-	if (saved.status & STA_NANO)
-		saved.modes |= ADJ_NANO;
+	if (timex_get_field_uint(&saved, ADJ_STATUS) & STA_NANO)
+		modes |= ADJ_NANO;
 	else
-		saved.modes |= ADJ_MICRO;
+		modes |= ADJ_MICRO;
+
+	timex_set_field_uint(&saved, ADJ_MODES, modes);
 
 	/* restore original clock flags */
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	rval = tv->func(CLOCK_REALTIME, &saved);
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 }
 
 static struct tst_test test = {
@@ -221,6 +260,7 @@ static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
 	.needs_root = 1,
 	.restore_wallclock = 1,
 };
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests
  2020-04-22  5:37   ` [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests Viresh Kumar
@ 2020-04-23 13:50     ` Cyril Hrubis
  2020-04-24  7:19       ` Viresh Kumar
  0 siblings, 1 reply; 15+ messages in thread
From: Cyril Hrubis @ 2020-04-23 13:50 UTC (permalink / raw)
  To: ltp

Hi!
Pushed with a few changes, thanks.

* Changed the nonzero check to check if nanoseconds are valid,
  which covers the 64bit check as well.

* Pushed the bad address handling down to the test, which means that
  we have to convert the struct tst_ts for each syscall, but I think
  that it's cleaner that way and we also map only single bad address per
  test.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 2/5] syscalls/clock_settime: Add support for time64 tests
  2020-04-22  5:37   ` [LTP] [PATCH V4 2/5] syscalls/clock_settime: " Viresh Kumar
@ 2020-04-23 15:08     ` Cyril Hrubis
  0 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2020-04-23 15:08 UTC (permalink / raw)
  To: ltp

Hi!
Here as well, pushed with a minor changes.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V5 3/5] syscalls/clock_getres: Add support for time64 tests
  2020-04-22  5:37 ` [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants Viresh Kumar
                     ` (4 preceding siblings ...)
  2020-04-22  5:37   ` [LTP] [PATCH V4 5/5] syscalls/clock_adjtime: " Viresh Kumar
@ 2020-04-24  7:18   ` Viresh Kumar
  2020-04-24  7:18     ` [LTP] [PATCH V5 4/5] syscalls/clock_nanosleep: " Viresh Kumar
  2020-04-24  7:18     ` [LTP] [PATCH V5 5/5] syscalls/clock_adjtime: " Viresh Kumar
  5 siblings, 2 replies; 15+ messages in thread
From: Viresh Kumar @ 2020-04-24  7:18 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_getres()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 include/tst_timer.h                           | 18 ++++++
 .../syscalls/clock_getres/clock_getres01.c    | 58 ++++++++++++-------
 2 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/include/tst_timer.h b/include/tst_timer.h
index 0c6b934157f9..4823d350fdc6 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -131,6 +131,9 @@ struct tst_ts {
 
 static inline void *tst_ts_get(struct tst_ts *t)
 {
+	if (!t)
+		return NULL;
+
 	switch (t->type) {
 	case TST_LIBC_TIMESPEC:
 		return &t->ts.libc_ts;
@@ -144,6 +147,21 @@ static inline void *tst_ts_get(struct tst_ts *t)
 	}
 }
 
+static inline int libc_clock_getres(clockid_t clk_id, void *ts)
+{
+	return clock_getres(clk_id, ts);
+}
+
+static inline int sys_clock_getres(clockid_t clk_id, void *ts)
+{
+	return tst_syscall(__NR_clock_getres, clk_id, ts);
+}
+
+static inline int sys_clock_getres64(clockid_t clk_id, void *ts)
+{
+	return tst_syscall(__NR_clock_getres_time64, clk_id, ts);
+}
+
 static inline int libc_clock_gettime(clockid_t clk_id, void *ts)
 {
 	return clock_gettime(clk_id, ts);
diff --git a/testcases/kernel/syscalls/clock_getres/clock_getres01.c b/testcases/kernel/syscalls/clock_getres/clock_getres01.c
index fcdf53b9cb79..5b83c2460f05 100644
--- a/testcases/kernel/syscalls/clock_getres/clock_getres01.c
+++ b/testcases/kernel/syscalls/clock_getres/clock_getres01.c
@@ -12,11 +12,9 @@
 
 #include <errno.h>
 
-#include "tst_test.h"
-#include "lapi/syscalls.h"
+#include "tst_timer.h"
 #include "lapi/posix_clocks.h"
-
-static struct timespec *res;
+#include "lapi/abisize.h"
 
 static struct test_case {
 	char *name;
@@ -37,29 +35,45 @@ static struct test_case {
 	{"-1", -1, -1, EINVAL},
 };
 
-static const char *variant_desc[] = {
-	"default (vdso or syscall)",
-	"syscall",
-	"syscall with NULL res parameter" };
+static struct tst_ts *tspec, *nspec = NULL;
+
+static struct test_variants {
+	int (*func)(clockid_t clk_id, void *ts);
+	enum tst_ts_type type;
+	struct tst_ts **spec;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = libc_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &tspec, .desc = "vDSO or syscall with libc spec"},
+	{ .func = libc_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &nspec, .desc = "vDSO or syscall with libc spec with NULL res"},
+	{ .func = sys_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &tspec, .desc = "syscall with libc spec"},
+	{ .func = sys_clock_getres, .type = TST_LIBC_TIMESPEC, .spec = &nspec, .desc = "syscall with libc spec with NULL res"},
+	{ .func = sys_clock_getres, .type = TST_KERN_OLD_TIMESPEC, .spec = &tspec, .desc = "syscall with kernel spec32"},
+	{ .func = sys_clock_getres, .type = TST_KERN_OLD_TIMESPEC, .spec = &nspec, .desc = "syscall with kernel spec32 with NULL res"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_getres, .type = TST_KERN_TIMESPEC, .spec = &tspec, .desc = "syscall with kernel spec64"},
+	{ .func = sys_clock_getres, .type = TST_KERN_TIMESPEC, .spec = &nspec, .desc = "syscall with kernel spec64 with NULL res"},
+#endif
+
+#if (__NR_clock_getres_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_getres64, .type = TST_KERN_TIMESPEC, .spec = &tspec, .desc = "syscall time64 with kernel spec64"},
+	{ .func = sys_clock_getres64, .type = TST_KERN_TIMESPEC, .spec = &nspec, .desc = "syscall time64 with kernel spec64 with NULL res"},
+#endif
+};
 
 static void setup(void)
 {
-	tst_res(TINFO, "Testing variant: %s", variant_desc[tst_variant]);
+	tspec->type = variants[tst_variant].type;
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 }
 
 static void do_test(unsigned int i)
 {
-	switch (tst_variant) {
-	case 0:
-		TEST(clock_getres(tcase[i].clk_id, res));
-		break;
-	case 1:
-		TEST(tst_syscall(__NR_clock_getres, tcase[i].clk_id, res));
-		break;
-	case 2:
-		TEST(tst_syscall(__NR_clock_getres, tcase[i].clk_id, NULL));
-		break;
-	}
+	struct test_variants *tv = &variants[tst_variant];
+
+	TEST(tv->func(tcase[i].clk_id, tst_ts_get(*tv->spec)));
 
 	if (TST_RET != tcase[i].ret) {
 		if (TST_ERR == EINVAL) {
@@ -84,10 +98,10 @@ static void do_test(unsigned int i)
 static struct tst_test test = {
 	.test = do_test,
 	.tcnt = ARRAY_SIZE(tcase),
-	.test_variants = 3,
+	.test_variants = ARRAY_SIZE(variants),
 	.setup = setup,
 	.bufs = (struct tst_buffers []) {
-		{&res, .size = sizeof(*res)},
+		{&tspec, .size = sizeof(*tspec)},
 		{},
 	}
 };
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V5 4/5] syscalls/clock_nanosleep: Add support for time64 tests
  2020-04-24  7:18   ` [LTP] [PATCH V5 3/5] syscalls/clock_getres: " Viresh Kumar
@ 2020-04-24  7:18     ` Viresh Kumar
  2020-04-24  7:18     ` [LTP] [PATCH V5 5/5] syscalls/clock_adjtime: " Viresh Kumar
  1 sibling, 0 replies; 15+ messages in thread
From: Viresh Kumar @ 2020-04-24  7:18 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_nanosleep()
syscall tests.

This also moves the tests from clock_nanosleep2/ directory to
clock_nanosleep/ directory as it was added mistakenly there, as there is
no clock_nanosleep2() syscall.

Also note that this patch doesn't update clock_nanosleep02.c test as
that uses the sample test pattern and will result in many other changes
to core libraries of LTP test suite.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 include/tst_timer.h                           |  20 ++++
 runtest/syscalls                              |   2 +-
 .../syscalls/clock_nanosleep/.gitignore       |   1 +
 .../clock_nanosleep/clock_nanosleep01.c       | 100 +++++++++++++-----
 .../clock_nanosleep/clock_nanosleep03.c       |  66 ++++++++++--
 .../clock_nanosleep/clock_nanosleep04.c       |  88 +++++++++++++++
 .../syscalls/clock_nanosleep2/.gitignore      |   1 -
 .../kernel/syscalls/clock_nanosleep2/Makefile |  10 --
 .../clock_nanosleep2/clock_nanosleep2_01.c    |  45 --------
 9 files changed, 243 insertions(+), 90 deletions(-)
 create mode 100644 testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/.gitignore
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/Makefile
 delete mode 100644 testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c

diff --git a/include/tst_timer.h b/include/tst_timer.h
index 4823d350fdc6..256e1d71e1bc 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -192,6 +192,26 @@ static inline int sys_clock_settime64(clockid_t clk_id, void *ts)
 	return tst_syscall(__NR_clock_settime64, clk_id, ts);
 }
 
+static inline int libc_clock_nanosleep(clockid_t clk_id, int flags,
+				       void *request, void *remain)
+{
+	return clock_nanosleep(clk_id, flags, request, remain);
+}
+
+static inline int sys_clock_nanosleep(clockid_t clk_id, int flags,
+				      void *request, void *remain)
+{
+	return tst_syscall(__NR_clock_nanosleep, clk_id, flags,
+			   request, remain);
+}
+
+static inline int sys_clock_nanosleep64(clockid_t clk_id, int flags,
+				        void *request, void *remain)
+{
+	return tst_syscall(__NR_clock_nanosleep_time64, clk_id, flags,
+			   request, remain);
+}
+
 /*
  * Returns tst_ts seconds.
  */
diff --git a/runtest/syscalls b/runtest/syscalls
index f6df32859df6..6c23f75d3389 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -90,8 +90,8 @@ clock_adjtime02 clock_adjtime02
 clock_getres01 clock_getres01
 clock_nanosleep01 clock_nanosleep01
 clock_nanosleep02 clock_nanosleep02
-clock_nanosleep2_01 clock_nanosleep2_01
 clock_nanosleep03 clock_nanosleep03
+clock_nanosleep04 clock_nanosleep04
 
 clock_gettime01 clock_gettime01
 clock_gettime02 clock_gettime02
diff --git a/testcases/kernel/syscalls/clock_nanosleep/.gitignore b/testcases/kernel/syscalls/clock_nanosleep/.gitignore
index 406897cded6d..1ab03a335f37 100644
--- a/testcases/kernel/syscalls/clock_nanosleep/.gitignore
+++ b/testcases/kernel/syscalls/clock_nanosleep/.gitignore
@@ -1,3 +1,4 @@
 /clock_nanosleep01
 /clock_nanosleep02
 /clock_nanosleep03
+/clock_nanosleep04
diff --git a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c
index d1fb0ee664c9..85152d0a1713 100644
--- a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c
+++ b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep01.c
@@ -9,10 +9,10 @@
 
 #include <limits.h>
 
-#include "lapi/syscalls.h"
+#include "tst_safe_clocks.h"
 #include "tst_sig_proc.h"
 #include "tst_timer.h"
-#include "tst_test.h"
+#include "lapi/abisize.h"
 
 static void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
 {
@@ -30,7 +30,8 @@ struct test_case {
 	int ttype;		   /* test type (enum) */
 	const char *desc;	   /* test description (name) */
 	int flags;		   /* clock_nanosleep flags parameter */
-	struct timespec rq;
+	long tv_sec;
+	long tv_nsec;
 	int exp_ret;
 	int exp_err;
 };
@@ -46,45 +47,74 @@ static struct test_case tcase[] = {
 		TYPE_NAME(NORMAL),
 		.clk_id = CLOCK_REALTIME,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 0, .tv_nsec = -1},
-		.exp_ret = EINVAL,
-		.exp_err = 0,
+		.tv_sec = 0,
+		.tv_nsec = -1,
+		.exp_ret = -1,
+		.exp_err = EINVAL,
 	},
 	{
 		TYPE_NAME(NORMAL),
 		.clk_id = CLOCK_REALTIME,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 0, .tv_nsec = 1000000000},
-		.exp_ret = EINVAL,
-		.exp_err = 0,
+		.tv_sec = 0,
+		.tv_nsec = 1000000000,
+		.exp_ret = -1,
+		.exp_err = EINVAL,
 	},
 	{
 		TYPE_NAME(NORMAL),
 		.clk_id = CLOCK_THREAD_CPUTIME_ID,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 0, .tv_nsec = 500000000},
-		.exp_ret = EINVAL,
-		.exp_err = 0,
+		.tv_sec = 0,
+		.tv_nsec = 500000000,
+		.exp_ret = -1,
+		.exp_err = ENOTSUP,
 	},
 	{
 		TYPE_NAME(SEND_SIGINT),
 		.clk_id = CLOCK_REALTIME,
 		.flags = 0,
-		.rq = (struct timespec) {.tv_sec = 10, .tv_nsec = 0},
-		.exp_ret = EINTR,
-		.exp_err = 0,
+		.tv_sec = 10,
+		.tv_nsec = 0,
+		.exp_ret = -1,
+		.exp_err = EINTR,
 	},
 };
 
+static struct tst_ts rq;
+
+static struct test_variants {
+	int (*func)(clockid_t clock_id, int flags, void *request, void *remain);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = libc_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .func = sys_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .func = sys_clock_nanosleep, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_nanosleep, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_nanosleep_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_nanosleep64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 void setup(void)
 {
+	rq.type = variants[tst_variant].type;
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
 	SAFE_SIGNAL(SIGINT, sighandler);
 }
 
 static void do_test(unsigned int i)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	struct test_case *tc = &tcase[i];
-	struct timespec rm = {0};
+	struct tst_ts rm = {.type = tv->type, };
 	pid_t pid = 0;
 
 	tst_res(TINFO, "case %s", tc->desc);
@@ -92,7 +122,29 @@ static void do_test(unsigned int i)
 	if (tc->ttype == SEND_SIGINT)
 		pid = create_sig_proc(SIGINT, 40, 500000);
 
-	TEST(clock_nanosleep(tc->clk_id, tc->flags, &tc->rq, &rm));
+	tst_ts_set_sec(&rq, tc->tv_sec);
+	tst_ts_set_nsec(&rq, tc->tv_nsec);
+
+	TEST(tv->func(tc->clk_id, tc->flags, tst_ts_get(&rq), tst_ts_get(&rm)));
+
+	if (tv->func == libc_clock_nanosleep) {
+		/*
+		 * The return value and error number are differently set for
+		 * libc syscall as compared to kernel syscall.
+		 */
+		if (TST_RET) {
+			TST_ERR = TST_RET;
+			TST_RET = -1;
+		}
+
+		/*
+		 * nsleep isn't implemented by kernelf or
+		 * CLOCK_THREAD_CPUTIME_ID and it returns ENOTSUP, but libc
+		 * changes that error value to EINVAL.
+		 */
+		if (tc->clk_id == CLOCK_THREAD_CPUTIME_ID)
+			tc->exp_err = EINVAL;
+	}
 
 	if (pid) {
 		SAFE_KILL(pid, SIGTERM);
@@ -100,12 +152,10 @@ static void do_test(unsigned int i)
 	}
 
 	if (tc->ttype == SEND_SIGINT) {
-		long long expect_ms = tst_timespec_to_ms(tc->rq);
-		long long remain_ms = tst_timespec_to_ms(rm);
-
-		tst_res(TINFO, "remain time: %lds %ldns", rm.tv_sec, rm.tv_nsec);
+		long long expect_ms = tst_ts_to_ms(rq);
+		long long remain_ms = tst_ts_to_ms(rm);
 
-		if (!rm.tv_sec && !rm.tv_nsec) {
+		if (tst_ts_valid(&rm)) {
 			tst_res(TFAIL | TTERRNO,
 				"The clock_nanosleep() haven't updated"
 				" timestamp with remaining time");
@@ -120,20 +170,20 @@ static void do_test(unsigned int i)
 		}
 	}
 
-	if (TST_RET != tc->exp_ret) {
+	if ((TST_RET != tc->exp_ret) || (TST_ERR != tc->exp_err)) {
 		tst_res(TFAIL | TTERRNO, "returned %ld, expected %d,"
 			" expected errno: %s (%d)", TST_RET,
 			tc->exp_ret, tst_strerrno(tc->exp_err), tc->exp_err);
 		return;
 	}
 
-	tst_res(TPASS, "returned %s (%ld)",
-		tst_strerrno(TST_RET), TST_RET);
+	tst_res(TPASS, "returned %s (%d)", tst_strerrno(TST_ERR), TST_ERR);
 }
 
 static struct tst_test test = {
 	.tcnt = ARRAY_SIZE(tcase),
 	.test = do_test,
+	.test_variants = ARRAY_SIZE(variants),
 	.setup = setup,
 	.forks_child = 1,
 };
diff --git a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c
index 68773d59e346..edcd57c076bf 100644
--- a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c
+++ b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep03.c
@@ -19,33 +19,83 @@
 #include "tst_safe_clocks.h"
 #include "tst_timer.h"
 #include "lapi/namespaces_constants.h"
-#include "tst_test.h"
+#include "lapi/abisize.h"
 
 #define OFFSET_S 10
 #define SLEEP_US 100000
 
+static struct test_variants {
+	int (*gettime)(clockid_t clk_id, void *ts);
+	int (*func)(clockid_t clock_id, int flags, void *request, void *remain);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .gettime = libc_clock_gettime, .func = libc_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_nanosleep_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .gettime = sys_clock_gettime64, .func = sys_clock_nanosleep64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 static void verify_clock_nanosleep(void)
 {
-	struct timespec start, end, sleep_abs;
+	struct test_variants *tv = &variants[tst_variant];
+	struct tst_ts start, end, sleep_abs;
+
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+
+	start.type = end.type = sleep_abs.type = tv->type;
 
 	SAFE_UNSHARE(CLONE_NEWTIME);
 
 	SAFE_FILE_PRINTF("/proc/self/timens_offsets", "%d %d 0", CLOCK_MONOTONIC, OFFSET_S);
 
-	SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &start);
+	TEST(tv->gettime(CLOCK_MONOTONIC, tst_ts_get(&start)));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_MONOTONIC));
+		return;
+	}
 
-	sleep_abs = tst_timespec_add_us(start, 1000000 * OFFSET_S + SLEEP_US);
+	sleep_abs = tst_ts_add_us(start, 1000000 * OFFSET_S + SLEEP_US);
 
 	if (!SAFE_FORK()) {
-		clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleep_abs, NULL);
+		TEST(tv->func(CLOCK_MONOTONIC, TIMER_ABSTIME, tst_ts_get(&sleep_abs), NULL));
+		/*
+		 * The return value and error number are differently set for
+		 * libc syscall as compared to kernel syscall.
+		 */
+		if ((tv->func == libc_clock_nanosleep) && TST_RET) {
+			TST_ERR = TST_RET;
+			TST_RET = -1;
+		}
+
+		if (TST_RET == -1) {
+			tst_res(TFAIL | TTERRNO, "clock_nanosleep(2) failed for clock %s",
+				tst_clock_name(CLOCK_MONOTONIC));
+		}
+
 		exit(0);
 	}
 
 	SAFE_WAIT(NULL);
 
-	SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &end);
+	TEST(tv->gettime(CLOCK_MONOTONIC, tst_ts_get(&end)));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(CLOCK_MONOTONIC));
+		return;
+	}
 
-	long long diff = tst_timespec_diff_us(end, start);
+	long long diff = tst_ts_diff_us(end, start);
 
 	if (diff > 5 * SLEEP_US) {
 		tst_res(TFAIL, "clock_nanosleep() slept too long %lli", diff);
@@ -62,11 +112,11 @@ static void verify_clock_nanosleep(void)
 
 static struct tst_test test = {
 	.test_all = verify_clock_nanosleep,
+	.test_variants = ARRAY_SIZE(variants),
 	.needs_root = 1,
 	.forks_child = 1,
 	.needs_kconfigs = (const char *[]) {
 		"CONFIG_TIME_NS=y",
 		NULL
 	}
-
 };
diff --git a/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c
new file mode 100644
index 000000000000..38bcfcb194b1
--- /dev/null
+++ b/testcases/kernel/syscalls/clock_nanosleep/clock_nanosleep04.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) M. Koehrer <mathias_koehrer@arcor.de>, 2009
+ * Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include "tst_safe_clocks.h"
+#include "tst_timer.h"
+#include "lapi/abisize.h"
+
+#define NSEC_IN_SEC 1000000000
+
+static clockid_t tcase[] = {
+	CLOCK_MONOTONIC,
+	CLOCK_REALTIME,
+};
+
+static struct test_variants {
+	int (*gettime)(clockid_t clk_id, void *ts);
+	int (*func)(clockid_t clock_id, int flags, void *request, void *remain);
+	enum tst_ts_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .gettime = libc_clock_gettime, .func = libc_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "vDSO or syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_LIBC_TIMESPEC, .desc = "syscall with libc spec"},
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with kernel spec32"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .gettime = sys_clock_gettime, .func = sys_clock_nanosleep, .type = TST_KERN_TIMESPEC, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_nanosleep_time64 != __LTP__NR_INVALID_SYSCALL)
+	{ .gettime = sys_clock_gettime64, .func = sys_clock_nanosleep64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
+void setup(void)
+{
+	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
+}
+
+static void do_test(unsigned int i)
+{
+	struct test_variants *tv = &variants[tst_variant];
+	struct tst_ts ts = {.type = tv->type};
+	long long sec, nsec;
+
+	TEST(tv->gettime(tcase[i], tst_ts_get(&ts)));
+	if (TST_RET == -1) {
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2) failed for clock %s",
+			tst_clock_name(tcase[i]));
+		return;
+	}
+
+	sec = tst_ts_get_sec(ts);
+	nsec = tst_ts_get_nsec(ts);
+
+	nsec += NSEC_IN_SEC/10;
+	if (nsec >= NSEC_IN_SEC) {
+		sec += 1;
+		nsec %= NSEC_IN_SEC;
+	}
+
+	tst_ts_set_sec(&ts, sec);
+	tst_ts_set_nsec(&ts, nsec);
+
+	TEST(tv->func(tcase[i], TIMER_ABSTIME, tst_ts_get(&ts), NULL));
+
+	if (TST_RET) {
+		tst_res(TFAIL | TTERRNO, "clock_nanosleep(2) failed for clock %s",
+			tst_clock_name(tcase[i]));
+	}
+
+	tst_res(TPASS, "clock_nanosleep(2) passed for clock %s",
+		tst_clock_name(tcase[i]));
+}
+
+static struct tst_test test = {
+	.tcnt = ARRAY_SIZE(tcase),
+	.test = do_test,
+	.test_variants = ARRAY_SIZE(variants),
+	.setup = setup,
+};
diff --git a/testcases/kernel/syscalls/clock_nanosleep2/.gitignore b/testcases/kernel/syscalls/clock_nanosleep2/.gitignore
deleted file mode 100644
index 5be9cd0e8a8d..000000000000
--- a/testcases/kernel/syscalls/clock_nanosleep2/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/clock_nanosleep2_01
diff --git a/testcases/kernel/syscalls/clock_nanosleep2/Makefile b/testcases/kernel/syscalls/clock_nanosleep2/Makefile
deleted file mode 100644
index 262eef71b02b..000000000000
--- a/testcases/kernel/syscalls/clock_nanosleep2/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (c) International Business Machines  Corp., 2009
-
-top_srcdir		?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-LDLIBS			+= -lpthread -lrt
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c b/testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c
deleted file mode 100644
index d82d74d2d9fa..000000000000
--- a/testcases/kernel/syscalls/clock_nanosleep2/clock_nanosleep2_01.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) M. Koehrer <mathias_koehrer@arcor.de>, 2009
- * Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz>
- */
-
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-#include "tst_test.h"
-#include "lapi/syscalls.h"
-
-#define NSEC_IN_SEC 1000000000
-
-const clockid_t CLOCK_TO_USE = CLOCK_MONOTONIC;
-static int clock_nanosleep2(clockid_t clock_id, int flags,
-			    const struct timespec *req, struct timespec *rem)
-{
-	return tst_syscall(__NR_clock_nanosleep, clock_id, flags, req, rem);
-}
-
-static void verify_clock_nanosleep2(void)
-{
-	struct timespec ts;
-
-	clock_gettime(CLOCK_TO_USE, &ts);
-	ts.tv_nsec += NSEC_IN_SEC/10;
-	if (ts.tv_nsec >= NSEC_IN_SEC) {
-		ts.tv_sec += 1;
-		ts.tv_nsec %= NSEC_IN_SEC;
-	}
-
-	TEST(clock_nanosleep2(CLOCK_TO_USE, TIMER_ABSTIME, &ts, NULL));
-
-	if (TST_RET)
-		tst_res(TFAIL | TTERRNO, "clock_nanosleep2() failed");
-	else
-		tst_res(TPASS, "clock_nanosleep2() passed");
-}
-
-static struct tst_test test = {
-	.test_all = verify_clock_nanosleep2,
-};
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V5 5/5] syscalls/clock_adjtime: Add support for time64 tests
  2020-04-24  7:18   ` [LTP] [PATCH V5 3/5] syscalls/clock_getres: " Viresh Kumar
  2020-04-24  7:18     ` [LTP] [PATCH V5 4/5] syscalls/clock_nanosleep: " Viresh Kumar
@ 2020-04-24  7:18     ` Viresh Kumar
  2020-04-27 14:15       ` Cyril Hrubis
  1 sibling, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2020-04-24  7:18 UTC (permalink / raw)
  To: ltp

This adds support for time64 tests to the existing clock_adjtime()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 .../syscalls/clock_adjtime/clock_adjtime.h    | 216 +++++++++++++++---
 .../syscalls/clock_adjtime/clock_adjtime01.c  | 124 ++++++----
 .../syscalls/clock_adjtime/clock_adjtime02.c  |  95 +++++---
 3 files changed, 332 insertions(+), 103 deletions(-)

diff --git a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
index d7f553a3a04b..138e6ca7f3d0 100644
--- a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
+++ b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
@@ -16,43 +16,191 @@
 #include <sys/types.h>
 #include "lapi/timex.h"
 
-static int sys_clock_adjtime(clockid_t, struct timex *);
-static void timex_show(char *, struct timex);
+#ifndef __kernel_timex
+struct __kernel_timex_timeval {
+	__kernel_time64_t       tv_sec;
+	long long		tv_usec;
+};
 
-/*
- * bad pointer w/ libc causes SIGSEGV signal, call syscall directly
- */
-static int sys_clock_adjtime(clockid_t clk_id, struct timex *txc)
+struct __kernel_timex {
+	unsigned int modes;	/* mode selector */
+	int :32;            /* pad */
+	long long offset;	/* time offset (usec) */
+	long long freq;	/* frequency offset (scaled ppm) */
+	long long maxerror;/* maximum error (usec) */
+	long long esterror;/* estimated error (usec) */
+	int status;		/* clock command/status */
+	int :32;            /* pad */
+	long long constant;/* pll time constant */
+	long long precision;/* clock precision (usec) (read only) */
+	long long tolerance;/* clock frequency tolerance (ppm)
+				   * (read only)
+				   */
+	struct __kernel_timex_timeval time;	/* (read only, except for ADJ_SETOFFSET) */
+	long long tick;	/* (modified) usecs between clock ticks */
+
+	long long ppsfreq;/* pps frequency (scaled ppm) (ro) */
+	long long jitter; /* pps jitter (us) (ro) */
+	int shift;              /* interval duration (s) (shift) (ro) */
+	int :32;            /* pad */
+	long long stabil;            /* pps stability (scaled ppm) (ro) */
+	long long jitcnt; /* jitter limit exceeded (ro) */
+	long long calcnt; /* calibration intervals (ro) */
+	long long errcnt; /* calibration errors (ro) */
+	long long stbcnt; /* stability limit exceeded (ro) */
+
+	int tai;		/* TAI offset (ro) */
+
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32; int  :32;
+	int  :32; int  :32; int  :32;
+};
+#endif
+
+enum tst_timex_type {
+	TST_LIBC_TIMEX,
+	TST_KERN_TIMEX
+};
+
+struct tst_timex {
+	enum tst_timex_type type;
+	union {
+		struct timex libc_timex;
+		struct __kernel_timex kern_timex;
+	} ts;
+};
+
+static inline void *tst_timex_get(struct tst_timex *t)
+{
+	switch (t->type) {
+	case TST_LIBC_TIMEX:
+		return &t->ts.libc_timex;
+	case TST_KERN_TIMEX:
+		return &t->ts.kern_timex;
+	default:
+		tst_brk(TBROK, "Invalid type: %d", t->type);
+		return NULL;
+	}
+}
+
+static inline int sys_clock_adjtime(clockid_t clk_id, void *timex)
 {
-	return tst_syscall(__NR_clock_adjtime, clk_id, txc);
+	return tst_syscall(__NR_clock_adjtime, clk_id, timex);
 }
 
-static void timex_show(char *given, struct timex txc)
+static inline int sys_clock_adjtime64(clockid_t clk_id, void *timex)
 {
-	tst_res(TINFO,  "%s\n"
-			"             mode: %d\n"
-			"           offset: %ld\n"
-			"        frequency: %ld\n"
-			"         maxerror: %ld\n"
-			"         esterror: %ld\n"
-			"           status: %d (0x%x)\n"
-			"    time_constant: %ld\n"
-			"        precision: %ld\n"
-			"        tolerance: %ld\n"
-			"             tick: %ld\n"
-			"         raw time: %d(s) %d(us)",
-			given,
-			txc.modes,
-			txc.offset,
-			txc.freq,
-			txc.maxerror,
-			txc.esterror,
-			txc.status,
-			txc.status,
-			txc.constant,
-			txc.precision,
-			txc.tolerance,
-			txc.tick,
-			(int)txc.time.tv_sec,
-			(int)txc.time.tv_usec);
+	return tst_syscall(__NR_clock_adjtime64, clk_id, timex);
+}
+
+#define _timex_show(_timex, _desc)					\
+	tst_res(TINFO,  "%s\n"						\
+			"             mode: %u\n"			\
+			"           offset: "#_desc"\n"			\
+			"        frequency: "#_desc"\n"			\
+			"         maxerror: "#_desc"\n"			\
+			"         esterror: "#_desc"\n"			\
+			"           status: %d (0x%x)\n"		\
+			"    time_constant: "#_desc"\n"			\
+			"        precision: "#_desc"\n"			\
+			"        tolerance: "#_desc"\n"			\
+			"             tick: "#_desc"\n"			\
+			"         raw time: "#_desc"(s) "#_desc"(us)",	\
+			given,						\
+			_timex.modes,					\
+			_timex.offset,					\
+			_timex.freq,					\
+			_timex.maxerror,				\
+			_timex.esterror,				\
+			_timex.status,					\
+			_timex.status,					\
+			_timex.constant,				\
+			_timex.precision,				\
+			_timex.tolerance,				\
+			_timex.tick,					\
+			_timex.time.tv_sec,				\
+			_timex.time.tv_usec)
+
+static inline void timex_show(char *given, struct tst_timex *timex)
+{
+	switch (timex->type) {
+	case TST_LIBC_TIMEX:
+		_timex_show(timex->ts.libc_timex, %ld);
+		return;
+	case TST_KERN_TIMEX:
+		_timex_show(timex->ts.kern_timex, %lld);
+		return;
+	default:
+		tst_res(TFAIL, "Invalid type: %d", timex->type);
+	}
+}
+
+#define ADJ_MODES	0
+
+#define _select_field(_timex, _field)					\
+{									\
+	if (_field == ADJ_MODES)					\
+		return &_timex.modes;					\
+	if (_field == ADJ_OFFSET)					\
+		return &_timex.offset;					\
+	if (_field == ADJ_FREQUENCY)					\
+		return &_timex.freq;					\
+	if (_field == ADJ_MAXERROR)					\
+		return &_timex.maxerror;				\
+	if (_field == ADJ_ESTERROR)					\
+		return &_timex.esterror;				\
+	if (_field == ADJ_TIMECONST)					\
+		return &_timex.constant;				\
+	if (_field == ADJ_TICK)						\
+		return &_timex.tick;					\
+	if (_field == ADJ_STATUS)					\
+		return &_timex.status;					\
+	tst_res(TFAIL, "Invalid type: %d", timex->type);		\
+	return NULL;							\
+}
+
+static inline void *_get_field(struct tst_timex *timex, unsigned int field)
+{
+	switch (timex->type) {
+	case TST_LIBC_TIMEX:
+		_select_field(timex->ts.libc_timex, field);
+	case TST_KERN_TIMEX:
+		_select_field(timex->ts.kern_timex, field);
+	default:
+		tst_res(TFAIL, "Invalid type: %d", timex->type);
+		return NULL;
+	}
+}
+
+#define timex_get_set_field_type(_type_libc, _type_kern)		\
+static inline _type_kern						\
+timex_get_field_##_type_libc(struct tst_timex *timex, unsigned int field) \
+{									\
+	switch (timex->type) {						\
+	case TST_LIBC_TIMEX:						\
+		return *((_type_libc*)_get_field(timex, field));	\
+	case TST_KERN_TIMEX:						\
+		return *((_type_kern*)_get_field(timex, field));	\
+	default:							\
+		tst_res(TFAIL, "Invalid type: %d", timex->type);	\
+		return 0;						\
+	}								\
+}									\
+									\
+static inline void							\
+timex_set_field_##_type_libc(struct tst_timex *timex, unsigned int field, \
+			    _type_kern value)				\
+{									\
+	switch (timex->type) {						\
+	case TST_LIBC_TIMEX:						\
+		*((_type_libc*)_get_field(timex, field)) = value;	\
+		return;							\
+	case TST_KERN_TIMEX:						\
+		*((_type_kern*)_get_field(timex, field)) = value;	\
+		return;							\
+	default:							\
+		tst_res(TFAIL, "Invalid type: %d", timex->type);	\
+	}								\
 }
+timex_get_set_field_type(uint, uint);
+timex_get_set_field_type(long, long long);
diff --git a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c
index 1262d34fa0d6..a5b8792e50e3 100644
--- a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c
+++ b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime01.c
@@ -55,15 +55,15 @@
  */
 
 #include "clock_adjtime.h"
+#include "lapi/abisize.h"
 
 static long hz;
-static struct timex saved, ttxc;
+static struct tst_timex saved, ttxc;
 static int supported;
 
 struct test_case {
 	unsigned int modes;
 	long highlimit;
-	long *ptr;
 	long delta;
 };
 
@@ -80,79 +80,103 @@ struct test_case tc[] = {
 	{
 	 .modes = ADJ_OFFSET,
 	 .highlimit = 500000,
-	 .ptr = &ttxc.offset,
 	 .delta = 10000,
 	},
 	{
 	 .modes = ADJ_FREQUENCY,
-	 .ptr = &ttxc.freq,
 	 .delta = 100,
 	},
 	{
 	 .modes = ADJ_MAXERROR,
-	 .ptr = &ttxc.maxerror,
 	 .delta = 100,
 	},
 	{
 	 .modes = ADJ_ESTERROR,
-	 .ptr = &ttxc.esterror,
 	 .delta = 100,
 	},
 	{
 	 .modes = ADJ_TIMECONST,
-	 .ptr = &ttxc.constant,
 	 .delta = 1,
 	},
 	{
 	 .modes = ADJ_TICK,
 	 .highlimit = 1100000,
-	 .ptr = &ttxc.tick,
 	 .delta = 1000,
 	},
 };
 
+static struct test_variants {
+	int (*func)(clockid_t clk_id, void *timex);
+	enum tst_timex_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = sys_clock_adjtime, .type = TST_LIBC_TIMEX, .desc = "syscall with libc spec"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_adjtime, .type = TST_KERN_TIMEX, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_adjtime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_adjtime64, .type = TST_KERN_TIMEX, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 static void verify_clock_adjtime(unsigned int i)
 {
-	long ptroff, *ptr = NULL;
-	struct timex verify;
+	struct test_variants *tv = &variants[tst_variant];
+	struct tst_timex verify;
+	long long val;
+	int rval;
 
-	memset(&ttxc, 0, sizeof(struct timex));
-	memset(&verify, 0, sizeof(struct timex));
+	memset(&ttxc, 0, sizeof(ttxc));
+	memset(&verify, 0, sizeof(verify));
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &ttxc);
-	timex_show("GET", ttxc);
+	ttxc.type = verify.type = tv->type;
+
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(&ttxc));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 
-	ttxc.modes = tc[i].modes;
+	timex_show("GET", &ttxc);
 
-	if (tc[i].ptr && tc[i].delta) {
+	timex_set_field_uint(&ttxc, ADJ_MODES, tc[i].modes);
 
-		*tc[i].ptr += tc[i].delta;
+	if (tc[i].delta) {
+		val = timex_get_field_long(&ttxc, tc[i].modes);
+		val += tc[i].delta;
 
 		/* fix limits, if existent, so no errors occur */
+		if (tc[i].highlimit && val >= tc[i].highlimit)
+			val = tc[i].highlimit;
 
-		if (tc[i].highlimit) {
-			if (*tc[i].ptr >= tc[i].highlimit)
-				*tc[i].ptr = tc[i].highlimit;
-		}
+		timex_set_field_long(&ttxc, tc[i].modes, val);
 	}
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &ttxc);
-	timex_show("SET", ttxc);
-
-	if (tc[i].ptr) {
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(&ttxc));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 
-		/* adjtimex field being tested so we can verify later */
+	timex_show("SET", &ttxc);
 
-		ptroff = (long) tc[i].ptr - (long) &ttxc;
-		ptr = (void *) &verify + ptroff;
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(&verify));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
 	}
 
-	TEST(sys_clock_adjtime(CLOCK_REALTIME, &verify));
-	timex_show("VERIFY", verify);
+	timex_show("VERIFY", &verify);
 
-	if (tc[i].ptr && *tc[i].ptr != *ptr) {
+	if (tc[i].delta &&
+	    timex_get_field_long(&ttxc, tc[i].modes) !=
+	    timex_get_field_long(&verify, tc[i].modes)) {
 		tst_res(TFAIL, "clock_adjtime(): could not set value (mode=%x)",
-				tc[i].modes);
+			tc[i].modes);
 	}
 
 	if (TST_RET < 0) {
@@ -165,14 +189,23 @@ static void verify_clock_adjtime(unsigned int i)
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	size_t i;
 	int rval;
 
-	rval = SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+
+	saved.type = tv->type;
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(&saved));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
+
 	supported = 1;
 
 	if (rval != TIME_OK && rval != TIME_ERROR) {
-		timex_show("SAVE_STATUS", saved);
+		timex_show("SAVE_STATUS", &saved);
 		tst_brk(TBROK | TTERRNO, "clock has on-going leap changes, "
 				"returned: %i", rval);
 	}
@@ -188,7 +221,7 @@ static void setup(void)
 
 		/* fix usec as being test default resolution */
 
-		if (saved.modes & ADJ_NANO) {
+		if (timex_get_field_uint(&saved, ADJ_MODES) & ADJ_NANO) {
 			if (tc[i].modes == ADJ_OFFSET) {
 				tc[i].highlimit *= 1000;
 				tc[i].delta *= 1000;
@@ -199,21 +232,29 @@ static void setup(void)
 
 static void cleanup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
+	unsigned int modes = ADJ_ALL;
+	int rval;
+
 	if (supported == 0)
 		return;
 
-	saved.modes = ADJ_ALL;
-
 	/* restore clock resolution based on original status flag */
 
-	if (saved.status & STA_NANO)
-		saved.modes |= ADJ_NANO;
+	if (timex_get_field_uint(&saved, ADJ_STATUS) & STA_NANO)
+		modes |= ADJ_NANO;
 	else
-		saved.modes |= ADJ_MICRO;
+		modes |= ADJ_MICRO;
+
+	timex_set_field_uint(&saved, ADJ_MODES, modes);
 
 	/* restore original clock flags */
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(&saved));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 }
 
 static struct tst_test test = {
@@ -221,6 +262,7 @@ static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
 	.needs_root = 1,
 	.restore_wallclock = 1,
 };
diff --git a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c
index ba8eae54f5ed..9f957f7643b0 100644
--- a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c
+++ b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime02.c
@@ -56,9 +56,10 @@
  */
 
 #include "clock_adjtime.h"
+#include "lapi/abisize.h"
 
 static long hz;
-static struct timex saved, ttxc;
+static struct tst_timex saved, ttxc;
 static int supported;
 
 static void cleanup(void);
@@ -68,7 +69,6 @@ struct test_case {
 	unsigned int modes;
 	long lowlimit;
 	long highlimit;
-	long *ptr;
 	long delta;
 	int exp_err;
 	int droproot;
@@ -92,7 +92,6 @@ struct test_case tc[] = {
 	 .clktype = CLOCK_REALTIME,
 	 .modes = ADJ_TICK,
 	 .lowlimit = 900000,
-	 .ptr = &ttxc.tick,
 	 .delta = 1,
 	 .exp_err = EINVAL,
 	},
@@ -100,7 +99,6 @@ struct test_case tc[] = {
 	 .clktype = CLOCK_REALTIME,
 	 .modes = ADJ_TICK,
 	 .highlimit = 1100000,
-	 .ptr = &ttxc.tick,
 	 .delta = 1,
 	 .exp_err = EINVAL,
 	},
@@ -112,19 +110,43 @@ struct test_case tc[] = {
 	},
 };
 
+static struct test_variants {
+	int (*func)(clockid_t clk_id, void *timex);
+	enum tst_timex_type type;
+	char *desc;
+} variants[] = {
+#if defined(TST_ABI32)
+	{ .func = sys_clock_adjtime, .type = TST_LIBC_TIMEX, .desc = "syscall with libc spec"},
+#endif
+
+#if defined(TST_ABI64)
+	{ .func = sys_clock_adjtime, .type = TST_KERN_TIMEX, .desc = "syscall with kernel spec64"},
+#endif
+
+#if (__NR_clock_adjtime64 != __LTP__NR_INVALID_SYSCALL)
+	{ .func = sys_clock_adjtime64, .type = TST_KERN_TIMEX, .desc = "syscall time64 with kernel spec64"},
+#endif
+};
+
 static void verify_clock_adjtime(unsigned int i)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	uid_t whoami = 0;
-	struct timex *txcptr;
+	struct tst_timex *txcptr = &ttxc;
 	struct passwd *nobody;
 	static const char name[] = "nobody";
+	int rval;
 
-	txcptr = &ttxc;
+	memset(txcptr, 0, sizeof(*txcptr));
 
-	memset(txcptr, 0, sizeof(struct timex));
+	txcptr->type = tv->type;
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(txcptr));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, txcptr);
-	timex_show("GET", *txcptr);
+	timex_show("GET", txcptr);
 
 	if (tc[i].droproot) {
 		nobody = SAFE_GETPWNAM(name);
@@ -132,24 +154,23 @@ static void verify_clock_adjtime(unsigned int i)
 		SAFE_SETEUID(whoami);
 	}
 
-	txcptr->modes = tc[i].modes;
-
-	if (tc[i].ptr) {
+	timex_set_field_uint(txcptr, ADJ_MODES, tc[i].modes);
 
+	if (tc[i].delta) {
 		if (tc[i].lowlimit)
-			*tc[i].ptr = tc[i].lowlimit - tc[i].delta;
+			timex_set_field_long(&ttxc, tc[i].modes, tc[i].lowlimit - tc[i].delta);
 
 		if (tc[i].highlimit)
-			*tc[i].ptr = tc[i].highlimit + tc[i].delta;
+			timex_set_field_long(&ttxc, tc[i].modes, tc[i].highlimit + tc[i].delta);
 	}
 
 	/* special case: EFAULT for bad addresses */
-	if (tc[i].exp_err == EFAULT)
-		txcptr = tst_get_bad_addr(cleanup);
-
-	TEST(sys_clock_adjtime(tc[i].clktype, txcptr));
-	if (txcptr && tc[i].exp_err != EFAULT)
-		timex_show("TEST", *txcptr);
+	if (tc[i].exp_err == EFAULT) {
+		TEST(tv->func(tc[i].clktype, tst_get_bad_addr(NULL)));
+	} else {
+		TEST(tv->func(tc[i].clktype, tst_timex_get(txcptr)));
+		timex_show("TEST", txcptr);
+	}
 
 	if (TST_RET >= 0) {
 		tst_res(TFAIL, "clock_adjtime(): passed unexpectedly (mode=%x, "
@@ -173,14 +194,23 @@ static void verify_clock_adjtime(unsigned int i)
 
 static void setup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
 	size_t i;
 	int rval;
 
-	rval = SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	tst_res(TINFO, "Testing variant: %s", tv->desc);
+
+	saved.type = tv->type;
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(&saved));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
+
 	supported = 1;
 
 	if (rval != TIME_OK && rval != TIME_ERROR) {
-		timex_show("SAVE_STATUS", saved);
+		timex_show("SAVE_STATUS", &saved);
 		tst_brk(TBROK | TTERRNO, "clock has on-going leap changes, "
 				"returned: %i", rval);
 	}
@@ -199,21 +229,29 @@ static void setup(void)
 
 static void cleanup(void)
 {
+	struct test_variants *tv = &variants[tst_variant];
+	unsigned int modes = ADJ_ALL;
+	int rval;
+
 	if (supported == 0)
 		return;
 
-	saved.modes = ADJ_ALL;
-
 	/* restore clock resolution based on original status flag */
 
-	if (saved.status & STA_NANO)
-		saved.modes |= ADJ_NANO;
+	if (timex_get_field_uint(&saved, ADJ_STATUS) & STA_NANO)
+		modes |= ADJ_NANO;
 	else
-		saved.modes |= ADJ_MICRO;
+		modes |= ADJ_MICRO;
+
+	timex_set_field_uint(&saved, ADJ_MODES, modes);
 
 	/* restore original clock flags */
 
-	SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
+	rval = tv->func(CLOCK_REALTIME, tst_timex_get(&saved));
+	if (rval < 0) {
+		tst_res(TFAIL | TERRNO, "clock_adjtime() failed %i", rval);
+		return;
+	}
 }
 
 static struct tst_test test = {
@@ -221,6 +259,7 @@ static struct tst_test test = {
 	.setup = setup,
 	.cleanup = cleanup,
 	.tcnt = ARRAY_SIZE(tc),
+	.test_variants = ARRAY_SIZE(variants),
 	.needs_root = 1,
 	.restore_wallclock = 1,
 };
-- 
2.25.0.rc1.19.g042ed3e048af


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests
  2020-04-23 13:50     ` Cyril Hrubis
@ 2020-04-24  7:19       ` Viresh Kumar
  2020-04-24 15:02         ` Cyril Hrubis
  0 siblings, 1 reply; 15+ messages in thread
From: Viresh Kumar @ 2020-04-24  7:19 UTC (permalink / raw)
  To: ltp

On 23-04-20, 15:50, Cyril Hrubis wrote:
> Hi!
> Pushed with a few changes, thanks.
> 
> * Changed the nonzero check to check if nanoseconds are valid,
>   which covers the 64bit check as well.
> 
> * Pushed the bad address handling down to the test, which means that
>   we have to convert the struct tst_ts for each syscall, but I think
>   that it's cleaner that way and we also map only single bad address per
>   test.

Thanks. I have resent the pending patches from this series with
modification based on your changes to this patch, so you won't be
required waste that much time on this :)

-- 
viresh

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests
  2020-04-24  7:19       ` Viresh Kumar
@ 2020-04-24 15:02         ` Cyril Hrubis
  0 siblings, 0 replies; 15+ messages in thread
From: Cyril Hrubis @ 2020-04-24 15:02 UTC (permalink / raw)
  To: ltp

Hi!
> Thanks. I have resent the pending patches from this series with
> modification based on your changes to this patch, so you won't be
> required waste that much time on this :)

I have pushed next two with a minor changes, thanks. I will finish the
last one next week.

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V5 5/5] syscalls/clock_adjtime: Add support for time64 tests
  2020-04-24  7:18     ` [LTP] [PATCH V5 5/5] syscalls/clock_adjtime: " Viresh Kumar
@ 2020-04-27 14:15       ` Cyril Hrubis
  2020-04-28  4:30         ` Viresh Kumar
  0 siblings, 1 reply; 15+ messages in thread
From: Cyril Hrubis @ 2020-04-27 14:15 UTC (permalink / raw)
  To: ltp

Hi!
I've cleaned up the code and pushed, thanks.

Fixed things such as:

* Macros should be uppercase, otherwise it's confusing

* All local variables has to be passed to macros as parameters
  this one is confusing as hell

* No variables and parameters stating with underscore, unless
  we defined fallback for kernel types these are reserved for
  kernel/libc

* The tst_get_bad_addr() allocates a page for each call, so I have moved
  it to setup

* etc...

-- 
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [LTP] [PATCH V5 5/5] syscalls/clock_adjtime: Add support for time64 tests
  2020-04-27 14:15       ` Cyril Hrubis
@ 2020-04-28  4:30         ` Viresh Kumar
  0 siblings, 0 replies; 15+ messages in thread
From: Viresh Kumar @ 2020-04-28  4:30 UTC (permalink / raw)
  To: ltp

On 27-04-20, 16:15, Cyril Hrubis wrote:
> Hi!
> I've cleaned up the code and pushed, thanks.
> 
> Fixed things such as:
> 
> * Macros should be uppercase, otherwise it's confusing
> 
> * All local variables has to be passed to macros as parameters
>   this one is confusing as hell
> 
> * No variables and parameters stating with underscore, unless
>   we defined fallback for kernel types these are reserved for
>   kernel/libc
> 
> * The tst_get_bad_addr() allocates a page for each call, so I have moved
>   it to setup
> 
> * etc...

Thanks again.

-- 
viresh

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2020-04-28  4:30 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <a143f48ffeec14739d35c07dfb95f237981a322d.1587712683.git.viresh.kumar@linaro.org>
2020-04-22  5:37 ` [LTP] [PATCH V4 0/5] syscalls/clock_*(): Add support for time64 variants Viresh Kumar
2020-04-22  5:37   ` [LTP] [PATCH V4 1/5] syscalls/clock_gettime: Add support for time64 tests Viresh Kumar
2020-04-23 13:50     ` Cyril Hrubis
2020-04-24  7:19       ` Viresh Kumar
2020-04-24 15:02         ` Cyril Hrubis
2020-04-22  5:37   ` [LTP] [PATCH V4 2/5] syscalls/clock_settime: " Viresh Kumar
2020-04-23 15:08     ` Cyril Hrubis
2020-04-22  5:37   ` [LTP] [PATCH V4 3/5] syscalls/clock_getres: " Viresh Kumar
2020-04-22  5:37   ` [LTP] [PATCH V4 4/5] syscalls/clock_nanosleep: " Viresh Kumar
2020-04-22  5:37   ` [LTP] [PATCH V4 5/5] syscalls/clock_adjtime: " Viresh Kumar
2020-04-24  7:18   ` [LTP] [PATCH V5 3/5] syscalls/clock_getres: " Viresh Kumar
2020-04-24  7:18     ` [LTP] [PATCH V5 4/5] syscalls/clock_nanosleep: " Viresh Kumar
2020-04-24  7:18     ` [LTP] [PATCH V5 5/5] syscalls/clock_adjtime: " Viresh Kumar
2020-04-27 14:15       ` Cyril Hrubis
2020-04-28  4:30         ` Viresh Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).