Created
April 16, 2023 08:46
-
-
Save xctan/1794ede6d60cea7cf8b9701109fe7536 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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