Spawn Processes using memory primitives rather than and elf loader.
This allows us to remove the temporary syscall for that style of process spawn.
This commit is contained in:
parent
b06c76e477
commit
23895b5c6c
26 changed files with 403 additions and 94 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include "object/process.h"
|
||||
#include "scheduler/process_manager.h"
|
||||
#include "scheduler/scheduler.h"
|
||||
#include "usr/zcall_internal.h"
|
||||
|
||||
#define EFER 0xC0000080
|
||||
#define STAR 0xC0000081
|
||||
|
|
@ -46,36 +47,35 @@ void InitSyscall() {
|
|||
}
|
||||
|
||||
uint64_t star_val = GetMSR(STAR);
|
||||
// FIXME: Fix GDT such that we can properly set the user CS.
|
||||
// Due to the ability to jump from a 64 bit kernel into compatibility mode,
|
||||
// we set the user_cs to the kernel_cs because it adds 16 to jump to 64-bit
|
||||
// mode. See AMD Manual 3.4 instruction SYSRET for more info.
|
||||
uint64_t kernel_cs = 0x8;
|
||||
uint64_t user_cs = kernel_cs;
|
||||
// Due to the ability to jump from a 64 bit kernel into compatibility mode,
|
||||
// this will actually use CS 0x20 (and SS 0x18).
|
||||
// See AMD Manual 3.4 instruction SYSRET for more info.
|
||||
uint64_t user_cs = 0x18;
|
||||
star_val |= (kernel_cs << 32) | (user_cs << 48);
|
||||
SetMSR(STAR, star_val);
|
||||
SetMSR(LSTAR, reinterpret_cast<uint64_t>(syscall_enter));
|
||||
}
|
||||
|
||||
uint64_t ProcessSpawnElf(ZProcessSpawnElfReq* req) {
|
||||
uint64_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) {
|
||||
auto& curr_proc = gScheduler->CurrentProcess();
|
||||
auto cap = curr_proc.GetCapability(req->cap_id);
|
||||
auto cap = curr_proc.GetCapability(req->proc_cap);
|
||||
if (cap.empty()) {
|
||||
return ZE_NOT_FOUND;
|
||||
}
|
||||
if (!cap->CheckType(Capability::PROCESS)) {
|
||||
return ZE_INVALID;
|
||||
}
|
||||
|
||||
if (!cap->HasPermissions(ZC_PROC_SPAWN_PROC)) {
|
||||
return ZE_DENIED;
|
||||
}
|
||||
dbgln("Proc spawn: %u:%u", req->elf_base, req->elf_size);
|
||||
RefPtr<Process> proc = Process::Create();
|
||||
gProcMan->InsertProcess(proc);
|
||||
uint64_t entry = LoadElfProgram(*proc, req->elf_base, req->elf_size);
|
||||
proc->CreateThread()->Start(entry, 0, 0);
|
||||
return 0;
|
||||
|
||||
resp->proc_cap = curr_proc.AddCapability(proc);
|
||||
resp->as_cap = curr_proc.AddCapability(proc->vmas());
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
uint64_t ThreadCreate(ZThreadCreateReq* req, ZThreadCreateResp* resp) {
|
||||
|
|
@ -92,8 +92,8 @@ uint64_t ThreadCreate(ZThreadCreateReq* req, ZThreadCreateResp* resp) {
|
|||
return ZE_DENIED;
|
||||
}
|
||||
|
||||
Process& parent_proc = cap->obj<Process>();
|
||||
auto thread = parent_proc.CreateThread();
|
||||
auto parent_proc = cap->obj<Process>();
|
||||
auto thread = parent_proc->CreateThread();
|
||||
resp->thread_cap = curr_proc.AddCapability(thread);
|
||||
|
||||
return Z_OK;
|
||||
|
|
@ -113,9 +113,43 @@ uint64_t ThreadStart(ZThreadStartReq* req) {
|
|||
return ZE_DENIED;
|
||||
}
|
||||
|
||||
Thread& thread = cap->obj<Thread>();
|
||||
auto thread = cap->obj<Thread>();
|
||||
// FIXME: validate entry point is in user space.
|
||||
thread.Start(req->entry, req->arg1, req->arg2);
|
||||
thread->Start(req->entry, req->arg1, req->arg2);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
uint64_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) {
|
||||
auto& curr_proc = gScheduler->CurrentProcess();
|
||||
auto as_cap = curr_proc.GetCapability(req->as_cap);
|
||||
auto mem_cap = curr_proc.GetCapability(req->mem_cap);
|
||||
if (as_cap.empty() || mem_cap.empty()) {
|
||||
return ZE_NOT_FOUND;
|
||||
}
|
||||
if (!as_cap->CheckType(Capability::ADDRESS_SPACE) ||
|
||||
!mem_cap->CheckType(Capability::MEMORY_OBJECT)) {
|
||||
return ZE_INVALID;
|
||||
}
|
||||
if (!as_cap->HasPermissions(ZC_WRITE) || !mem_cap->HasPermissions(ZC_WRITE)) {
|
||||
return ZE_DENIED;
|
||||
}
|
||||
auto as = as_cap->obj<AddressSpace>();
|
||||
auto mo = mem_cap->obj<MemoryObject>();
|
||||
// FIXME: Validation necessary.
|
||||
if (req->offset != 0) {
|
||||
as->MapInMemoryObject(req->offset, mo);
|
||||
resp->vaddr = req->offset;
|
||||
} else {
|
||||
resp->vaddr = as->MapInMemoryObject(mo);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t MemoryObjectCreate(ZMemoryObjectCreateReq* req,
|
||||
ZMemoryObjectCreateResp* resp) {
|
||||
auto& curr_proc = gScheduler->CurrentProcess();
|
||||
resp->mem_cap =
|
||||
curr_proc.AddCapability(MakeRefCounted<MemoryObject>(req->size));
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
extern "C" uint64_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
|
||||
|
|
@ -123,14 +157,13 @@ extern "C" uint64_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
|
|||
switch (call_id) {
|
||||
case Z_PROCESS_EXIT:
|
||||
// FIXME: kill process here.
|
||||
dbgln("Exit code: %u", req);
|
||||
thread.Exit();
|
||||
panic("Returned from thread exit");
|
||||
break;
|
||||
case Z_DEBUG_PRINT:
|
||||
dbgln("[Debug] %s", req);
|
||||
break;
|
||||
case Z_PROCESS_SPAWN:
|
||||
return ProcessSpawnElf(reinterpret_cast<ZProcessSpawnElfReq*>(req));
|
||||
return ProcessSpawn(reinterpret_cast<ZProcessSpawnReq*>(req),
|
||||
reinterpret_cast<ZProcessSpawnResp*>(resp));
|
||||
case Z_THREAD_CREATE:
|
||||
return ThreadCreate(reinterpret_cast<ZThreadCreateReq*>(req),
|
||||
reinterpret_cast<ZThreadCreateResp*>(resp));
|
||||
|
|
@ -140,6 +173,17 @@ extern "C" uint64_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
|
|||
thread.Exit();
|
||||
panic("Returned from thread exit");
|
||||
break;
|
||||
|
||||
case Z_ADDRESS_SPACE_MAP:
|
||||
return AddressSpaceMap(reinterpret_cast<ZAddressSpaceMapReq*>(req),
|
||||
reinterpret_cast<ZAddressSpaceMapResp*>(resp));
|
||||
case Z_MEMORY_OBJECT_CREATE:
|
||||
return MemoryObjectCreate(
|
||||
reinterpret_cast<ZMemoryObjectCreateReq*>(req),
|
||||
reinterpret_cast<ZMemoryObjectCreateResp*>(resp));
|
||||
case Z_DEBUG_PRINT:
|
||||
dbgln("[Debug] %s", req);
|
||||
break;
|
||||
default:
|
||||
panic("Unhandled syscall number: %x", call_id);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue