From 32aecd42a2c7b011c7061889fa3343b0efe1862a Mon Sep 17 00:00:00 2001 From: NarcolepticK Date: Mon, 1 Oct 2018 21:07:25 -0400 Subject: [PATCH] LLE Mapped Buffer: Corrected behavior --- src/core/hle/kernel/ipc.cpp | 77 +++++++++++++++---------------------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index 070bb6619..9875fc68a 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -39,6 +39,7 @@ ResultCode TranslateCommandBuffer(SharedPtr src_thread, SharedPtr dst_cmd_buf; Memory::ReadBlock(*dst_process, dst_address, dst_cmd_buf.data(), @@ -148,54 +149,44 @@ ResultCode TranslateCommandBuffer(SharedPtr src_thread, SharedPtr(dest_descInfo.size); IPC::MappedBufferPermissions dest_permissions = dest_descInfo.perms; - if (permissions == dest_permissions && size == dest_size) { - // Readonly buffers do not need to be copied over to the target - // process again because they were (presumably) not modified. This - // behavior is consistent with the real kernel. - if (permissions != IPC::MappedBufferPermissions::R) { - // Copy the modified buffer back into the target process - Memory::CopyBlock(*src_process, *dst_process, source_address, - dest_address, size); - } - - // Unmap the Reserved page before the buffer - ResultCode result = src_process->vm_manager.UnmapRange( - page_start - Memory::PAGE_SIZE, Memory::PAGE_SIZE); - ASSERT(result == RESULT_SUCCESS); - - // Unmap the buffer from the source process - result = src_process->vm_manager.UnmapRange( - page_start, num_pages * Memory::PAGE_SIZE); - ASSERT(result == RESULT_SUCCESS); - - // Check if this is the last mapped buffer - VAddr next_reserve = page_start + num_pages * Memory::PAGE_SIZE; - auto& vma = - src_process->vm_manager.FindVMA(next_reserve + Memory::PAGE_SIZE) - ->second; - if (vma.type == VMAType::Free) { - // Unmap the Reserved page after the last buffer - result = src_process->vm_manager.UnmapRange(next_reserve, - Memory::PAGE_SIZE); - ASSERT(result == RESULT_SUCCESS); - } - - break; + ASSERT(permissions == dest_permissions && size == dest_size); + // Readonly buffers do not need to be copied over to the target + // process again because they were (presumably) not modified. This + // behavior is consistent with the real kernel. + if (permissions != IPC::MappedBufferPermissions::R) { + // Copy the modified buffer back into the target process + Memory::CopyBlock(*src_process, *dst_process, source_address, + dest_address, size); } + + VAddr prev_reserve = page_start - Memory::PAGE_SIZE; + VAddr next_reserve = page_start + num_pages * Memory::PAGE_SIZE; + + auto& prev_vma = src_process->vm_manager.FindVMA(prev_reserve)->second; + auto& next_vma = src_process->vm_manager.FindVMA(next_reserve)->second; + ASSERT(prev_vma.meminfo_state == MemoryState::Reserved && + next_vma.meminfo_state == MemoryState::Reserved); + + // Unmap the buffer and guard pages from the source process + ResultCode result = src_process->vm_manager.UnmapRange( + page_start - Memory::PAGE_SIZE, (num_pages + 2) * Memory::PAGE_SIZE); + ASSERT(result == RESULT_SUCCESS); + + target_index += 1; + break; } - j += 1; + target_index += 1; } i += 1; @@ -224,15 +215,7 @@ ResultCode TranslateCommandBuffer(SharedPtr src_thread, SharedPtrvm_manager.MapMemoryBlockToBase( Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer, 0, static_cast(reserve_buffer->size()), Kernel::MemoryState::Reserved);