From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87912C43613 for ; Fri, 21 Jun 2019 10:23:01 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5506620675 for ; Fri, 21 Jun 2019 10:23:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="WUjauVXj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5506620675 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WSeisEiGm/Unqr2XRBEKm8lejZXL3QZqq4s5Ds/24JI=; b=WUjauVXjIp+kwd tYOb6q3Ha+l4hJAcgtF5YC+WlzQXz7G9fF9Y3Ljnm7gF4JiCY5sxcUrr5ITZNkxeATKpfJouoNmrD B4nKgYZUjjd8LPoy3QYtDyw8iCPzJjj5t5cyfMLsqHrGJ3GwutTfhvvcZ+VZKiABIXhxPCG4FezBJ Drf3ERgt+GlVF8Io6fHzHn/T7kffDPTlctKgu4HjtH5MLU7eUADc20gp2kA0wPrWZ2PJr2Lk6V5Uv ggZouhTGgflySvX5IrSBCLzRJ/6BZG8FqqF7nIV4v10TkJs+KK7ht+ZMdYVEQv5pd0BKf8khdVPj2 1k6vp6n2FvRB6cYZQViw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1heGh7-0002w1-M5; Fri, 21 Jun 2019 10:22:57 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1heGFN-0004bB-D4 for linux-arm-kernel@lists.infradead.org; Fri, 21 Jun 2019 09:54:20 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EABCC14F6; Fri, 21 Jun 2019 02:54:16 -0700 (PDT) Received: from e119884-lin.cambridge.arm.com (e119884-lin.cambridge.arm.com [10.1.196.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 609CB3F246; Fri, 21 Jun 2019 02:54:14 -0700 (PDT) From: Vincenzo Frascino To: linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v7 25/25] kselftest: Extend vDSO selftest Date: Fri, 21 Jun 2019 10:52:52 +0100 Message-Id: <20190621095252.32307-26-vincenzo.frascino@arm.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190621095252.32307-1-vincenzo.frascino@arm.com> References: <20190621095252.32307-1-vincenzo.frascino@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190621_025417_604516_F4DBB22B X-CRM114-Status: GOOD ( 17.66 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Shuah Khan , Andre Przywara , Arnd Bergmann , Huw Davies , Catalin Marinas , Daniel Lezcano , Will Deacon , Russell King , Ralf Baechle , Mark Salyzyn , Paul Burton , Dmitry Safonov <0x7f454c46@gmail.com>, Rasmus Villemoes , Thomas Gleixner , Shijith Thotton , Peter Collingbourne Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org The current version of the multiarch vDSO selftest verifies only gettimeofday. Extend the vDSO selftest to the other library functions: - time - clock_getres - clock_gettime The extension has been used to verify the unified vdso library on the supported architectures. Cc: Shuah Khan Signed-off-by: Vincenzo Frascino --- tools/testing/selftests/vDSO/Makefile | 2 + tools/testing/selftests/vDSO/vdso_config.h | 90 +++++++ tools/testing/selftests/vDSO/vdso_full_test.c | 244 ++++++++++++++++++ 3 files changed, 336 insertions(+) create mode 100644 tools/testing/selftests/vDSO/vdso_config.h create mode 100644 tools/testing/selftests/vDSO/vdso_full_test.c diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile index 9e03d61f52fd..68e9b4a1cdcf 100644 --- a/tools/testing/selftests/vDSO/Makefile +++ b/tools/testing/selftests/vDSO/Makefile @@ -5,6 +5,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) TEST_GEN_PROGS := $(OUTPUT)/vdso_test +TEST_GEN_PROGS += $(OUTPUT)/vdso_full_test ifeq ($(ARCH),x86) TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86 endif @@ -18,6 +19,7 @@ endif all: $(TEST_GEN_PROGS) $(OUTPUT)/vdso_test: parse_vdso.c vdso_test.c +$(OUTPUT)/vdso_full_test: parse_vdso.c vdso_full_test.c $(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c $(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \ vdso_standalone_test_x86.c parse_vdso.c \ diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h new file mode 100644 index 000000000000..eeb725df6045 --- /dev/null +++ b/tools/testing/selftests/vDSO/vdso_config.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * vdso_config.h: Configuration options for vDSO tests. + * Copyright (c) 2019 Arm Ltd. + */ +#ifndef __VDSO_CONFIG_H__ +#define __VDSO_CONFIG_H__ + +/* + * Each architecture exports its vDSO implementation with different names + * and a different version from the others, so we need to handle it as a + * special case. + */ +#if defined(__arm__) +#define VDSO_VERSION 0 +#define VDSO_NAMES 1 +#define VDSO_32BIT 1 +#elif defined(__aarch64__) +#define VDSO_VERSION 3 +#define VDSO_NAMES 0 +#elif defined(__powerpc__) +#define VDSO_VERSION 1 +#define VDSO_NAMES 0 +#define VDSO_32BIT 1 +#elif defined(__powerpc64__) +#define VDSO_VERSION 1 +#define VDSO_NAMES 0 +#elif defined (__s390__) +#define VDSO_VERSION 2 +#define VDSO_NAMES 0 +#define VDSO_32BIT 1 +#elif defined (__s390X__) +#define VDSO_VERSION 2 +#define VDSO_NAMES 0 +#elif defined(__mips__) +#define VDSO_VERSION 0 +#define VDSO_NAMES 1 +#define VDSO_32BIT 1 +#elif defined(__sparc__) +#define VDSO_VERSION 0 +#define VDSO_NAMES 1 +#define VDSO_32BIT 1 +#elif defined(__i386__) +#define VDSO_VERSION 0 +#define VDSO_NAMES 1 +#define VDSO_32BIT 1 +#elif defined(__x86_64__) +#define VDSO_VERSION 0 +#define VDSO_NAMES 1 +#elif defined(__riscv__) +#define VDSO_VERSION 5 +#define VDSO_NAMES 1 +#define VDSO_32BIT 1 +#else /* nds32 */ +#define VDSO_VERSION 4 +#define VDSO_NAMES 1 +#define VDSO_32BIT 1 +#endif + +static const char *versions[6] = { + "LINUX_2.6", + "LINUX_2.6.15", + "LINUX_2.6.29", + "LINUX_2.6.39", + "LINUX_4", + "LINUX_4.15", +}; + +static const char *names[2][5] = { + { + "__kernel_gettimeofday", + "__kernel_clock_gettime", + "__kernel_time", + "__kernel_clock_getres", +#if defined(VDSO_32BIT) + "__kernel_clock_gettime64", +#endif + }, + { + "__vdso_gettimeofday", + "__vdso_clock_gettime", + "__vdso_time", + "__vdso_clock_getres", +#if defined(VDSO_32BIT) + "__vdso_clock_gettime64", +#endif + }, +}; + +#endif /* __VDSO_CONFIG_H__ */ diff --git a/tools/testing/selftests/vDSO/vdso_full_test.c b/tools/testing/selftests/vDSO/vdso_full_test.c new file mode 100644 index 000000000000..3d603f1394af --- /dev/null +++ b/tools/testing/selftests/vDSO/vdso_full_test.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * vdso_full_test.c: Sample code to test all the timers. + * Copyright (c) 2019 Arm Ltd. + * + * Compile with: + * gcc -std=gnu99 vdso_full_test.c parse_vdso.c + * + */ + +#include +#include +#include +#include +#include +#include +#define _GNU_SOURCE +#include +#include + +#include "../kselftest.h" +#include "vdso_config.h" + +extern void *vdso_sym(const char *version, const char *name); +extern void vdso_init_from_sysinfo_ehdr(uintptr_t base); +extern void vdso_init_from_auxv(void *auxv); + +static const char *version; +static const char **name; + +typedef long (*vdso_gettimeofday_t)(struct timeval *tv, struct timezone *tz); +typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts); +typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts); +typedef time_t (*vdso_time_t)(time_t *t); + +static int vdso_test_gettimeofday(void) +{ + /* Find gettimeofday. */ + vdso_gettimeofday_t vdso_gettimeofday = + (vdso_gettimeofday_t)vdso_sym(version, name[0]); + + if (!vdso_gettimeofday) { + printf("Could not find %s\n", name[0]); + return KSFT_SKIP; + } + + struct timeval tv; + long ret = vdso_gettimeofday(&tv, 0); + + if (ret == 0) { + printf("The time is %lld.%06lld\n", + (long long)tv.tv_sec, (long long)tv.tv_usec); + } else { + printf("%s failed\n", name[0]); + return KSFT_FAIL; + } + + return KSFT_PASS; +} + +static int vdso_test_clock_gettime(clockid_t clk_id) +{ + /* Find clock_gettime. */ + vdso_clock_gettime_t vdso_clock_gettime = + (vdso_clock_gettime_t)vdso_sym(version, name[1]); + + if (!vdso_clock_gettime) { + printf("Could not find %s\n", name[1]); + return KSFT_SKIP; + } + + struct timespec ts; + long ret = vdso_clock_gettime(clk_id, &ts); + + if (ret == 0) { + printf("The time is %lld.%06lld\n", + (long long)ts.tv_sec, (long long)ts.tv_nsec); + } else { + printf("%s failed\n", name[1]); + return KSFT_FAIL; + } + + return KSFT_PASS; +} + +static int vdso_test_time(void) +{ + /* Find time. */ + vdso_time_t vdso_time = + (vdso_time_t)vdso_sym(version, name[2]); + + if (!vdso_time) { + printf("Could not find %s\n", name[2]); + return KSFT_SKIP; + } + + long ret = vdso_time(NULL); + + if (ret > 0) { + printf("The time in hours since January 1, 1970 is %lld\n", + (long long)(ret / 3600)); + } else { + printf("%s failed\n", name[2]); + return KSFT_FAIL; + } + + return KSFT_PASS; +} + +static int vdso_test_clock_getres(clockid_t clk_id) +{ + /* Find clock_getres. */ + vdso_clock_getres_t vdso_clock_getres = + (vdso_clock_getres_t)vdso_sym(version, name[3]); + + if (!vdso_clock_getres) { + printf("Could not find %s\n", name[3]); + return KSFT_SKIP; + } + + struct timespec ts, sys_ts; + long ret = vdso_clock_getres(clk_id, &ts); + + if (ret == 0) { + printf("The resolution is %lld %lld\n", + (long long)ts.tv_sec, (long long)ts.tv_nsec); + } else { + printf("%s failed\n", name[3]); + return KSFT_FAIL; + } + + ret = syscall(SYS_clock_getres, clk_id, &sys_ts); + + if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec)) { + printf("%s failed\n", name[3]); + return KSFT_FAIL; + } + + return KSFT_PASS; +} + +const char *vdso_clock_name[12] = { + "CLOCK_REALTIME", + "CLOCK_MONOTONIC", + "CLOCK_PROCESS_CPUTIME_ID", + "CLOCK_THREAD_CPUTIME_ID", + "CLOCK_MONOTONIC_RAW", + "CLOCK_REALTIME_COARSE", + "CLOCK_MONOTONIC_COARSE", + "CLOCK_BOOTTIME", + "CLOCK_REALTIME_ALARM", + "CLOCK_BOOTTIME_ALARM", + "CLOCK_SGI_CYCLE", + "CLOCK_TAI", +}; + +/* + * This function calls vdso_test_clock_gettime and vdso_test_clock_getres + * with different values for clock_id. + */ +static inline int vdso_test_clock(clockid_t clock_id) +{ + int ret0, ret1; + + ret0 = vdso_test_clock_gettime(clock_id); + /* A skipped test is considered passed */ + if (ret0 == KSFT_SKIP) + ret0 = KSFT_PASS; + + ret1 = vdso_test_clock_getres(clock_id); + /* A skipped test is considered passed */ + if (ret1 == KSFT_SKIP) + ret1 = KSFT_PASS; + + ret0 += ret1; + + printf("clock_id: %s", vdso_clock_name[clock_id]); + + if (ret0 > 0) + printf(" [FAIL]\n"); + else + printf(" [PASS]\n"); + + return ret0; +} + +int main(int argc, char **argv) +{ + unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); + int ret; + + if (!sysinfo_ehdr) { + printf("AT_SYSINFO_EHDR is not present!\n"); + return KSFT_SKIP; + } + + version = versions[VDSO_VERSION]; + name = (const char **)&names[VDSO_NAMES]; + + printf("[vDSO kselftest] VDSO_VERSION: %s\n", version); + + vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR)); + + ret = vdso_test_gettimeofday(); + +#if _POSIX_TIMERS > 0 + +#ifdef CLOCK_REALTIME + ret += vdso_test_clock(CLOCK_REALTIME); +#endif + +#ifdef CLOCK_BOOTTIME + ret += vdso_test_clock(CLOCK_BOOTTIME); +#endif + +#ifdef CLOCK_TAI + ret += vdso_test_clock(CLOCK_TAI); +#endif + +#ifdef CLOCK_REALTIME_COARSE + ret += vdso_test_clock(CLOCK_REALTIME_COARSE); +#endif + +#ifdef CLOCK_MONOTONIC + ret += vdso_test_clock(CLOCK_MONOTONIC); +#endif + +#ifdef CLOCK_MONOTONIC_RAW + ret += vdso_test_clock(CLOCK_MONOTONIC_RAW); +#endif + +#ifdef CLOCK_MONOTONIC_COARSE + ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE); +#endif + +#endif + + ret += vdso_test_time(); + + if (ret > 0) + return KSFT_FAIL; + + return KSFT_PASS; +} -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel