mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 00:54:09 +08:00
fbb0de7950
A driver to let userspace turn memfd regions into dma-bufs. Use case: Allows qemu create dmabufs for the vga framebuffer or virtio-gpu ressources. Then they can be passed around to display those guest things on the host. To spice client for classic full framebuffer display, and hopefully some day to wayland server for seamless guest window display. qemu test branch: https://git.kraxel.org/cgit/qemu/log/?h=sirius/udmabuf Cc: David Airlie <airlied@linux.ie> Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Daniel Vetter <daniel@ffwll.ch> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/20180827093444.23623-1-kraxel@redhat.com
97 lines
2.0 KiB
C
97 lines
2.0 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <malloc.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
#include <sys/syscall.h>
|
|
#include <linux/memfd.h>
|
|
#include <linux/udmabuf.h>
|
|
|
|
#define TEST_PREFIX "drivers/dma-buf/udmabuf"
|
|
#define NUM_PAGES 4
|
|
|
|
static int memfd_create(const char *name, unsigned int flags)
|
|
{
|
|
return syscall(__NR_memfd_create, name, flags);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
struct udmabuf_create create;
|
|
int devfd, memfd, buf, ret;
|
|
off_t size;
|
|
void *mem;
|
|
|
|
devfd = open("/dev/udmabuf", O_RDWR);
|
|
if (devfd < 0) {
|
|
printf("%s: [skip,no-udmabuf]\n", TEST_PREFIX);
|
|
exit(77);
|
|
}
|
|
|
|
memfd = memfd_create("udmabuf-test", MFD_CLOEXEC);
|
|
if (memfd < 0) {
|
|
printf("%s: [skip,no-memfd]\n", TEST_PREFIX);
|
|
exit(77);
|
|
}
|
|
|
|
size = getpagesize() * NUM_PAGES;
|
|
ret = ftruncate(memfd, size);
|
|
if (ret == -1) {
|
|
printf("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX);
|
|
exit(1);
|
|
}
|
|
|
|
memset(&create, 0, sizeof(create));
|
|
|
|
/* should fail (offset not page aligned) */
|
|
create.memfd = memfd;
|
|
create.offset = getpagesize()/2;
|
|
create.size = getpagesize();
|
|
buf = ioctl(devfd, UDMABUF_CREATE, &create);
|
|
if (buf >= 0) {
|
|
printf("%s: [FAIL,test-1]\n", TEST_PREFIX);
|
|
exit(1);
|
|
}
|
|
|
|
/* should fail (size not multiple of page) */
|
|
create.memfd = memfd;
|
|
create.offset = 0;
|
|
create.size = getpagesize()/2;
|
|
buf = ioctl(devfd, UDMABUF_CREATE, &create);
|
|
if (buf >= 0) {
|
|
printf("%s: [FAIL,test-2]\n", TEST_PREFIX);
|
|
exit(1);
|
|
}
|
|
|
|
/* should fail (not memfd) */
|
|
create.memfd = 0; /* stdin */
|
|
create.offset = 0;
|
|
create.size = size;
|
|
buf = ioctl(devfd, UDMABUF_CREATE, &create);
|
|
if (buf >= 0) {
|
|
printf("%s: [FAIL,test-3]\n", TEST_PREFIX);
|
|
exit(1);
|
|
}
|
|
|
|
/* should work */
|
|
create.memfd = memfd;
|
|
create.offset = 0;
|
|
create.size = size;
|
|
buf = ioctl(devfd, UDMABUF_CREATE, &create);
|
|
if (buf < 0) {
|
|
printf("%s: [FAIL,test-4]\n", TEST_PREFIX);
|
|
exit(1);
|
|
}
|
|
|
|
fprintf(stderr, "%s: ok\n", TEST_PREFIX);
|
|
close(buf);
|
|
close(memfd);
|
|
close(devfd);
|
|
return 0;
|
|
}
|