Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions accel/tcg/user-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,11 @@ int cpu_signal_handler(int host_signum, void *pinfo,
}
}
if (info->si_signo == SIGBUS) {
/* Keep a target-queued SIGBUS on the target signal path. */
if (info->si_code == SI_KERNEL && info->si_addr != NULL) {
mmap_unlock();
return 0;
}
int ret = lock_interpret(info, uc);
if (!ret) {
mmap_unlock();
Expand Down
2 changes: 2 additions & 0 deletions linux-user/elfload.c
Original file line number Diff line number Diff line change
Expand Up @@ -3480,6 +3480,8 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
info->load_bias = interp_info.load_bias;
info->entry = interp_info.entry;
info->interpreter_path = elf_interpreter;
info->interpreter_start_code = interp_info.start_code;
info->interpreter_end_code = interp_info.end_code;
//g_free(elf_interpreter);
}
#if defined(CONFIG_LATX_KZT)
Expand Down
117 changes: 117 additions & 0 deletions linux-user/fd-trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,123 @@ enum {

TargetFdTrans **target_fd_trans;
unsigned int target_fd_max;
/* Guest threads share and can concurrently grow this descriptor table. */
static pthread_mutex_t target_fd_trans_mutex = PTHREAD_MUTEX_INITIALIZER;

static TargetFdTrans *fd_trans_lookup_locked(int fd)
{
if (fd >= 0 && fd < target_fd_max) {
return target_fd_trans[fd];
}
return NULL;
}

static void fd_trans_register_locked(int fd, TargetFdTrans *trans)
{
if (fd >= target_fd_max) {
unsigned int oldmax = target_fd_max;
unsigned int newmax = ((fd >> 6) + 1) << 6;
TargetFdTrans **new_trans;

new_trans = g_renew(TargetFdTrans *, target_fd_trans, newmax);
memset(new_trans + oldmax, 0,
(newmax - oldmax) * sizeof(*new_trans));
target_fd_trans = new_trans;
target_fd_max = newmax;
}
target_fd_trans[fd] = trans;
}

TargetFdDataFunc fd_trans_target_to_host_data(int fd)
{
TargetFdTrans *trans;
TargetFdDataFunc func = NULL;

pthread_mutex_lock(&target_fd_trans_mutex);
trans = fd_trans_lookup_locked(fd);
if (trans) {
func = trans->target_to_host_data;
}
pthread_mutex_unlock(&target_fd_trans_mutex);
return func;
}

TargetFdDataFunc fd_trans_host_to_target_data(int fd)
{
TargetFdTrans *trans;
TargetFdDataFunc func = NULL;

pthread_mutex_lock(&target_fd_trans_mutex);
trans = fd_trans_lookup_locked(fd);
if (trans) {
func = trans->host_to_target_data;
}
pthread_mutex_unlock(&target_fd_trans_mutex);
return func;
}

TargetFdAddrFunc fd_trans_target_to_host_addr(int fd)
{
TargetFdTrans *trans;
TargetFdAddrFunc func = NULL;

pthread_mutex_lock(&target_fd_trans_mutex);
trans = fd_trans_lookup_locked(fd);
if (trans) {
func = trans->target_to_host_addr;
}
pthread_mutex_unlock(&target_fd_trans_mutex);
return func;
}

void fd_trans_register(int fd, TargetFdTrans *trans)
{
pthread_mutex_lock(&target_fd_trans_mutex);
fd_trans_register_locked(fd, trans);
pthread_mutex_unlock(&target_fd_trans_mutex);
}

void fd_trans_unregister(int fd)
{
pthread_mutex_lock(&target_fd_trans_mutex);
if (fd >= 0 && fd < target_fd_max) {
target_fd_trans[fd] = NULL;
}
pthread_mutex_unlock(&target_fd_trans_mutex);
}

void fd_trans_dup(int oldfd, int newfd)
{
TargetFdTrans *trans;

if (oldfd == newfd) {
return;
}

pthread_mutex_lock(&target_fd_trans_mutex);
trans = fd_trans_lookup_locked(oldfd);
if (newfd >= 0 && newfd < target_fd_max) {
target_fd_trans[newfd] = NULL;
}
if (trans) {
fd_trans_register_locked(newfd, trans);
}
pthread_mutex_unlock(&target_fd_trans_mutex);
}

void fd_trans_fork_start(void)
{
pthread_mutex_lock(&target_fd_trans_mutex);
}

void fd_trans_fork_end(int child)
{
if (child) {
pthread_mutex_init(&target_fd_trans_mutex, NULL);
} else {
pthread_mutex_unlock(&target_fd_trans_mutex);
}
}

static void tswap_nlmsghdr(struct nlmsghdr *nlh)
{
Expand Down
59 changes: 6 additions & 53 deletions linux-user/fd-trans.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,59 +28,12 @@ extern TargetFdTrans **target_fd_trans;

extern unsigned int target_fd_max;

static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd)
{
if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
return target_fd_trans[fd]->target_to_host_data;
}
return NULL;
}

static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd)
{
if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
return target_fd_trans[fd]->host_to_target_data;
}
return NULL;
}

