Skip to content

Commit

Permalink
Linux: Converts passthrough syscalls to direct passthrough handlers
Browse files Browse the repository at this point in the history
Reimagining of FEX-Emu#3355 without any json generators or new concepts.

Fixes some mislabeling of system calls. Some getting inlined when they
shouldn't be, a lot not getting inlined when they can be.

This really cleans up the syscall implementation, all syscalls that can
be passthrough implementations require a very small two line
declaration.
Additionally cleans up a bit of implementation cruft where some
passthrough syscalls were using the glibc syscall handler, and some were
using the glibc implementation. We have had multiple issues in the past
where the glibc implementation does something subtly different than the
raw syscall and breaks things. Now all passthrough handlers do a system
call directly, removing at least one indirection and some ambiguity.

This makes it significantly easier to add new passthrough syscalls as
well. Only need to do a version check and add the three lines per
syscall. Which there are new syscalls incoming that we will want to add.

Tangible improvements:
- Syscalls are lower overhead than ever.
- When I'm adding more syscalls I have less chance of mucking it up.
  • Loading branch information
Sonicadvance1 committed Feb 24, 2024
1 parent 7e2f20c commit ab1b408
Show file tree
Hide file tree
Showing 44 changed files with 938 additions and 2,138 deletions.
15 changes: 1 addition & 14 deletions Source/Tools/LinuxEmulation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,23 @@ set (SRCS
LinuxSyscalls/x32/IoctlEmulation.cpp
LinuxSyscalls/x64/EPoll.cpp
LinuxSyscalls/x64/FD.cpp
LinuxSyscalls/x64/IO.cpp
LinuxSyscalls/x64/Ioctl.cpp
LinuxSyscalls/x64/Info.cpp
LinuxSyscalls/x64/Memory.cpp
LinuxSyscalls/x64/Msg.cpp
LinuxSyscalls/x64/NotImplemented.cpp
LinuxSyscalls/x64/Semaphore.cpp
LinuxSyscalls/x64/Sched.cpp
LinuxSyscalls/x64/Signals.cpp
LinuxSyscalls/x64/Socket.cpp
LinuxSyscalls/x64/Thread.cpp
LinuxSyscalls/x64/Syscalls.cpp
LinuxSyscalls/x64/Time.cpp
LinuxSyscalls/Syscalls/EPoll.cpp
LinuxSyscalls/Syscalls/FD.cpp
LinuxSyscalls/Syscalls/FS.cpp
LinuxSyscalls/Syscalls/Passthrough.cpp
LinuxSyscalls/Syscalls/Info.cpp
LinuxSyscalls/Syscalls/IO.cpp
LinuxSyscalls/Syscalls/IOUring.cpp
LinuxSyscalls/Syscalls/Key.cpp
LinuxSyscalls/Syscalls/Memory.cpp
LinuxSyscalls/Syscalls/Msg.cpp
LinuxSyscalls/Syscalls/Namespace.cpp
LinuxSyscalls/Syscalls/Sched.cpp
LinuxSyscalls/Syscalls/Semaphore.cpp
LinuxSyscalls/Syscalls/SHM.cpp
LinuxSyscalls/Syscalls/Signals.cpp
LinuxSyscalls/Syscalls/Socket.cpp
LinuxSyscalls/Syscalls/Thread.cpp
LinuxSyscalls/Syscalls/Time.cpp
LinuxSyscalls/Syscalls/Timer.cpp
LinuxSyscalls/Syscalls/NotImplemented.cpp
LinuxSyscalls/Syscalls/Stubs.cpp)
Expand Down
9 changes: 0 additions & 9 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,10 @@ class SignalDelegator;
void RegisterFS(FEX::HLE::SyscallHandler *Handler);
void RegisterInfo(FEX::HLE::SyscallHandler *Handler);
void RegisterIO(FEX::HLE::SyscallHandler *Handler);
void RegisterIOUring(FEX::HLE::SyscallHandler *Handler);
void RegisterKey(FEX::HLE::SyscallHandler *Handler);
void RegisterMemory(FEX::HLE::SyscallHandler *Handler);
void RegisterMsg(FEX::HLE::SyscallHandler *Handler);
void RegisterNamespace(FEX::HLE::SyscallHandler *Handler);
void RegisterNuma(FEX::HLE::SyscallHandler *Handler);
void RegisterSched(FEX::HLE::SyscallHandler *Handler);
void RegisterSemaphore(FEX::HLE::SyscallHandler *Handler);
void RegisterSHM(FEX::HLE::SyscallHandler *Handler);
void RegisterSignals(FEX::HLE::SyscallHandler *Handler);
void RegisterSocket(FEX::HLE::SyscallHandler *Handler);
void RegisterThread(FEX::HLE::SyscallHandler *Handler);
void RegisterTime(FEX::HLE::SyscallHandler *Handler);
void RegisterTimer(FEX::HLE::SyscallHandler *Handler);
void RegisterNotImplemented(FEX::HLE::SyscallHandler *Handler);
void RegisterStubs(FEX::HLE::SyscallHandler *Handler);
Expand Down
8 changes: 1 addition & 7 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/EPoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,10 @@ namespace FEX::HLE {
void RegisterEpoll(FEX::HLE::SyscallHandler *Handler) {
using namespace FEXCore::IR;

REGISTER_SYSCALL_IMPL_PASS_FLAGS(epoll_create, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(epoll_create, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int size) -> uint64_t {
uint64_t Result = epoll_create(size);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(epoll_create1, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int flags) -> uint64_t {
uint64_t Result = epoll_create1(flags);
SYSCALL_ERRNO();
});
}
}
288 changes: 5 additions & 283 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FD.cpp

Large diffs are not rendered by default.

166 changes: 8 additions & 158 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,55 +25,37 @@ namespace FEX::HLE {
void RegisterFS(FEX::HLE::SyscallHandler *Handler) {
using namespace FEXCore::IR;

REGISTER_SYSCALL_IMPL_PASS_FLAGS(getcwd, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, char *buf, size_t size) -> uint64_t {
uint64_t Result = syscall(SYSCALL_DEF(getcwd), buf, size);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(chdir, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path) -> uint64_t {
uint64_t Result = ::chdir(path);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(fchdir, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int fd) -> uint64_t {
uint64_t Result = ::fchdir(fd);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(rename, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(rename, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *oldpath, const char *newpath) -> uint64_t {
uint64_t Result = ::rename(oldpath, newpath);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(mkdir, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(mkdir, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *pathname, mode_t mode) -> uint64_t {
uint64_t Result = ::mkdir(pathname, mode);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(rmdir, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(rmdir, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *pathname) -> uint64_t {
uint64_t Result = ::rmdir(pathname);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(link, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(link, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *oldpath, const char *newpath) -> uint64_t {
uint64_t Result = ::link(oldpath, newpath);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(unlink, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(unlink, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *pathname) -> uint64_t {
uint64_t Result = ::unlink(pathname);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(symlink, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(symlink, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *target, const char *linkpath) -> uint64_t {
uint64_t Result = ::symlink(target, linkpath);
SYSCALL_ERRNO();
Expand All @@ -85,103 +67,24 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(chmod, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(chmod, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *pathname, mode_t mode) -> uint64_t {
uint64_t Result = ::chmod(pathname, mode);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(umask, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, mode_t mask) -> uint64_t {
uint64_t Result = ::umask(mask);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_FLAGS(mknod, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *pathname, mode_t mode, dev_t dev) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Mknod(pathname, mode, dev);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(ustat, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, dev_t dev, struct ustat *ubuf) -> uint64_t {
// Doesn't exist on AArch64, will return -ENOSYS
// Since version 2.28 of GLIBC it has stopped providing a wrapper for this syscall
uint64_t Result = syscall(SYSCALL_DEF(ustat), dev, ubuf);
SYSCALL_ERRNO();
});

/*
arg1 is one of: void, unsigned int fs_index, const char *fsname
arg2 is one of: void, char *buf
*/
REGISTER_SYSCALL_IMPL_PASS_FLAGS(sysfs, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int option, uint64_t arg1, uint64_t arg2) -> uint64_t {
// Doesn't exist on AArch64, will return -ENOSYS
uint64_t Result = syscall(SYSCALL_DEF(sysfs), option, arg1, arg2);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(truncate, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path, off_t length) -> uint64_t {
uint64_t Result = ::truncate(path, length);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(creat, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(creat, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *pathname, mode_t mode) -> uint64_t {
uint64_t Result = ::creat(pathname, mode);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(chroot, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path) -> uint64_t {
uint64_t Result = ::chroot(path);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(sync, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame) -> uint64_t {
sync();
return 0; // always successful
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(acct, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *filename) -> uint64_t {
uint64_t Result = ::acct(filename);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(mount, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) -> uint64_t {
uint64_t Result = ::mount(source, target, filesystemtype, mountflags, data);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(umount2, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *target, int flags) -> uint64_t {
uint64_t Result = ::umount2(target, flags);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(swapon, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path, int swapflags) -> uint64_t {
uint64_t Result = ::swapon(path, swapflags);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(swapoff, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path) -> uint64_t {
uint64_t Result = ::swapoff(path);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(syncfs, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int fd) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(syncfs), fd);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL(setxattr,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path, const char *name, const void *value, size_t size, int flags) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Setxattr(path, name, value, size, flags);
Expand All @@ -194,12 +97,6 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(fsetxattr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int fd, const char *name, const void *value, size_t size, int flags) -> uint64_t {
uint64_t Result = ::fsetxattr(fd, name, value, size, flags);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL(getxattr,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path, const char *name, void *value, size_t size) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Getxattr(path, name, value, size);
Expand All @@ -212,12 +109,6 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(fgetxattr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int fd, const char *name, void *value, size_t size) -> uint64_t {
uint64_t Result = ::fgetxattr(fd, name, value, size);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL(listxattr,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path, char *list, size_t size) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Listxattr(path, list, size);
Expand All @@ -230,12 +121,6 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(flistxattr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int fd, char *list, size_t size) -> uint64_t {
uint64_t Result = ::flistxattr(fd, list, size);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL(removexattr,
[](FEXCore::Core::CpuStateFrame *Frame, const char *path, const char *name) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Removexattr(path, name);
Expand All @@ -247,40 +132,5 @@ namespace FEX::HLE {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.LRemovexattr(path, name);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(fremovexattr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int fd, const char *name) -> uint64_t {
uint64_t Result = ::fremovexattr(fd, name);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(fanotify_init, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, unsigned int flags, unsigned int event_f_flags) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(fanotify_init), flags, event_f_flags);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(fanotify_mark, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int fanotify_fd, unsigned int flags, uint64_t mask, int dirfd, const char *pathname) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(fanotify_mark), fanotify_fd, flags, mask, dirfd, pathname);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(pivot_root, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, const char *new_root, const char *put_old) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(pivot_root), new_root, put_old);
SYSCALL_ERRNO();
});

if (Handler->IsHostKernelVersionAtLeast(5, 14, 0)) {
REGISTER_SYSCALL_IMPL_PASS_FLAGS(quotactl_fd, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, uint32_t fd, uint32_t cmd, uint32_t id, void* addr) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(quotactl_fd), fd, cmd, id, addr);
SYSCALL_ERRNO();
});
}
else {
REGISTER_SYSCALL_IMPL(quotactl_fd, UnimplementedSyscallSafe);
}
}
}
40 changes: 2 additions & 38 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,52 +19,16 @@ namespace FEX::HLE {
void RegisterIO(FEX::HLE::SyscallHandler *Handler) {
using namespace FEXCore::IR;

REGISTER_SYSCALL_IMPL_PASS_FLAGS(iopl, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(iopl, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int level) -> uint64_t {
// Just claim we don't have permission
return -EPERM;
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(ioperm, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(ioperm, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, unsigned long from, unsigned long num, int turn_on) -> uint64_t {
// ioperm not available on our architecture
return -EPERM;
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_setup, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, unsigned nr_events, aio_context_t *ctx_idp) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(io_setup), nr_events, ctx_idp);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_destroy, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, aio_context_t ctx_id) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(io_destroy), ctx_id);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_submit, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, aio_context_t ctx_id, long nr, struct iocb **iocbpp) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(io_submit), ctx_id, nr, iocbpp);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_cancel, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, aio_context_t ctx_id, struct iocb *iocb, struct io_event *result) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(io_cancel), ctx_id, iocb, result);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(ioprio_set, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int which, int who) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(ioprio_set), which, who);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(ioprio_get, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int which, int who, int ioprio) -> uint64_t {
uint64_t Result = ::syscall(SYSCALL_DEF(ioprio_get), which, who, ioprio);
SYSCALL_ERRNO();
});
}
}
Loading

0 comments on commit ab1b408

Please sign in to comment.