Add udmabuf misc device

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
This commit is contained in:
Gerd Hoffmann
2018-08-27 11:34:44 +02:00
orang tua b972cece94
melakukan fbb0de7950
8 mengubah file dengan 439 tambahan dan 0 penghapusan

Melihat File

@@ -0,0 +1,5 @@
CFLAGS += -I../../../../../usr/include/
TEST_GEN_PROGS := udmabuf
include ../../lib.mk

Melihat File

@@ -0,0 +1,96 @@
// 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;
}