mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Map MappedBuffer guard pages in a single operation. (#7158)
This commit is contained in:
		
							parent
							
								
									f9bbae81aa
								
							
						
					
					
						commit
						3b31720c4d
					
				
					 2 changed files with 21 additions and 19 deletions
				
			
		|  | @ -195,18 +195,13 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy | ||||||
| 
 | 
 | ||||||
|             // TODO(Subv): Perform permission checks.
 |             // TODO(Subv): Perform permission checks.
 | ||||||
| 
 | 
 | ||||||
|             // Reserve a page of memory before the mapped buffer
 |             // Create a buffer which contains the mapped buffer and two additional guard pages.
 | ||||||
|             std::shared_ptr<BackingMem> reserve_buffer = |  | ||||||
|                 std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |  | ||||||
|             dst_process->vm_manager.MapBackingMemoryToBase( |  | ||||||
|                 Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer, |  | ||||||
|                 Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Reserved); |  | ||||||
| 
 |  | ||||||
|             std::shared_ptr<BackingMem> buffer = |             std::shared_ptr<BackingMem> buffer = | ||||||
|                 std::make_shared<BufferMem>(num_pages * Memory::CITRA_PAGE_SIZE); |                 std::make_shared<BufferMem>((num_pages + 2) * Memory::CITRA_PAGE_SIZE); | ||||||
|             memory.ReadBlock(*src_process, source_address, buffer->GetPtr() + page_offset, size); |             memory.ReadBlock(*src_process, source_address, | ||||||
|  |                              buffer->GetPtr() + Memory::CITRA_PAGE_SIZE + page_offset, size); | ||||||
| 
 | 
 | ||||||
|             // Map the page(s) into the target process' address space.
 |             // Map the guard pages and mapped pages at once.
 | ||||||
|             target_address = |             target_address = | ||||||
|                 dst_process->vm_manager |                 dst_process->vm_manager | ||||||
|                     .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, |                     .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, | ||||||
|  | @ -214,16 +209,25 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy | ||||||
|                                             Kernel::MemoryState::Shared) |                                             Kernel::MemoryState::Shared) | ||||||
|                     .Unwrap(); |                     .Unwrap(); | ||||||
| 
 | 
 | ||||||
|  |             // Change the permissions and state of the guard pages.
 | ||||||
|  |             const VAddr low_guard_address = target_address; | ||||||
|  |             const VAddr high_guard_address = | ||||||
|  |                 low_guard_address + static_cast<VAddr>(buffer->GetSize()) - Memory::CITRA_PAGE_SIZE; | ||||||
|  |             ASSERT(dst_process->vm_manager.ChangeMemoryState( | ||||||
|  |                        low_guard_address, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Shared, | ||||||
|  |                        Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Reserved, | ||||||
|  |                        Kernel::VMAPermission::None) == RESULT_SUCCESS); | ||||||
|  |             ASSERT(dst_process->vm_manager.ChangeMemoryState( | ||||||
|  |                        high_guard_address, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Shared, | ||||||
|  |                        Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Reserved, | ||||||
|  |                        Kernel::VMAPermission::None) == RESULT_SUCCESS); | ||||||
|  | 
 | ||||||
|  |             // Get proper mapped buffer address and store it in the cmd buffer.
 | ||||||
|  |             target_address += Memory::CITRA_PAGE_SIZE; | ||||||
|             cmd_buf[i++] = target_address + page_offset; |             cmd_buf[i++] = target_address + page_offset; | ||||||
| 
 | 
 | ||||||
|             // Reserve a page of memory after the mapped buffer
 |  | ||||||
|             dst_process->vm_manager.MapBackingMemoryToBase( |  | ||||||
|                 Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer, |  | ||||||
|                 static_cast<u32>(reserve_buffer->GetSize()), Kernel::MemoryState::Reserved); |  | ||||||
| 
 |  | ||||||
|             mapped_buffer_context.push_back({permissions, size, source_address, |             mapped_buffer_context.push_back({permissions, size, source_address, | ||||||
|                                              target_address + page_offset, std::move(buffer), |                                              target_address + page_offset, std::move(buffer)}); | ||||||
|                                              std::move(reserve_buffer)}); |  | ||||||
| 
 | 
 | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -26,7 +26,6 @@ struct MappedBufferContext { | ||||||
|     VAddr target_address; |     VAddr target_address; | ||||||
| 
 | 
 | ||||||
|     std::shared_ptr<BackingMem> buffer; |     std::shared_ptr<BackingMem> buffer; | ||||||
|     std::shared_ptr<BackingMem> reserve_buffer; |  | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|  | @ -36,7 +35,6 @@ private: | ||||||
|         ar& source_address; |         ar& source_address; | ||||||
|         ar& target_address; |         ar& target_address; | ||||||
|         ar& buffer; |         ar& buffer; | ||||||
|         ar& reserve_buffer; |  | ||||||
|     } |     } | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue