Map MappedBuffer guard pages in a single operation. (#7158)

This commit is contained in:
PabloMK7 2023-11-14 10:33:38 +01:00 committed by GitHub
parent f9bbae81aa
commit 3b31720c4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 19 deletions

View File

@ -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;
} }

View File

@ -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;
}; };