Skip to content

Commit e865b97

Browse files
Chen-Gangvivier
authored andcommitted
linux-user: syscall: ioctls: support DRM_IOCTL_VERSION
Another DRM_IOCTL_* commands will be done later. Signed-off-by: Chen Gang <[email protected]> Reviewed-by: Laurent Vivier <[email protected]> Message-Id: <[email protected]> Signed-off-by: Laurent Vivier <[email protected]>
1 parent d43624c commit e865b97

File tree

5 files changed

+139
-0
lines changed

5 files changed

+139
-0
lines changed

configure

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,6 +3194,13 @@ if ! check_include "ifaddrs.h" ; then
31943194
have_ifaddrs_h=no
31953195
fi
31963196

3197+
#########################################
3198+
# libdrm check
3199+
have_drm_h=no
3200+
if check_include "libdrm/drm.h" ; then
3201+
have_drm_h=yes
3202+
fi
3203+
31973204
##########################################
31983205
# VTE probe
31993206

@@ -7377,6 +7384,9 @@ fi
73777384
if test "$have_ifaddrs_h" = "yes" ; then
73787385
echo "HAVE_IFADDRS_H=y" >> $config_host_mak
73797386
fi
7387+
if test "$have_drm_h" = "yes" ; then
7388+
echo "HAVE_DRM_H=y" >> $config_host_mak
7389+
fi
73807390
if test "$have_broken_size_max" = "yes" ; then
73817391
echo "HAVE_BROKEN_SIZE_MAX=y" >> $config_host_mak
73827392
fi

linux-user/ioctls.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,11 @@
574574
IOCTL_SPECIAL(SIOCDELRT, IOC_W, do_ioctl_rt,
575575
MK_PTR(MK_STRUCT(STRUCT_rtentry)))
576576

577+
#ifdef HAVE_DRM_H
578+
IOCTL_SPECIAL(DRM_IOCTL_VERSION, IOC_RW, do_ioctl_drm,
579+
MK_PTR(MK_STRUCT(STRUCT_drm_version)))
580+
#endif
581+
577582
#ifdef TARGET_TIOCSTART
578583
IOCTL_IGNORE(TIOCSTART)
579584
IOCTL_IGNORE(TIOCSTOP)

linux-user/syscall.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@
112112
#include <linux/if_alg.h>
113113
#include <linux/rtc.h>
114114
#include <sound/asound.h>
115+
#ifdef HAVE_DRM_H
116+
#include <libdrm/drm.h>
117+
#endif
115118
#include "linux_loop.h"
116119
#include "uname.h"
117120

@@ -5276,6 +5279,101 @@ static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp,
52765279
}
52775280
#endif
52785281

