mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Fix fork() syscall
This commit is contained in:
parent
5cb799df89
commit
061363d85d
@ -40,7 +40,6 @@ using Tasking::TTL::Untrusted;
|
|||||||
|
|
||||||
static inline bool CheckTrust(int TrustLevel)
|
static inline bool CheckTrust(int TrustLevel)
|
||||||
{
|
{
|
||||||
// SmartTimeoutLock(SyscallsLock, 10000); - This is already done in the caller
|
|
||||||
Token token = TaskManager->GetCurrentThread()->Security.UniqueToken;
|
Token token = TaskManager->GetCurrentThread()->Security.UniqueToken;
|
||||||
if (TaskManager->GetSecurityManager()->IsTokenTrusted(token, TrustLevel))
|
if (TaskManager->GetSecurityManager()->IsTokenTrusted(token, TrustLevel))
|
||||||
return true;
|
return true;
|
||||||
@ -340,17 +339,12 @@ static int sys_sleep(SyscallsFrame *Frame, uint64_t Milliseconds)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _ChildPID = 0;
|
|
||||||
|
|
||||||
static int sys_fork(SyscallsFrame *Frame)
|
static int sys_fork(SyscallsFrame *Frame)
|
||||||
{
|
{
|
||||||
UNUSED(Frame);
|
UNUSED(Frame);
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
||||||
return SYSCALL_ACCESS_DENIED;
|
return SYSCALL_ACCESS_DENIED;
|
||||||
|
|
||||||
fixme("sys_fork: %#lx", Frame);
|
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
|
||||||
|
|
||||||
Tasking::PCB *Parent = TaskManager->GetCurrentThread()->Parent;
|
Tasking::PCB *Parent = TaskManager->GetCurrentThread()->Parent;
|
||||||
Tasking::TCB *Thread = TaskManager->GetCurrentThread();
|
Tasking::TCB *Thread = TaskManager->GetCurrentThread();
|
||||||
|
|
||||||
@ -378,34 +372,19 @@ static int sys_fork(SyscallsFrame *Frame)
|
|||||||
Thread->Info.Compatibility,
|
Thread->Info.Compatibility,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
strncpy(NewThread->Name, Thread->Name, sizeof(Thread->Name));
|
||||||
|
|
||||||
if (!NewThread)
|
if (!NewThread)
|
||||||
{
|
{
|
||||||
error("Failed to create thread for fork");
|
error("Failed to create thread for fork");
|
||||||
return SYSCALL_ERROR;
|
return SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
_ChildPID = (int)NewThread->ID;
|
|
||||||
|
|
||||||
memcpy(NewThread->FPU, Thread->FPU, sizeof(CPU::x64::FXState));
|
|
||||||
NewThread->Stack->Fork(Thread->Stack);
|
|
||||||
|
|
||||||
strncpy(NewThread->Name, Thread->Name, sizeof(Thread->Name));
|
|
||||||
NewThread->Info = Thread->Info;
|
|
||||||
#ifdef a86
|
|
||||||
NewThread->ShadowGSBase = Thread->ShadowGSBase;
|
|
||||||
NewThread->GSBase = Thread->GSBase;
|
|
||||||
NewThread->FSBase = Thread->FSBase;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CPU::Interrupts(CPU::Disable);
|
|
||||||
static int RetChild = 0;
|
static int RetChild = 0;
|
||||||
static uint64_t ReturnAddress = 0;
|
static uint64_t ReturnAddress = 0;
|
||||||
static uint64_t ChildStackPointer = 0;
|
static uint64_t ChildStackPointer = 0;
|
||||||
|
|
||||||
#if defined(a86)
|
TaskManager->Schedule();
|
||||||
asmv("int $0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
|
|
||||||
#elif defined(aa64)
|
|
||||||
asmv("svc #0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (RetChild--)
|
if (RetChild--)
|
||||||
{
|
{
|
||||||
@ -413,28 +392,41 @@ static int sys_fork(SyscallsFrame *Frame)
|
|||||||
asmv("movq %0, %%rcx\n"
|
asmv("movq %0, %%rcx\n"
|
||||||
:
|
:
|
||||||
: "r"(ReturnAddress));
|
: "r"(ReturnAddress));
|
||||||
asmv("movq $0, %rax\n"); // Return 0 to the child
|
|
||||||
asmv("mov %0, %%rsp\n"
|
asmv("mov %0, %%rsp\n"
|
||||||
:
|
:
|
||||||
: "r"(ChildStackPointer));
|
: "r"(ChildStackPointer));
|
||||||
asmv("mov %0, %%rbp\n"
|
asmv("mov %0, %%rbp\n"
|
||||||
:
|
:
|
||||||
: "r"(ChildStackPointer));
|
: "r"(ChildStackPointer));
|
||||||
asmv("swapgs\n"); // Swap GS back to the user GS
|
asmv("movq $0, %rax\n"); // Return 0 to the child
|
||||||
asmv("sti\n"); // Enable interrupts
|
asmv("swapgs\n"); // Swap GS back to the user GS
|
||||||
asmv("sysretq\n"); // Return to rcx address in user mode
|
asmv("sti\n"); // Enable interrupts
|
||||||
|
asmv("sysretq\n"); // Return to rcx address in user mode
|
||||||
}
|
}
|
||||||
RetChild = 1;
|
RetChild = 1;
|
||||||
ReturnAddress = Frame->ReturnAddress;
|
ReturnAddress = Frame->ReturnAddress;
|
||||||
ChildStackPointer = Frame->StackPointer;
|
ChildStackPointer = Frame->StackPointer;
|
||||||
|
|
||||||
|
memcpy(NewThread->FPU, Thread->FPU, sizeof(CPU::x64::FXState));
|
||||||
|
NewThread->Stack->Fork(Thread->Stack);
|
||||||
|
NewThread->Info = Thread->Info;
|
||||||
NewThread->Registers = Thread->Registers;
|
NewThread->Registers = Thread->Registers;
|
||||||
|
|
||||||
|
if (Thread->Security.IsCritical)
|
||||||
|
NewThread->SetCritical(true);
|
||||||
|
TaskManager->GetSecurityManager()->TrustToken(NewProcess->Security.UniqueToken,
|
||||||
|
(Tasking::TTL)TaskManager->GetSecurityManager()->GetTokenTrustLevel(Parent->Security.UniqueToken));
|
||||||
|
TaskManager->GetSecurityManager()->TrustToken(NewThread->Security.UniqueToken,
|
||||||
|
(Tasking::TTL)TaskManager->GetSecurityManager()->GetTokenTrustLevel(Thread->Security.UniqueToken));
|
||||||
|
|
||||||
|
#ifdef a86
|
||||||
|
NewThread->ShadowGSBase = Thread->ShadowGSBase;
|
||||||
|
NewThread->GSBase = Thread->GSBase;
|
||||||
|
NewThread->FSBase = Thread->FSBase;
|
||||||
|
#endif
|
||||||
|
|
||||||
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", Thread->Name, Thread->ID, NewThread->Name, NewThread->ID);
|
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", Thread->Name, Thread->ID, NewThread->Name, NewThread->ID);
|
||||||
NewThread->Status = Tasking::TaskStatus::Ready;
|
NewThread->Status = Tasking::TaskStatus::Ready;
|
||||||
|
|
||||||
if (_ChildPID == (int)TaskManager->GetCurrentThread()->ID)
|
|
||||||
return 0;
|
|
||||||
return (int)NewThread->ID;
|
return (int)NewThread->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ NewLock(SyscallsLock);
|
|||||||
|
|
||||||
extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
|
extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
|
||||||
{
|
{
|
||||||
CPU::Interrupts(CPU::Enable);
|
|
||||||
SmartLock(SyscallsLock); /* TODO: This should be replaced or moved somewhere else. */
|
SmartLock(SyscallsLock); /* TODO: This should be replaced or moved somewhere else. */
|
||||||
|
|
||||||
Tasking::TaskInfo *Ptinfo = &TaskManager->GetCurrentProcess()->Info;
|
Tasking::TaskInfo *Ptinfo = &TaskManager->GetCurrentProcess()->Info;
|
||||||
|
@ -201,7 +201,7 @@ namespace InterProcessCommunication
|
|||||||
warn("Interrupts are disabled. This may cause a kernel hang.");
|
warn("Interrupts are disabled. This may cause a kernel hang.");
|
||||||
debug("Waiting for IPC %d (now %s)", ID, Hnd->Listening ? "listening" : "ready");
|
debug("Waiting for IPC %d (now %s)", ID, Hnd->Listening ? "listening" : "ready");
|
||||||
while (Hnd->Listening)
|
while (Hnd->Listening)
|
||||||
CPU::Pause();
|
TaskManager->Schedule();
|
||||||
debug("IPC %d is ready", ID);
|
debug("IPC %d is ready", ID);
|
||||||
return IPCSuccess;
|
return IPCSuccess;
|
||||||
}
|
}
|
||||||
|
@ -48,16 +48,6 @@ NewLock(TaskingLock);
|
|||||||
|
|
||||||
namespace Tasking
|
namespace Tasking
|
||||||
{
|
{
|
||||||
void Task::Schedule()
|
|
||||||
{
|
|
||||||
if (!StopScheduler)
|
|
||||||
TaskingScheduler_OneShot(1);
|
|
||||||
// APIC::InterruptCommandRegisterLow icr;
|
|
||||||
// icr.Vector = CPU::x86::IRQ16;
|
|
||||||
// icr.Level = APIC::APICLevel::Assert;
|
|
||||||
// ((APIC::APIC *)Interrupts::apic[0])->IPI(GetCurrentCPU()->ID, icr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(a86)
|
#if defined(a86)
|
||||||
__naked __used __no_stack_protector NIF void IdleProcessLoop()
|
__naked __used __no_stack_protector NIF void IdleProcessLoop()
|
||||||
{
|
{
|
||||||
|
@ -289,7 +289,14 @@ namespace Tasking
|
|||||||
Security *GetSecurityManager() { return &SecurityManager; }
|
Security *GetSecurityManager() { return &SecurityManager; }
|
||||||
void CleanupProcessesThread();
|
void CleanupProcessesThread();
|
||||||
void Panic() { StopScheduler = true; }
|
void Panic() { StopScheduler = true; }
|
||||||
void Schedule();
|
__always_inline inline void Schedule()
|
||||||
|
{
|
||||||
|
#if defined(a86)
|
||||||
|
asmv("int $0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
|
||||||
|
#elif defined(aa64)
|
||||||
|
asmv("svc #0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
void SignalShutdown();
|
void SignalShutdown();
|
||||||
void RevertProcessCreation(PCB *Process);
|
void RevertProcessCreation(PCB *Process);
|
||||||
void RevertThreadCreation(TCB *Thread);
|
void RevertThreadCreation(TCB *Thread);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user