[kernel] Add VMA interface

Finished the VMA kobject and added the related syscalls. Processes can
now allocate memory! Other changes in this commit:

- stop using g_frame_allocator and add frame_allocator::get()
- make sure to release all handles in the process dtor
- fix kutil::map::iterator never comparing to end()
This commit is contained in:
2020-09-23 00:29:05 -07:00
parent d4283731e4
commit 0e0975e5f6
13 changed files with 245 additions and 173 deletions

View File

@@ -19,9 +19,7 @@ enum class vm_flags : uint32_t
contiguous = 0x00000002,
large_pages = 0x00000100,
huge_pages = 0x00000200,
offset_linear = 0x80000000
huge_pages = 0x00000200
};
IS_BITFIELD(vm_flags);
@@ -55,14 +53,12 @@ public:
/// the given base address is zero, a base address will be chosen
/// automatically.
/// \arg s The target address space
/// \arg base [in] The desired base address [out] the actual base address
/// \returns j6_status_ok on success
j6_status_t add_to(vm_space *s, uintptr_t *base);
/// \arg base The base address this area will be mapped to
void add_to(vm_space *s, uintptr_t base);
/// Remove this virtual area from a process' virtual address space.
/// \arg s The target address space
/// \returns j6_status_ok on success
j6_status_t remove_from(vm_space *s);
void remove_from(vm_space *s);
/// Commit contiguous physical pages to this area
/// \arg phys The physical address of the first page
@@ -77,35 +73,17 @@ public:
/// \returns True if successful
bool uncommit(uintptr_t offset, size_t count);
/// Reserve a range of this area to never commit
/// \arg offset The offset from the start of this area
/// \arg count The number of pages
/// \returns True if successful
bool reserve(uintptr_t offset, size_t count);
/// Unreserve a range of this area to allow commits
/// \arg offset The offset from the start of this area
/// \arg count The number of pages
/// \returns True if successful
bool unreserve(uintptr_t offset, size_t count);
enum class state : uint8_t { none, reserved, mapped };
/// Get the physical page representing an offset in this area
/// \arg offset The offset into the area
/// \arg phys [out] The physical page address
/// \returns State of the given address
state get(uintptr_t offset, uintptr_t *phys);
/// Get the flags set for this area
vm_flags flags() const { return m_flags; }
protected:
virtual void on_no_handles() override;
private:
struct mapping {
uintptr_t offset;
size_t count;
uintptr_t phys;
state state;
int compare(const struct mapping &o) const {
return offset > o.offset ? 1 : offset < o.offset ? -1 : 0;
@@ -116,14 +94,12 @@ private:
};
size_t overlaps(uintptr_t offset, size_t pages, size_t *count);
bool add(uintptr_t offset, size_t count, state desired, uintptr_t phys);
bool remove(uintptr_t offset, size_t count, state expected);
void map(uintptr_t offset, size_t count, uintptr_t phys);
void unmap(uintptr_t offset, size_t count);
size_t m_size;
vm_flags m_flags;
kutil::map<vm_space*, uintptr_t> m_procs;
kutil::map<vm_space*, uintptr_t> m_spaces;
kutil::vector<mapping> m_mappings;
};