Clean up includes so that osdep.h is included first and headers
which it implies are not included manually.
This commit was created with scripts/clean-includes, with the changes
to the following files manually reverted:
    contrib/libvhost-user/libvhost-user-glib.h
    contrib/libvhost-user/libvhost-user.c
    contrib/libvhost-user/libvhost-user.h
    contrib/plugins/hotblocks.c
    contrib/plugins/hotpages.c
    contrib/plugins/howvec.c
    contrib/plugins/lockstep.c
    linux-user/mips64/cpu_loop.c
    linux-user/mips64/signal.c
    linux-user/sparc64/cpu_loop.c
    linux-user/sparc64/signal.c
    linux-user/x86_64/cpu_loop.c
    linux-user/x86_64/signal.c
    target/s390x/gen-features.c
    tests/fp/platform.h
    tests/migration/s390x/a-b-bios.c
    tests/plugin/bb.c
    tests/plugin/empty.c
    tests/plugin/insn.c
    tests/plugin/mem.c
    tests/test-rcu-simpleq.c
    tests/test-rcu-slist.c
    tests/test-rcu-tailq.c
    tests/uefi-test-tools/UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.c
contrib/plugins/, tests/plugin/, and tests/test-rcu-slist.c appear not
to include osdep.h intentionally.  The remaining reverts are the same
as in commit bbfff19688d.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20201113061216.2483385-1-armbru@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Acked-by: Alexander Bulekov <alxndr@bu.edu>
		
	
			
		
			
				
	
	
		
			330 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			330 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Virtio vhost-user GPU Device
 | 
						|
 *
 | 
						|
 * DRM helpers
 | 
						|
 *
 | 
						|
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 | 
						|
 * See the COPYING file in the top-level directory.
 | 
						|
 */
 | 
						|
 | 
						|
#include "qemu/osdep.h"
 | 
						|
#include "vugbm.h"
 | 
						|
 | 
						|
static bool
 | 
						|
mem_alloc_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    buf->mmap = g_malloc(buf->width * buf->height * 4);
 | 
						|
    buf->stride = buf->width * 4;
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mem_free_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    g_free(buf->mmap);
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
mem_map_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    return buf->mmap != NULL;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mem_unmap_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
mem_device_destroy(struct vugbm_device *dev)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
#ifdef CONFIG_MEMFD
 | 
						|
struct udmabuf_create {
 | 
						|
        uint32_t memfd;
 | 
						|
        uint32_t flags;
 | 
						|
        uint64_t offset;
 | 
						|
        uint64_t size;
 | 
						|
};
 | 
						|
 | 
						|
#define UDMABUF_CREATE _IOW('u', 0x42, struct udmabuf_create)
 | 
						|
 | 
						|
static size_t
 | 
						|