static inline TargetFdAddrFunc fd_trans_target_to_host_addr(int fd)
{
if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
return target_fd_trans[fd]->target_to_host_addr;
}
return NULL;
}

static inline void fd_trans_register(int fd, TargetFdTrans *trans)
{
unsigned int oldmax;

if (fd >= target_fd_max) {
oldmax = target_fd_max;
target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */
target_fd_trans = g_renew(TargetFdTrans *,
target_fd_trans, target_fd_max);
memset((void *)(target_fd_trans + oldmax), 0,
(target_fd_max - oldmax) * sizeof(TargetFdTrans *));
}
target_fd_trans[fd] = trans;
}

static inline void fd_trans_unregister(int fd)
{
if (fd >= 0 && fd < target_fd_max) {
target_fd_trans[fd] = NULL;
}
}

static inline void fd_trans_dup(int oldfd, int newfd)
{
fd_trans_unregister(newfd);
if (oldfd < target_fd_max && target_fd_trans[oldfd]) {
fd_trans_register(newfd, target_fd_trans[oldfd]);
}
}
TargetFdDataFunc fd_trans_target_to_host_data(int fd);
TargetFdDataFunc fd_trans_host_to_target_data(int fd);
TargetFdAddrFunc fd_trans_target_to_host_addr(int fd);
void fd_trans_register(int fd, TargetFdTrans *trans);
void fd_trans_unregister(int fd);
void fd_trans_dup(int oldfd, int newfd);

extern TargetFdTrans target_packet_trans;
#ifdef CONFIG_RTNETLINK
Expand Down
14 changes: 13 additions & 1 deletion linux-user/ioctl/ioctl_def/def_amdgpu_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
TARGET_IOWR('d', 0x47, union drm_amdgpu_gem_wait_idle)
#define TARGET_DRM_IOCTL_AMDGPU_GEM_VA \
TARGET_IOWR('d', 0x48, struct drm_amdgpu_gem_va)
/* libdrm built against the pre-timeline GEM_VA UAPI uses this command. */
#define TARGET_DRM_IOCTL_AMDGPU_GEM_VA_OLD \
TARGET_IOWR('d', 0x48, struct target_drm_amdgpu_gem_va_old)
#define DRM_IOCTL_AMDGPU_GEM_VA_OLD DRM_IOCTL_AMDGPU_GEM_VA
#define TARGET_DRM_IOCTL_AMDGPU_WAIT_CS \
TARGET_IOWR('d', 0x49, union drm_amdgpu_wait_cs)
#define TARGET_DRM_IOCTL_AMDGPU_GEM_OP \
Expand Down Expand Up @@ -87,4 +91,12 @@ struct target_drm_amdgpu_fence_to_handle_in {
abi_uint what;
abi_uint pad;
};

struct target_drm_amdgpu_gem_va_old {
abi_uint handle;
abi_uint _pad;
abi_uint operation;
abi_uint flags;
abi_ullong va_address;
abi_ullong offset_in_bo;
abi_ullong map_size;
};
32 changes: 31 additions & 1 deletion linux-user/ioctl/ioctl_syscall/syscall_amdgpu_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ static inline abi_long target_to_host_drm_amdgpu_gem_metadata
return 0;
}

static inline abi_long target_to_host_drm_amdgpu_gem_va_old
(struct drm_amdgpu_gem_va *host_ver,
struct target_drm_amdgpu_gem_va_old *target_ver)
{
memset(host_ver, 0, sizeof(*host_ver));
__get_user(host_ver->handle, &target_ver->handle);
__get_user(host_ver->_pad, &target_ver->_pad);
__get_user(host_ver->operation, &target_ver->operation);
__get_user(host_ver->flags, &target_ver->flags);
__get_user(host_ver->va_address, &target_ver->va_address);
__get_user(host_ver->offset_in_bo, &target_ver->offset_in_bo);
__get_user(host_ver->map_size, &target_ver->map_size);
return 0;
}

static inline void host_to_target_drm_amdgpu_gem_metadata
(struct target_drm_amdgpu_gem_metadata *target_ver,
struct drm_amdgpu_gem_metadata *host_ver)
Expand Down Expand Up @@ -90,6 +105,8 @@ static abi_long do_ioctl_amdgpu_drm(const IOCTLEntry *ie,
struct drm_amdgpu_gem_metadata *drm_amdgpu_gem_metadata;
struct target_drm_amdgpu_fence_to_handle_in *target_drm_amdgpu_fence_to_handle_in;
union drm_amdgpu_fence_to_handle *drm_amdgpu_fence_to_handle;
struct target_drm_amdgpu_gem_va_old *target_drm_amdgpu_gem_va_old;
struct drm_amdgpu_gem_va *drm_amdgpu_gem_va;
switch (ie->host_cmd) {
case DRM_IOCTL_AMDGPU_INFO:
if (!lock_user_struct(VERIFY_READ, target_drm_amdgpu_info, arg, 0)) {
Expand Down Expand Up @@ -125,6 +142,20 @@ static abi_long do_ioctl_amdgpu_drm(const IOCTLEntry *ie,
}
unlock_user_struct(target_drm_amdgpu_gem_metadata, arg, 0);
return ret;
case DRM_IOCTL_AMDGPU_GEM_VA:
if (!lock_user_struct(VERIFY_READ,
target_drm_amdgpu_gem_va_old, arg, 0)) {
return -TARGET_EFAULT;
}
drm_amdgpu_gem_va = (struct drm_amdgpu_gem_va *)buf_temp;
ret = target_to_host_drm_amdgpu_gem_va_old(
drm_amdgpu_gem_va, target_drm_amdgpu_gem_va_old);
if (!is_error(ret)) {
ret = get_errno(safe_ioctl(fd, ie->host_cmd,
drm_amdgpu_gem_va));
}
unlock_user_struct(target_drm_amdgpu_gem_va_old, arg, 0);
return ret;
case DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE:
if (!lock_user_struct(VERIFY_READ,
target_drm_amdgpu_fence_to_handle_in, arg, 0)) {
Expand All @@ -147,4 +178,3 @@ static abi_long do_ioctl_amdgpu_drm(const IOCTLEntry *ie,
}
return -TARGET_ENOSYS;
}

8 changes: 8 additions & 0 deletions linux-user/ioctl/ioctl_type/type_amdgpu_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ STRUCT(drm_amdgpu_gem_wait_idle_in,
TYPE_INT,
TYPE_INT,
TYPE_ULONGLONG)
STRUCT(drm_amdgpu_gem_va_old,
TYPE_INT,
TYPE_INT,
TYPE_INT,
TYPE_INT,
TYPE_ULONGLONG,
TYPE_ULONGLONG,
TYPE_ULONGLONG)
#ifdef CONFIG_AMDGPU_GEN_VA_OLD
STRUCT(drm_amdgpu_gem_va,
TYPE_INT,
Expand Down
2 changes: 2 additions & 0 deletions linux-user/ioctl/ioctls/ioctl_amdgpu_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_GEM_METADATA, IOC_RW, do_ioctl_amdgpu_drm,
MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_metadata)))
IOCTL(DRM_IOCTL_AMDGPU_GEM_WAIT_IDLE, IOC_RW,
MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_wait_idle_in)))
IOCTL_SPECIAL(DRM_IOCTL_AMDGPU_GEM_VA_OLD, IOC_W, do_ioctl_amdgpu_drm,
MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_va_old)))
IOCTL(DRM_IOCTL_AMDGPU_GEM_VA, IOC_RW,
MK_PTR(MK_STRUCT(STRUCT_drm_amdgpu_gem_va)))
IOCTL(DRM_IOCTL_AMDGPU_WAIT_CS, IOC_RW,
Expand Down
22 changes: 22 additions & 0 deletions linux-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
#include "target_elf.h"
#include "cpu_loop-common.h"
#include "crypto/init.h"
#if defined(CONFIG_LATX) && defined(TARGET_X86_64)
#include "pressure-vessel.h"
#endif
int mydebug = 1;

#ifdef CONFIG_LATX
Expand Down Expand Up @@ -217,6 +220,7 @@ void fork_start(void)
mmap_fork_start();
sigact_fork_start();
path_fork_start();
fd_trans_fork_start();
cpu_list_lock();
}

