diff mbox series

[1/2] syscalls/clock_gettime: create syscall clock_gettime tests

Message ID 20190206171703.5761-1-rafael.tinoco@linaro.org
State New
Headers show
Series [1/2] syscalls/clock_gettime: create syscall clock_gettime tests | expand

Commit Message

Rafael David Tinoco Feb. 6, 2019, 5:17 p.m. UTC
Fixes: 342

clock_gettime01 creates a new test, using new API, based on existing and
older kernel/timers/clock_gettime02 test. clock_gettime02 creates
another test based on older kernel/timers/clock_gettime03 test. Both
will be deleted in the next commits.

Signed-off-by: Rafael David Tinoco <rafael.tinoco@linaro.org>
---
 runtest/syscalls                              |   3 +
 .../kernel/syscalls/clock_gettime/.gitignore  |   2 +
 .../kernel/syscalls/clock_gettime/Makefile    |  10 ++
 .../syscalls/clock_gettime/clock_gettime01.c  | 134 +++++++++++++++
 .../syscalls/clock_gettime/clock_gettime02.c  | 155 ++++++++++++++++++
 5 files changed, 304 insertions(+)
 create mode 100644 testcases/kernel/syscalls/clock_gettime/.gitignore
 create mode 100644 testcases/kernel/syscalls/clock_gettime/Makefile
 create mode 100644 testcases/kernel/syscalls/clock_gettime/clock_gettime01.c
 create mode 100644 testcases/kernel/syscalls/clock_gettime/clock_gettime02.c

Comments

