Commit 2e9a9725 authored by Mark Brown's avatar Mark Brown Committed by Shuah Khan
Browse files

selftests: vdso: Add a selftest for vDSO getcpu()



Provide a very basic selftest for getcpu() which similarly to our existing
test for gettimeofday() looks up the function in the vDSO and prints the
results it gets if the function exists and succeeds.

Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
parent cd76ca4d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
vdso_test
vdso_test_gettimeofday
vdso_test_getcpu
vdso_standalone_test_x86
+2 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ include ../lib.mk
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_gettimeofday
TEST_GEN_PROGS := $(OUTPUT)/vdso_test_gettimeofday $(OUTPUT)/vdso_test_getcpu
ifeq ($(ARCH),x86)
TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86
endif
@@ -18,6 +18,7 @@ endif

all: $(TEST_GEN_PROGS)
$(OUTPUT)/vdso_test_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c
$(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.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 \
+54 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * vdso_test_getcpu.c: Sample code to test parse_vdso.c and vDSO getcpu()
 *
 * Copyright (c) 2020 Arm Ltd
 */

#include <stdint.h>
#include <elf.h>
#include <stdio.h>
#include <sys/auxv.h>
#include <sys/time.h>

#include "../kselftest.h"
#include "parse_vdso.h"

const char *version = "LINUX_2.6";
const char *name = "__vdso_getcpu";

struct getcpu_cache;
typedef long (*getcpu_t)(unsigned int *, unsigned int *,
			 struct getcpu_cache *);

int main(int argc, char **argv)
{
	unsigned long sysinfo_ehdr;
	unsigned int cpu, node;
	getcpu_t get_cpu;
	long ret;

	sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
	if (!sysinfo_ehdr) {
		printf("AT_SYSINFO_EHDR is not present!\n");
		return KSFT_SKIP;
	}

	vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));

	get_cpu = (getcpu_t)vdso_sym(version, name);
	if (!get_cpu) {
		printf("Could not find %s\n", name);
		return KSFT_SKIP;
	}

	ret = get_cpu(&cpu, &node, 0);
	if (ret == 0) {
		printf("Running on CPU %u node %u\n", cpu, node);
	} else {
		printf("%s failed\n", name);
		return KSFT_FAIL;
	}

	return 0;
}