Expand All @@ -225,6 +229,7 @@ void fork_end(int child)
mmap_fork_end(child);
sigact_fork_end(child);
path_fork_end(child);
fd_trans_fork_end(child);
if (child) {
CPUState *cpu, *next_cpu;
/* Child processes created by fork() only have a single thread.
Expand Down Expand Up @@ -1287,6 +1292,9 @@ int main(int argc, char **argv, char **envp)
unsigned int inherited_guest_mdwe = 0;
bool inherited_guest_tsc_disabled = false;
#endif
#if defined(CONFIG_LATX) && defined(TARGET_X86_64)
char **pressure_vessel_payload;
#endif

#if defined(CONFIG_LATX) && defined(__loongarch__)
/* Lets check hwcap */
Expand Down Expand Up @@ -1448,6 +1456,11 @@ int main(int argc, char **argv, char **envp)
/* Scan interp_prefix dir for replacement files. */
init_paths(interp_prefix);

#if defined(CONFIG_LATX) && defined(TARGET_X86_64)
pressure_vessel_payload = latx_pressure_vessel_prepare(exec_path,
target_argv, envlist);
#endif

init_qemu_uname_release();

/*
Expand Down Expand Up @@ -1546,6 +1559,15 @@ int main(int argc, char **argv, char **envp)
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);

#if defined(CONFIG_LATX) && defined(TARGET_X86_64)
if (pressure_vessel_payload) {
execve(pressure_vessel_payload[0], pressure_vessel_payload,
target_environ);
error_report("cannot launch Steam pressure-vessel payload %s: %s",
pressure_vessel_payload[0], strerror(errno));
}
#endif

#define KERNEL_CONFIG_LSM_MMAP_MIN_ADDR 65536
/*
* Read in mmap_min_addr kernel parameter. This value is used
Expand Down
1 change: 1 addition & 0 deletions linux-user/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ linux_user_ss.add(files(
'linuxload.c',
'main.c',
'mmap.c',
'pressure-vessel.c',
'safe-syscall.S',
'signal.c',
'strace.c',
Expand Down
Loading