MemoryManager.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #pragma once
  2. #include <AK/AKString.h>
  3. #include <AK/Badge.h>
  4. #include <AK/Bitmap.h>
  5. #include <AK/ByteBuffer.h>
  6. #include <AK/HashTable.h>
  7. #include <AK/NonnullRefPtrVector.h>
  8. #include <AK/RefCounted.h>
  9. #include <AK/RefPtr.h>
  10. #include <AK/Types.h>
  11. #include <AK/Vector.h>
  12. #include <AK/Weakable.h>
  13. #include <Kernel/Arch/i386/CPU.h>
  14. #include <Kernel/FileSystem/InodeIdentifier.h>
  15. #include <Kernel/VM/PhysicalPage.h>
  16. #include <Kernel/VM/PhysicalRegion.h>
  17. #include <Kernel/VM/Region.h>
  18. #include <Kernel/VM/VMObject.h>
  19. #define PAGE_ROUND_UP(x) ((((u32)(x)) + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1)))
  20. class KBuffer;
  21. class SynthFSInode;
  22. enum class PageFaultResponse {
  23. ShouldCrash,
  24. Continue,
  25. };
  26. #define MM MemoryManager::the()
  27. class MemoryManager {
  28. AK_MAKE_ETERNAL
  29. friend class PageDirectory;
  30. friend class PhysicalPage;
  31. friend class PhysicalRegion;
  32. friend class Region;
  33. friend class VMObject;
  34. friend Optional<KBuffer> procfs$mm(InodeIdentifier);
  35. friend Optional<KBuffer> procfs$memstat(InodeIdentifier);
  36. public:
  37. static MemoryManager& the();
  38. static void initialize();
  39. PageFaultResponse handle_page_fault(const PageFault&);
  40. bool map_region(Process&, Region&);
  41. bool unmap_region(Region&);
  42. void populate_page_directory(PageDirectory&);
  43. void enter_process_paging_scope(Process&);
  44. bool validate_user_read(const Process&, VirtualAddress) const;
  45. bool validate_user_write(const Process&, VirtualAddress) const;
  46. enum class ShouldZeroFill {
  47. No,
  48. Yes
  49. };
  50. RefPtr<PhysicalPage> allocate_user_physical_page(ShouldZeroFill);
  51. RefPtr<PhysicalPage> allocate_supervisor_physical_page();
  52. void deallocate_user_physical_page(PhysicalPage&&);
  53. void deallocate_supervisor_physical_page(PhysicalPage&&);
  54. void remap_region(PageDirectory&, Region&);
  55. void map_for_kernel(VirtualAddress, PhysicalAddress);
  56. RefPtr<Region> allocate_kernel_region(size_t, const StringView& name, bool user_accessible = false);
  57. RefPtr<Region> allocate_user_accessible_kernel_region(size_t, const StringView& name);
  58. void map_region_at_address(PageDirectory&, Region&, VirtualAddress);
  59. unsigned user_physical_pages() const { return m_user_physical_pages; }
  60. unsigned user_physical_pages_used() const { return m_user_physical_pages_used; }
  61. unsigned super_physical_pages() const { return m_super_physical_pages; }
  62. unsigned super_physical_pages_used() const { return m_super_physical_pages_used; }
  63. private:
  64. MemoryManager();
  65. ~MemoryManager();
  66. void register_vmo(VMObject&);
  67. void unregister_vmo(VMObject&);
  68. void register_region(Region&);
  69. void unregister_region(Region&);
  70. void remap_region_page(Region&, unsigned page_index_in_region);
  71. void initialize_paging();
  72. void flush_entire_tlb();
  73. void flush_tlb(VirtualAddress);
  74. RefPtr<PhysicalPage> allocate_page_table(PageDirectory&, unsigned index);
  75. void map_protected(VirtualAddress, size_t length);
  76. void create_identity_mapping(PageDirectory&, VirtualAddress, size_t length);
  77. void remove_identity_mapping(PageDirectory&, VirtualAddress, size_t);
  78. static Region* region_from_vaddr(Process&, VirtualAddress);
  79. static const Region* region_from_vaddr(const Process&, VirtualAddress);
  80. static Region* user_region_from_vaddr(Process&, VirtualAddress);
  81. static Region* kernel_region_from_vaddr(VirtualAddress);
  82. bool copy_on_write(Region&, unsigned page_index_in_region);
  83. bool page_in_from_inode(Region&, unsigned page_index_in_region);
  84. bool zero_page(Region& region, unsigned page_index_in_region);
  85. u8* quickmap_page(PhysicalPage&);
  86. void unquickmap_page();
  87. PageDirectory& kernel_page_directory() { return *m_kernel_page_directory; }
  88. PageTableEntry& ensure_pte(PageDirectory&, VirtualAddress);
  89. RefPtr<PageDirectory> m_kernel_page_directory;
  90. PageTableEntry* m_page_table_zero { nullptr };
  91. PageTableEntry* m_page_table_one { nullptr };
  92. VirtualAddress m_quickmap_addr;
  93. unsigned m_user_physical_pages { 0 };
  94. unsigned m_user_physical_pages_used { 0 };
  95. unsigned m_super_physical_pages { 0 };
  96. unsigned m_super_physical_pages_used { 0 };
  97. NonnullRefPtrVector<PhysicalRegion> m_user_physical_regions;
  98. NonnullRefPtrVector<PhysicalRegion> m_super_physical_regions;
  99. HashTable<VMObject*> m_vmos;
  100. HashTable<Region*> m_user_regions;
  101. HashTable<Region*> m_kernel_regions;
  102. bool m_quickmap_in_use { false };
  103. };
  104. struct ProcessPagingScope {
  105. ProcessPagingScope(Process&);
  106. ~ProcessPagingScope();
  107. };