Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinuxSyscalls: Update for new v6.13 syscalls #4283

Merged
merged 1 commit into from
Jan 21, 2025
Merged
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
LinuxSyscalls: Update for new v6.13 syscalls
Just four new *at variants of the xattr syscalls.
This will also let us use the *at variants for the non-at versions but I
didn't implement that optimization because this is brand new.
Sonicadvance1 committed Jan 20, 2025
commit fca4c7e6bfafb5443b1313c6bd7899f3402301b3
Original file line number Diff line number Diff line change
@@ -348,6 +348,10 @@ enum Syscalls_Arm64 {
SYSCALL_Arm64_lsm_set_self_attr = 460,
SYSCALL_Arm64_lsm_list_modules = 461,
SYSCALL_Arm64_mseal = 462,
SYSCALL_Arm64_setxattrat = 463,
SYSCALL_Arm64_getxattrat = 464,
SYSCALL_Arm64_listxattrat = 465,
SYSCALL_Arm64_removexattrat = 466,
SYSCALL_Arm64_MAX = 512,

// Unsupported syscalls on this host
80 changes: 80 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp
Original file line number Diff line number Diff line change
@@ -1171,6 +1171,86 @@ uint64_t FileManager::LRemovexattr(const char* path, const char* name) {
return ::lremovexattr(SelfPath, name);
}

uint64_t FileManager::SetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(setxattrat), dfd, pathname, at_flags, name, uargs, usize);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(setxattrat), Path.first, Path.second, at_flags, name, uargs, usize);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(setxattrat), dfd, SelfPath, at_flags, name, uargs, usize);
}

uint64_t FileManager::GetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(getxattrat), dfd, pathname, at_flags, name, uargs, usize);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(getxattrat), Path.first, Path.second, at_flags, name, uargs, usize);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(getxattrat), dfd, SelfPath, at_flags, name, uargs, usize);
}

uint64_t FileManager::ListxattrAt(int dfd, const char* pathname, uint32_t at_flags, char* list, size_t size) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(listxattrat), dfd, pathname, at_flags, list, size);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(listxattrat), Path.first, Path.second, at_flags, list, size);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(listxattrat), dfd, SelfPath, at_flags, list, size);
}

uint64_t FileManager::RemovexattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name) {
if (IsSelfNoFollow(pathname, at_flags)) {
// See Statx
return syscall(SYSCALL_DEF(removexattrat), dfd, pathname, at_flags, name);
}

auto NewPath = GetSelf(pathname);
const char* SelfPath = NewPath ? NewPath->data() : nullptr;

FDPathTmpData TmpFilename;
auto Path = GetEmulatedFDPath(dfd, SelfPath, (at_flags & AT_SYMLINK_NOFOLLOW) == 0, TmpFilename);
if (Path.first != -1) {
uint64_t Result = syscall(SYSCALL_DEF(removexattrat), Path.first, Path.second, at_flags, name);
if (Result != -1) {
return Result;
}
}
return syscall(SYSCALL_DEF(removexattrat), dfd, SelfPath, at_flags, name);
}

void FileManager::UpdatePID(uint32_t PID) {
CurrentPID = PID;

11 changes: 11 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.h
Original file line number Diff line number Diff line change
@@ -75,6 +75,17 @@ class FileManager final {
uint64_t LListxattr(const char* path, char* list, size_t size);
uint64_t Removexattr(const char* path, const char* name);
uint64_t LRemovexattr(const char* path, const char* name);
struct xattr_args {
uint64_t value;
uint32_t size;
uint32_t flags;
};

uint64_t SetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize);
uint64_t GetxattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name, const xattr_args* uargs, size_t usize);
uint64_t ListxattrAt(int dfd, const char* pathname, uint32_t at_flags, char* list, size_t size);
uint64_t RemovexattrAt(int dfd, const char* pathname, uint32_t at_flags, const char* name);

// vfs
uint64_t Statfs(const char* path, void* buf);

26 changes: 26 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FS.cpp
Original file line number Diff line number Diff line change
@@ -126,5 +126,31 @@ void RegisterFS(FEX::HLE::SyscallHandler* Handler) {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.LRemovexattr(path, name);
SYSCALL_ERRNO();
});
if (Handler->IsHostKernelVersionAtLeast(6, 13, 0)) {
REGISTER_SYSCALL_IMPL(
setxattrat, [](int dfd, const char* pathname, uint32_t at_flags, const char* name, const FileManager::xattr_args* uargs, size_t usize) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.SetxattrAt(dfd, pathname, at_flags, name, uargs, usize);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(
getxattrat, [](int dfd, const char* pathname, uint32_t at_flags, const char* name, const FileManager::xattr_args* uargs, size_t usize) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.GetxattrAt(dfd, pathname, at_flags, name, uargs, usize);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL(listxattrat, [](int dfd, const char* pathname, uint32_t at_flags, char* list, size_t size) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.ListxattrAt(dfd, pathname, at_flags, list, size);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(removexattrat, [](int dfd, const char* pathname, uint32_t at_flags, const char* name) -> uint64_t {
uint64_t Result = FEX::HLE::_SyscallHandler->FM.RemovexattrAt(dfd, pathname, at_flags, name);
SYSCALL_ERRNO();
});
} else {
REGISTER_SYSCALL_IMPL(setxattrat, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(getxattrat, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(listxattrat, UnimplementedSyscallSafe);
REGISTER_SYSCALL_IMPL(removexattrat, UnimplementedSyscallSafe);
}
}
} // namespace FEX::HLE
4 changes: 4 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x32/SyscallsEnum.h
Original file line number Diff line number Diff line change
@@ -480,6 +480,10 @@ enum Syscalls_x86 {
SYSCALL_x86_lsm_set_self_attr = 460,
SYSCALL_x86_lsm_list_modules = 461,
SYSCALL_x86_mseal = 462,
SYSCALL_x86_setxattrat = 463,
SYSCALL_x86_getxattrat = 464,
SYSCALL_x86_listxattrat = 465,
SYSCALL_x86_removexattrat = 466,
SYSCALL_x86_MAX = 512,
};
} // namespace FEX::HLE::x32
4 changes: 4 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x64/SyscallsEnum.h
Original file line number Diff line number Diff line change
@@ -400,6 +400,10 @@ enum Syscalls_x64 {
SYSCALL_x64_lsm_set_self_attr = 460,
SYSCALL_x64_lsm_list_modules = 461,
SYSCALL_x64_mseal = 462,
SYSCALL_x64_setxattrat = 463,
SYSCALL_x64_getxattrat = 464,
SYSCALL_x64_listxattrat = 465,
SYSCALL_x64_removexattrat = 466,
SYSCALL_x64_MAX = 512,

// Unsupported syscalls on this host