Cyril Hrubis Feb. 7, 2019, 12:31 p.m. UTC | #1
Hi!
> +struct test_case {
> +	clockid_t clocktype;
> +	int exp_ret;
> +	int exp_err;
> +	int unsupported;
> +};
> +
> +struct test_case tc[] = {
> +	{
> +	 .clocktype = CLOCK_REALTIME,
> +	 },
> +	{
> +	 .clocktype = CLOCK_REALTIME_COARSE,
> +#ifndef CLOCK_REALTIME_COARSE
> +	 .exp_ret = -1,
> +	 .exp_err = EINVAL,
> +#endif

Depending on the constant beind defined is completely wrong here. The
only way how to figure out if the clock is being supported or not is to
call the clock_gettime() with correct paramters and check for EINVAL.

So I guess that in this test we should call clock_gettime() for
paticular clock and:

* For certain clocks that are implemented for long enough, we expect
  success, I would say that at least CLOCK_REALTIME, CLOCK_MONOTONIC and
  CLOCK_*_CPUTIME_ID should be implemented for long enough to be
  supported everywhere

* The rest of the clocks should be allowed either to pass or return EINVAL

* In case that the call passed we should check that the timespec has
  been changed (we should zero it before the call)

* Also many architectures have vDSO for clock_gettime() we should also
  check that the syscall and vDSO are consistent in this case

> +	 },
> +	{
> +	 .clocktype = CLOCK_MONOTONIC,
> +#ifndef CLOCK_MONOTONIC
> +	 .exp_ret = -1,
> +	 .exp_err = EINVAL,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_MONOTONIC_COARSE,
> +#ifndef CLOCK_MONOTONIC_COARSE
> +	 .exp_ret = -1,
> +	 .exp_err = EINVAL,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_MONOTONIC_RAW,
> +#ifndef CLOCK_MONOTONIC_RAW
> +	 .exp_ret = -1,
> +	 .exp_err = EINVAL,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_BOOTTIME,
> +#ifndef CLOCK_BOOTTIME
> +	 .exp_ret = -1,
> +	 .exp_err = EINVAL,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_PROCESS_CPUTIME_ID,
> +#ifndef CLOCK_PROCESS_CPUTIME_ID
> +	 .exp_ret = -1,
> +	 .exp_err = EINVAL,
> +#endif
> +	 },
> +{
> +	 .clocktype = CLOCK_THREAD_CPUTIME_ID,
> +#ifndef CLOCK_THREAD_CPUTIME_ID
> +	 .exp_ret = -1,
> +	 .exp_err = EINVAL,
> +#endif
> +	 },
> +};
> +
> +static void verify_clock_gettime(unsigned int i)
> +{
> +	struct timespec spec;
> +
> +	TEST(clock_gettime(tc[i].clocktype, &spec));
> +
> +	if (TST_RET == -1 && tc[i].exp_ret == -1) {
> +
> +		if (tc[i].exp_err == TST_ERR) {
> +			tst_res(TPASS, "clock_gettime(2): unsupported clock %s "
> +					"failed as expected",
> +					tst_clock_name(tc[i].clocktype));
> +		} else {
> +			tst_res(TFAIL | TTERRNO, "clock_gettime(2): "
> +					"unsupported clock %s failed "
> +					"unexpectedly",
> +					tst_clock_name(tc[i].clocktype));
> +		}
> +		return;
> +	}
> +
> +	if (TST_RET == -1 && tc[i].exp_ret == 0) {
> +
> +		tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s "
> +					"failed unexpectedly",
> +					tst_clock_name(tc[i].clocktype));
> +		return;
> +	}
> +
> +	if (TST_RET == 0 && tc[i].exp_ret == -1) {
> +
> +		tst_res(TFAIL, "clock_gettime(2): unsupported clock %s passed "
> +				"unexpectedly",
> +				tst_clock_name(tc[i].clocktype));
> +		return;
> +	}
> +
> +	tst_res(TPASS, "clock_gettime(2): clock %s passed",
> +			tst_clock_name(tc[i].clocktype));
> +}
> +
> +static struct tst_test test = {
> +	.test = verify_clock_gettime,
> +	.tcnt = ARRAY_SIZE(tc),
> +	.needs_root = 1,
> +};
> diff --git a/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c b/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c
> new file mode 100644
> index 000000000..5985cdec0
> --- /dev/null
> +++ b/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 Linaro Limited. All rights reserved.
> + * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
> + */
> +/*
> + * Bad argument tests for clock_gettime(2) on multiple clocks:
> + *
> + *  1) MAX_CLOCKS                - bad clock
> + *  2) MAX_CLOCKS + 1            - bad clock
> + *  3) CLOCK_REALTIME            - bad time spec ptr (if supported)
> + *  4) CLOCK_MONOTONIC           - bad time spec ptr (if supported)
> + *  5) CLOCK_REALTIME_COARSE     - bad time spec ptr (if supported)
> + *  6) CLOCK_MONOTONIC_COARSE    - bad time spec ptr (if supported)
> + *  7) CLOCK_MONOTONIC_RAW       - bad time spec ptr (if supported)
> + *  8) CLOCK_BOOTTIME            - bad time spec ptr (if supported)
> + *  9) CLOCK_PROCESS_CPUTIME_ID  - bad time spec ptr (if supported)
> + * 10) CLOCK_THREAD_CPUTIME_ID   - bad time spec ptr (if supported)
> + */
> +
> +#include "config.h"
> +#include "tst_test.h"
> +#include "lapi/syscalls.h"
> +#include "lapi/posix_clocks.h"
> +#include "tst_timer.h"
> +#include "tst_safe_clocks.h"
> +
> +#define DELTA_SEC 10
> +#define NSEC_PER_SEC (1000000000L)
> +#define MAX_CLOCKS 16
> +
> +struct test_case {
> +	clockid_t clocktype;
> +	int exp_err;
> +};
> +
> +struct test_case tc[] = {
> +	{
> +	 .clocktype = MAX_CLOCKS,
> +	 .exp_err = EINVAL,
> +	 },
> +	{
> +	 .clocktype = MAX_CLOCKS + 1,
> +	 .exp_err = EINVAL,
> +	 },
> +	{
> +	 .clocktype = CLOCK_REALTIME,
> +	 .exp_err = EFAULT,
> +	 },
> +	{
> +	 .clocktype = CLOCK_MONOTONIC,
> +	 .exp_err = EFAULT,
> +	 },
> +	/*
> +	 * Different POSIX clocks have different (*clock_get)() handlers.
> +	 * It justifies testing EFAULT for all.
> +	 */
> +	{
> +	 .clocktype = CLOCK_REALTIME_COARSE,
> +#ifndef CLOCK_REALTIME_COARSE
> +	 .exp_err = EINVAL,
> +#else
> +	 .exp_err = EFAULT,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_MONOTONIC_COARSE,
> +#ifndef CLOCK_MONOTONIC_COARSE
> +	 .exp_err = EINVAL,
> +#else
> +	 .exp_err = EFAULT,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_MONOTONIC_RAW,
> +#ifndef CLOCK_MONOTONIC_RAW
> +	 .exp_err = EINVAL,
> +#else
> +	 .exp_err = EFAULT,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_BOOTTIME,
> +#ifndef CLOCK_BOOTTIME
> +	 .exp_err = EINVAL,
> +#else
> +	 .exp_err = EFAULT,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_PROCESS_CPUTIME_ID,
> +#ifndef CLOCK_PROCESS_CPUTIME_ID
> +	 .exp_err = EINVAL,
> +#else
> +	 .exp_err = EFAULT,
> +#endif
> +	 },
> +	{
> +	 .clocktype = CLOCK_THREAD_CPUTIME_ID,
> +#ifndef CLOCK_THREAD_CPUTIME_ID
> +	 .exp_err = EINVAL,
> +#else
> +	 .exp_err = EFAULT,
> +#endif
> +	 },
> +};
> +
> +/*
> + * Some tests may cause libc to segfault when passing bad arguments.
> + */
> +static int sys_clock_gettime(clockid_t clk_id, struct timespec *tp)
> +{
> +	return tst_syscall(__NR_clock_gettime, clk_id, tp);
> +}
> +
> +static void verify_clock_gettime(unsigned int i)
> +{
> +	struct timespec spec, *specptr;
> +
> +	specptr = &spec;
> +
> +	/* bad pointer case */
> +	if (tc[i].exp_err == EFAULT)
> +		specptr = tst_get_bad_addr(NULL);
> +
> +	TEST(sys_clock_gettime(tc[i].clocktype, specptr));
> +
> +	if (TST_RET == -1) {
> +
> +		if (tc[i].exp_err == TST_ERR) {
> +			tst_res(TPASS, "clock_gettime(2): %sclock %s failed as "
> +					"expected", (tc[i].exp_err == EINVAL) ?
> +					"unsupported " : "",
> +					tst_clock_name(tc[i].clocktype));
> +		} else {
> +			tst_res(TFAIL | TTERRNO, "clock_gettime(2): %sclock %s "
> +					"failed unexpectedly",
> +					(tc[i].exp_err == EINVAL) ?
> +					"unsupported " : "",
> +					tst_clock_name(tc[i].clocktype));
> +		}
> +		return;
> +	}
> +
> +	tst_res(TFAIL, "clock_gettime(2): %sclock %s passed unexpectedly",
> +			(tc[i].exp_err == EINVAL) ? "unsupported " : "",
> +			tst_clock_name(tc[i].clocktype));
> +}
> +
> +static struct tst_test test = {
> +	.test = verify_clock_gettime,
> +	.tcnt = ARRAY_SIZE(tc),
> +	.needs_root = 1,
> +	.restore_wallclock = 1,
> +};
> -- 
> 2.20.1
>
Rafael David Tinoco Feb. 7, 2019, 12:36 p.m. UTC | #2
Hey o/

