Skip to content

Instantly share code, notes, and snippets.

@xctan
Created April 16, 2023 08:46
Show Gist options
  • Save xctan/1794ede6d60cea7cf8b9701109fe7536 to your computer and use it in GitHub Desktop.
Save xctan/1794ede6d60cea7cf8b9701109fe7536 to your computer and use it in GitHub Desktop.
diff --git a/configure b/configure
index 800b5850f4..a93f5426ef 100755
--- a/configure
+++ b/configure
@@ -836,6 +836,8 @@ for opt do
;;
--enable-linux-user) linux_user="yes"
;;
+ --enable-linux-user-drm-amdgpu) meson_option_add "-Ddrm_amdgpu=true"
+ ;;
--disable-bsd-user) bsd_user="no"
;;
--enable-bsd-user) bsd_user="yes"
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 071f7ca253..54b44a29a9 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -686,8 +686,12 @@
IOCTL_SPECIAL(DRM_IOCTL_VERSION, IOC_RW, do_ioctl_drm,
MK_PTR(MK_STRUCT(STRUCT_drm_version)))
+#ifdef CONFIG_DRM_AMDGPU
+#else
IOCTL_SPECIAL(DRM_IOCTL_I915_GETPARAM, IOC_RW, do_ioctl_drm_i915,
MK_PTR(MK_STRUCT(STRUCT_drm_i915_getparam)))
+#endif /* CONFIG_DRM_AMDGPU */
+
#endif
#ifdef TARGET_TIOCSTART
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 69f740ff98..bb0db61990 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -123,8 +123,12 @@
#endif
#ifdef HAVE_DRM_H
#include <libdrm/drm.h>
+#ifdef CONFIG_DRM_AMDGPU
+#include <libdrm/amdgpu_drm.h>
+#else
#include <libdrm/i915_drm.h>
#endif
+#endif
#include "linux_loop.h"
#include "uname.h"
@@ -5648,6 +5652,10 @@ static abi_long do_ioctl_drm(const IOCTLEntry *ie,
uint8_t *buf_temp,
return -TARGET_ENOSYS;
}
+#ifdef CONFIG_DRM_AMDGPU
+
+#else
+
static abi_long do_ioctl_drm_i915_getparam(const IOCTLEntry *ie,
struct drm_i915_getparam *gparam,
int fd, abi_long arg)
@@ -5682,6 +5690,8 @@ static abi_long do_ioctl_drm_i915(const IOCTLEntry *ie,
uint8_t *buf_temp,
}
}
+#endif /* CONFIG_DRM_AMDGPU */
+
#endif
static abi_long do_ioctl_TUNSETTXFILTER(const IOCTLEntry *ie, uint8_t
*buf_temp,
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index cc37054cb5..e435649693 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1227,9 +1227,14 @@ struct target_rtc_pll_info {
/* drm ioctls */
#define TARGET_DRM_IOCTL_VERSION TARGET_IOWRU('d', 0x00)
+#ifdef CONFIG_DRM_AMDGPU
+
+#else
/* drm i915 ioctls */
#define TARGET_DRM_IOCTL_I915_GETPARAM TARGET_IOWRU('d', 0x46)
+#endif /* CONFIG_DRM_AMDGPU */
+
/* from asm/termbits.h */
#define TARGET_NCC 8
diff --git a/meson.build b/meson.build
index c44d05a13f..841306f414 100644
--- a/meson.build
+++ b/meson.build
@@ -1962,6 +1962,7 @@ config_host_data.set('CONFIG_GPROF', get_option('gprof'))
config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION',
get_option('live_block_migration').allowed())
config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
+config_host_data.set('CONFIG_DRM_AMDGPU', get_option('drm_amdgpu'))
# has_header
config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
diff --git a/meson_options.txt b/meson_options.txt
index fc9447d267..f85f76f355 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -327,3 +327,6 @@ option('slirp_smbd', type : 'feature', value : 'auto',
option('hexagon_idef_parser', type : 'boolean', value : true,
description: 'use idef-parser to automatically generate TCG code for
the Hexagon frontend')
+
+option('drm_amdgpu', type : 'boolean', value: false,
+ description: 'drm amdgpu ioctl support')
\ No newline at end of file
--
2.40.0
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
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 83ccf785b5..fa0a583954 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -696,6 +696,22 @@
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
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_GEM_CREATE, IOC_RW, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_create)))
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_GEM_MMAP, IOC_RW, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_mmap)))
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_CTX, IOC_RW, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_ctx)))
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_CS, IOC_RW, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_cs)))
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_INFO, IOC_W, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_info)))
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_GEM_METADATA, IOC_RW, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_metadata)))
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_GEM_VA, IOC_RW, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_va)))
+ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_WAIT_CS, IOC_RW, do_ioctl_drm_amdgpu,
+ MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_wait_cs)))
#else
IOCTL_SPECIAL(DRM_IOCTL_I915_GETPARAM, IOC_RW, do_ioctl_drm_i915,
MK_PTR(MK_STRUCT(STRUCT_drm_i915_getparam)))
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 698b44da03..c276e4ef02 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5746,6 +5746,318 @@ static abi_long do_ioctl_drm(const IOCTLEntry *ie,
uint8_t *buf_temp,
#ifdef CONFIG_DRM_AMDGPU
+static abi_long do_ioctl_drm_amdgpu_gem_create(
+ const IOCTLEntry *ie,
+ union drm_amdgpu_gem_create
*host_create,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ union target_drm_amdgpu_gem_create *target_create;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_create, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+
+ __get_user(host_create->in.bo_size, &target_create->in.bo_size);
+ __get_user(host_create->in.alignment, &target_create->in.alignment);
+ __get_user(host_create->in.domains, &target_create->in.domains);
+ __get_user(host_create->in.domain_flags, &target_create->in.domain_flags);
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_create));
+
+ if (!is_error(ret)) {
+ __put_user(host_create->out.handle, &target_create->out.handle);
+ __put_user(host_create->out._pad, &target_create->out._pad);
+ }
+
+ unlock_user_struct(target_create, arg, 0);
+ return ret;
+}
+
+static abi_long do_ioctl_drm_amdgpu_gem_mmap(
+ const IOCTLEntry *ie,
+ union drm_amdgpu_gem_mmap
*host_mmap,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ union target_drm_amdgpu_gem_mmap *target_mmap;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_mmap, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+
+ __get_user(host_mmap->in.handle, &target_mmap->in.handle);
+ __get_user(host_mmap->in._pad, &target_mmap->in._pad);
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_mmap));
+
+ if (!is_error(ret)) {
+ __put_user(host_mmap->out.addr_ptr, &target_mmap->out.addr_ptr);
+ }
+
+ unlock_user_struct(target_mmap, arg, 0);
+ return ret;
+}
+
+static abi_long do_ioctl_drm_amdgpu_ctx(const IOCTLEntry *ie,
+ union drm_amdgpu_ctx *host_ctx,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ struct target_drm_amdgpu_ctx *target_ctx;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_ctx, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+
+ __get_user(host_ctx->in.op, &target_ctx->op);
+ __get_user(host_ctx->in.flags, &target_ctx->flags);
+ __get_user(host_ctx->in.ctx_id, &target_ctx->ctx_id);
+ __get_user(host_ctx->in.priority, &target_ctx->priority);
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ctx));
+
+ if (!is_error(ret)) {
+ memcpy(target_ctx, host_ctx, sizeof(*target_ctx));
+ }
+
+ unlock_user_struct(target_ctx, arg, 0);
+ return ret;
+}
+
+static abi_long do_ioctl_drm_amdgpu_cs(const IOCTLEntry *ie,
+ union drm_amdgpu_cs *host_info,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ union target_drm_amdgpu_cs *target_info;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_info, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+
+ __get_user(host_info->in.ctx_id, &target_info->in.ctx_id);
+ __get_user(host_info->in.bo_list_handle, &target_info->in.bo_list_handle);
+ __get_user(host_info->in.num_chunks, &target_info->in.num_chunks);
+ __get_user(host_info->in.flags, &target_info->in.flags);
+
+ host_info->in.chunks = (abi_ullong)lock_user(
+ VERIFY_READ,
+ target_info->in.chunks,
+ target_info->in.num_chunks *
sizeof(abi_long),
+ 1);
+ void *chunks = (void *)host_info->in.chunks;
+ if (!host_info->in.chunks) {
+ unlock_user_struct(target_info, arg, 0);
+ return -EFAULT;
+ }
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_info));
+
+ if (is_error(ret)) {
+ goto fail;
+ }
+
+ __put_user(host_info->out.handle, &target_info->out.handle);
+ unlock_user(chunks, target_info->in.chunks, 0);
+ unlock_user_struct(target_info, arg, 0);
+ return ret;
+
+fail:
+ unlock_user_struct(target_info, arg, 0);
+ return -EFAULT;
+}
+
+static abi_long do_ioctl_drm_amdgpu_info(const IOCTLEntry *ie,
+ struct drm_amdgpu_info *host_info,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ struct target_drm_amdgpu_info *target_info;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_info, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+ __get_user(host_info->return_pointer, &target_info->return_pointer);
+ __get_user(host_info->return_size, &target_info->return_size);
+ __get_user(host_info->query, &target_info->query);
+ __get_user(host_info->read_mmr_reg.dword_offset, &target_info->value[0]);
+ __get_user(host_info->read_mmr_reg.count, &target_info->value[1]);
+ __get_user(host_info->read_mmr_reg.instance, &target_info->value[2]);
+ __get_user(host_info->read_mmr_reg.flags, &target_info->value[3]);
+
+ abi_ullong return_pointer = host_info->return_pointer;
+ host_info->return_pointer = (abi_ullong)lock_user(VERIFY_WRITE,
+ return_pointer,
+ host_info->return_size,
+ 1);
+ if (!host_info->return_pointer) {
+ unlock_user_struct(target_info, arg, 0);
+ return -EFAULT;
+ }
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_info));
+
+ if (!is_error(ret)) {
+ unlock_user((void *)host_info->return_pointer,
+ return_pointer,
+ host_info->return_size);
+ } else {
+ unlock_user((void *)host_info->return_pointer,
+ return_pointer, 0);
+ }
+
+ unlock_user_struct(target_info, arg, 0);
+ return ret;
+}
+
+static abi_long do_ioctl_drm_amdgpu_gem_metadata(
+ const IOCTLEntry *ie,
+ struct drm_amdgpu_gem_metadata
*host_metadata,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ struct target_drm_amdgpu_gem_metadata *target_metadata;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_metadata, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+ __get_user(host_metadata->handle, &target_metadata->handle);
+ __get_user(host_metadata->op, &target_metadata->op);
+ __get_user(host_metadata->data.flags, &target_metadata->flags);
+ __get_user(host_metadata->data.tiling_info, &target_metadata->tiling_info);
+ __get_user(host_metadata->data.data_size_bytes,
+ &target_metadata->data_size_bytes);
+ for (int i = 0; i < 64; i++) {
+ __get_user(host_metadata->data.data[i], &target_metadata->data[i]);
+ }
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_metadata));
+
+ if (!is_error(ret)) {
+ __put_user(host_metadata->handle, &target_metadata->handle);
+ __put_user(host_metadata->op, &target_metadata->op);
+ __put_user(host_metadata->data.flags, &target_metadata->flags);
+ __put_user(host_metadata->data.tiling_info,
+ &target_metadata->tiling_info);
+ __put_user(host_metadata->data.data_size_bytes,
+ &target_metadata->data_size_bytes);
+ for (int i = 0; i < 64; i++) {
+ __put_user(host_metadata->data.data[i], &target_metadata->data[i]);
+ }
+ }
+
+ unlock_user_struct(target_metadata, arg, 0);
+ return ret;
+}
+
+static abi_long do_ioctl_drm_amdgpu_gem_va(const IOCTLEntry *ie,
+ struct drm_amdgpu_gem_va *host_va,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ struct target_drm_amdgpu_gem_va *target_va;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_va, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+ __get_user(host_va->handle, &target_va->handle);
+ __get_user(host_va->_pad, &target_va->_pad);
+ __get_user(host_va->operation, &target_va->operation);
+ __get_user(host_va->flags, &target_va->flags);
+ __get_user(host_va->va_address, &target_va->va_address);
+ __get_user(host_va->offset_in_bo, &target_va->offset_in_bo);
+ __get_user(host_va->map_size, &target_va->map_size);
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_va));
+
+ if (!is_error(ret)) {
+ __put_user(host_va->handle, &target_va->handle);
+ __put_user(host_va->_pad, &target_va->_pad);
+ __put_user(host_va->operation, &target_va->operation);
+ __put_user(host_va->flags, &target_va->flags);
+ __put_user(host_va->va_address, &target_va->va_address);
+ __put_user(host_va->offset_in_bo, &target_va->offset_in_bo);
+ __put_user(host_va->map_size, &target_va->map_size);
+ }
+
+ unlock_user_struct(target_va, arg, 0);
+ return ret;
+}
+
+static abi_long do_ioctl_drm_amdgpu_wait_cs(
+ const IOCTLEntry *ie,
+ union drm_amdgpu_wait_cs
*host_wait_cs,
+ int fd, abi_long arg)
+{
+ abi_long ret;
+ union target_drm_amdgpu_wait_cs *target_wait_cs;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_wait_cs, arg, 0)) {
+ return -TARGET_EFAULT;
+ }
+ __get_user(host_wait_cs->in.handle, &target_wait_cs->in.handle);
+ __get_user(host_wait_cs->in.timeout, &target_wait_cs->in.timeout);
+ __get_user(host_wait_cs->in.ip_type, &target_wait_cs->in.ip_type);
+ __get_user(host_wait_cs->in.ip_instance, &target_wait_cs->in.ip_instance);
+ __get_user(host_wait_cs->in.ring, &target_wait_cs->in.ring);
+ __get_user(host_wait_cs->in.ctx_id, &target_wait_cs->in.ctx_id);
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_wait_cs));
+
+ if (!is_error(ret)) {
+ __put_user(host_wait_cs->out.status, &target_wait_cs->out.status);
+ }
+
+ unlock_user_struct(target_wait_cs, arg, 0);
+ return ret;
+}
+
+static abi_long do_ioctl_drm_amdgpu(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg)
+{
+ switch (ie->host_cmd) {
+ case DRM_IOCTL_AMDGPU_GEM_CREATE:
+ return do_ioctl_drm_amdgpu_gem_create(
+ ie,
+ (union drm_amdgpu_gem_create
*)buf_temp,
+ fd, arg);
+ case DRM_IOCTL_AMDGPU_GEM_MMAP:
+ return do_ioctl_drm_amdgpu_gem_mmap(
+ ie,
+ (union drm_amdgpu_gem_mmap
*)buf_temp,
+ fd, arg);
+
+ case DRM_IOCTL_AMDGPU_CTX:
+ return do_ioctl_drm_amdgpu_ctx(ie,
+ (union drm_amdgpu_ctx *)buf_temp,
+ fd, arg);
+ case DRM_IOCTL_AMDGPU_CS:
+ return do_ioctl_drm_amdgpu_cs(ie,
+ (union drm_amdgpu_cs *)buf_temp,
+ fd, arg);
+ case DRM_IOCTL_AMDGPU_INFO:
+ return do_ioctl_drm_amdgpu_info(ie,
+ (struct drm_amdgpu_info *)buf_temp,
+ fd, arg);
+ case DRM_IOCTL_AMDGPU_GEM_METADATA:
+ return do_ioctl_drm_amdgpu_gem_metadata(
+ ie,
+ (struct drm_amdgpu_gem_metadata
*)buf_temp,
+ fd, arg);
+ case DRM_IOCTL_AMDGPU_GEM_VA:
+ return do_ioctl_drm_amdgpu_gem_va(ie,
+ (struct drm_amdgpu_gem_va *)buf_temp,
+ fd, arg);
+ case DRM_IOCTL_AMDGPU_WAIT_CS:
+ return do_ioctl_drm_amdgpu_wait_cs(ie,
+ (union drm_amdgpu_wait_cs
*)buf_temp,
+ fd, arg);
+ default:
+ return -TARGET_ENOSYS;
+ }
+}
+
#else
static abi_long do_ioctl_drm_i915_getparam(const IOCTLEntry *ie,
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 5429834236..d3d12ab918 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1233,7 +1233,15 @@ struct target_rtc_pll_info {
#define TARGET_DRM_IOCTL_PRIME_HANDLE_TO_FD TARGET_IOWRU('d', 0x2d)
#ifdef CONFIG_DRM_AMDGPU
-
+/* drm amdgpu ioctls */
+#define TARGET_DRM_IOCTL_AMDGPU_GEM_CREATE TARGET_IOWRU('d', 0x40)
+#define TARGET_DRM_IOCTL_AMDGPU_GEM_MMAP TARGET_IOWRU('d', 0x41)
+#define TARGET_DRM_IOCTL_AMDGPU_CTX TARGET_IOWRU('d', 0x42)
+#define TARGET_DRM_IOCTL_AMDGPU_CS TARGET_IOWRU('d', 0x44)
+#define TARGET_DRM_IOCTL_AMDGPU_INFO TARGET_IOWU('d', 0x45)
+#define TARGET_DRM_IOCTL_AMDGPU_GEM_METADATA TARGET_IOWRU('d', 0x46)
+#define TARGET_DRM_IOCTL_AMDGPU_GEM_VA TARGET_IOWRU('d', 0x48)
+#define TARGET_DRM_IOCTL_AMDGPU_WAIT_CS TARGET_IOWRU('d', 0x49)
#else
/* drm i915 ioctls */
#define TARGET_DRM_IOCTL_I915_GETPARAM TARGET_IOWRU('d', 0x46)
@@ -2724,6 +2732,96 @@ struct target_drm_prime_handle {
int fd;
};
+/* amdgpu specific */
+union target_drm_amdgpu_gem_create {
+ struct {
+ abi_ullong bo_size;
+ abi_ullong alignment;
+ abi_ulong domains;
+ abi_ulong domain_flags;
+ } in;
+ struct {
+ int handle;
+ int _pad;
+ } out;
+};
+
+union target_drm_amdgpu_gem_mmap {
+ struct {
+ int handle;
+ int _pad;
+ } in;
+ struct {
+ abi_ulong addr_ptr;
+ } out;
+};
+
+struct target_drm_amdgpu_ctx {
+ int op;
+ int flags;
+ int ctx_id;
+ int priority;
+};
+
+struct target_drm_amdgpu_info {
+ abi_ulong return_pointer;
+ int return_size;
+ int query;
+ int value[4];
+};
+
+struct target_drm_amdgpu_gem_metadata {
+ int handle;
+ int op;
+ abi_ulong flags;
+ abi_ulong tiling_info;
+ int data_size_bytes;
+ int data[64];
+};
+
+struct target_drm_amdgpu_gem_va {
+ int handle;
+ int _pad;
+ int operation;
+ int flags;
+ abi_ulong va_address;
+ abi_ulong offset_in_bo;
+ abi_ulong map_size;
+};
+
+struct target_drm_amdgpu_cs_chunk {
+ int chunk_id;
+ int length_dw;
+ abi_ulong chunk_data;
+};
+
+union target_drm_amdgpu_cs {
+ struct {
+ int ctx_id;
+ int bo_list_handle;
+ int num_chunks;
+ int flags;
+ abi_ulong chunks;
+ } in;
+ struct {
+ abi_ulong handle;
+ } out;
+};
+
+union target_drm_amdgpu_wait_cs {
+ struct {
+ abi_ullong handle;
+ abi_ullong timeout;
+ int ip_type;
+ int ip_instance;
+ int ring;
+ int ctx_id;
+ } in;
+ struct {
+ abi_ullong status;
+ } out;
+};
+
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 2a48b2ec47..b90bfdbbfd 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -355,6 +355,61 @@ STRUCT(drm_prime_handle,
TYPE_INT, /* flags */
TYPE_INT) /* fd */
+/* amdgpu specific */
+STRUCT(drm_amdgpu_gem_create,
+ TYPE_INT, /* [out] handle */
+ TYPE_INT, /* [out] _pad; [in] bo_size */
+ TYPE_ULONGLONG, /* [in] alignment */
+ TYPE_ULONGLONG, /* [in] domains */
+ TYPE_ULONGLONG) /* [in] domain_flags */
+
+STRUCT(drm_amdgpu_gem_mmap,
+ TYPE_ULONGLONG) /* [out] addr_ptr */
+
+STRUCT(drm_amdgpu_ctx,
+ TYPE_INT, /* [in] op */
+ TYPE_INT, /* [in] flags */
+ TYPE_INT, /* [in] ctx_id */
+ TYPE_INT) /* [in] priority */
+
+STRUCT(drm_amdgpu_cs,
+ TYPE_INT, /* [in] ctx_id */
+ TYPE_INT, /* [in] bo_list_handle */
+ TYPE_INT, /* [in] num_chunks */
+ TYPE_INT, /* [in] flags */
+ TYPE_PTRVOID) /* [in] chunks */
+
+STRUCT(drm_amdgpu_info,
+ TYPE_PTRVOID, /* return pointer */
+ TYPE_INT, /* return size */
+ TYPE_INT, /* query id */
+ MK_ARRAY(TYPE_INT, 4)) /* union */
+
+STRUCT(drm_amdgpu_gem_metadata,
+ TYPE_INT, /* handle */
+ TYPE_INT, /* op */
+ TYPE_ULONGLONG, /* flags */
+ TYPE_ULONGLONG, /* tiling_info */
+ TYPE_INT, /* data_size_bytes */
+ MK_ARRAY(TYPE_INT, 64)) /* data */
+
+STRUCT(drm_amdgpu_gem_va,
+ TYPE_INT, /* handle */
+ TYPE_INT, /* pad */
+ TYPE_INT, /* operation */
+ TYPE_INT, /* flags */
+ TYPE_ULONGLONG, /* va_address */
+ TYPE_ULONGLONG, /* offset_in_bo */
+ TYPE_ULONGLONG) /* map_size */
+
+STRUCT(drm_amdgpu_wait_cs,
+ TYPE_ULONGLONG, /* [in] handle; [out] status */
+ TYPE_ULONGLONG, /* [in] timeout */
+ TYPE_INT, /* [in] ip_type */
+ TYPE_INT, /* [in] ip_instance */
+ TYPE_INT, /* [in] ring */
+ TYPE_INT) /* [in] ctx_id */
+
STRUCT(drm_i915_getparam,
TYPE_INT, /* param */
TYPE_PTRVOID) /* value */
--
2.40.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment