Merge pull request #4374 from MarcZX100/codex/carry-getpriority-3632

feat(libkernel): implement getpriority for the guest process
This commit is contained in:
Dean 2026-10-14 10:36:42 +13:00 committed by GitHub
commit 665ad7da74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 0 deletions

View File

@ -118,10 +118,15 @@ bool hasPriorityRange(int policy) {
return policy == 1 || policy == 3;
}
constexpr int guestNoProcess = 3;
constexpr int guestFault = 14;
constexpr int guestInvalid = 22;
constexpr int guestRlimitCpu = 0;
constexpr int guestRlimitFsize = 1;
constexpr int guestPriorityProcess = 0;
constexpr int guestPriorityGroup = 1;
constexpr int guestPriorityUser = 2;
constexpr int guestNice = 0;
constexpr int guestRlimitData = 2;
constexpr int guestRlimitCore = 4;
constexpr int guestRlimitSbsize = 9;
@ -548,6 +553,20 @@ int APS5_VABI getrlimit_nid_postfix(int resource, GuestResourceLimit* limit) {
}
}
int APS5_VABI getpriority_nid_postfix(int which, int who) {
if (which != guestPriorityProcess && which != guestPriorityGroup && which != guestPriorityUser) {
*__error_nid_postfix() = guestInvalid;
return -1;
}
const bool found = which == guestPriorityUser ? (who == 0 ? getuid_nid_postfix() : who) == getuid_nid_postfix()
: who == 0 || who == getpid_nid_postfix();
if (!found) {
*__error_nid_postfix() = guestNoProcess;
return -1;
}
return guestNice;
}
int APS5_VABI sceKernelIsTrinityMode(void) {
return 0;
}

View File

@ -5,7 +5,13 @@ extern "C" int* APS5_VABI __error_nid_postfix();
extern "C" {
int APS5_VABI sched_get_priority_max_nid_postfix(int policy);
int APS5_VABI sched_get_priority_min_nid_postfix(int policy);
int APS5_VABI getpriority_nid_postfix(int which, int who);
int APS5_VABI getpid_nid_postfix(void);
int* APS5_VABI __error_nid_postfix();
}
static constexpr int PrioProcess = 0;
static constexpr int PrioGroup = 1;
static constexpr int PrioUser = 2;
static void Require(bool value) { if (!value) std::abort(); }
static bool Rejects(int policy) {
*__error_nid_postfix() = 0;
@ -13,6 +19,14 @@ static bool Rejects(int policy) {
*__error_nid_postfix() = 0;
return max && sched_get_priority_min_nid_postfix(policy) == -1 && *__error_nid_postfix() == 22;
}
static void RequireNice(int which, int who) {
*__error_nid_postfix() = 13;
Require(getpriority_nid_postfix(which, who) == 0 && *__error_nid_postfix() == 13);
}
static void RequireError(int which, int who, int error) {
*__error_nid_postfix() = 0;
Require(getpriority_nid_postfix(which, who) == -1 && *__error_nid_postfix() == error);
}
int main() {
Require(Rejects(-1) && Rejects(2) && Rejects(5));
for (int policy : {1, 3}) {
@ -20,4 +34,16 @@ int main() {
Require(sched_get_priority_min_nid_postfix(policy) == 256);
}
Require(Rejects(0) && Rejects(4));
const int self = getpid_nid_postfix();
RequireNice(PrioProcess, 0);
RequireNice(PrioProcess, self);
RequireNice(PrioGroup, 0);
RequireNice(PrioGroup, self);
RequireNice(PrioUser, 0);
RequireError(PrioProcess, self + 1, 3);
RequireError(PrioProcess, -1, 3);
RequireError(PrioGroup, self + 1, 3);
RequireError(PrioUser, 1000, 3);
RequireError(3, 0, 22);
RequireError(-1, self, 22);
}

View File

@ -172,3 +172,4 @@
- [sceKernelGetPageTableStats](../../../core/libs/prx/libkernel/DirectMemory/Export.cpp) (libkernel) - reports 2048 page-table entries on each side (a 4 GiB pool of 2 MiB entries, the constants of [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/kernel/memory.cpp)) and all of them available: no entries are counted as used, so a title never sees page-table pressure. KytyPS5 counts the 2 MiB entries of the committed CPU- or GPU-accessible ranges as used, which this port does not do. The four `int*` arguments follow OpenOrbis' `libkernel.h`, the Orbital type database and SharpProspero; a null pointer returns `SCE_KERNEL_ERROR_EFAULT` as in KytyPS5. None of the values is measured on a console. PPSA30601 (Resonance) calls it during start-up
- [clock_settime](../../../core/libs/prx/libkernel/Time/Time.cpp) (libkernel) validates like FreeBSD 11.4's [`kern_clock_settime`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/sys/kern/kern_time.c#L396-L412) for a root caller: `EFAULT` for a null time, `EINVAL` for any clock but `CLOCK_REALTIME`, a negative second count or a nanosecond count outside 0 to 999999999. A valid `CLOCK_REALTIME` request throws, naming the requested time, since the host clock is never set and no guest clock offset is kept. FreeBSD checks `PRIV_CLOCK_SETTIME` first, which a jailed process fails with `EPERM`; whether a title holds it on the console is unverified. PS5MC (PPSA99420) imports it; no call site is known
- [chflags](../../../core/libs/prx/libkernel/File/src/Stdio.cpp) (libkernel) follows FreeBSD 11.4's [`kern_chflagsat`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/sys/kern/vfs_syscalls.c#L2366-L2383) and UFS's [`ufs_setattr`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/sys/ufs/ufs/ufs_vnops.c#L509-L556) for a root caller: the path lookup reports `EFAULT`, `ENOENT` and `ENOTDIR`, a flag outside the 17 UFS stores (`VNOVAL` included) `EOPNOTSUPP`, and `SF_SNAPSHOT` `EPERM`. Neither host keeps BSD file flags, so every file is taken to have none (`stat` reports `st_flags` 0): flags 0 succeed without touching the file, and any other flag throws, naming the flags. `UF_READONLY`, `UF_HIDDEN`, `UF_SYSTEM` and `UF_ARCHIVE` are FreeBSD's names for the Windows attributes but are not mapped to them: UFS stores them without enforcing them, `FILE_ATTRIBUTE_READONLY` already carries the owner write bit of `chmod` on Windows, and Linux has no equivalent a process can set without `CAP_LINUX_IMMUTABLE`. The console's filesystem types, `EROFS` on read-only mounts and the change-time update are not modelled
- [getpriority](../../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) follows FreeBSD 11.4's [`sys_getpriority`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/sys/kern/kern_resource.c#L93-L165) for the only guest process, which is taken to run at nice 0: `PRIO_PROCESS` and `PRIO_PGRP` with 0 or its own pid (the guest is taken to lead its own process group, see `kill`) and `PRIO_USER` with 0 or its user id 0 return 0, any other id fails with `ESRCH` and any other `which` with `EINVAL`. As in FreeBSD's libc, where `getpriority` is the bare system call, errno is left unchanged on success. The nice value of a title process on the console is unverified, and the host nice of the process or of the threads `APS5_THREAD_PRIORITY=high` raises is not reported