diff options
author | Jeremiah Griffin <jzgriffin@google.com> | 2024-05-01 15:53:57 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-05-01 15:53:57 +0000 |
commit | 07b7c15db5bf1e8d708331b32ed325353e2fac28 (patch) | |
tree | 81430dbd58cc7bf182f1919306652e5249b7fbc4 | |
parent | 09fc54a7b8ae1f3aa3019fcc87756f6f99395cc0 (diff) | |
parent | 9934caf97a2d6244827a376312797bf6ef39ad62 (diff) | |
download | binary_translation-07b7c15db5bf1e8d708331b32ed325353e2fac28.tar.gz |
Merge "kernel_api: Implement riscv_hwprobe" into main
-rw-r--r-- | kernel_api/riscv64/gen_syscall_emulation_riscv64_to_x86_64-inl.h | 3 | ||||
-rw-r--r-- | kernel_api/riscv64/guest_types.h | 34 | ||||
-rw-r--r-- | kernel_api/riscv64/syscall_emulation.cc | 54 | ||||
-rw-r--r-- | kernel_api/tools/custom_syscalls.json | 6 |
4 files changed, 97 insertions, 0 deletions
diff --git a/kernel_api/riscv64/gen_syscall_emulation_riscv64_to_x86_64-inl.h b/kernel_api/riscv64/gen_syscall_emulation_riscv64_to_x86_64-inl.h index 5c9ba7b4..4e241a15 100644 --- a/kernel_api/riscv64/gen_syscall_emulation_riscv64_to_x86_64-inl.h +++ b/kernel_api/riscv64/gen_syscall_emulation_riscv64_to_x86_64-inl.h @@ -524,6 +524,9 @@ long RunGuestSyscallImpl(long guest_nr, case 259: // __NR_riscv_flush_icache // missing on x86_64 return RunGuestSyscall___NR_riscv_flush_icache(arg_1, arg_2, arg_3); + case 258: // __NR_riscv_hwprobe + // missing on x86_64 + return RunGuestSyscall___NR_riscv_hwprobe(arg_1, arg_2, arg_3, arg_4, arg_5); case 293: // __NR_rseq // missing prototype KAPI_TRACE("unsupported syscall __NR_rseq"); diff --git a/kernel_api/riscv64/guest_types.h b/kernel_api/riscv64/guest_types.h index 6fe7e810..55faefe1 100644 --- a/kernel_api/riscv64/guest_types.h +++ b/kernel_api/riscv64/guest_types.h @@ -107,6 +107,40 @@ CHECK_FIELD_LAYOUT(Guest_stat, st_atim, 576, 128); CHECK_FIELD_LAYOUT(Guest_stat, st_mtim, 704, 128); CHECK_FIELD_LAYOUT(Guest_stat, st_ctim, 832, 128); +struct Guest_riscv_hwprobe { + int64_t key; + uint64_t value; +}; + +CHECK_STRUCT_LAYOUT(Guest_riscv_hwprobe, 128, 64); +CHECK_FIELD_LAYOUT(Guest_riscv_hwprobe, key, 0, 64); +CHECK_FIELD_LAYOUT(Guest_riscv_hwprobe, value, 64, 64); + +// Each RISCV_HWPROBE_KEY_* represents a capability key. These constants are sorted +// such that each capability key appears in numeric order, followed by the possible +// values for that key in numeric order. +// clang-format off +#define RISCV_HWPROBE_KEY_MVENDORID 0 +#define RISCV_HWPROBE_KEY_MARCHID 1 +#define RISCV_HWPROBE_KEY_MIMPID 2 +#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3 +#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0) +#define RISCV_HWPROBE_KEY_IMA_EXT_0 4 +#define RISCV_HWPROBE_IMA_FD (1 << 0) +#define RISCV_HWPROBE_IMA_C (1 << 1) +#define RISCV_HWPROBE_IMA_V (1 << 2) +#define RISCV_HWPROBE_EXT_ZBA (1 << 3) +#define RISCV_HWPROBE_EXT_ZBB (1 << 4) +#define RISCV_HWPROBE_EXT_ZBS (1 << 5) +#define RISCV_HWPROBE_KEY_CPUPERF_0 5 +#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0) +#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0) +#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0) +#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0) +#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0) +#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0) +// clang-format on + } // namespace berberis #endif // BERBERIS_KERNEL_API_RISCV64_GUEST_TYPES_ARCH_H_ diff --git a/kernel_api/riscv64/syscall_emulation.cc b/kernel_api/riscv64/syscall_emulation.cc index 0a56a728..f9ad1388 100644 --- a/kernel_api/riscv64/syscall_emulation.cc +++ b/kernel_api/riscv64/syscall_emulation.cc @@ -15,8 +15,10 @@ */ #include <fcntl.h> // AT_FDCWD, AT_SYMLINK_NOFOLLOW +#include <linux/sched.h> #include <linux/unistd.h> #include <sys/stat.h> +#include <sys/sysinfo.h> #include <sys/types.h> #include <cerrno> @@ -65,6 +67,35 @@ int FstatatForGuest(int dirfd, const char* path, struct stat* buf, int flags) { return syscall(__NR_newfstatat, dirfd, real_path ? real_path : path, buf, flags); } +void Hwprobe(Guest_riscv_hwprobe& pair) { + switch (pair.key) { + case RISCV_HWPROBE_KEY_MVENDORID: + pair.value = 0; + break; + case RISCV_HWPROBE_KEY_MARCHID: + pair.value = 0; + break; + case RISCV_HWPROBE_KEY_MIMPID: + pair.value = 0; + break; + case RISCV_HWPROBE_KEY_BASE_BEHAVIOR: + pair.value = RISCV_HWPROBE_BASE_BEHAVIOR_IMA; + break; + case RISCV_HWPROBE_KEY_IMA_EXT_0: + pair.value = RISCV_HWPROBE_IMA_FD | RISCV_HWPROBE_IMA_C | RISCV_HWPROBE_IMA_V | + RISCV_HWPROBE_EXT_ZBA | RISCV_HWPROBE_EXT_ZBB | RISCV_HWPROBE_EXT_ZBS; + break; + case RISCV_HWPROBE_KEY_CPUPERF_0: + pair.value = RISCV_HWPROBE_MISALIGNED_FAST; + break; + default: + TRACE("unsupported __riscv_hwprobe capability key: %ld", pair.key); + pair.key = -1; + pair.value = 0; + break; + } +} + long RunGuestSyscall___NR_execveat(long arg_1, long arg_2, long arg_3, long arg_4, long arg_5) { UNUSED(arg_1, arg_2, arg_3, arg_4, arg_5); KAPI_TRACE("unimplemented syscall __NR_execveat"); @@ -104,6 +135,29 @@ long RunGuestSyscall___NR_newfstatat(long arg_1, long arg_2, long arg_3, long ar return result; } +long RunGuestSyscall___NR_riscv_hwprobe(long arg_1, + long arg_2, + long arg_3, + long arg_4, + long arg_5) { + UNUSED(arg_3, arg_4); // cpu_count, cpus_in + + // There are currently no flags defined by the kernel. This may change in the future. + static constexpr unsigned int kFlagsAll = 0; + + auto pairs = bit_cast<Guest_riscv_hwprobe*>(arg_1); + auto pair_count = bit_cast<size_t>(arg_2); + auto flags = static_cast<unsigned int>(bit_cast<unsigned long>(arg_5)); + if ((flags & ~kFlagsAll) != 0) { + return -EINVAL; + } + + for (size_t i = 0; i < pair_count; ++i) { + Hwprobe(pairs[i]); + } + return 0; +} + long RunGuestSyscall___NR_riscv_flush_icache(long arg_1, long arg_2, long arg_3) { static constexpr uint64_t kFlagsLocal = 1UL; static constexpr uint64_t kFlagsAll = kFlagsLocal; diff --git a/kernel_api/tools/custom_syscalls.json b/kernel_api/tools/custom_syscalls.json index 356e80c4..b91ecce0 100644 --- a/kernel_api/tools/custom_syscalls.json +++ b/kernel_api/tools/custom_syscalls.json @@ -201,6 +201,12 @@ "params": ["void*", "void*", "int32"] } }, + "__NR_riscv_hwprobe": { + "riscv64": { + "id": "258", + "params": ["struct riscv_hwprobe*", "size_t", "size_t", "unsigned long*", "unsigned int"] + } + }, "__NR_rt_sigaction": { "custom_reason": "changes signal action" }, |