qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/3] linux-user: Add more drm ioctls for mesa


From: Xiongchuan Tan
Subject: [PATCH 2/3] linux-user: Add more drm ioctls for mesa
Date: Mon, 10 Apr 2023 18:11:17 +0800

Signed-off-by: Xiongchuan Tan <tanxiongchuan@isrc.iscas.ac.cn>
---
 linux-user/ioctls.h        | 11 ++++-
 linux-user/syscall.c       | 98 ++++++++++++++++++++++++++++++++++++--
 linux-user/syscall_defs.h  | 34 +++++++++++++
 linux-user/syscall_types.h | 24 ++++++++++
 4 files changed, 163 insertions(+), 4 deletions(-)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 54b44a29a9..83ccf785b5 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -685,7 +685,16 @@
 #ifdef HAVE_DRM_H
   IOCTL_SPECIAL(DRM_IOCTL_VERSION, IOC_RW, do_ioctl_drm,
                 MK_PTR(MK_STRUCT(STRUCT_drm_version)))
-
+  IOCTL_SPECIAL(DRM_IOCTL_GET_MAGIC, IOC_R, do_ioctl_drm,
+                MK_PTR(MK_STRUCT(STRUCT_drm_auth)))
+  IOCTL_SPECIAL(DRM_IOCTL_GET_CLIENT, IOC_RW, do_ioctl_drm,
+                MK_PTR(MK_STRUCT(STRUCT_drm_client)))
+  IOCTL_SPECIAL(DRM_IOCTL_GEM_CLOSE, IOC_W, do_ioctl_drm,
+                MK_PTR(MK_STRUCT(STRUCT_drm_gem_close)))
+  IOCTL_SPECIAL(DRM_IOCTL_GET_CAP, IOC_RW, do_ioctl_drm,
+                MK_PTR(MK_STRUCT(STRUCT_drm_get_cap)))
+  IOCTL_SPECIAL(DRM_IOCTL_PRIME_HANDLE_TO_FD, IOC_RW, do_ioctl_drm,
+                MK_PTR(MK_STRUCT(STRUCT_drm_prime_handle)))
 #ifdef CONFIG_DRM_AMDGPU
 #else
   IOCTL_SPECIAL(DRM_IOCTL_I915_GETPARAM, IOC_RW, do_ioctl_drm_i915,
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb0db61990..698b44da03 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5624,15 +5624,48 @@ static inline void host_to_target_drmversion(
     unlock_drm_version(host_ver, target_ver, true);
 }
 
+static abi_long do_ioctl_drm_get_client(const IOCTLEntry *ie,
+                                        struct drm_client *host_client,
+                                        int fd, abi_long arg)
+{
+    abi_long ret;
+    struct target_drm_client *target_client;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_client, arg, 0)) {
+        return -TARGET_EFAULT;
+    }
+
+    __get_user(host_client->idx, &target_client->idx);
+    __get_user(host_client->auth, &target_client->auth);
+    __get_user(host_client->pid, &target_client->pid);
+    __get_user(host_client->uid, &target_client->uid);
+    __get_user(host_client->magic, &target_client->magic);
+    __get_user(host_client->iocs, &target_client->iocs);
+
+    ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_client));
+
+    if (!is_error(ret)) {
+        __put_user(host_client->idx, &target_client->idx);
+        __put_user(host_client->auth, &target_client->auth);
+        __put_user(host_client->pid, &target_client->pid);
+        __put_user(host_client->uid, &target_client->uid);
+        __put_user(host_client->magic, &target_client->magic);
+        __put_user(host_client->iocs, &target_client->iocs);
+    }
+
+    unlock_user_struct(target_client, arg, 0);
+    return ret;
+}
+
 static abi_long do_ioctl_drm(const IOCTLEntry *ie, uint8_t *buf_temp,
                              int fd, int cmd, abi_long arg)
 {
-    struct drm_version *ver;
-    struct target_drm_version *target_ver;
     abi_long ret;
 
     switch (ie->host_cmd) {
-    case DRM_IOCTL_VERSION:
+    case DRM_IOCTL_VERSION: {
+        struct drm_version *ver;
+        struct target_drm_version *target_ver;
         if (!lock_user_struct(VERIFY_WRITE, target_ver, arg, 0)) {
             return -TARGET_EFAULT;
         }
@@ -5649,6 +5682,65 @@ static abi_long do_ioctl_drm(const IOCTLEntry *ie, 
uint8_t *buf_temp,
         unlock_user_struct(target_ver, arg, 0);
         return ret;
     }
+    case DRM_IOCTL_GET_MAGIC: {
+        struct drm_auth *auth;
+        struct target_drm_auth *target_auth;
+        if (!lock_user_struct(VERIFY_READ, target_auth, arg, 0)) {
+            return -TARGET_EFAULT;
+        }
+        auth = (struct drm_auth *)buf_temp;
+        __get_user(auth->magic, &target_auth->magic);
+        ret = get_errno(safe_ioctl(fd, ie->host_cmd, auth));
+        unlock_user_struct(target_auth, arg, 0);
+        return ret;
+    }
+    case DRM_IOCTL_GEM_CLOSE: {
+        struct drm_gem_close *gem_close;
+        struct target_drm_gem_close *target_gem_close;
+        if (!lock_user_struct(VERIFY_WRITE, target_gem_close, arg, 0)) {
+            return -TARGET_EFAULT;
+        }
+        gem_close = (struct drm_gem_close *)buf_temp;
+        __get_user(gem_close->handle, &target_gem_close->handle);
+        ret = get_errno(safe_ioctl(fd, ie->host_cmd, gem_close));
+        __put_user(gem_close->handle, &target_gem_close->handle);
+        unlock_user_struct(target_gem_close, arg, 0);
+        return ret;
+    }
+    case DRM_IOCTL_GET_CAP: {
+        struct drm_get_cap *cap;
+        struct target_drm_get_cap *target_cap;
+        if (!lock_user_struct(VERIFY_WRITE, target_cap, arg, 0)) {
+            return -TARGET_EFAULT;
+        }
+        cap = (struct drm_get_cap *)buf_temp;
+        __get_user(cap->capability, &target_cap->capability);
+        __get_user(cap->value, &target_cap->value);
+        ret = get_errno(safe_ioctl(fd, ie->host_cmd, cap));
+        __put_user(cap->value, &target_cap->value);
+        unlock_user_struct(target_cap, arg, 0);
+        return ret;
+    }
+    case DRM_IOCTL_GET_CLIENT:
+        return do_ioctl_drm_get_client(ie,
+                                       (struct drm_client *)buf_temp,
+                                       fd, arg);
+    case DRM_IOCTL_PRIME_HANDLE_TO_FD: {
+        struct drm_prime_handle *prime_handle;
+        struct target_drm_prime_handle *target_prime_handle;
+        if (!lock_user_struct(VERIFY_WRITE, target_prime_handle, arg, 0)) {
+            return -TARGET_EFAULT;
+        }
+        prime_handle = (struct drm_prime_handle *)buf_temp;
+        __get_user(prime_handle->handle, &target_prime_handle->handle);
+        __get_user(prime_handle->flags, &target_prime_handle->flags);
+        __get_user(prime_handle->fd, &target_prime_handle->fd);
+        ret = get_errno(safe_ioctl(fd, ie->host_cmd, prime_handle));
+        __put_user(prime_handle->fd, &target_prime_handle->fd);
+        unlock_user_struct(target_prime_handle, arg, 0);
+        return ret;
+    }
+    }
     return -TARGET_ENOSYS;
 }
 
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index e435649693..5429834236 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1226,6 +1226,11 @@ struct target_rtc_pll_info {
 
 /* drm ioctls */
 #define TARGET_DRM_IOCTL_VERSION      TARGET_IOWRU('d', 0x00)
+#define TARGET_DRM_IOCTL_GET_MAGIC    TARGET_IORU('d', 0x02)
+#define TARGET_DRM_IOCTL_GET_CLIENT   TARGET_IOWRU('d', 0x05)
+#define TARGET_DRM_IOCTL_GEM_CLOSE    TARGET_IOWU('d', 0x09)
+#define TARGET_DRM_IOCTL_GET_CAP      TARGET_IOWRU('d', 0x0c)
+#define TARGET_DRM_IOCTL_PRIME_HANDLE_TO_FD  TARGET_IOWRU('d', 0x2d)
 
 #ifdef CONFIG_DRM_AMDGPU
 
@@ -2690,6 +2695,35 @@ struct target_drm_version {
     abi_ulong desc;
 };
 
+struct target_drm_auth {
+    int magic;
+};
+
+struct target_drm_client {
+    int idx;
+    int auth;
+    abi_ulong pid;
+    abi_ulong uid;
+    abi_ulong magic;
+    abi_ulong iocs;
+};
+
+struct target_drm_gem_close {
+    int handle;
+    int pad;
+};
+
+struct target_drm_get_cap {
+    abi_ulong capability;
+    abi_ulong value;
+};
+
+struct target_drm_prime_handle {
+    int handle;
+    int flags;
+    int fd;
+};
+
 struct target_drm_i915_getparam {
     int param;
     abi_ulong value;
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index c3b43f8022..2a48b2ec47 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -331,6 +331,30 @@ STRUCT(drm_version,
        TYPE_ULONG, /* desc_len */
        TYPE_PTRVOID) /* desc */
 
+STRUCT(drm_auth,
+       TYPE_INT) /* magic */
+
+STRUCT(drm_client,
+       TYPE_INT, /* idx */
+       TYPE_INT, /* auth */
+       TYPE_ULONG, /* pid */
+       TYPE_ULONG, /* uid */
+       TYPE_ULONG, /* magic */
+       TYPE_ULONG) /* iocs */
+
+STRUCT(drm_gem_close,
+       TYPE_INT, /* handle */
+       TYPE_INT) /* pad */
+
+STRUCT(drm_get_cap,
+       TYPE_ULONGLONG, /* capability */
+       TYPE_ULONGLONG) /* value */
+
+STRUCT(drm_prime_handle,
+       TYPE_INT, /* handle */
+       TYPE_INT, /* flags */
+       TYPE_INT) /* fd */
+
 STRUCT(drm_i915_getparam,
        TYPE_INT, /* param */
        TYPE_PTRVOID) /* value */
-- 
2.40.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]