Skip to content

Commit 6786dbd

Browse files
alessandrocarminatihaxtibal
authored andcommitted
selftests/devmem: initial testset
This patch introduces a new series of tests for devmem. Test cases are mapped against the tested Function's expectations defined in /drivers/char/mem.c. Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
1 parent ae11e20 commit 6786dbd

13 files changed

Lines changed: 1712 additions & 0 deletions

File tree

tools/testing/selftests/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ TARGETS += cpu-hotplug
1616
TARGETS += damon
1717
TARGETS += devices/error_logs
1818
TARGETS += devices/probe
19+
TARGETS += devmem/devmem
1920
TARGETS += dmabuf-heaps
2021
TARGETS += drivers/dma-buf
2122
TARGETS += drivers/ntsync
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
# Kselftest Makefile for devmem test
3+
4+
CFLAGS += -Wall -O2
5+
6+
TEST_GEN_PROGS_EXTENDED := devmem
7+
8+
$(OUTPUT)/devmem: devmem.c $(OUTPUT)/ram_map.o $(OUTPUT)/secret.o $(OUTPUT)/tests.o $(OUTPUT)/utils.o $(OUTPUT)/debug.o
9+
$(CC) $^ -o $@ $(CFLAGS)
10+
11+
EXTRA_CLEAN += $(OUTPUT)/ram_map.o $(OUTPUT)/secret.o $(OUTPUT)/tests.o $(OUTPUT)/utils.o $(OUTPUT)/debug.o
12+
13+
include ../lib.mk
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* devmem test debug.c
4+
*
5+
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
6+
* Written by Alessandro Carminati (acarmina@redhat.com)
7+
*/
8+
9+
#include <stdio.h>
10+
#include <stdarg.h>
11+
12+
#define DEBUG_FLAG 0
13+
int pdebug = DEBUG_FLAG;
14+
15+
void deb_printf(const char *fmt, ...)
16+
{
17+
va_list args;
18+
19+
if (pdebug) {
20+
va_start(args, fmt);
21+
vprintf(fmt, args);
22+
va_end(args);
23+
}
24+
}
25+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: GPL-2.0+ */
2+
/*
3+
* devmem test debug.h
4+
*
5+
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
6+
* Written by Alessandro Carminati (acarmina@redhat.com)
7+
*/
8+
9+
#ifndef DEBUG_H
10+
#define DEBUG_H
11+
extern int pdebug;
12+
void deb_printf(const char *fmt, ...);
13+
#endif
14+
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/* devmem test devmem.c
3+
*
4+
* Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
5+
* Written by Alessandro Carminati (acarmina@redhat.com)
6+
*/
7+
8+
#define _GNU_SOURCE
9+
10+
#include <stdbool.h>
11+
#include <stddef.h>
12+
#include <stdint.h>
13+
#include <stdio.h>
14+
#include <stdlib.h>
15+
#include <string.h>
16+
#include <unistd.h>
17+
18+
#include "utils.h"
19+
#include "secret.h"
20+
#include "debug.h"
21+
#include "ram_map.h"
22+
#include "tests.h"
23+
#include "debug.h"
24+
#include "../kselftest.h"
25+
26+
struct char_mem_test test_set[] = {
27+
{
28+
"test_devmem_access",
29+
&test_devmem_access,
30+
"Test whether /dev/mem is accessible - memory_open FE_1, FE_2, FE_4",
31+
F_ARCH_ALL|F_BITS_ALL|F_MISC_FATAL|F_MISC_INIT_PRV
32+
},
33+
{ "test_open_devnum",
34+
&test_open_devnum,
35+
"Test open /dev/mem provides the correct min, maj - memory_open - FE_3",
36+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ},
37+
{
38+
"test_strict_devmem",
39+
&test_strict_devmem,
40+
"Test Strict Devmem enabled - Dependency",
41+
F_ARCH_ALL|F_BITS_ALL|F_MISC_STRICT_DEVMEM_PRV|F_MISC_DONT_CARE
42+
},
43+
{
44+
"test_read_at_addr_32bit_ge",
45+
&test_read_at_addr_32bit_ge,
46+
"Test read 64bit ppos vs 32 bit addr - read_mem - FE_1",
47+
F_ARCH_ALL|F_BITS_B32|F_MISC_INIT_REQ
48+
},
49+
{
50+
"test_read_outside_linear_map",
51+
&test_read_outside_linear_map,
52+
"Test read outside linear map - read_mem - FE_2",
53+
F_ARCH_ALL|F_BITS_B32|F_MISC_INIT_REQ
54+
},
55+
{
56+
"test_read_secret_area",
57+
&test_read_secret_area,
58+
"Test read memfd_secret area can not being accessed - read_mem - FE_4",
59+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ
60+
},
61+
{
62+
"test_read_allowed_area",
63+
&test_read_allowed_area,
64+
"test read allowed area - read_mem - FE_5",
65+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ
66+
},
67+
{
68+
"test_read_allowed_area_ppos_advance",
69+
&test_read_allowed_area_ppos_advance,
70+
"test read allowed area increments ppos - read_mem - FE_3",
71+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ
72+
},
73+
{
74+
"test_read_restricted_area",
75+
&test_read_restricted_area,
76+
"test read restricted returns zeros - read_mem - FE_6",
77+
F_ARCH_X86|F_BITS_ALL|F_MISC_INIT_REQ|F_MISC_STRICT_DEVMEM_REQ
78+
},
79+
{
80+
"test_write_outside_area",
81+
&test_write_outside_area,
82+
"test write outside - write_mem - FE_2",
83+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ|F_MISC_WARN_ON_FAILURE
84+
},
85+
{
86+
"test_seek_seek_set",
87+
&test_seek_seek_set,
88+
"test seek funcction SEEK_SET - memory_lseek - FE_4",
89+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ
90+
},
91+
{
92+
"test_seek_seek_cur",
93+
&test_seek_seek_cur,
94+
"test seek function SEEK_CUR - memory_lseek - FE_3",
95+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ
96+
},
97+
{
98+
"test_seek_seek_other",
99+
&test_seek_seek_other,
100+
"test seek function SEEK_END other - memory_lseek - FE_5",
101+
F_ARCH_ALL|F_BITS_ALL|F_MISC_INIT_REQ
102+
},
103+
};
104+
105+
int main(int argc, char *argv[])
106+
{
107+
int tests_skipped = 0;
108+
int tests_failed = 0;
109+
int tests_passed = 0;
110+
int i, tmp_res;
111+
struct test_context t;
112+
char *str_res, *str_warn;
113+
struct char_mem_test *current;
114+
115+
t.srcbuf = malloc_pb(BOUNCE_BUF_SIZE);
116+
t.dstbuf = malloc_pb(BOUNCE_BUF_SIZE);
117+
if (!t.srcbuf || !t.dstbuf) {
118+
printf("can't allocate buffers!\n");
119+
exit(-1);
120+
}
121+
// seet verbose flag from cmdline
122+
t.verbose = false;
123+
if ((argc >= 2) && (!strcmp(argv[1], "-v"))) {
124+
t.verbose = true;
125+
pdebug = 1;
126+
}
127+
128+
t.map = parse_iomem();
129+
if (!t.map)
130+
goto exit;
131+
132+
if (t.verbose) {
133+
report_physical_memory(t.map);
134+
dump_ram_map(t.map);
135+
}
136+
137+
for (i = 0; i < ARRAY_SIZE(test_set); i++) {
138+
str_warn = NO_WARN_STR;
139+
current = test_set + i;
140+
tmp_res = test_needed(&t, current);
141+
switch (tmp_res) {
142+
case TEST_INCOHERENT:
143+
deb_printf("Incoherent sequence Detected\n");
144+
exit(-1);
145+
break;
146+
case TEST_ALLOWED:
147+
deb_printf("allowed sequence Detected\n");
148+
str_res = "";
149+
printf("%s - (%s) ", current->name, current->descr);
150+
tmp_res = current->fn(&t);
151+
switch (tmp_res) {
152+
case FAIL:
153+
str_res = DC_STR;
154+
if (!(current->flags & F_MISC_DONT_CARE)) {
155+
str_res = KO_STR;
156+
tests_failed++;
157+
}
158+
break;
159+
case SKIPPED:
160+
tests_skipped++;
161+
str_res = SKP_STR;
162+
if (current->flags & F_MISC_WARN_ON_FAILURE)
163+
str_warn = WARN_STR;
164+
break;
165+
case PASS:
166+
str_res = DC_STR;
167+
if (!(current->flags & F_MISC_DONT_CARE)) {
168+
tests_passed++;
169+
str_res = OK_STR;
170+
}
171+
if (current->flags & F_MISC_WARN_ON_SUCCESS)
172+
str_warn = WARN_STR;
173+
break;
174+
default:
175+
tests_failed++;
176+
printf("corrupted data\n");
177+
exit(-1);
178+
}
179+
ksft_print_msg("%s %s\n", str_res, str_warn);
180+
if ((tmp_res == FAIL) &&
181+
(current->flags & F_MISC_FATAL)) {
182+
printf("fatal test failed end the chain\n");
183+
goto cleanup;
184+
}
185+
case TEST_DENIED:
186+
deb_printf("denied sequence Detected\n");
187+
}
188+
}
189+
190+
cleanup:
191+
close(t.fd);
192+
free_ram_map(t.map);
193+
free_pb(t.srcbuf);
194+
free_pb(t.dstbuf);
195+
exit:
196+
printf("Run tests = %d (passed=%d, skipped=%d failed=%d)\n",
197+
tests_skipped+tests_failed+tests_passed, tests_passed,
198+
tests_skipped, tests_failed);
199+
return tests_skipped+tests_failed;
200+
}

0 commit comments

Comments
 (0)