From b4902a79ef7b73f6e2a307a6a9c666f38e0467c3 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Fri, 16 Jun 2023 14:25:45 -0700 Subject: [PATCH] [zion] Add per-process CapabilityTable object Store this information in it's own object to make the API clearer. --- zion/CMakeLists.txt | 1 + zion/capability/capability_table.cpp | 41 +++++++++++++ zion/capability/capability_table.h | 54 +++++++++++++++++ zion/object/process.cpp | 88 +++++++--------------------- zion/object/process.h | 3 +- 5 files changed, 119 insertions(+), 68 deletions(-) create mode 100644 zion/capability/capability_table.cpp create mode 100644 zion/capability/capability_table.h diff --git a/zion/CMakeLists.txt b/zion/CMakeLists.txt index 5fad7bf..1f41a07 100644 --- a/zion/CMakeLists.txt +++ b/zion/CMakeLists.txt @@ -2,6 +2,7 @@ add_executable(zion boot/acpi.cpp boot/boot_info.cpp capability/capability.cpp + capability/capability_table.cpp common/gdt.cpp common/load_gdt.s common/msr.cpp diff --git a/zion/capability/capability_table.cpp b/zion/capability/capability_table.cpp new file mode 100644 index 0000000..c1ad7fd --- /dev/null +++ b/zion/capability/capability_table.cpp @@ -0,0 +1,41 @@ +#include "capability/capability_table.h" + +CapabilityTable::CapabilityTable() {} + +uint64_t CapabilityTable::AddExistingCapability(const RefPtr& cap) { + MutexHolder h(lock_); + cap->set_id(next_cap_id_++); + capabilities_.PushBack(cap); + return cap->id(); +} + +RefPtr CapabilityTable::GetCapability(uint64_t id) { + MutexHolder h(lock_); + auto iter = capabilities_.begin(); + while (iter != capabilities_.end()) { + if (*iter && iter->id() == id) { + return *iter; + } + ++iter; + } + dbgln("Bad cap access %u", id); + dbgln("Num caps: %u", capabilities_.size()); + return {}; +} + +RefPtr CapabilityTable::ReleaseCapability(uint64_t id) { + MutexHolder h(lock_); + auto iter = capabilities_.begin(); + while (iter != capabilities_.end()) { + if (*iter && iter->id() == id) { + // FIXME: Do an actual release here. + auto cap = *iter; + *iter = {nullptr}; + return cap; + } + ++iter; + } + dbgln("Bad cap release: %u", id); + dbgln("Num caps: %u", capabilities_.size()); + return {}; +} diff --git a/zion/capability/capability_table.h b/zion/capability/capability_table.h new file mode 100644 index 0000000..ed77bd8 --- /dev/null +++ b/zion/capability/capability_table.h @@ -0,0 +1,54 @@ +#pragma once + +#include "capability/capability.h" +#include "lib/linked_list.h" +#include "lib/mutex.h" +#include "lib/ref_ptr.h" + +class CapabilityTable { + public: + CapabilityTable(); + + CapabilityTable(CapabilityTable&) = delete; + CapabilityTable& operator=(CapabilityTable&) = delete; + + template + uint64_t AddNewCapability(const RefPtr& object, Capability::Type type, + uint64_t permissions); + uint64_t AddExistingCapability(const RefPtr& cap); + + // FIXME: Remove reliance on this. + template + void AddNewCapabilityWithId(uint64_t id, const RefPtr& object, + Capability::Type type, uint64_t permissions); + + RefPtr GetCapability(uint64_t id); + RefPtr ReleaseCapability(uint64_t id); + + private: + Mutex lock_{"cap table"}; + // FIXME: store this id here rather than in the capability. + uint64_t next_cap_id_ = 0x100; + // FIXME: use a map data structure. + LinkedList> capabilities_; +}; + +template +uint64_t CapabilityTable::AddNewCapability(const RefPtr& object, + Capability::Type type, + uint64_t permissions) { + MutexHolder h(lock_); + uint64_t id = next_cap_id_++; + capabilities_.PushBack( + MakeRefCounted(object, type, id, permissions)); + return id; +} + +template +void CapabilityTable::AddNewCapabilityWithId(uint64_t id, + const RefPtr& object, + Capability::Type type, + uint64_t permissions) { + capabilities_.PushBack( + MakeRefCounted(object, type, id, permissions)); +} diff --git a/zion/object/process.cpp b/zion/object/process.cpp index e049df8..e4f658f 100644 --- a/zion/object/process.cpp +++ b/zion/object/process.cpp @@ -22,11 +22,11 @@ RefPtr Process::RootProcess() { } RefPtr Process::Create() { auto proc = MakeRefCounted(); - proc->caps_.PushBack( - MakeRefCounted(proc, Capability::PROCESS, Z_INIT_PROC_SELF, - ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD)); - proc->caps_.PushBack(MakeRefCounted( - proc->vmas(), Capability::ADDRESS_SPACE, Z_INIT_VMAS_SELF, ZC_WRITE)); + proc->caps_.AddNewCapabilityWithId(Z_INIT_PROC_SELF, proc, + Capability::PROCESS, + ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD); + proc->caps_.AddNewCapabilityWithId(Z_INIT_VMAS_SELF, proc->vmas(), + Capability::ADDRESS_SPACE, ZC_WRITE); return proc; } @@ -66,88 +66,42 @@ void Process::CheckState() { } RefPtr Process::ReleaseCapability(uint64_t cid) { - MutexHolder lock(mutex_); - auto iter = caps_.begin(); - while (iter != caps_.end()) { - if (*iter && iter->id() == cid) { - auto cap = *iter; - *iter = {nullptr}; - return cap; - } - ++iter; - } - dbgln("Bad cap release: %u", cid); - dbgln("Num caps: %u", caps_.size()); - return {}; + return caps_.ReleaseCapability(cid); } RefPtr Process::GetCapability(uint64_t cid) { - MutexHolder lock(mutex_); - auto iter = caps_.begin(); - while (iter != caps_.end()) { - if (*iter && iter->id() == cid) { - return *iter; - } - ++iter; - } - dbgln("Bad cap access %u", cid); - dbgln("Num caps: %u", caps_.size()); - return {}; + return caps_.GetCapability(cid); } uint64_t Process::AddCapability(const RefPtr& cap) { - MutexHolder lock(mutex_); - cap->set_id(next_cap_id_++); - caps_.PushBack(cap); - return cap->id(); + return caps_.AddExistingCapability(cap); } uint64_t Process::AddCapability(const RefPtr& thread) { - MutexHolder lock(mutex_); - uint64_t cap_id = next_cap_id_++; - caps_.PushBack( - MakeRefCounted(thread, Capability::THREAD, cap_id, ZC_WRITE)); - return cap_id; + return caps_.AddNewCapability(thread, Capability::THREAD, ZC_WRITE); } -uint64_t Process::AddCapability(const RefPtr& p) { - MutexHolder lock(mutex_); - uint64_t cap_id = next_cap_id_++; - caps_.PushBack(MakeRefCounted(p, Capability::PROCESS, cap_id, - ZC_WRITE | ZC_PROC_SPAWN_THREAD)); - return cap_id; +uint64_t Process::AddCapability(const RefPtr& proc) { + return caps_.AddNewCapability(proc, Capability::PROCESS, + ZC_WRITE | ZC_PROC_SPAWN_THREAD); } + uint64_t Process::AddCapability(const RefPtr& vmas) { - MutexHolder lock(mutex_); - uint64_t cap_id = next_cap_id_++; - caps_.PushBack(MakeRefCounted(vmas, Capability::ADDRESS_SPACE, - cap_id, ZC_WRITE)); - return cap_id; + return caps_.AddNewCapability(vmas, Capability::ADDRESS_SPACE, ZC_WRITE); } + uint64_t Process::AddCapability(const RefPtr& vmmo) { - MutexHolder lock(mutex_); - uint64_t cap_id = next_cap_id_++; - caps_.PushBack(MakeRefCounted(vmmo, Capability::MEMORY_OBJECT, - cap_id, ZC_WRITE)); - return cap_id; + return caps_.AddNewCapability(vmmo, Capability::MEMORY_OBJECT, ZC_WRITE); } + uint64_t Process::AddCapability(const RefPtr& chan) { - MutexHolder lock(mutex_); - uint64_t cap_id = next_cap_id_++; - caps_.PushBack(MakeRefCounted(chan, Capability::CHANNEL, cap_id, - ZC_WRITE | ZC_READ)); - return cap_id; + return caps_.AddNewCapability(chan, Capability::CHANNEL, ZC_WRITE | ZC_READ); } uint64_t Process::AddCapability(const RefPtr& port) { - MutexHolder lock(mutex_); - uint64_t cap_id = next_cap_id_++; - caps_.PushBack(MakeRefCounted(port, Capability::PORT, cap_id, - ZC_WRITE | ZC_READ)); - return cap_id; + return caps_.AddNewCapability(port, Capability::PORT, ZC_WRITE | ZC_READ); } void Process::AddCapability(uint64_t cap_id, const RefPtr& vmmo) { - MutexHolder lock(mutex_); - caps_.PushBack(MakeRefCounted(vmmo, Capability::MEMORY_OBJECT, - cap_id, ZC_WRITE)); + caps_.AddNewCapabilityWithId(cap_id, vmmo, Capability::MEMORY_OBJECT, + ZC_WRITE); } diff --git a/zion/object/process.h b/zion/object/process.h index f6ea681..b94a720 100644 --- a/zion/object/process.h +++ b/zion/object/process.h @@ -3,6 +3,7 @@ #include #include "capability/capability.h" +#include "capability/capability_table.h" #include "lib/linked_list.h" #include "lib/mutex.h" #include "lib/ref_ptr.h" @@ -63,5 +64,5 @@ class Process : public KernelObject { uint64_t next_cap_id_ = 0x100; LinkedList> threads_; - LinkedList> caps_; + CapabilityTable caps_; };