mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-03-04 00:27:40 +00:00
[orbis-kernel][rpcsx-os] POC thr_new implementation (disabled by default)
This commit is contained in:
parent
5bb820084e
commit
7bfa977086
@ -94,7 +94,8 @@ orbis::SysResult orbis::sys_evf_create(Thread *thread, ptr<char> name,
|
||||
switch (attrs & (kEvfAttrSingle | kEvfAttrMulti)) {
|
||||
case 0:
|
||||
case kEvfAttrSingle | kEvfAttrMulti:
|
||||
return ErrorCode::INVAL;
|
||||
attrs = (attrs & ~(kEvfAttrSingle | kEvfAttrMulti)) | kEvfAttrSingle;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -103,7 +104,11 @@ orbis::SysResult orbis::sys_evf_create(Thread *thread, ptr<char> name,
|
||||
switch (attrs & (kEvfAttrThPrio | kEvfAttrThFifo)) {
|
||||
case 0:
|
||||
case kEvfAttrThPrio | kEvfAttrThFifo:
|
||||
return ErrorCode::INVAL;
|
||||
attrs = (attrs & ~(kEvfAttrThPrio | kEvfAttrThFifo)) | kEvfAttrThFifo;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
char _name[32];
|
||||
|
@ -36,12 +36,6 @@
|
||||
|
||||
static int g_gpuPid;
|
||||
|
||||
struct ThreadParam {
|
||||
void (*startFunc)(void *);
|
||||
void *arg;
|
||||
orbis::Thread *thread;
|
||||
};
|
||||
|
||||
static void printStackTrace(ucontext_t *context, int fileno) {
|
||||
unw_cursor_t cursor;
|
||||
|
||||
@ -158,19 +152,10 @@ static void printStackTrace(ucontext_t *context, orbis::Thread *thread,
|
||||
|
||||
__attribute__((no_stack_protector)) static void
|
||||
handle_signal(int sig, siginfo_t *info, void *ucontext) {
|
||||
std::uint64_t hostFs = _readgsbase_u64();
|
||||
if (hostFs != 0) {
|
||||
if (auto hostFs = _readgsbase_u64()) {
|
||||
_writefsbase_u64(hostFs);
|
||||
}
|
||||
|
||||
if (sig == SIGSYS) {
|
||||
auto prevContext = std::exchange(rx::thread::g_current->context, ucontext);
|
||||
orbis::syscall_entry(rx::thread::g_current);
|
||||
rx::thread::g_current->context = prevContext;
|
||||
_writefsbase_u64(rx::thread::g_current->fsBase);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_gpuPid > 0) {
|
||||
// stop gpu thread
|
||||
::kill(g_gpuPid, SIGINT);
|
||||
@ -234,14 +219,9 @@ static void setupSigHandlers() {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct sigaction act;
|
||||
sigset_t mask;
|
||||
memset(&act, 0, sizeof(act));
|
||||
sigemptyset(&mask);
|
||||
|
||||
struct sigaction act{};
|
||||
act.sa_sigaction = handle_signal;
|
||||
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
|
||||
act.sa_mask = mask;
|
||||
|
||||
if (sigaction(SIGSYS, &act, NULL)) {
|
||||
perror("Error sigaction:");
|
||||
@ -367,22 +347,22 @@ static int ps4Exec(orbis::Process *mainProcess,
|
||||
mainProcess->sysent = &orbis::ps4_sysvec;
|
||||
mainProcess->ops = &rx::procOpsTable;
|
||||
|
||||
orbis::Thread mainThread;
|
||||
mainThread.tproc = mainProcess;
|
||||
mainThread.tid = mainProcess->pid;
|
||||
mainThread.state = orbis::ThreadState::RUNNING;
|
||||
auto [baseId, mainThread] = mainProcess->threadsMap.emplace();
|
||||
mainThread->tproc = mainProcess;
|
||||
mainThread->tid = mainProcess->pid + baseId;
|
||||
mainThread->state = orbis::ThreadState::RUNNING;
|
||||
|
||||
const auto stackEndAddress = 0x7'ffff'c000ull;
|
||||
const auto stackSize = 0x40000 * 16;
|
||||
auto stackStartAddress = stackEndAddress - stackSize;
|
||||
mainThread.stackStart =
|
||||
mainThread->stackStart =
|
||||
rx::vm::map(reinterpret_cast<void *>(stackStartAddress), stackSize,
|
||||
rx::vm::kMapProtCpuWrite | rx::vm::kMapProtCpuRead,
|
||||
rx::vm::kMapFlagAnonymous | rx::vm::kMapFlagFixed |
|
||||
rx::vm::kMapFlagPrivate | rx::vm::kMapFlagStack);
|
||||
|
||||
mainThread.stackEnd =
|
||||
reinterpret_cast<std::byte *>(mainThread.stackStart) + stackSize;
|
||||
mainThread->stackEnd =
|
||||
reinterpret_cast<std::byte *>(mainThread->stackStart) + stackSize;
|
||||
|
||||
rx::vfs::mount("/dev/dmem0", createDmemCharacterDevice(0));
|
||||
rx::vfs::mount("/dev/dmem1", createDmemCharacterDevice(1));
|
||||
@ -402,9 +382,9 @@ static int ps4Exec(orbis::Process *mainProcess,
|
||||
rx::vfs::mount("/dev/gc", createGcCharacterDevice());
|
||||
rx::vfs::mount("/dev/rng", createRngCharacterDevice());
|
||||
|
||||
rx::procOpsTable.open(&mainThread, "/dev/stdin", 0, 0);
|
||||
rx::procOpsTable.open(&mainThread, "/dev/stdout", 0, 0);
|
||||
rx::procOpsTable.open(&mainThread, "/dev/stderr", 0, 0);
|
||||
rx::procOpsTable.open(mainThread, "/dev/stdin", 0, 0);
|
||||
rx::procOpsTable.open(mainThread, "/dev/stdout", 0, 0);
|
||||
rx::procOpsTable.open(mainThread, "/dev/stderr", 0, 0);
|
||||
|
||||
std::vector<std::uint64_t> argvOffsets;
|
||||
std::vector<std::uint64_t> envpOffsets;
|
||||
@ -415,7 +395,7 @@ static int ps4Exec(orbis::Process *mainProcess,
|
||||
// *reinterpret_cast<std::uint32_t *>(
|
||||
// reinterpret_cast<std::byte *>(libkernel->base) + 0x6c2e4) = ~0;
|
||||
|
||||
StackWriter stack{reinterpret_cast<std::uint64_t>(mainThread.stackEnd)};
|
||||
StackWriter stack{reinterpret_cast<std::uint64_t>(mainThread->stackEnd)};
|
||||
|
||||
for (auto elem : argv) {
|
||||
argvOffsets.push_back(stack.pushString(elem));
|
||||
@ -469,8 +449,8 @@ static int ps4Exec(orbis::Process *mainProcess,
|
||||
});;
|
||||
context->uc_mcontext.gregs[REG_RIP] = libkernel->entryPoint;
|
||||
|
||||
mainThread.context = context;
|
||||
rx::thread::invoke(&mainThread);
|
||||
mainThread->context = context;
|
||||
rx::thread::invoke(mainThread);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,16 @@
|
||||
#include "orbis/thread/Process.hpp"
|
||||
#include "orbis/thread/Thread.hpp"
|
||||
#include "orbis/utils/Rc.hpp"
|
||||
#include "thread.hpp"
|
||||
#include "vfs.hpp"
|
||||
#include "vm.hpp"
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace orbis;
|
||||
@ -421,11 +424,52 @@ SysResult thr_create(orbis::Thread *thread, orbis::ptr<struct ucontext> ctxt,
|
||||
ptr<orbis::slong> arg, orbis::sint flags) {
|
||||
return ErrorCode::NOTSUP;
|
||||
}
|
||||
SysResult thr_new(orbis::Thread *thread, orbis::ptr<struct thr_param> param,
|
||||
SysResult thr_new(orbis::Thread *thread, orbis::ptr<thr_param> param,
|
||||
orbis::sint param_size) {
|
||||
return {}; // FIXME: remove when we ready for MT
|
||||
auto _param = uread(param);
|
||||
|
||||
auto proc = thread->tproc;
|
||||
auto [baseId, childThread] = proc->threadsMap.emplace();
|
||||
childThread->tproc = proc;
|
||||
childThread->tid = proc->pid + baseId;
|
||||
childThread->state = orbis::ThreadState::RUNQ;
|
||||
childThread->stackStart = _param.stack_base;
|
||||
childThread->stackEnd = _param.stack_base + _param.stack_size;
|
||||
childThread->fsBase = reinterpret_cast<std::uintptr_t>(_param.tls_base);
|
||||
|
||||
uwrite(_param.parent_tid, slong(childThread->tid));
|
||||
|
||||
// FIXME: implement scheduler
|
||||
|
||||
std::printf("Starting child thread %lu\n", (long)(proc->pid + baseId));
|
||||
|
||||
std::thread {
|
||||
[=, childThread = Ref<Thread>(childThread)] {
|
||||
uwrite(_param.child_tid, slong(childThread->tid));
|
||||
auto context = new ucontext_t{};
|
||||
|
||||
context->uc_mcontext.gregs[REG_RDI] = reinterpret_cast<std::uintptr_t>(_param.arg);
|
||||
context->uc_mcontext.gregs[REG_RSI] = reinterpret_cast<std::uintptr_t>(_param.arg);
|
||||
context->uc_mcontext.gregs[REG_RSP] = reinterpret_cast<std::uintptr_t>(childThread->stackEnd);
|
||||
context->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<std::uintptr_t>(_param.start_func);
|
||||
|
||||
childThread->context = context;
|
||||
childThread->state = orbis::ThreadState::RUNNING;
|
||||
rx::thread::invoke(childThread.get());
|
||||
}
|
||||
}.detach();
|
||||
|
||||
return {};
|
||||
}
|
||||
SysResult thr_exit(orbis::Thread *thread, orbis::ptr<orbis::slong> state) {
|
||||
std::printf("Requested exit of thread %u, state %p\n", (unsigned)thread->tid, state);
|
||||
// FIXME: do sys_mtx(WAKE) if state is not null
|
||||
|
||||
// FIXME: implement exit
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(60));
|
||||
}
|
||||
return ErrorCode::NOTSUP;
|
||||
}
|
||||
SysResult thr_kill(orbis::Thread *thread, orbis::slong id, orbis::sint sig) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "thread.hpp"
|
||||
#include "orbis/sys/sysentry.hpp"
|
||||
#include <asm/prctl.h>
|
||||
#include <csignal>
|
||||
#include <immintrin.h>
|
||||
#include <link.h>
|
||||
#include <linux/prctl.h>
|
||||
@ -15,7 +17,19 @@ struct LibcInfo {
|
||||
std::uint64_t textSize = 0;
|
||||
};
|
||||
|
||||
static LibcInfo libcInfo;
|
||||
LibcInfo libcInfo;
|
||||
|
||||
static __attribute__((no_stack_protector)) void
|
||||
handleSigSys(int sig, siginfo_t *info, void *ucontext) {
|
||||
if (auto hostFs = _readgsbase_u64()) {
|
||||
_writefsbase_u64(hostFs);
|
||||
}
|
||||
|
||||
auto prevContext = std::exchange(rx::thread::g_current->context, ucontext);
|
||||
orbis::syscall_entry(rx::thread::g_current);
|
||||
rx::thread::g_current->context = prevContext;
|
||||
_writefsbase_u64(rx::thread::g_current->fsBase);
|
||||
}
|
||||
|
||||
void rx::thread::initialize() {
|
||||
auto processPhdr = [](struct dl_phdr_info *info, size_t, void *data) {
|
||||
@ -50,6 +64,15 @@ void rx::thread::initialize() {
|
||||
|
||||
std::printf("libc text %zx-%zx\n", libcInfo.textBegin,
|
||||
libcInfo.textBegin + libcInfo.textSize);
|
||||
|
||||
struct sigaction act {};
|
||||
act.sa_sigaction = handleSigSys;
|
||||
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
|
||||
|
||||
if (sigaction(SIGSYS, &act, NULL)) {
|
||||
perror("Error sigaction:");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void rx::thread::deinitialize() {}
|
||||
@ -57,6 +80,14 @@ void rx::thread::deinitialize() {}
|
||||
void rx::thread::invoke(orbis::Thread *thread) {
|
||||
g_current = thread;
|
||||
|
||||
sigset_t unblockSigs{};
|
||||
sigset_t oldSigmask{};
|
||||
sigaddset(&unblockSigs, SIGSYS);
|
||||
if (pthread_sigmask(SIG_UNBLOCK, &unblockSigs, &oldSigmask)) {
|
||||
perror("pthread_sigmask failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
std::uint64_t hostFs = _readfsbase_u64();
|
||||
_writegsbase_u64(hostFs);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user