Skip to content

Commit df188cd

Browse files
ricardobranco777pevik
authored andcommitted
userfaultfd: Add test using UFFD_USER_MODE_ONLY
Signed-off-by: Ricardo Branco <rbranco@suse.de> Reviewed-by: Petr Vorel <pvorel@suse.cz> Reviewed-by: Cyril Hrubis <chrubis@suse.cz> Link: #1280
1 parent 36b915c commit df188cd

1 file changed

Lines changed: 44 additions & 14 deletions

File tree

testcases/kernel/syscalls/userfaultfd/userfaultfd01.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,38 @@
99
* from a different thread.
1010
*/
1111

12-
#include "config.h"
1312
#include <poll.h>
1413
#include "tst_test.h"
1514
#include "tst_safe_macros.h"
1615
#include "tst_safe_pthread.h"
1716
#include "lapi/userfaultfd.h"
1817

18+
#define BEFORE_5_11 1
19+
#define AFTER_5_11 2
20+
#define DESC(x) .flags = x, .desc = #x
21+
22+
static struct tcase {
23+
int flags;
24+
const char *desc;
25+
int kver;
26+
} tcases[] = {
27+
{ DESC(O_CLOEXEC | O_NONBLOCK) },
28+
{ DESC(O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY), .kver = AFTER_5_11, },
29+
};
30+
1931
static int page_size;
2032
static char *page;
2133
static void *copy_page;
2234
static int uffd;
35+
static int kver;
36+
37+
static void setup(void)
38+
{
39+
if (tst_kvercmp(5, 11, 0) >= 0)
40+
kver = AFTER_5_11;
41+
else
42+
kver = BEFORE_5_11;
43+
}
2344

2445
static void set_pages(void)
2546
{
@@ -30,10 +51,16 @@ static void set_pages(void)
3051
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
3152
}
3253

33-
static void handle_thread(void)
54+
static void reset_pages(void)
55+
{
56+
SAFE_MUNMAP(page, page_size);
57+
SAFE_MUNMAP(copy_page, page_size);
58+
}
59+
60+
static void *handle_thread(void)
3461
{
3562
static struct uffd_msg msg;
36-
struct uffdio_copy uffdio_copy;
63+
struct uffdio_copy uffdio_copy = {};
3764

3865
struct pollfd pollfd;
3966
int nready;
@@ -47,7 +74,7 @@ static void handle_thread(void)
4774
SAFE_READ(1, uffd, &msg, sizeof(msg));
4875

4976
if (msg.event != UFFD_EVENT_PAGEFAULT)
50-
tst_brk(TBROK | TERRNO, "Received unexpected UFFD_EVENT");
77+
tst_brk(TBROK | TERRNO, "Received unexpected UFFD_EVENT %d", msg.event);
5178

5279
memset(copy_page, 'X', page_size);
5380

@@ -56,25 +83,27 @@ static void handle_thread(void)
5683
uffdio_copy.dst = (unsigned long) msg.arg.pagefault.address
5784
& ~(page_size - 1);
5885
uffdio_copy.len = page_size;
59-
uffdio_copy.mode = 0;
60-
uffdio_copy.copy = 0;
6186
SAFE_IOCTL(uffd, UFFDIO_COPY, &uffdio_copy);
6287

6388
close(uffd);
89+
return NULL;
6490
}
6591

66-
static void run(void)
92+
static void run(unsigned int i)
6793
{
6894
pthread_t thr;
69-
struct uffdio_api uffdio_api;
95+
struct uffdio_api uffdio_api = {};
7096
struct uffdio_register uffdio_register;
97+
struct tcase *tc = &tcases[i];
98+
99+
if (tc->kver == AFTER_5_11 && kver == BEFORE_5_11)
100+
tst_brk(TCONF, "%s requires kernel >= 5.11", tc->desc);
71101

72102
set_pages();
73103

74-
uffd = SAFE_USERFAULTFD(O_CLOEXEC | O_NONBLOCK, false);
104+
uffd = SAFE_USERFAULTFD(tc->flags, false);
75105

76106
uffdio_api.api = UFFD_API;
77-
uffdio_api.features = 0;
78107
SAFE_IOCTL(uffd, UFFDIO_API, &uffdio_api);
79108

80109
uffdio_register.range.start = (unsigned long) page;
@@ -83,8 +112,7 @@ static void run(void)
83112

84113
SAFE_IOCTL(uffd, UFFDIO_REGISTER, &uffdio_register);
85114

86-
SAFE_PTHREAD_CREATE(&thr, NULL,
87-
(void * (*)(void *)) handle_thread, NULL);
115+
SAFE_PTHREAD_CREATE(&thr, NULL, (void *) handle_thread, NULL);
88116

89117
char c = page[0xf];
90118

@@ -94,9 +122,11 @@ static void run(void)
94122
tst_res(TFAIL, "Pagefault not handled!");
95123

96124
SAFE_PTHREAD_JOIN(thr, NULL);
125+
reset_pages();
97126
}
98127

99128
static struct tst_test test = {
100-
.test_all = run,
101-
.min_kver = "4.3",
129+
.setup = setup,
130+
.test = run,
131+
.tcnt = ARRAY_SIZE(tcases),
102132
};

0 commit comments

Comments
 (0)