mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[kernel] Remove 'allowed' page table flag
The allowed flag was janky and easy to get lost when doing page table manipulation. All allocation goes throug vm_area now, so 'allowed' can be dropped.
This commit is contained in:
@@ -91,7 +91,6 @@ vm_area_shared::commit(uintptr_t phys, uintptr_t offset, size_t count)
|
|||||||
.phys = phys});
|
.phys = phys});
|
||||||
n = 1;
|
n = 1;
|
||||||
|
|
||||||
|
|
||||||
// Try to expand to abutting similar areas
|
// Try to expand to abutting similar areas
|
||||||
if (o > 0 &&
|
if (o > 0 &&
|
||||||
m_mappings[o-1].end() == offset &&
|
m_mappings[o-1].end() == offset &&
|
||||||
|
|||||||
@@ -100,27 +100,6 @@ page_table::iterator::next(level l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
page_table::iterator::allowed() const
|
|
||||||
{
|
|
||||||
level d = depth();
|
|
||||||
while (true) {
|
|
||||||
if (entry(d) & flag::allowed) return true;
|
|
||||||
else if (d == level::pml4) return false;
|
|
||||||
--d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
page_table::iterator::allow(level at, bool allowed)
|
|
||||||
{
|
|
||||||
for (level l = level::pdp; l <= at; ++l)
|
|
||||||
ensure_table(l);
|
|
||||||
|
|
||||||
if (allowed) entry(at) |= flag::allowed;
|
|
||||||
else entry(at) &= ~flag::allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
page_table::iterator::operator!=(const iterator &o) const
|
page_table::iterator::operator!=(const iterator &o) const
|
||||||
{
|
{
|
||||||
@@ -159,7 +138,7 @@ page_table::iterator::ensure_table(level l)
|
|||||||
uintptr_t phys = reinterpret_cast<uintptr_t>(table) & ~page_offset;
|
uintptr_t phys = reinterpret_cast<uintptr_t>(table) & ~page_offset;
|
||||||
|
|
||||||
uint64_t &parent = entry(l - 1);
|
uint64_t &parent = entry(l - 1);
|
||||||
flag flags = table_flags | (parent & flag::allowed);
|
flag flags = table_flags;
|
||||||
if (m_index[0] < memory::pml4e_kernel)
|
if (m_index[0] < memory::pml4e_kernel)
|
||||||
flags |= flag::user;
|
flags |= flag::user;
|
||||||
|
|
||||||
@@ -185,7 +164,6 @@ page_table::get(int i, uint16_t *flags) const
|
|||||||
void
|
void
|
||||||
page_table::set(int i, page_table *p, uint16_t flags)
|
page_table::set(int i, page_table *p, uint16_t flags)
|
||||||
{
|
{
|
||||||
if (entries[i] & flag::allowed) flags |= flag::allowed;
|
|
||||||
entries[i] =
|
entries[i] =
|
||||||
(reinterpret_cast<uint64_t>(p) - page_offset) |
|
(reinterpret_cast<uint64_t>(p) - page_offset) |
|
||||||
(flags & 0xfff);
|
(flags & 0xfff);
|
||||||
|
|||||||
@@ -28,10 +28,7 @@ struct page_table
|
|||||||
page = 0x0080, /// Entry is a large page
|
page = 0x0080, /// Entry is a large page
|
||||||
pte_mtrr2 = 0x0080, /// MTRR selector bit 2 on PT entries
|
pte_mtrr2 = 0x0080, /// MTRR selector bit 2 on PT entries
|
||||||
global = 0x0100, /// Entry is not PCID-specific
|
global = 0x0100, /// Entry is not PCID-specific
|
||||||
mtrr2 = 0x1000, /// MTRR selector bit 2 on PD and PDP entries
|
mtrr2 = 0x1000 /// MTRR selector bit 2 on PD and PDP entries
|
||||||
|
|
||||||
// jsix-defined
|
|
||||||
allowed = 0x0800 /// Allocation here is allowed
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Helper for getting the next level value
|
/// Helper for getting the next level value
|
||||||
@@ -103,12 +100,6 @@ struct page_table
|
|||||||
/// Increment iteration to the next entry aligned to the given level
|
/// Increment iteration to the next entry aligned to the given level
|
||||||
void next(level l);
|
void next(level l);
|
||||||
|
|
||||||
/// Check if allocation is allowed at the current location
|
|
||||||
bool allowed() const;
|
|
||||||
|
|
||||||
/// Mark allocation allowed at the given depth for the current location
|
|
||||||
void allow(level at, bool allowed);
|
|
||||||
|
|
||||||
/// Increment iteration to the next entry at the deepest level
|
/// Increment iteration to the next entry at the deepest level
|
||||||
inline void increment() { next(level::page); }
|
inline void increment() { next(level::page); }
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,6 @@ vm_space::clear(const vm_area &vma, uintptr_t offset, size_t count, bool free)
|
|||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
uint64_t &e = it.entry(page_table::level::pt);
|
uint64_t &e = it.entry(page_table::level::pt);
|
||||||
bool allowed = (e & page_table::flag::allowed);
|
|
||||||
uintptr_t phys = e & ~0xfffull;
|
uintptr_t phys = e & ~0xfffull;
|
||||||
|
|
||||||
if (e & page_table::flag::present) {
|
if (e & page_table::flag::present) {
|
||||||
@@ -212,7 +211,7 @@ vm_space::clear(const vm_area &vma, uintptr_t offset, size_t count, bool free)
|
|||||||
fa.free(e & ~0xfffull, 1);
|
fa.free(e & ~0xfffull, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
e = 0 | (allowed ? page_table::flag::allowed : page_table::flag::none);
|
e = 0;
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,24 +228,6 @@ vm_space::lookup(const vm_area &vma, uintptr_t offset)
|
|||||||
return base + offset;
|
return base + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
vm_space::allow(uintptr_t start, size_t length, bool allow)
|
|
||||||
{
|
|
||||||
using level = page_table::level;
|
|
||||||
kassert((start & 0xfff) == 0, "non-page-aligned address");
|
|
||||||
kassert((length & 0xfff) == 0, "non-page-aligned length");
|
|
||||||
|
|
||||||
const uintptr_t end = start + length;
|
|
||||||
page_table::iterator it {start, m_pml4};
|
|
||||||
|
|
||||||
while (it.vaddress() < end) {
|
|
||||||
level d = it.align();
|
|
||||||
while (it.end(d) > end) ++d;
|
|
||||||
it.allow(d-1, allow);
|
|
||||||
it.next(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
vm_space::active() const
|
vm_space::active() const
|
||||||
{
|
{
|
||||||
@@ -276,8 +257,6 @@ vm_space::handle_fault(uintptr_t addr, fault_type fault)
|
|||||||
{
|
{
|
||||||
uintptr_t page = addr & ~0xfffull;
|
uintptr_t page = addr & ~0xfffull;
|
||||||
|
|
||||||
page_table::iterator it {addr, m_pml4};
|
|
||||||
|
|
||||||
// TODO: Handle more fult types
|
// TODO: Handle more fult types
|
||||||
if (fault && fault_type::present)
|
if (fault && fault_type::present)
|
||||||
return false;
|
return false;
|
||||||
@@ -285,33 +264,18 @@ vm_space::handle_fault(uintptr_t addr, fault_type fault)
|
|||||||
uintptr_t base = 0;
|
uintptr_t base = 0;
|
||||||
vm_area *area = get(addr, &base);
|
vm_area *area = get(addr, &base);
|
||||||
|
|
||||||
if ((!area || !area->allowed(page-base)) && !it.allowed())
|
if (!area || !area->allowed(page-base))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uintptr_t phys = 0;
|
uintptr_t phys = 0;
|
||||||
size_t n = frame_allocator::get().allocate(1, &phys);
|
size_t n = frame_allocator::get().allocate(1, &phys);
|
||||||
kassert(n, "Failed to allocate a new page during page fault");
|
kassert(n, "Failed to allocate a new page during page fault");
|
||||||
|
|
||||||
page_table::flag flags =
|
if (area->flags() && vm_flags::zero)
|
||||||
page_table::flag::present |
|
kutil::memset(memory::to_virtual<void>(phys), 0, memory::frame_size);
|
||||||
page_table::flag::write |
|
|
||||||
(area
|
|
||||||
? page_table::flag::none
|
|
||||||
: page_table::flag::allowed) |
|
|
||||||
(is_kernel()
|
|
||||||
? page_table::flag::global
|
|
||||||
: page_table::flag::user);
|
|
||||||
|
|
||||||
if (area) {
|
uintptr_t offset = page - base;
|
||||||
if (area->flags() && vm_flags::zero)
|
area->commit(phys, offset, 1);
|
||||||
kutil::memset(memory::to_virtual<void>(phys), 0, memory::frame_size);
|
|
||||||
|
|
||||||
uintptr_t offset = page - base;
|
|
||||||
area->commit(phys, offset, 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
it.entry(page_table::level::pt) = phys | flags;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,13 +64,6 @@ public:
|
|||||||
/// Look up the address of a given VMA's offset
|
/// Look up the address of a given VMA's offset
|
||||||
uintptr_t lookup(const vm_area &vma, uintptr_t offset);
|
uintptr_t lookup(const vm_area &vma, uintptr_t offset);
|
||||||
|
|
||||||
/// Mark whether allocation is allowed or not in a range of
|
|
||||||
/// virtual memory.
|
|
||||||
/// \arg start The starting virtual address of the area
|
|
||||||
/// \arg length The length in bytes of the area
|
|
||||||
/// \arg allow True if allocation should be allowed
|
|
||||||
void allow(uintptr_t start, size_t length, bool allow);
|
|
||||||
|
|
||||||
/// Check if this space is the current active space
|
/// Check if this space is the current active space
|
||||||
bool active() const;
|
bool active() const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user