cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

valid-adjtimex.c (6547B)


      1/* valid adjtimex test
      2 *              by: John Stultz <john.stultz@linaro.org>
      3 *              (C) Copyright Linaro 2015
      4 *              Licensed under the GPLv2
      5 *
      6 *  This test validates adjtimex interface with valid
      7 *  and invalid test data.
      8 *
      9 *  Usage: valid-adjtimex
     10 *
     11 *  To build:
     12 *	$ gcc valid-adjtimex.c -o valid-adjtimex -lrt
     13 *
     14 *   This program is free software: you can redistribute it and/or modify
     15 *   it under the terms of the GNU General Public License as published by
     16 *   the Free Software Foundation, either version 2 of the License, or
     17 *   (at your option) any later version.
     18 *
     19 *   This program is distributed in the hope that it will be useful,
     20 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     21 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     22 *   GNU General Public License for more details.
     23 */
     24
     25
     26
     27#include <stdio.h>
     28#include <stdlib.h>
     29#include <time.h>
     30#include <sys/time.h>
     31#include <sys/timex.h>
     32#include <string.h>
     33#include <signal.h>
     34#include <unistd.h>
     35#include "../kselftest.h"
     36
     37#define NSEC_PER_SEC 1000000000LL
     38#define USEC_PER_SEC 1000000LL
     39
     40#define ADJ_SETOFFSET 0x0100
     41
     42#include <sys/syscall.h>
     43static int clock_adjtime(clockid_t id, struct timex *tx)
     44{
     45	return syscall(__NR_clock_adjtime, id, tx);
     46}
     47
     48
     49/* clear NTP time_status & time_state */
     50int clear_time_state(void)
     51{
     52	struct timex tx;
     53	int ret;
     54
     55	tx.modes = ADJ_STATUS;
     56	tx.status = 0;
     57	ret = adjtimex(&tx);
     58	return ret;
     59}
     60
     61#define NUM_FREQ_VALID 32
     62#define NUM_FREQ_OUTOFRANGE 4
     63#define NUM_FREQ_INVALID 2
     64
     65long valid_freq[NUM_FREQ_VALID] = {
     66	-499<<16,
     67	-450<<16,
     68	-400<<16,
     69	-350<<16,
     70	-300<<16,
     71	-250<<16,
     72	-200<<16,
     73	-150<<16,
     74	-100<<16,
     75	-75<<16,
     76	-50<<16,
     77	-25<<16,
     78	-10<<16,
     79	-5<<16,
     80	-1<<16,
     81	-1000,
     82	1<<16,
     83	5<<16,
     84	10<<16,
     85	25<<16,
     86	50<<16,
     87	75<<16,
     88	100<<16,
     89	150<<16,
     90	200<<16,
     91	250<<16,
     92	300<<16,
     93	350<<16,
     94	400<<16,
     95	450<<16,
     96	499<<16,
     97};
     98
     99long outofrange_freq[NUM_FREQ_OUTOFRANGE] = {
    100	-1000<<16,
    101	-550<<16,
    102	550<<16,
    103	1000<<16,
    104};
    105
    106#define LONG_MAX (~0UL>>1)
    107#define LONG_MIN (-LONG_MAX - 1)
    108
    109long invalid_freq[NUM_FREQ_INVALID] = {
    110	LONG_MAX,
    111	LONG_MIN,
    112};
    113
    114int validate_freq(void)
    115{
    116	struct timex tx;
    117	int ret, pass = 0;
    118	int i;
    119
    120	clear_time_state();
    121
    122	memset(&tx, 0, sizeof(struct timex));
    123	/* Set the leap second insert flag */
    124
    125	printf("Testing ADJ_FREQ... ");
    126	fflush(stdout);
    127	for (i = 0; i < NUM_FREQ_VALID; i++) {
    128		tx.modes = ADJ_FREQUENCY;
    129		tx.freq = valid_freq[i];
    130
    131		ret = adjtimex(&tx);
    132		if (ret < 0) {
    133			printf("[FAIL]\n");
    134			printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
    135				valid_freq[i], valid_freq[i]>>16);
    136			pass = -1;
    137			goto out;
    138		}
    139		tx.modes = 0;
    140		ret = adjtimex(&tx);
    141		if (tx.freq != valid_freq[i]) {
    142			printf("Warning: freq value %ld not what we set it (%ld)!\n",
    143					tx.freq, valid_freq[i]);
    144		}
    145	}
    146	for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) {
    147		tx.modes = ADJ_FREQUENCY;
    148		tx.freq = outofrange_freq[i];
    149
    150		ret = adjtimex(&tx);
    151		if (ret < 0) {
    152			printf("[FAIL]\n");
    153			printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
    154				outofrange_freq[i], outofrange_freq[i]>>16);
    155			pass = -1;
    156			goto out;
    157		}
    158		tx.modes = 0;
    159		ret = adjtimex(&tx);
    160		if (tx.freq == outofrange_freq[i]) {
    161			printf("[FAIL]\n");
    162			printf("ERROR: out of range value %ld actually set!\n",
    163					tx.freq);
    164			pass = -1;
    165			goto out;
    166		}
    167	}
    168
    169
    170	if (sizeof(long) == 8) { /* this case only applies to 64bit systems */
    171		for (i = 0; i < NUM_FREQ_INVALID; i++) {
    172			tx.modes = ADJ_FREQUENCY;
    173			tx.freq = invalid_freq[i];
    174			ret = adjtimex(&tx);
    175			if (ret >= 0) {
    176				printf("[FAIL]\n");
    177				printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n",
    178					invalid_freq[i]);
    179				pass = -1;
    180				goto out;
    181			}
    182		}
    183	}
    184
    185	printf("[OK]\n");
    186out:
    187	/* reset freq to zero */
    188	tx.modes = ADJ_FREQUENCY;
    189	tx.freq = 0;
    190	ret = adjtimex(&tx);
    191
    192	return pass;
    193}
    194
    195
    196int set_offset(long long offset, int use_nano)
    197{
    198	struct timex tmx = {};
    199	int ret;
    200
    201	tmx.modes = ADJ_SETOFFSET;
    202	if (use_nano) {
    203		tmx.modes |= ADJ_NANO;
    204
    205		tmx.time.tv_sec = offset / NSEC_PER_SEC;
    206		tmx.time.tv_usec = offset % NSEC_PER_SEC;
    207
    208		if (offset < 0 && tmx.time.tv_usec) {
    209			tmx.time.tv_sec -= 1;
    210			tmx.time.tv_usec += NSEC_PER_SEC;
    211		}
    212	} else {
    213		tmx.time.tv_sec = offset / USEC_PER_SEC;
    214		tmx.time.tv_usec = offset % USEC_PER_SEC;
    215
    216		if (offset < 0 && tmx.time.tv_usec) {
    217			tmx.time.tv_sec -= 1;
    218			tmx.time.tv_usec += USEC_PER_SEC;
    219		}
    220	}
    221
    222	ret = clock_adjtime(CLOCK_REALTIME, &tmx);
    223	if (ret < 0) {
    224		printf("(sec: %ld  usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec);
    225		printf("[FAIL]\n");
    226		return -1;
    227	}
    228	return 0;
    229}
    230
    231int set_bad_offset(long sec, long usec, int use_nano)
    232{
    233	struct timex tmx = {};
    234	int ret;
    235
    236	tmx.modes = ADJ_SETOFFSET;
    237	if (use_nano)
    238		tmx.modes |= ADJ_NANO;
    239
    240	tmx.time.tv_sec = sec;
    241	tmx.time.tv_usec = usec;
    242	ret = clock_adjtime(CLOCK_REALTIME, &tmx);
    243	if (ret >= 0) {
    244		printf("Invalid (sec: %ld  usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec);
    245		printf("[FAIL]\n");
    246		return -1;
    247	}
    248	return 0;
    249}
    250
    251int validate_set_offset(void)
    252{
    253	printf("Testing ADJ_SETOFFSET... ");
    254	fflush(stdout);
    255
    256	/* Test valid values */
    257	if (set_offset(NSEC_PER_SEC - 1, 1))
    258		return -1;
    259
    260	if (set_offset(-NSEC_PER_SEC + 1, 1))
    261		return -1;
    262
    263	if (set_offset(-NSEC_PER_SEC - 1, 1))
    264		return -1;
    265
    266	if (set_offset(5 * NSEC_PER_SEC, 1))
    267		return -1;
    268
    269	if (set_offset(-5 * NSEC_PER_SEC, 1))
    270		return -1;
    271
    272	if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1))
    273		return -1;
    274
    275	if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1))
    276		return -1;
    277
    278	if (set_offset(USEC_PER_SEC - 1, 0))
    279		return -1;
    280
    281	if (set_offset(-USEC_PER_SEC + 1, 0))
    282		return -1;
    283
    284	if (set_offset(-USEC_PER_SEC - 1, 0))
    285		return -1;
    286
    287	if (set_offset(5 * USEC_PER_SEC, 0))
    288		return -1;
    289
    290	if (set_offset(-5 * USEC_PER_SEC, 0))
    291		return -1;
    292
    293	if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0))
    294		return -1;
    295
    296	if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0))
    297		return -1;
    298
    299	/* Test invalid values */
    300	if (set_bad_offset(0, -1, 1))
    301		return -1;
    302	if (set_bad_offset(0, -1, 0))
    303		return -1;
    304	if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1))
    305		return -1;
    306	if (set_bad_offset(0, 2 * USEC_PER_SEC, 0))
    307		return -1;
    308	if (set_bad_offset(0, NSEC_PER_SEC, 1))
    309		return -1;
    310	if (set_bad_offset(0, USEC_PER_SEC, 0))
    311		return -1;
    312	if (set_bad_offset(0, -NSEC_PER_SEC, 1))
    313		return -1;
    314	if (set_bad_offset(0, -USEC_PER_SEC, 0))
    315		return -1;
    316
    317	printf("[OK]\n");
    318	return 0;
    319}
    320
    321int main(int argc, char **argv)
    322{
    323	if (validate_freq())
    324		return ksft_exit_fail();
    325
    326	if (validate_set_offset())
    327		return ksft_exit_fail();
    328
    329	return ksft_exit_pass();
    330}