udmabuf_get_size(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    return ROUND_UP(buf->width * buf->height * 4, qemu_real_host_page_size);
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
udmabuf_alloc_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    buf->memfd = memfd_create("udmabuf-bo", MFD_ALLOW_SEALING);
 | 
						|
    if (buf->memfd < 0) {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = ftruncate(buf->memfd, udmabuf_get_size(buf));
 | 
						|
    if (ret < 0) {
 | 
						|
        close(buf->memfd);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    ret = fcntl(buf->memfd, F_ADD_SEALS, F_SEAL_SHRINK);
 | 
						|
    if (ret < 0) {
 | 
						|
        close(buf->memfd);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    buf->stride = buf->width * 4;
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
udmabuf_free_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    close(buf->memfd);
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
udmabuf_map_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    buf->mmap = mmap(NULL, udmabuf_get_size(buf),
 | 
						|
                     PROT_READ | PROT_WRITE, MAP_SHARED, buf->memfd, 0);
 | 
						|
    if (buf->mmap == MAP_FAILED) {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
udmabuf_get_fd(struct vugbm_buffer *buf, int *fd)
 | 
						|
{
 | 
						|
    struct udmabuf_create create = {
 | 
						|
        .memfd = buf->memfd,
 | 
						|
        .offset = 0,
 | 
						|
        .size = udmabuf_get_size(buf),
 | 
						|
    };
 | 
						|
 | 
						|
    *fd = ioctl(buf->dev->fd, UDMABUF_CREATE, &create);
 | 
						|
 | 
						|
    return *fd >= 0;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
udmabuf_unmap_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    munmap(buf->mmap, udmabuf_get_size(buf));
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
udmabuf_device_destroy(struct vugbm_device *dev)
 | 
						|
{
 | 
						|
    close(dev->fd);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef CONFIG_GBM
 | 
						|
static bool
 | 
						|
alloc_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    struct gbm_device *dev = buf->dev->dev;
 | 
						|
 | 
						|
    assert(!buf->bo);
 | 
						|
 | 
						|
    buf->bo = gbm_bo_create(dev, buf->width, buf->height,
 | 
						|
                            buf->format,
 | 
						|
                            GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR);
 | 
						|
 | 
						|
    if (buf->bo) {
 | 
						|
        buf->stride = gbm_bo_get_stride(buf->bo);
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
free_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    gbm_bo_destroy(buf->bo);
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
map_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    uint32_t stride;
 | 
						|
 | 
						|
    buf->mmap = gbm_bo_map(buf->bo, 0, 0, buf->width, buf->height,
 | 
						|
                           GBM_BO_TRANSFER_READ_WRITE, &stride,
 | 
						|
                           &buf->mmap_data);
 | 
						|
 | 
						|
    assert(stride == buf->stride);
 | 
						|
 | 
						|
    return buf->mmap != NULL;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
unmap_bo(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    gbm_bo_unmap(buf->bo, buf->mmap_data);
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
get_fd(struct vugbm_buffer *buf, int *fd)
 | 
						|
{
 | 
						|
    *fd = gbm_bo_get_fd(buf->bo);
 | 
						|
 | 
						|
    return *fd >= 0;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
device_destroy(struct vugbm_device *dev)
 | 
						|
{
 | 
						|
    gbm_device_destroy(dev->dev);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void
 | 
						|
vugbm_device_destroy(struct vugbm_device *dev)
 | 
						|
{
 | 
						|
    if (!dev->inited) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dev->device_destroy(dev);
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
vugbm_device_init(struct vugbm_device *dev, int fd)
 | 
						|
{
 | 
						|
    dev->fd = fd;
 | 
						|
 | 
						|
#ifdef CONFIG_GBM
 | 
						|
    dev->dev = gbm_create_device(fd);
 | 
						|
#endif
 | 
						|
 | 
						|
    if (0) {
 | 
						|
        /* nothing */
 | 
						|
    }
 | 
						|
#ifdef CONFIG_GBM
 | 
						|
    else if (dev->dev != NULL) {
 | 
						|
        dev->alloc_bo = alloc_bo;
 | 
						|
        dev->free_bo = free_bo;
 | 
						|
        dev->get_fd = get_fd;
 | 
						|
        dev->map_bo = map_bo;
 | 
						|
        dev->unmap_bo = unmap_bo;
 | 
						|
        dev->device_destroy = device_destroy;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
#ifdef CONFIG_MEMFD
 | 
						|
    else if (g_file_test("/dev/udmabuf", G_FILE_TEST_EXISTS)) {
 | 
						|
        dev->fd = open("/dev/udmabuf", O_RDWR);
 | 
						|
        if (dev->fd < 0) {
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
        g_debug("Using experimental udmabuf backend");
 | 
						|
        dev->alloc_bo = udmabuf_alloc_bo;
 | 
						|
        dev->free_bo = udmabuf_free_bo;
 | 
						|
        dev->get_fd = udmabuf_get_fd;
 | 
						|
        dev->map_bo = udmabuf_map_bo;
 | 
						|
        dev->unmap_bo = udmabuf_unmap_bo;
 | 
						|
        dev->device_destroy = udmabuf_device_destroy;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    else {
 | 
						|
        g_debug("Using mem fallback");
 | 
						|
        dev->alloc_bo = mem_alloc_bo;
 | 
						|
        dev->free_bo = mem_free_bo;
 | 
						|
        dev->map_bo = mem_map_bo;
 | 
						|
        dev->unmap_bo = mem_unmap_bo;
 | 
						|
        dev->device_destroy = mem_device_destroy;
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    dev->inited = true;
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
vugbm_buffer_map(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    struct vugbm_device *dev = buf->dev;
 | 
						|
 | 
						|
    return dev->map_bo(buf);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
vugbm_buffer_unmap(struct vugbm_buffer *buf)
 | 
						|
{
 | 
						|
    struct vugbm_device *dev = buf->dev;
 | 
						|
 | 
						|
    dev->unmap_bo(buf);
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
vugbm_buffer_can_get_dmabuf_fd(struct vugbm_buffer *buffer)
 | 
						|
{
 | 
						|
    if (!buffer->dev->get_fd) {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
vugbm_buffer_get_dmabuf_fd(struct vugbm_buffer *buffer, int *fd)
 | 
						|
{
 | 
						|
    if (!vugbm_buffer_can_get_dmabuf_fd(buffer) ||
 | 
						|
        !buffer->dev->get_fd(buffer, fd)) {
 | 
						|
        g_warning("Failed to get dmabuf");
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (*fd < 0) {
 | 
						|
        g_warning("error: dmabuf_fd < 0");
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
vugbm_buffer_create(struct vugbm_buffer *buffer, struct vugbm_device *dev,
 | 
						|
                    uint32_t width, uint32_t height)
 | 
						|
{
 | 
						|
    buffer->dev = dev;
 | 
						|
    buffer->width = width;
 | 
						|
    buffer->height = height;
 | 
						|
    buffer->format = GBM_FORMAT_XRGB8888;
 | 
						|
    buffer->stride = 0; /* modified during alloc */
 | 
						|
    if (!dev->alloc_bo(buffer)) {
 | 
						|
        g_warning("alloc_bo failed");
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!vugbm_buffer_map(buffer)) {
 | 
						|
        g_warning("map_bo failed");
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
 | 
						|
err:
 | 
						|
    dev->free_bo(buffer);
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
vugbm_buffer_destroy(struct vugbm_buffer *buffer)
 | 
						|
{
 | 
						|
    struct vugbm_device *dev = buffer->dev;
 | 
						|
 | 
						|
    vugbm_buffer_unmap(buffer);
 | 
						|
    dev->free_bo(buffer);
 | 
						|
}
 |