162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#define _GNU_SOURCE 362306a36Sopenharmony_ci#define __EXPORTED_HEADERS__ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <stdio.h> 662306a36Sopenharmony_ci#include <stdlib.h> 762306a36Sopenharmony_ci#include <unistd.h> 862306a36Sopenharmony_ci#include <string.h> 962306a36Sopenharmony_ci#include <errno.h> 1062306a36Sopenharmony_ci#include <fcntl.h> 1162306a36Sopenharmony_ci#include <malloc.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <sys/ioctl.h> 1462306a36Sopenharmony_ci#include <sys/syscall.h> 1562306a36Sopenharmony_ci#include <linux/memfd.h> 1662306a36Sopenharmony_ci#include <linux/udmabuf.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define TEST_PREFIX "drivers/dma-buf/udmabuf" 1962306a36Sopenharmony_ci#define NUM_PAGES 4 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic int memfd_create(const char *name, unsigned int flags) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci return syscall(__NR_memfd_create, name, flags); 2462306a36Sopenharmony_ci} 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciint main(int argc, char *argv[]) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci struct udmabuf_create create; 2962306a36Sopenharmony_ci int devfd, memfd, buf, ret; 3062306a36Sopenharmony_ci off_t size; 3162306a36Sopenharmony_ci void *mem; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci devfd = open("/dev/udmabuf", O_RDWR); 3462306a36Sopenharmony_ci if (devfd < 0) { 3562306a36Sopenharmony_ci printf("%s: [skip,no-udmabuf: Unable to access DMA buffer device file]\n", 3662306a36Sopenharmony_ci TEST_PREFIX); 3762306a36Sopenharmony_ci exit(77); 3862306a36Sopenharmony_ci } 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci memfd = memfd_create("udmabuf-test", MFD_ALLOW_SEALING); 4162306a36Sopenharmony_ci if (memfd < 0) { 4262306a36Sopenharmony_ci printf("%s: [skip,no-memfd]\n", TEST_PREFIX); 4362306a36Sopenharmony_ci exit(77); 4462306a36Sopenharmony_ci } 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK); 4762306a36Sopenharmony_ci if (ret < 0) { 4862306a36Sopenharmony_ci printf("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX); 4962306a36Sopenharmony_ci exit(77); 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci size = getpagesize() * NUM_PAGES; 5462306a36Sopenharmony_ci ret = ftruncate(memfd, size); 5562306a36Sopenharmony_ci if (ret == -1) { 5662306a36Sopenharmony_ci printf("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX); 5762306a36Sopenharmony_ci exit(1); 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci memset(&create, 0, sizeof(create)); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* should fail (offset not page aligned) */ 6362306a36Sopenharmony_ci create.memfd = memfd; 6462306a36Sopenharmony_ci create.offset = getpagesize()/2; 6562306a36Sopenharmony_ci create.size = getpagesize(); 6662306a36Sopenharmony_ci buf = ioctl(devfd, UDMABUF_CREATE, &create); 6762306a36Sopenharmony_ci if (buf >= 0) { 6862306a36Sopenharmony_ci printf("%s: [FAIL,test-1]\n", TEST_PREFIX); 6962306a36Sopenharmony_ci exit(1); 7062306a36Sopenharmony_ci } 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* should fail (size not multiple of page) */ 7362306a36Sopenharmony_ci create.memfd = memfd; 7462306a36Sopenharmony_ci create.offset = 0; 7562306a36Sopenharmony_ci create.size = getpagesize()/2; 7662306a36Sopenharmony_ci buf = ioctl(devfd, UDMABUF_CREATE, &create); 7762306a36Sopenharmony_ci if (buf >= 0) { 7862306a36Sopenharmony_ci printf("%s: [FAIL,test-2]\n", TEST_PREFIX); 7962306a36Sopenharmony_ci exit(1); 8062306a36Sopenharmony_ci } 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci /* should fail (not memfd) */ 8362306a36Sopenharmony_ci create.memfd = 0; /* stdin */ 8462306a36Sopenharmony_ci create.offset = 0; 8562306a36Sopenharmony_ci create.size = size; 8662306a36Sopenharmony_ci buf = ioctl(devfd, UDMABUF_CREATE, &create); 8762306a36Sopenharmony_ci if (buf >= 0) { 8862306a36Sopenharmony_ci printf("%s: [FAIL,test-3]\n", TEST_PREFIX); 8962306a36Sopenharmony_ci exit(1); 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci /* should work */ 9362306a36Sopenharmony_ci create.memfd = memfd; 9462306a36Sopenharmony_ci create.offset = 0; 9562306a36Sopenharmony_ci create.size = size; 9662306a36Sopenharmony_ci buf = ioctl(devfd, UDMABUF_CREATE, &create); 9762306a36Sopenharmony_ci if (buf < 0) { 9862306a36Sopenharmony_ci printf("%s: [FAIL,test-4]\n", TEST_PREFIX); 9962306a36Sopenharmony_ci exit(1); 10062306a36Sopenharmony_ci } 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci fprintf(stderr, "%s: ok\n", TEST_PREFIX); 10362306a36Sopenharmony_ci close(buf); 10462306a36Sopenharmony_ci close(memfd); 10562306a36Sopenharmony_ci close(devfd); 10662306a36Sopenharmony_ci return 0; 10762306a36Sopenharmony_ci} 108