5282+
#ifdef HAVE_DRM_H
5283+
5284+
static void unlock_drm_version(struct drm_version *host_ver,
5285+
struct target_drm_version *target_ver,
5286+
bool copy)
5287+
{
5288+
unlock_user(host_ver->name, target_ver->name,
5289+
copy ? host_ver->name_len : 0);
5290+
unlock_user(host_ver->date, target_ver->date,
5291+
copy ? host_ver->date_len : 0);
5292+
unlock_user(host_ver->desc, target_ver->desc,
5293+
copy ? host_ver->desc_len : 0);
5294+
}
5295+
5296+
static inline abi_long target_to_host_drmversion(struct drm_version *host_ver,
5297+
struct target_drm_version *target_ver)
5298+
{
5299+
memset(host_ver, 0, sizeof(*host_ver));
5300+
5301+
__get_user(host_ver->name_len, &target_ver->name_len);
5302+
if (host_ver->name_len) {
5303+
host_ver->name = lock_user(VERIFY_WRITE, target_ver->name,
5304+
target_ver->name_len, 0);
5305+
if (!host_ver->name) {
5306+
return -EFAULT;
5307+
}
5308+
}
5309+
5310+
__get_user(host_ver->date_len, &target_ver->date_len);
5311+
if (host_ver->date_len) {
5312+
host_ver->date = lock_user(VERIFY_WRITE, target_ver->date,
5313+
target_ver->date_len, 0);
5314+
if (!host_ver->date) {
5315+
goto err;
5316+
}
5317+
}
5318+
5319+
__get_user(host_ver->desc_len, &target_ver->desc_len);
5320+
if (host_ver->desc_len) {
5321+
host_ver->desc = lock_user(VERIFY_WRITE, target_ver->desc,
5322+
target_ver->desc_len, 0);
5323+
if (!host_ver->desc) {
5324+
goto err;
5325+
}
5326+
}
5327+
5328+
return 0;
5329+
err:
5330+
unlock_drm_version(host_ver, target_ver, false);
5331+
return -EFAULT;
5332+
}
5333+
5334+
static inline void host_to_target_drmversion(
5335+
struct target_drm_version *target_ver,
5336+
struct drm_version *host_ver)
5337+
{
5338+
__put_user(host_ver->version_major, &target_ver->version_major);
5339+
__put_user(host_ver->version_minor, &target_ver->version_minor);
5340+
__put_user(host_ver->version_patchlevel, &target_ver->version_patchlevel);
5341+
__put_user(host_ver->name_len, &target_ver->name_len);
5342+
__put_user(host_ver->date_len, &target_ver->date_len);
5343+
__put_user(host_ver->desc_len, &target_ver->desc_len);
5344+
unlock_drm_version(host_ver, target_ver, true);
5345+
}
5346+
5347+
static abi_long do_ioctl_drm(const IOCTLEntry *ie, uint8_t *buf_temp,
5348+
int fd, int cmd, abi_long arg)
5349+
{
5350+
struct drm_version *ver;
5351+
struct target_drm_version *target_ver;
5352+
abi_long ret;
5353+
5354+
switch (ie->host_cmd) {
5355+
case DRM_IOCTL_VERSION:
5356+
if (!lock_user_struct(VERIFY_WRITE, target_ver, arg, 0)) {
5357+
return -TARGET_EFAULT;
5358+
}
5359+
ver = (struct drm_version *)buf_temp;
5360+
ret = target_to_host_drmversion(ver, target_ver);
5361+
if (!is_error(ret)) {
5362+
ret = get_errno(safe_ioctl(fd, ie->host_cmd, ver));
5363+
if (is_error(ret)) {
5364+
unlock_drm_version(ver, target_ver, false);
5365+
} else {
5366+
host_to_target_drmversion(target_ver, ver);
5367+
}
5368+
}
5369+
unlock_user_struct(target_ver, arg, 0);
5370+
return ret;
5371+
}
5372+
return -TARGET_ENOSYS;
5373+
}
5374+
5375+
#endif
5376+
52795377
static IOCTLEntry ioctl_entries[] = {
52805378
#define IOCTL(cmd, access, ...) \
52815379
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },

linux-user/syscall_defs.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,9 @@ struct target_rtc_pll_info {
11671167
#define TARGET_DM_TARGET_MSG TARGET_IOWRU(0xfd, 0x0e)
11681168
#define TARGET_DM_DEV_SET_GEOMETRY TARGET_IOWRU(0xfd, 0x0f)
11691169

1170+
/* drm ioctls */
1171+
#define TARGET_DRM_IOCTL_VERSION TARGET_IOWRU('d', 0x00)
1172+
11701173
/* from asm/termbits.h */
11711174

11721175
#define TARGET_NCC 8
@@ -2598,6 +2601,18 @@ struct target_mq_attr {
25982601
abi_long mq_curmsgs;
25992602
};
26002603

2604+
struct target_drm_version {
2605+
int version_major;
2606+
int version_minor;
2607+
int version_patchlevel;
2608+
abi_ulong name_len;
2609+
abi_ulong name;
2610+
abi_ulong date_len;
2611+
abi_ulong date;
2612+
abi_ulong desc_len;
2613+
abi_ulong desc;
2614+
};
2615+
26012616
#include "socket.h"
26022617

26032618
#include "errno_defs.h"

linux-user/syscall_types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,17 @@ STRUCT(dm_target_versions,
292292
STRUCT(dm_target_msg,
293293
TYPE_ULONGLONG) /* sector */
294294

295+
STRUCT(drm_version,
296+
TYPE_INT, /* version_major */
297+
TYPE_INT, /* version_minor */
298+
TYPE_INT, /* version_patchlevel */
299+
TYPE_ULONG, /* name_len */
300+
TYPE_PTRVOID, /* name */
301+
TYPE_ULONG, /* date_len */
302+
TYPE_PTRVOID, /* date */
303+
TYPE_ULONG, /* desc_len */
304+
TYPE_PTRVOID) /* desc */
305+
295306
STRUCT(file_clone_range,
296307
TYPE_LONGLONG, /* src_fd */
297308
TYPE_ULONGLONG, /* src_offset */

0 commit comments

Comments
 (0)