0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <stdio.h>
0028 #include <stdlib.h>
0029 #include <time.h>
0030 #include <sys/time.h>
0031 #include <sys/timex.h>
0032 #include <string.h>
0033 #include <signal.h>
0034 #include <unistd.h>
0035 #include "../kselftest.h"
0036
0037 #define NSEC_PER_SEC 1000000000LL
0038 #define USEC_PER_SEC 1000000LL
0039
0040 #define ADJ_SETOFFSET 0x0100
0041
0042 #include <sys/syscall.h>
0043 int clock_adjtime(clockid_t id, struct timex *tx)
0044 {
0045 return syscall(__NR_clock_adjtime, id, tx);
0046 }
0047
0048
0049
0050 int clear_time_state(void)
0051 {
0052 struct timex tx;
0053 int ret;
0054
0055 tx.modes = ADJ_STATUS;
0056 tx.status = 0;
0057 ret = adjtimex(&tx);
0058 return ret;
0059 }
0060
0061 #define NUM_FREQ_VALID 32
0062 #define NUM_FREQ_OUTOFRANGE 4
0063 #define NUM_FREQ_INVALID 2
0064
0065 long valid_freq[NUM_FREQ_VALID] = {
0066 -499<<16,
0067 -450<<16,
0068 -400<<16,
0069 -350<<16,
0070 -300<<16,
0071 -250<<16,
0072 -200<<16,
0073 -150<<16,
0074 -100<<16,
0075 -75<<16,
0076 -50<<16,
0077 -25<<16,
0078 -10<<16,
0079 -5<<16,
0080 -1<<16,
0081 -1000,
0082 1<<16,
0083 5<<16,
0084 10<<16,
0085 25<<16,
0086 50<<16,
0087 75<<16,
0088 100<<16,
0089 150<<16,
0090 200<<16,
0091 250<<16,
0092 300<<16,
0093 350<<16,
0094 400<<16,
0095 450<<16,
0096 499<<16,
0097 };
0098
0099 long outofrange_freq[NUM_FREQ_OUTOFRANGE] = {
0100 -1000<<16,
0101 -550<<16,
0102 550<<16,
0103 1000<<16,
0104 };
0105
0106 #define LONG_MAX (~0UL>>1)
0107 #define LONG_MIN (-LONG_MAX - 1)
0108
0109 long invalid_freq[NUM_FREQ_INVALID] = {
0110 LONG_MAX,
0111 LONG_MIN,
0112 };
0113
0114 int validate_freq(void)
0115 {
0116 struct timex tx;
0117 int ret, pass = 0;
0118 int i;
0119
0120 clear_time_state();
0121
0122 memset(&tx, 0, sizeof(struct timex));
0123
0124
0125 printf("Testing ADJ_FREQ... ");
0126 fflush(stdout);
0127 for (i = 0; i < NUM_FREQ_VALID; i++) {
0128 tx.modes = ADJ_FREQUENCY;
0129 tx.freq = valid_freq[i];
0130
0131 ret = adjtimex(&tx);
0132 if (ret < 0) {
0133 printf("[FAIL]\n");
0134 printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
0135 valid_freq[i], valid_freq[i]>>16);
0136 pass = -1;
0137 goto out;
0138 }
0139 tx.modes = 0;
0140 ret = adjtimex(&tx);
0141 if (tx.freq != valid_freq[i]) {
0142 printf("Warning: freq value %ld not what we set it (%ld)!\n",
0143 tx.freq, valid_freq[i]);
0144 }
0145 }
0146 for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) {
0147 tx.modes = ADJ_FREQUENCY;
0148 tx.freq = outofrange_freq[i];
0149
0150 ret = adjtimex(&tx);
0151 if (ret < 0) {
0152 printf("[FAIL]\n");
0153 printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
0154 outofrange_freq[i], outofrange_freq[i]>>16);
0155 pass = -1;
0156 goto out;
0157 }
0158 tx.modes = 0;
0159 ret = adjtimex(&tx);
0160 if (tx.freq == outofrange_freq[i]) {
0161 printf("[FAIL]\n");
0162 printf("ERROR: out of range value %ld actually set!\n",
0163 tx.freq);
0164 pass = -1;
0165 goto out;
0166 }
0167 }
0168
0169
0170 if (sizeof(long) == 8) {
0171 for (i = 0; i < NUM_FREQ_INVALID; i++) {
0172 tx.modes = ADJ_FREQUENCY;
0173 tx.freq = invalid_freq[i];
0174 ret = adjtimex(&tx);
0175 if (ret >= 0) {
0176 printf("[FAIL]\n");
0177 printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n",
0178 invalid_freq[i]);
0179 pass = -1;
0180 goto out;
0181 }
0182 }
0183 }
0184
0185 printf("[OK]\n");
0186 out:
0187
0188 tx.modes = ADJ_FREQUENCY;
0189 tx.freq = 0;
0190 ret = adjtimex(&tx);
0191
0192 return pass;
0193 }
0194
0195
0196 int set_offset(long long offset, int use_nano)
0197 {
0198 struct timex tmx = {};
0199 int ret;
0200
0201 tmx.modes = ADJ_SETOFFSET;
0202 if (use_nano) {
0203 tmx.modes |= ADJ_NANO;
0204
0205 tmx.time.tv_sec = offset / NSEC_PER_SEC;
0206 tmx.time.tv_usec = offset % NSEC_PER_SEC;
0207
0208 if (offset < 0 && tmx.time.tv_usec) {
0209 tmx.time.tv_sec -= 1;
0210 tmx.time.tv_usec += NSEC_PER_SEC;
0211 }
0212 } else {
0213 tmx.time.tv_sec = offset / USEC_PER_SEC;
0214 tmx.time.tv_usec = offset % USEC_PER_SEC;
0215
0216 if (offset < 0 && tmx.time.tv_usec) {
0217 tmx.time.tv_sec -= 1;
0218 tmx.time.tv_usec += USEC_PER_SEC;
0219 }
0220 }
0221
0222 ret = clock_adjtime(CLOCK_REALTIME, &tmx);
0223 if (ret < 0) {
0224 printf("(sec: %ld usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec);
0225 printf("[FAIL]\n");
0226 return -1;
0227 }
0228 return 0;
0229 }
0230
0231 int set_bad_offset(long sec, long usec, int use_nano)
0232 {
0233 struct timex tmx = {};
0234 int ret;
0235
0236 tmx.modes = ADJ_SETOFFSET;
0237 if (use_nano)
0238 tmx.modes |= ADJ_NANO;
0239
0240 tmx.time.tv_sec = sec;
0241 tmx.time.tv_usec = usec;
0242 ret = clock_adjtime(CLOCK_REALTIME, &tmx);
0243 if (ret >= 0) {
0244 printf("Invalid (sec: %ld usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec);
0245 printf("[FAIL]\n");
0246 return -1;
0247 }
0248 return 0;
0249 }
0250
0251 int validate_set_offset(void)
0252 {
0253 printf("Testing ADJ_SETOFFSET... ");
0254 fflush(stdout);
0255
0256
0257 if (set_offset(NSEC_PER_SEC - 1, 1))
0258 return -1;
0259
0260 if (set_offset(-NSEC_PER_SEC + 1, 1))
0261 return -1;
0262
0263 if (set_offset(-NSEC_PER_SEC - 1, 1))
0264 return -1;
0265
0266 if (set_offset(5 * NSEC_PER_SEC, 1))
0267 return -1;
0268
0269 if (set_offset(-5 * NSEC_PER_SEC, 1))
0270 return -1;
0271
0272 if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1))
0273 return -1;
0274
0275 if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1))
0276 return -1;
0277
0278 if (set_offset(USEC_PER_SEC - 1, 0))
0279 return -1;
0280
0281 if (set_offset(-USEC_PER_SEC + 1, 0))
0282 return -1;
0283
0284 if (set_offset(-USEC_PER_SEC - 1, 0))
0285 return -1;
0286
0287 if (set_offset(5 * USEC_PER_SEC, 0))
0288 return -1;
0289
0290 if (set_offset(-5 * USEC_PER_SEC, 0))
0291 return -1;
0292
0293 if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0))
0294 return -1;
0295
0296 if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0))
0297 return -1;
0298
0299
0300 if (set_bad_offset(0, -1, 1))
0301 return -1;
0302 if (set_bad_offset(0, -1, 0))
0303 return -1;
0304 if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1))
0305 return -1;
0306 if (set_bad_offset(0, 2 * USEC_PER_SEC, 0))
0307 return -1;
0308 if (set_bad_offset(0, NSEC_PER_SEC, 1))
0309 return -1;
0310 if (set_bad_offset(0, USEC_PER_SEC, 0))
0311 return -1;
0312 if (set_bad_offset(0, -NSEC_PER_SEC, 1))
0313 return -1;
0314 if (set_bad_offset(0, -USEC_PER_SEC, 0))
0315 return -1;
0316
0317 printf("[OK]\n");
0318 return 0;
0319 }
0320
0321 int main(int argc, char **argv)
0322 {
0323 if (validate_freq())
0324 return ksft_exit_fail();
0325
0326 if (validate_set_offset())
0327 return ksft_exit_fail();
0328
0329 return ksft_exit_pass();
0330 }