mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-23 18:56:03 +00:00
kern: devirtualize page table operations
This commit is contained in:
parent
ab81ed2795
commit
3fe072a1d0
4 changed files with 37 additions and 10 deletions
|
@ -22,9 +22,11 @@
|
||||||
|
|
||||||
namespace ams::kern::arch::arm64 {
|
namespace ams::kern::arch::arm64 {
|
||||||
|
|
||||||
class KPageTable : public KPageTableBase {
|
class KPageTable final : public KPageTableBase {
|
||||||
NON_COPYABLE(KPageTable);
|
NON_COPYABLE(KPageTable);
|
||||||
NON_MOVEABLE(KPageTable);
|
NON_MOVEABLE(KPageTable);
|
||||||
|
private:
|
||||||
|
friend class KPageTableBase;
|
||||||
public:
|
public:
|
||||||
using TraversalEntry = KPageTableImpl::TraversalEntry;
|
using TraversalEntry = KPageTableImpl::TraversalEntry;
|
||||||
using TraversalContext = KPageTableImpl::TraversalContext;
|
using TraversalContext = KPageTableImpl::TraversalContext;
|
||||||
|
@ -96,9 +98,9 @@ namespace ams::kern::arch::arm64 {
|
||||||
u64 m_ttbr;
|
u64 m_ttbr;
|
||||||
u8 m_asid;
|
u8 m_asid;
|
||||||
protected:
|
protected:
|
||||||
virtual Result Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll) override;
|
Result OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll);
|
||||||
virtual Result Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll) override;
|
Result OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll);
|
||||||
virtual void FinalizeUpdate(PageLinkedList *page_list) override;
|
void FinalizeUpdateImpl(PageLinkedList *page_list);
|
||||||
|
|
||||||
KPageTableManager &GetPageTableManager() const { return *m_manager; }
|
KPageTableManager &GetPageTableManager() const { return *m_manager; }
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -217,9 +217,13 @@ namespace ams::kern {
|
||||||
size_t GetRegionSize(KMemoryState state) const;
|
size_t GetRegionSize(KMemoryState state) const;
|
||||||
bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const;
|
bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const;
|
||||||
protected:
|
protected:
|
||||||
virtual Result Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll) = 0;
|
/* NOTE: These three functions (Operate, Operate, FinalizeUpdate) are virtual functions */
|
||||||
virtual Result Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll) = 0;
|
/* in Nintendo's kernel. We devirtualize them, since KPageTable is the only derived */
|
||||||
virtual void FinalizeUpdate(PageLinkedList *page_list) = 0;
|
/* class, and this avoids unnecessary virtual function calls. See "kern_select_page_table.hpp" */
|
||||||
|
/* for definition of these functions. */
|
||||||
|
Result Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll);
|
||||||
|
Result Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll);
|
||||||
|
void FinalizeUpdate(PageLinkedList *page_list);
|
||||||
|
|
||||||
ALWAYS_INLINE KPageTableImpl &GetImpl() { return m_impl; }
|
ALWAYS_INLINE KPageTableImpl &GetImpl() { return m_impl; }
|
||||||
ALWAYS_INLINE const KPageTableImpl &GetImpl() const { return m_impl; }
|
ALWAYS_INLINE const KPageTableImpl &GetImpl() const { return m_impl; }
|
||||||
|
|
|
@ -32,3 +32,24 @@
|
||||||
#error "Unknown architecture for KPageTable"
|
#error "Unknown architecture for KPageTable"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
/* NOTE: These three functions (Operate, Operate, FinalizeUpdate) are virtual functions */
|
||||||
|
/* in Nintendo's kernel. We devirtualize them, since KPageTable is the only derived */
|
||||||
|
/* class, and this avoids unnecessary virtual function calls. */
|
||||||
|
static_assert(std::derived_from<KPageTable, KPageTableBase>);
|
||||||
|
|
||||||
|
ALWAYS_INLINE Result KPageTableBase::Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll) {
|
||||||
|
return static_cast<KPageTable *>(this)->OperateImpl(page_list, virt_addr, num_pages, phys_addr, is_pa_valid, properties, operation, reuse_ll);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE Result KPageTableBase::Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll) {
|
||||||
|
return static_cast<KPageTable *>(this)->OperateImpl(page_list, virt_addr, num_pages, page_group, properties, operation, reuse_ll);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE void KPageTableBase::FinalizeUpdate(PageLinkedList *page_list) {
|
||||||
|
return static_cast<KPageTable *>(this)->FinalizeUpdateImpl(page_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -319,7 +319,7 @@ namespace ams::kern::arch::arm64 {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTable::Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll) {
|
Result KPageTable::OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll) {
|
||||||
/* Check validity of parameters. */
|
/* Check validity of parameters. */
|
||||||
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
||||||
MESOSPHERE_ASSERT(num_pages > 0);
|
MESOSPHERE_ASSERT(num_pages > 0);
|
||||||
|
@ -350,7 +350,7 @@ namespace ams::kern::arch::arm64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTable::Operate(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll) {
|
Result KPageTable::OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, const KPageGroup &page_group, const KPageProperties properties, OperationType operation, bool reuse_ll) {
|
||||||
/* Check validity of parameters. */
|
/* Check validity of parameters. */
|
||||||
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
||||||
MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize));
|
MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize));
|
||||||
|
@ -1429,7 +1429,7 @@ namespace ams::kern::arch::arm64 {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KPageTable::FinalizeUpdate(PageLinkedList *page_list) {
|
void KPageTable::FinalizeUpdateImpl(PageLinkedList *page_list) {
|
||||||
while (page_list->Peek()) {
|
while (page_list->Peek()) {
|
||||||
KVirtualAddress page = KVirtualAddress(page_list->Pop());
|
KVirtualAddress page = KVirtualAddress(page_list->Pop());
|
||||||
MESOSPHERE_ASSERT(this->GetPageTableManager().IsInPageTableHeap(page));
|
MESOSPHERE_ASSERT(this->GetPageTableManager().IsInPageTableHeap(page));
|
||||||
|
|
Loading…
Reference in a new issue