mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:32:45 +00:00 
			
		
		
		
	Kernel: Make allocate_supervisor_physical_page OOM-fallible
This commit is contained in:
		
							parent
							
								
									4d2f1a05ec
								
							
						
					
					
						commit
						bd5b56cab0
					
				
					 4 changed files with 11 additions and 21 deletions
				
			
		|  | @ -741,12 +741,9 @@ ErrorOr<NonnullOwnPtr<Region>> MemoryManager::allocate_contiguous_kernel_region( | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access, RefPtr<Memory::PhysicalPage>& dma_buffer_page) | ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access, RefPtr<Memory::PhysicalPage>& dma_buffer_page) | ||||||
| { | { | ||||||
|     dma_buffer_page = allocate_supervisor_physical_page(); |     dma_buffer_page = TRY(allocate_supervisor_physical_page()); | ||||||
|     if (dma_buffer_page.is_null()) |  | ||||||
|         return ENOMEM; |  | ||||||
|     // Do not enable Cache for this region as physical memory transfers are performed (Most architectures have this behaviour by default)
 |     // Do not enable Cache for this region as physical memory transfers are performed (Most architectures have this behaviour by default)
 | ||||||
|     auto region_or_error = allocate_kernel_region(dma_buffer_page->paddr(), PAGE_SIZE, name, access, Region::Cacheable::No); |     return allocate_kernel_region(dma_buffer_page->paddr(), PAGE_SIZE, name, access, Region::Cacheable::No); | ||||||
|     return region_or_error; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access) | ErrorOr<NonnullOwnPtr<Memory::Region>> MemoryManager::allocate_dma_buffer_page(StringView name, Memory::Region::Access access) | ||||||
|  | @ -956,22 +953,21 @@ ErrorOr<NonnullRefPtrVector<PhysicalPage>> MemoryManager::allocate_contiguous_su | ||||||
|     return physical_pages; |     return physical_pages; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RefPtr<PhysicalPage> MemoryManager::allocate_supervisor_physical_page() | ErrorOr<NonnullRefPtr<PhysicalPage>> MemoryManager::allocate_supervisor_physical_page() | ||||||
| { | { | ||||||
|     SpinlockLocker lock(s_mm_lock); |     SpinlockLocker lock(s_mm_lock); | ||||||
|     auto page = m_super_physical_region->take_free_page(); |     auto page = m_super_physical_region->take_free_page(); | ||||||
| 
 | 
 | ||||||
|     if (!page) { |     if (!page) { | ||||||
|         dmesgln("MM: no super physical pages available"); |         dmesgln("MM: no super physical pages available"); | ||||||
|         VERIFY_NOT_REACHED(); |         return ENOMEM; | ||||||
|         return {}; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto* ptr = quickmap_page(*page); |     auto* ptr = quickmap_page(*page); | ||||||
|     memset(ptr, 0, PAGE_SIZE); |     memset(ptr, 0, PAGE_SIZE); | ||||||
|     unquickmap_page(); |     unquickmap_page(); | ||||||
|     ++m_system_memory_info.super_physical_pages_used; |     ++m_system_memory_info.super_physical_pages_used; | ||||||
|     return page; |     return page.release_nonnull(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemoryManager::enter_process_address_space(Process& process) | void MemoryManager::enter_process_address_space(Process& process) | ||||||
|  |  | ||||||
|  | @ -172,7 +172,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     NonnullRefPtr<PhysicalPage> allocate_committed_user_physical_page(Badge<CommittedPhysicalPageSet>, ShouldZeroFill = ShouldZeroFill::Yes); |     NonnullRefPtr<PhysicalPage> allocate_committed_user_physical_page(Badge<CommittedPhysicalPageSet>, ShouldZeroFill = ShouldZeroFill::Yes); | ||||||
|     RefPtr<PhysicalPage> allocate_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes, bool* did_purge = nullptr); |     RefPtr<PhysicalPage> allocate_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes, bool* did_purge = nullptr); | ||||||
|     RefPtr<PhysicalPage> allocate_supervisor_physical_page(); |     ErrorOr<NonnullRefPtr<PhysicalPage>> allocate_supervisor_physical_page(); | ||||||
|     ErrorOr<NonnullRefPtrVector<PhysicalPage>> allocate_contiguous_supervisor_physical_pages(size_t size); |     ErrorOr<NonnullRefPtrVector<PhysicalPage>> allocate_contiguous_supervisor_physical_pages(size_t size); | ||||||
|     void deallocate_physical_page(PhysicalAddress); |     void deallocate_physical_page(PhysicalAddress); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,25 +37,19 @@ AHCIPort::AHCIPort(const AHCIPortHandler& handler, volatile AHCI::PortRegisters& | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     m_fis_receive_page = MM.allocate_supervisor_physical_page(); |     m_fis_receive_page = MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors(); | ||||||
|     if (m_fis_receive_page.is_null()) |  | ||||||
|         return; |  | ||||||
| 
 | 
 | ||||||
|     for (size_t index = 0; index < 1; index++) { |     for (size_t index = 0; index < 1; index++) { | ||||||
|         m_dma_buffers.append(MM.allocate_supervisor_physical_page().release_nonnull()); |         m_dma_buffers.append(MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors()); | ||||||
|     } |     } | ||||||
|     for (size_t index = 0; index < 1; index++) { |     for (size_t index = 0; index < 1; index++) { | ||||||
|         m_command_table_pages.append(MM.allocate_supervisor_physical_page().release_nonnull()); |         m_command_table_pages.append(MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto region_or_error = MM.allocate_dma_buffer_page("AHCI Port Command List", Memory::Region::Access::ReadWrite, m_command_list_page); |     m_command_list_region = MM.allocate_dma_buffer_page("AHCI Port Command List", Memory::Region::Access::ReadWrite, m_command_list_page).release_value_but_fixme_should_propagate_errors(); | ||||||
| 
 | 
 | ||||||
|     dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list page at {}", representative_port_index(), m_command_list_page->paddr()); |     dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list page at {}", representative_port_index(), m_command_list_page->paddr()); | ||||||
|     dbgln_if(AHCI_DEBUG, "AHCI Port {}: FIS receive page at {}", representative_port_index(), m_fis_receive_page->paddr()); |     dbgln_if(AHCI_DEBUG, "AHCI Port {}: FIS receive page at {}", representative_port_index(), m_fis_receive_page->paddr()); | ||||||
| 
 |  | ||||||
|     if (region_or_error.is_error()) |  | ||||||
|         TODO(); |  | ||||||
|     m_command_list_region = region_or_error.release_value(); |  | ||||||
|     dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list region at {}", representative_port_index(), m_command_list_region->vaddr()); |     dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list region at {}", representative_port_index(), m_command_list_region->vaddr()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ AHCIPortHandler::AHCIPortHandler(AHCIController& controller, u8 irq, AHCI::Maske | ||||||
| { | { | ||||||
|     // FIXME: Use the number of taken ports to determine how many pages we should allocate.
 |     // FIXME: Use the number of taken ports to determine how many pages we should allocate.
 | ||||||
|     for (size_t index = 0; index < (((size_t)AHCI::Limits::MaxPorts * 512) / PAGE_SIZE); index++) { |     for (size_t index = 0; index < (((size_t)AHCI::Limits::MaxPorts * 512) / PAGE_SIZE); index++) { | ||||||
|         m_identify_metadata_pages.append(MM.allocate_supervisor_physical_page().release_nonnull()); |         m_identify_metadata_pages.append(MM.allocate_supervisor_physical_page().release_value_but_fixme_should_propagate_errors()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     dbgln_if(AHCI_DEBUG, "AHCI Port Handler: IRQ {}", irq); |     dbgln_if(AHCI_DEBUG, "AHCI Port Handler: IRQ {}", irq); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Idan Horowitz
						Idan Horowitz