1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2019 Linaro Limited. All rights reserved.
4 * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
5 */
6
7 /*
8 * clock_adjtime() syscall might have as execution path:
9 *
10 * 1) a regular POSIX clock (only REALTIME clock implements adjtime())
11 * - will behave exactly like adjtimex() system call.
12 * - only one being tested here.
13 *
14 * 2) a dynamic POSIX clock (which ops are implemented by PTP clocks)
15 * - will trigger the PTP clock driver function "adjtime()"
16 * - different implementations from one PTP clock to another
17 * - might return EOPNOTSUPP (like ptp_kvm_caps, for example)
18 * - no entry point for clock_adjtime(), missing "CLOCK_PTP" model
19 *
20 * so it is sane to check possible adjustments:
21 *
22 * - ADJ_OFFSET - usec or nsec, kernel adjusts time gradually by offset
23 * (-512000 < offset < 512000)
24 * - ADJ_FREQUENCY - system clock frequency offset
25 * - ADJ_MAXERROR - maximum error (usec)
26 * - ADJ_ESTERROR - estimated time error in us
27 * - ADJ_STATUS - clock command/status of ntp implementation
28 * - ADJ_TIMECONST - PLL stiffness (jitter dependent) + poll int for PLL
29 * - ADJ_TICK - us between clock ticks
30 * (>= 900000/HZ, <= 1100000/HZ)
31 *
32 * and also the standalone ones (using .offset variable):
33 *
34 * - ADJ_OFFSET_SINGLESHOT - behave like adjtime()
35 * - ADJ_OFFSET_SS_READ - ret remaining time for completion after SINGLESHOT
36 *
37 * For ADJ_STATUS, consider the following flags:
38 *
39 * rw STA_PLL - enable phase-locked loop updates (ADJ_OFFSET)
40 * rw STA_PPSFREQ - enable PPS (pulse-per-second) freq discipline
41 * rw STA_PPSTIME - enable PPS time discipline
42 * rw STA_FLL - select freq-locked loop mode.
43 * rw STA_INS - ins leap sec after the last sec of UTC day (all days)
44 * rw STA_DEL - del leap sec at last sec of UTC day (all days)
45 * rw STA_UNSYNC - clock unsynced
46 * rw STA_FREQHOLD - hold freq. ADJ_OFFSET made w/out auto small adjs
47 * ro STA_PPSSIGNAL - valid PPS (pulse-per-second) signal is present
48 * ro STA_PPSJITTER - PPS signal jitter exceeded.
49 * ro STA_PPSWANDER - PPS signal wander exceeded.
50 * ro STA_PPSERROR - PPS signal calibration error.
51 * ro STA_CLOKERR - clock HW fault.
52 * ro STA_NANO - 0 = us, 1 = ns (set = ADJ_NANO, cl = ADJ_MICRO)
53 * rw STA_MODE - mode: 0 = phased locked loop. 1 = freq locked loop
54 * ro STA_CLK - clock source. unused.
55 */
56
57 #include "clock_adjtime.h"
58
59 static long hz;
60 static struct timex saved, ttxc;
61 static int supported;
62
63 struct test_case {
64 unsigned int modes;
65 long highlimit;
66 long *ptr;
67 long delta;
68 };
69
70 struct test_case tc[] = {
71 {
72 .modes = ADJ_OFFSET_SINGLESHOT,
73 },
74 {
75 .modes = ADJ_OFFSET_SS_READ,
76 },
77 {
78 .modes = ADJ_ALL,
79 },
80 {
81 .modes = ADJ_OFFSET,
82 .highlimit = 500000,
83 .ptr = &ttxc.offset,
84 .delta = 10000,
85 },
86 {
87 .modes = ADJ_FREQUENCY,
88 .ptr = &ttxc.freq,
89 .delta = 100,
90 },
91 {
92 .modes = ADJ_MAXERROR,
93 .ptr = &ttxc.maxerror,
94 .delta = 100,
95 },
96 {
97 .modes = ADJ_ESTERROR,
98 .ptr = &ttxc.esterror,
99 .delta = 100,
100 },
101 {
102 .modes = ADJ_TIMECONST,
103 .ptr = &ttxc.constant,
104 .delta = 1,
105 },
106 {
107 .modes = ADJ_TICK,
108 .highlimit = 1100000,
109 .ptr = &ttxc.tick,
110 .delta = 1000,
111 },
112 };
113
verify_clock_adjtime(unsigned int i)114 static void verify_clock_adjtime(unsigned int i)
115 {
116 long ptroff, *ptr = NULL;
117 struct timex verify;
118
119 memset(&ttxc, 0, sizeof(struct timex));
120 memset(&verify, 0, sizeof(struct timex));
121
122 SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &ttxc);
123 timex_show("GET", ttxc);
124
125 ttxc.modes = tc[i].modes;
126
127 if (tc[i].ptr && tc[i].delta) {
128
129 *tc[i].ptr += tc[i].delta;
130
131 /* fix limits, if existent, so no errors occur */
132
133 if (tc[i].highlimit) {
134 if (*tc[i].ptr >= tc[i].highlimit)
135 *tc[i].ptr = tc[i].highlimit;
136 }
137 }
138
139 SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &ttxc);
140 timex_show("SET", ttxc);
141
142 if (tc[i].ptr) {
143
144 /* adjtimex field being tested so we can verify later */
145
146 ptroff = (long) tc[i].ptr - (long) &ttxc;
147 ptr = (void *) &verify + ptroff;
148 }
149
150 TEST(sys_clock_adjtime(CLOCK_REALTIME, &verify));
151 timex_show("VERIFY", verify);
152
153 if (tc[i].ptr && *tc[i].ptr != *ptr) {
154 tst_res(TFAIL, "clock_adjtime(): could not set value (mode=%x)",
155 tc[i].modes);
156 }
157
158 if (TST_RET < 0) {
159 tst_res(TFAIL | TTERRNO, "clock_adjtime(): mode=%x, returned "
160 "error", tc[i].modes);
161 }
162
163 tst_res(TPASS, "clock_adjtime(): success (mode=%x)", tc[i].modes);
164 }
165
setup(void)166 static void setup(void)
167 {
168 size_t i;
169 int rval;
170
171 rval = SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
172 supported = 1;
173
174 if (rval != TIME_OK && rval != TIME_ERROR) {
175 timex_show("SAVE_STATUS", saved);
176 tst_brk(TBROK | TTERRNO, "clock has on-going leap changes, "
177 "returned: %i", rval);
178 }
179
180 hz = SAFE_SYSCONF(_SC_CLK_TCK);
181
182 for (i = 0; i < ARRAY_SIZE(tc); i++) {
183
184 /* fix high and low limits by dividing it per HZ value */
185
186 if (tc[i].modes == ADJ_TICK)
187 tc[i].highlimit /= hz;
188
189 /* fix usec as being test default resolution */
190
191 if (saved.modes & ADJ_NANO) {
192 if (tc[i].modes == ADJ_OFFSET) {
193 tc[i].highlimit *= 1000;
194 tc[i].delta *= 1000;
195 }
196 }
197 }
198 }
199
cleanup(void)200 static void cleanup(void)
201 {
202 if (supported == 0)
203 return;
204
205 saved.modes = ADJ_ALL;
206
207 /* restore clock resolution based on original status flag */
208
209 if (saved.status & STA_NANO)
210 saved.modes |= ADJ_NANO;
211 else
212 saved.modes |= ADJ_MICRO;
213
214 /* restore original clock flags */
215
216 SAFE_CLOCK_ADJTIME(CLOCK_REALTIME, &saved);
217 }
218
219 static struct tst_test test = {
220 .test = verify_clock_adjtime,
221 .setup = setup,
222 .cleanup = cleanup,
223 .tcnt = ARRAY_SIZE(tc),
224 .needs_root = 1,
225 .restore_wallclock = 1,
226 };
227