> On 7 Feb 2019, at 10:31, Cyril Hrubis <chrubis@suse.cz> wrote:

> 

> Hi!

>> +struct test_case {

>> +	clockid_t clocktype;

>> +	int exp_ret;

>> +	int exp_err;

>> +	int unsupported;

>> +};

>> +

>> +struct test_case tc[] = {

>> +	{

>> +	 .clocktype = CLOCK_REALTIME,

>> +	 },

>> +	{

>> +	 .clocktype = CLOCK_REALTIME_COARSE,

>> +#ifndef CLOCK_REALTIME_COARSE

>> +	 .exp_ret = -1,

>> +	 .exp_err = EINVAL,

>> +#endif

> 

> Depending on the constant beind defined is completely wrong here. The

> only way how to figure out if the clock is being supported or not is to

> call the clock_gettime() with correct paramters and check for EINVAL.

> 


Yes I had doubts about compilation vs runtime also for the #ifndefs. 

> So I guess that in this test we should call clock_gettime() for

> paticular clock and:

> 

> * For certain clocks that are implemented for long enough, we expect

>  success, I would say that at least CLOCK_REALTIME, CLOCK_MONOTONIC and

>  CLOCK_*_CPUTIME_ID should be implemented for long enough to be

>  supported everywhere


Alright.

> 

> * The rest of the clocks should be allowed either to pass or return EINVAL

> 


Makes sense.

> * In case that the call passed we should check that the timespec has

>  been changed (we should zero it before the call)


Ok.

> * Also many architectures have vDSO for clock_gettime() we should also

>  check that the syscall and vDSO are consistent in this case



Alright, will force the syscall and later use regular libc call to wrap into vDSO is available. 

Thanks for the feedback!

Rafael
<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div>Hey o/</div><div><br class=""><blockquote type="cite" class=""><div class="">On 7 Feb 2019, at 10:31, Cyril Hrubis &lt;<a href="mailto:chrubis@suse.cz" class="">chrubis@suse.cz</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Hi!</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><blockquote type="cite" style="font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">+struct test_case {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span>clockid_t clocktype;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span>int exp_ret;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span>int exp_err;<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span>int unsupported;<br class="">+};<br class="">+<br class="">+struct test_case tc[] = {<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span>{<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span><span class="Apple-converted-space">&nbsp;</span>.clocktype = CLOCK_REALTIME,<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span><span class="Apple-converted-space">&nbsp;</span>},<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span>{<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span><span class="Apple-converted-space">&nbsp;</span>.clocktype = CLOCK_REALTIME_COARSE,<br class="">+#ifndef CLOCK_REALTIME_COARSE<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span><span class="Apple-converted-space">&nbsp;</span>.exp_ret = -1,<br class="">+<span class="Apple-tab-span" style="white-space: pre;">	</span><span class="Apple-converted-space">&nbsp;</span>.exp_err = EINVAL,<br class="">+#endif</blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">Depending on the constant beind defined is completely wrong here. The</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">only way how to figure out if the clock is being supported or not is to</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">call the clock_gettime() with correct paramters and check for EINVAL.</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""></div></blockquote><div><br class=""></div><div>Yes I had doubts about compilation vs runtime also for the #ifndefs.&nbsp;</div><br class=""><blockquote type="cite" class=""><div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">So I guess that in this test we should call clock_gettime() for</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">paticular clock and:</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">* For certain clocks that are implemented for long enough, we expect</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">&nbsp;success, I would say that at least CLOCK_REALTIME, CLOCK_MONOTONIC and</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">&nbsp;CLOCK_*_CPUTIME_ID should be implemented for long enough to be</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">&nbsp;supported everywhere</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""></div></blockquote><div><br class=""></div><div>Alright.</div><br class=""><blockquote type="cite" class=""><div class=""><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">* The rest of the clocks should be allowed either to pass or return EINVAL</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""></div></blockquote><div><br class=""></div><div>Makes sense.</div><br class=""><blockquote type="cite" class=""><div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">* In case that the call passed we should check that the timespec has</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">&nbsp;been changed (we should zero it before the call)</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""></div></blockquote><div><br class=""></div><div>Ok.</div><br class=""><blockquote type="cite" class=""><div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">* Also many architectures have vDSO for clock_gettime() we should also</span><br style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Menlo-Regular; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">&nbsp;check that the syscall and vDSO are consistent in this case</span></div></blockquote></div><div><br class=""></div><div>Alright, will force the syscall and later use regular libc call to wrap into vDSO is available.&nbsp;</div><div><br class=""></div><div>Thanks for the feedback!</div><div><br class=""></div><div>Rafael</div></body></html>
diff mbox series

Patch

diff --git a/runtest/syscalls b/runtest/syscalls
index 668c87cd1..7bccda996 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -79,6 +79,9 @@  clock_nanosleep01 clock_nanosleep01
 clock_nanosleep02 clock_nanosleep02
 clock_nanosleep2_01 clock_nanosleep2_01
 
+clock_gettime01 clock_gettime01
+clock_gettime02 clock_gettime02
+
 clock_settime01 clock_settime01
 clock_settime02 clock_settime02
 
diff --git a/testcases/kernel/syscalls/clock_gettime/.gitignore b/testcases/kernel/syscalls/clock_gettime/.gitignore
new file mode 100644
index 000000000..0f9b24ab6
--- /dev/null
+++ b/testcases/kernel/syscalls/clock_gettime/.gitignore
@@ -0,0 +1,2 @@ 
+clock_gettime01
+clock_gettime02
diff --git a/testcases/kernel/syscalls/clock_gettime/Makefile b/testcases/kernel/syscalls/clock_gettime/Makefile
new file mode 100644
index 000000000..79f671f1c
--- /dev/null
+++ b/testcases/kernel/syscalls/clock_gettime/Makefile
@@ -0,0 +1,10 @@ 
+# Copyright (c) 2019 - Linaro Limited. All rights reserved.
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+LDLIBS+=-lrt
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
\ No newline at end of file
diff --git a/testcases/kernel/syscalls/clock_gettime/clock_gettime01.c b/testcases/kernel/syscalls/clock_gettime/clock_gettime01.c
new file mode 100644
index 000000000..89a2041e2
--- /dev/null
+++ b/testcases/kernel/syscalls/clock_gettime/clock_gettime01.c
@@ -0,0 +1,134 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Linaro Limited. All rights reserved.
+ * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
+ */
+/*
+ * Basic test for clock_gettime(2) on multiple clocks:
+ *
+ *  1) CLOCK_REALTIME
+ *  2) CLOCK_MONOTONIC
+ *  3) CLOCK_REALTIME_COARSE
+ *  4) CLOCK_MONOTONIC_COARSE
+ *  5) CLOCK_MONOTONIC_RAW
+ *  6) CLOCK_BOOTTIME
+ *  7) CLOCK_PROCESS_CPUTIME_ID
+ *  8) CLOCK_THREAD_CPUTIME_ID
+ *
+ *  If unsupported, checks for correct return code.
+ */
+
+#include "config.h"
+#include "tst_timer.h"
+#include "tst_safe_clocks.h"
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+
+struct test_case {
+	clockid_t clocktype;
+	int exp_ret;
+	int exp_err;
+	int unsupported;
+};
+
+struct test_case tc[] = {
+	{
+	 .clocktype = CLOCK_REALTIME,
+	 },
+	{
+	 .clocktype = CLOCK_REALTIME_COARSE,
+#ifndef CLOCK_REALTIME_COARSE
+	 .exp_ret = -1,
+	 .exp_err = EINVAL,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_MONOTONIC,
+#ifndef CLOCK_MONOTONIC
+	 .exp_ret = -1,
+	 .exp_err = EINVAL,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_MONOTONIC_COARSE,
+#ifndef CLOCK_MONOTONIC_COARSE
+	 .exp_ret = -1,
+	 .exp_err = EINVAL,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_MONOTONIC_RAW,
+#ifndef CLOCK_MONOTONIC_RAW
+	 .exp_ret = -1,
+	 .exp_err = EINVAL,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_BOOTTIME,
+#ifndef CLOCK_BOOTTIME
+	 .exp_ret = -1,
+	 .exp_err = EINVAL,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_PROCESS_CPUTIME_ID,
+#ifndef CLOCK_PROCESS_CPUTIME_ID
+	 .exp_ret = -1,
+	 .exp_err = EINVAL,
+#endif
+	 },
+{
+	 .clocktype = CLOCK_THREAD_CPUTIME_ID,
+#ifndef CLOCK_THREAD_CPUTIME_ID
+	 .exp_ret = -1,
+	 .exp_err = EINVAL,
+#endif
+	 },
+};
+
+static void verify_clock_gettime(unsigned int i)
+{
+	struct timespec spec;
+
+	TEST(clock_gettime(tc[i].clocktype, &spec));
+
+	if (TST_RET == -1 && tc[i].exp_ret == -1) {
+
+		if (tc[i].exp_err == TST_ERR) {
+			tst_res(TPASS, "clock_gettime(2): unsupported clock %s "
+					"failed as expected",
+					tst_clock_name(tc[i].clocktype));
+		} else {
+			tst_res(TFAIL | TTERRNO, "clock_gettime(2): "
+					"unsupported clock %s failed "
+					"unexpectedly",
+					tst_clock_name(tc[i].clocktype));
+		}
+		return;
+	}
+
+	if (TST_RET == -1 && tc[i].exp_ret == 0) {
+
+		tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s "
+					"failed unexpectedly",
+					tst_clock_name(tc[i].clocktype));
+		return;
+	}
+
+	if (TST_RET == 0 && tc[i].exp_ret == -1) {
+
+		tst_res(TFAIL, "clock_gettime(2): unsupported clock %s passed "
+				"unexpectedly",
+				tst_clock_name(tc[i].clocktype));
+		return;
+	}
+
+	tst_res(TPASS, "clock_gettime(2): clock %s passed",
+			tst_clock_name(tc[i].clocktype));
+}
+
+static struct tst_test test = {
+	.test = verify_clock_gettime,
+	.tcnt = ARRAY_SIZE(tc),
+	.needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c b/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c
new file mode 100644
index 000000000..5985cdec0
--- /dev/null
+++ b/testcases/kernel/syscalls/clock_gettime/clock_gettime02.c
@@ -0,0 +1,155 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Linaro Limited. All rights reserved.
+ * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
+ */
+/*
+ * Bad argument tests for clock_gettime(2) on multiple clocks:
+ *
+ *  1) MAX_CLOCKS                - bad clock
+ *  2) MAX_CLOCKS + 1            - bad clock
+ *  3) CLOCK_REALTIME            - bad time spec ptr (if supported)
+ *  4) CLOCK_MONOTONIC           - bad time spec ptr (if supported)
+ *  5) CLOCK_REALTIME_COARSE     - bad time spec ptr (if supported)
+ *  6) CLOCK_MONOTONIC_COARSE    - bad time spec ptr (if supported)
+ *  7) CLOCK_MONOTONIC_RAW       - bad time spec ptr (if supported)
+ *  8) CLOCK_BOOTTIME            - bad time spec ptr (if supported)
+ *  9) CLOCK_PROCESS_CPUTIME_ID  - bad time spec ptr (if supported)
+ * 10) CLOCK_THREAD_CPUTIME_ID   - bad time spec ptr (if supported)
+ */
+
+#include "config.h"
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/posix_clocks.h"
+#include "tst_timer.h"
+#include "tst_safe_clocks.h"
+
+#define DELTA_SEC 10
+#define NSEC_PER_SEC (1000000000L)
+#define MAX_CLOCKS 16
+
+struct test_case {
+	clockid_t clocktype;
+	int exp_err;
+};
+
+struct test_case tc[] = {
+	{
+	 .clocktype = MAX_CLOCKS,
+	 .exp_err = EINVAL,
+	 },
+	{
+	 .clocktype = MAX_CLOCKS + 1,
+	 .exp_err = EINVAL,
+	 },
+	{
+	 .clocktype = CLOCK_REALTIME,
+	 .exp_err = EFAULT,
+	 },
+	{
+	 .clocktype = CLOCK_MONOTONIC,
+	 .exp_err = EFAULT,
+	 },
+	/*
+	 * Different POSIX clocks have different (*clock_get)() handlers.
+	 * It justifies testing EFAULT for all.
+	 */
+	{
+	 .clocktype = CLOCK_REALTIME_COARSE,
+#ifndef CLOCK_REALTIME_COARSE
+	 .exp_err = EINVAL,
+#else
+	 .exp_err = EFAULT,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_MONOTONIC_COARSE,
+#ifndef CLOCK_MONOTONIC_COARSE
+	 .exp_err = EINVAL,
+#else
+	 .exp_err = EFAULT,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_MONOTONIC_RAW,
+#ifndef CLOCK_MONOTONIC_RAW
+	 .exp_err = EINVAL,
+#else
+	 .exp_err = EFAULT,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_BOOTTIME,
+#ifndef CLOCK_BOOTTIME
+	 .exp_err = EINVAL,
+#else
+	 .exp_err = EFAULT,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_PROCESS_CPUTIME_ID,
+#ifndef CLOCK_PROCESS_CPUTIME_ID
+	 .exp_err = EINVAL,
+#else
+	 .exp_err = EFAULT,
+#endif
+	 },
+	{
+	 .clocktype = CLOCK_THREAD_CPUTIME_ID,
+#ifndef CLOCK_THREAD_CPUTIME_ID
+	 .exp_err = EINVAL,
+#else
+	 .exp_err = EFAULT,
+#endif
+	 },
+};
+
+/*
+ * Some tests may cause libc to segfault when passing bad arguments.
+ */
+static int sys_clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+	return tst_syscall(__NR_clock_gettime, clk_id, tp);
+}
+
+static void verify_clock_gettime(unsigned int i)
+{
+	struct timespec spec, *specptr;
+
+	specptr = &spec;
+
+	/* bad pointer case */
+	if (tc[i].exp_err == EFAULT)
+		specptr = tst_get_bad_addr(NULL);
+
+	TEST(sys_clock_gettime(tc[i].clocktype, specptr));
+
+	if (TST_RET == -1) {
+
+		if (tc[i].exp_err == TST_ERR) {
+			tst_res(TPASS, "clock_gettime(2): %sclock %s failed as "
+					"expected", (tc[i].exp_err == EINVAL) ?
+					"unsupported " : "",
+					tst_clock_name(tc[i].clocktype));
+		} else {
+			tst_res(TFAIL | TTERRNO, "clock_gettime(2): %sclock %s "
+					"failed unexpectedly",
+					(tc[i].exp_err == EINVAL) ?
+					"unsupported " : "",
+					tst_clock_name(tc[i].clocktype));
+		}
+		return;
+	}
+
+	tst_res(TFAIL, "clock_gettime(2): %sclock %s passed unexpectedly",
+			(tc[i].exp_err == EINVAL) ? "unsupported " : "",
+			tst_clock_name(tc[i].clocktype));
+}
+
+static struct tst_test test = {
+	.test = verify_clock_gettime,
+	.tcnt = ARRAY_SIZE(tc),
+	.needs_root = 1,
+	.restore_wallclock = 1,
+};