From 226e4ebf56c8191ad38e789d4c0f2714531d2853 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Fri, 5 Jun 2020 05:10:25 +0000 Subject: wlroots: support virtio_wl shm allocation --- ...end-wayland-downgrade-to-wl_compositor-v3.patch | 6 +- ...002-util-support-virtio_wl-shm-allocation.patch | 281 +++++++++++++++++++++ pkgs/development/libraries/wlroots/default.nix | 5 +- 3 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch (limited to 'pkgs/development/libraries') diff --git a/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch b/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch index bec35f4d20c..c0d87cb2a80 100644 --- a/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch +++ b/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch @@ -1,7 +1,7 @@ -From 3b37c19286b621f266e6d447cd16f1f59a3cc24c Mon Sep 17 00:00:00 2001 +From 2b266b85c8bd07cfc4d6427081ca0eaff4410511 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Thu, 23 Jan 2020 14:35:41 +0000 -Subject: [PATCH] backend/wayland: downgrade to wl_compositor v3 +Subject: [PATCH 1/2] backend/wayland: downgrade to wl_compositor v3 Sommelier does not support v4. @@ -52,5 +52,5 @@ index 7a3a08d0..f332ad93 100644 output->pending_buffer = NULL; -- -2.24.1 +2.26.2 diff --git a/pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch b/pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch new file mode 100644 index 00000000000..ef9526af213 --- /dev/null +++ b/pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch @@ -0,0 +1,281 @@ +From 6262ddb96410fd2fd21edbd96d79f1149e698948 Mon Sep 17 00:00:00 2001 +From: Alyssa Ross +Date: Sat, 23 May 2020 03:42:33 +0000 +Subject: [PATCH 2/2] util: support virtio_wl shm allocation + +--- + include/util/virtio_wl.h | 14 ++++++ + include/util/virtio_wl_shm.h | 8 +++ + util/meson.build | 2 + + util/shm.c | 12 +++++ + util/virtio_wl.c | 96 ++++++++++++++++++++++++++++++++++++ + util/virtio_wl_shm.c | 65 ++++++++++++++++++++++++ + 6 files changed, 197 insertions(+) + create mode 100644 include/util/virtio_wl.h + create mode 100644 include/util/virtio_wl_shm.h + create mode 100644 util/virtio_wl.c + create mode 100644 util/virtio_wl_shm.c + +diff --git a/include/util/virtio_wl.h b/include/util/virtio_wl.h +new file mode 100644 +index 00000000..ae5c19b5 +--- /dev/null ++++ b/include/util/virtio_wl.h +@@ -0,0 +1,14 @@ ++#ifndef UTIL_VIRTIO_WL_H ++#define UTIL_VIRTIO_WL_H ++ ++struct virtwl_ioctl_txn; ++ ++int virtio_wl_connect(const char *name, uint32_t flags); ++ ++int32_t virtio_wl_sendmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn); ++int32_t virtio_wl_send(int sockfd, const void *buf, uint32_t len); ++ ++int32_t virtio_wl_recvmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn); ++int32_t virtio_wl_recv(int sockfd, void *buf, uint32_t len); ++ ++#endif +diff --git a/include/util/virtio_wl_shm.h b/include/util/virtio_wl_shm.h +new file mode 100644 +index 00000000..d9f9f045 +--- /dev/null ++++ b/include/util/virtio_wl_shm.h +@@ -0,0 +1,8 @@ ++#ifndef UTIL_VIRTIO_WL_SHM_H ++#define UTIL_VIRTIO_WL_SHM_H ++ ++#include ++ ++int allocate_virtio_wl_shm_file(size_t size); ++ ++#endif +diff --git a/util/meson.build b/util/meson.build +index c6614275..6ec6182b 100644 +--- a/util/meson.build ++++ b/util/meson.build +@@ -4,4 +4,6 @@ wlr_files += files( + 'region.c', + 'shm.c', + 'signal.c', ++ 'virtio_wl.c', ++ 'virtio_wl_shm.c', + ) +diff --git a/util/shm.c b/util/shm.c +index f7c7303e..d8110904 100644 +--- a/util/shm.c ++++ b/util/shm.c +@@ -2,11 +2,14 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include "util/shm.h" ++#include "util/virtio_wl_shm.h" + + static void randname(char *buf) { + struct timespec ts; +@@ -19,6 +22,11 @@ static void randname(char *buf) { + } + + int create_shm_file(void) { ++ if (getenv("WLR_VIRTIO_WL")) { ++ wlr_log(WLR_ERROR, "cannot use create_shm_file with virtio_wl"); ++ return -1; ++ } ++ + int retries = 100; + do { + char name[] = "/wlroots-XXXXXX"; +@@ -37,6 +45,10 @@ int create_shm_file(void) { + } + + int allocate_shm_file(size_t size) { ++ if (getenv("WLR_VIRTIO_WL")) { ++ return allocate_virtio_wl_shm_file(size); ++ } ++ + int fd = create_shm_file(); + if (fd < 0) { + return -1; +diff --git a/util/virtio_wl.c b/util/virtio_wl.c +new file mode 100644 +index 00000000..e7ee58ac +--- /dev/null ++++ b/util/virtio_wl.c +@@ -0,0 +1,96 @@ ++#define _POSIX_C_SOURCE 200809L ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "util/virtio_wl.h" ++ ++// This is essentially vendored reusable library code, so I consider ++// it exempt from the wlroots style guide. :) ++ ++int virtio_wl_connect(const char *name, uint32_t flags) ++{ ++ static int wl_fd = -1; ++ if (wl_fd < 0) ++ wl_fd = open("/dev/wl0", O_RDWR | O_CLOEXEC); ++ if (wl_fd < 0) ++ return wl_fd; ++ ++ struct virtwl_ioctl_new new_ctx = { ++ .type = name ? VIRTWL_IOCTL_NEW_CTX_NAMED : VIRTWL_IOCTL_NEW_CTX, ++ .fd = -1, ++ .flags = flags, ++ }; ++ // Device assumes name 32 bytes long if not null terminated. ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wstringop-truncation" ++ if (name) ++ strncpy(new_ctx.name, name, sizeof(new_ctx.name)); ++#pragma GCC diagnostic pop ++ ++ if (ioctl(wl_fd, VIRTWL_IOCTL_NEW, &new_ctx)) ++ return -1; ++ ++ return new_ctx.fd; ++} ++ ++int32_t virtio_wl_sendmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn) ++{ ++ int r = ioctl(sockfd, VIRTWL_IOCTL_SEND, ioctl_txn); ++ if (!r) ++ r = ioctl_txn->len > INT32_MAX ? INT32_MAX : ioctl_txn->len; ++ return r; ++} ++ ++int32_t virtio_wl_send(int sockfd, const void *buf, uint32_t len) ++{ ++ struct virtwl_ioctl_txn *ioctl_txn = malloc(sizeof(*ioctl_txn) + len); ++ if (!ioctl_txn) ++ return -1; ++ ++ for (size_t i = 0; i < VIRTWL_SEND_MAX_ALLOCS; i++) ++ ioctl_txn->fds[i] = -1; ++ ++ ioctl_txn->len = len; ++ memcpy((uint8_t *)ioctl_txn + sizeof(*ioctl_txn), buf, len); ++ ++ int r = virtio_wl_sendmsg(sockfd, ioctl_txn); ++ ++ free(ioctl_txn); ++ return r; ++} ++ ++int32_t virtio_wl_recvmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn) ++{ ++ if (ioctl(sockfd, VIRTWL_IOCTL_RECV, ioctl_txn)) ++ return -1; ++ ++ return ioctl_txn->len > INT32_MAX ? INT32_MAX : ioctl_txn->len; ++} ++ ++int32_t virtio_wl_recv(int sockfd, void *buf, uint32_t len) ++{ ++ struct virtwl_ioctl_txn *ioctl_txn = malloc(sizeof(*ioctl_txn) + len); ++ if (!ioctl_txn) ++ return -1; ++ ++ ioctl_txn->len = len; ++ ++ int rv = virtio_wl_recvmsg(sockfd, ioctl_txn); ++ if (rv < 0) ++ goto cleanup; ++ ++ memcpy(buf, (uint8_t *)ioctl_txn + sizeof(*ioctl_txn), ioctl_txn->len); ++ ++ for (size_t i = 0; i < VIRTWL_SEND_MAX_ALLOCS; i++) ++ if (ioctl_txn->fds[i] >= 0) ++ close(ioctl_txn->fds[i]); ++ ++ cleanup: ++ free(ioctl_txn); ++ return rv; ++} +diff --git a/util/virtio_wl_shm.c b/util/virtio_wl_shm.c +new file mode 100644 +index 00000000..b2109310 +--- /dev/null ++++ b/util/virtio_wl_shm.c +@@ -0,0 +1,65 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "util/virtio_wl.h" ++#include "util/virtio_wl_shm.h" ++ ++// This is essentially vendored reusable library code, so I consider ++// it exempt from the wlroots style guide. :) ++ ++int allocate_virtio_wl_shm_file(size_t size) ++{ ++ static const size_t NAME_SIZE = 224; ++ static const char *NAME = "wlroots"; ++ ++ int r; ++ uint8_t *message = NULL; ++ struct virtwl_ioctl_txn *ioctl_txn = NULL; ++ ++ int conn = virtio_wl_connect("__crosvm_memfd", 0); ++ if (conn < 0) ++ return conn; ++ ++ message = calloc(NAME_SIZE + 8, 1); ++ if (!message) { ++ r = -1; ++ goto cleanup; ++ } ++ strcpy((char *)message, NAME); ++ ++ // Encode size as 64-bit little-endian unsigned integer. ++ for (uint8_t i = 0; i < 8; i++) ++ message[NAME_SIZE + i] = (uint8_t)((uint64_t)size >> (8 * i)); ++ ++ if ((r = virtio_wl_send(conn, message, NAME_SIZE + 8)) < 0) ++ goto cleanup; ++ ++ int32_t len = 1; ++ if (!(ioctl_txn = malloc(sizeof(*ioctl_txn) + len))) { ++ r = -1; ++ goto cleanup; ++ } ++ ioctl_txn->len = len; ++ ++ if ((r = virtio_wl_recvmsg(conn, ioctl_txn)) < 0) ++ goto cleanup; ++ ++ if (((uint8_t *)ioctl_txn + sizeof(*ioctl_txn))[0]) { ++ // We don't actually know why we didn't get the ++ // memory, but out of memory is a reasonable guess. ++ errno = ENOMEM; ++ r = -1; ++ goto cleanup; ++ } ++ ++ r = ioctl_txn->fds[0]; ++ assert(r >= 0); ++ ++ cleanup: ++ free(message); ++ free(ioctl_txn); ++ return r; ++} +-- +2.26.2 + diff --git a/pkgs/development/libraries/wlroots/default.nix b/pkgs/development/libraries/wlroots/default.nix index da3876737e9..a2a8f42be16 100644 --- a/pkgs/development/libraries/wlroots/default.nix +++ b/pkgs/development/libraries/wlroots/default.nix @@ -1,7 +1,7 @@ { stdenv, fetchFromGitHub, meson, ninja, pkg-config, wayland , libGL, wayland-protocols, libinput, libxkbcommon, pixman , xcbutilwm, libX11, libcap, xcbutilimage, xcbutilerrors, mesa -, libpng, ffmpeg_4 +, libpng, ffmpeg_4, linuxHeaders }: stdenv.mkDerivation rec { @@ -17,6 +17,7 @@ stdenv.mkDerivation rec { patches = [ ./0001-backend-wayland-downgrade-to-wl_compositor-v3.patch + ./0002-util-support-virtio_wl-shm-allocation.patch ]; # $out for the library and $examples for the example programs (in examples): @@ -27,7 +28,7 @@ stdenv.mkDerivation rec { buildInputs = [ libGL wayland-protocols libinput libxkbcommon pixman xcbutilwm libX11 libcap xcbutilimage xcbutilerrors mesa - libpng ffmpeg_4 + libpng ffmpeg_4 linuxHeaders ]; postInstall = '' -- cgit 1.4.1