diff options
Diffstat (limited to 'tools/testing/selftests/x86/test_vdso.c')
| -rw-r--r-- | tools/testing/selftests/x86/test_vdso.c | 55 | 
1 files changed, 48 insertions, 7 deletions
| diff --git a/tools/testing/selftests/x86/test_vdso.c b/tools/testing/selftests/x86/test_vdso.c index 29973cde06d3..235259011704 100644 --- a/tools/testing/selftests/x86/test_vdso.c +++ b/tools/testing/selftests/x86/test_vdso.c @@ -26,20 +26,59 @@  # endif  #endif +/* max length of lines in /proc/self/maps - anything longer is skipped here */ +#define MAPS_LINE_LEN 128 +  int nerrs = 0; +typedef long (*getcpu_t)(unsigned *, unsigned *, void *); + +getcpu_t vgetcpu; +getcpu_t vdso_getcpu; + +static void *vsyscall_getcpu(void) +{  #ifdef __x86_64__ -# define VSYS(x) (x) +	FILE *maps; +	char line[MAPS_LINE_LEN]; +	bool found = false; + +	maps = fopen("/proc/self/maps", "r"); +	if (!maps) /* might still be present, but ignore it here, as we test vDSO not vsyscall */ +		return NULL; + +	while (fgets(line, MAPS_LINE_LEN, maps)) { +		char r, x; +		void *start, *end; +		char name[MAPS_LINE_LEN]; + +		/* sscanf() is safe here as strlen(name) >= strlen(line) */ +		if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s", +			   &start, &end, &r, &x, name) != 5) +			continue; + +		if (strcmp(name, "[vsyscall]")) +			continue; + +		/* assume entries are OK, as we test vDSO here not vsyscall */ +		found = true; +		break; +	} + +	fclose(maps); + +	if (!found) { +		printf("Warning: failed to find vsyscall getcpu\n"); +		return NULL; +	} +	return (void *) (0xffffffffff600800);  #else -# define VSYS(x) 0 +	return NULL;  #endif +} -typedef long (*getcpu_t)(unsigned *, unsigned *, void *); - -const getcpu_t vgetcpu = (getcpu_t)VSYS(0xffffffffff600800); -getcpu_t vdso_getcpu; -void fill_function_pointers() +static void fill_function_pointers()  {  	void *vdso = dlopen("linux-vdso.so.1",  			    RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); @@ -54,6 +93,8 @@ void fill_function_pointers()  	vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");  	if (!vdso_getcpu)  		printf("Warning: failed to find getcpu in vDSO\n"); + +	vgetcpu = (getcpu_t) vsyscall_getcpu();  }  static long sys_getcpu(unsigned * cpu, unsigned * node, |