1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #define _GNU_SOURCE |
3 | #define |
4 | |
5 | #include <stdio.h> |
6 | #include <stdlib.h> |
7 | #include <unistd.h> |
8 | #include <string.h> |
9 | #include <errno.h> |
10 | #include <fcntl.h> |
11 | #include <malloc.h> |
12 | |
13 | #include <sys/ioctl.h> |
14 | #include <sys/syscall.h> |
15 | #include <linux/memfd.h> |
16 | #include <linux/udmabuf.h> |
17 | |
18 | #define TEST_PREFIX "drivers/dma-buf/udmabuf" |
19 | #define NUM_PAGES 4 |
20 | |
21 | static int memfd_create(const char *name, unsigned int flags) |
22 | { |
23 | return syscall(__NR_memfd_create, name, flags); |
24 | } |
25 | |
26 | int main(int argc, char *argv[]) |
27 | { |
28 | struct udmabuf_create create; |
29 | int devfd, memfd, buf, ret; |
30 | off_t size; |
31 | void *mem; |
32 | |
33 | devfd = open("/dev/udmabuf" , O_RDWR); |
34 | if (devfd < 0) { |
35 | printf("%s: [skip,no-udmabuf: Unable to access DMA buffer device file]\n" , |
36 | TEST_PREFIX); |
37 | exit(77); |
38 | } |
39 | |
40 | memfd = memfd_create(name: "udmabuf-test" , flags: MFD_ALLOW_SEALING); |
41 | if (memfd < 0) { |
42 | printf("%s: [skip,no-memfd]\n" , TEST_PREFIX); |
43 | exit(77); |
44 | } |
45 | |
46 | ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK); |
47 | if (ret < 0) { |
48 | printf("%s: [skip,fcntl-add-seals]\n" , TEST_PREFIX); |
49 | exit(77); |
50 | } |
51 | |
52 | |
53 | size = getpagesize() * NUM_PAGES; |
54 | ret = ftruncate(memfd, size); |
55 | if (ret == -1) { |
56 | printf("%s: [FAIL,memfd-truncate]\n" , TEST_PREFIX); |
57 | exit(1); |
58 | } |
59 | |
60 | memset(&create, 0, sizeof(create)); |
61 | |
62 | /* should fail (offset not page aligned) */ |
63 | create.memfd = memfd; |
64 | create.offset = getpagesize()/2; |
65 | create.size = getpagesize(); |
66 | buf = ioctl(devfd, UDMABUF_CREATE, &create); |
67 | if (buf >= 0) { |
68 | printf("%s: [FAIL,test-1]\n" , TEST_PREFIX); |
69 | exit(1); |
70 | } |
71 | |
72 | /* should fail (size not multiple of page) */ |
73 | create.memfd = memfd; |
74 | create.offset = 0; |
75 | create.size = getpagesize()/2; |
76 | buf = ioctl(devfd, UDMABUF_CREATE, &create); |
77 | if (buf >= 0) { |
78 | printf("%s: [FAIL,test-2]\n" , TEST_PREFIX); |
79 | exit(1); |
80 | } |
81 | |
82 | /* should fail (not memfd) */ |
83 | create.memfd = 0; /* stdin */ |
84 | create.offset = 0; |
85 | create.size = size; |
86 | buf = ioctl(devfd, UDMABUF_CREATE, &create); |
87 | if (buf >= 0) { |
88 | printf("%s: [FAIL,test-3]\n" , TEST_PREFIX); |
89 | exit(1); |
90 | } |
91 | |
92 | /* should work */ |
93 | create.memfd = memfd; |
94 | create.offset = 0; |
95 | create.size = size; |
96 | buf = ioctl(devfd, UDMABUF_CREATE, &create); |
97 | if (buf < 0) { |
98 | printf("%s: [FAIL,test-4]\n" , TEST_PREFIX); |
99 | exit(1); |
100 | } |
101 | |
102 | fprintf(stderr, "%s: ok\n" , TEST_PREFIX); |
103 | close(buf); |
104 | close(memfd); |
105 | close(devfd); |
106 | return 0; |
107 | } |
108 | |