From 140cd5e209e5b764360fb3298a6a3cc6afe0f69a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 3 Apr 2019 16:31:26 -0400 Subject: [PATCH 1/2] kernel/transfer_memory: Add accessors to data and sizes Also amend erroneous use of size_t. We should be using u64 here. --- src/core/hle/kernel/transfer_memory.cpp | 22 +++++++++++++++------- src/core/hle/kernel/transfer_memory.h | 20 ++++++++++++++++---- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp index 23228e1b5..26c4e5e67 100644 --- a/src/core/hle/kernel/transfer_memory.cpp +++ b/src/core/hle/kernel/transfer_memory.cpp @@ -14,8 +14,8 @@ namespace Kernel { TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {} TransferMemory::~TransferMemory() = default; -SharedPtr TransferMemory::Create(KernelCore& kernel, VAddr base_address, - size_t size, MemoryPermission permissions) { +SharedPtr TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size, + MemoryPermission permissions) { SharedPtr transfer_memory{new TransferMemory(kernel)}; transfer_memory->base_address = base_address; @@ -26,7 +26,15 @@ SharedPtr TransferMemory::Create(KernelCore& kernel, VAddr base_ return transfer_memory; } -ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermission permissions) { +const u8* TransferMemory::GetPointer() const { + return backing_block.get()->data(); +} + +u64 TransferMemory::GetSize() const { + return memory_size; +} + +ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission permissions) { if (memory_size != size) { return ERR_INVALID_SIZE; } @@ -39,13 +47,13 @@ ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermissio return ERR_INVALID_STATE; } + backing_block = std::make_shared>(size); + const auto map_state = owner_permissions == MemoryPermission::None ? MemoryState::TransferMemoryIsolated : MemoryState::TransferMemory; auto& vm_manager = owner_process->VMManager(); - const auto map_result = vm_manager.MapMemoryBlock( - address, std::make_shared>(size), 0, size, map_state); - + const auto map_result = vm_manager.MapMemoryBlock(address, backing_block, 0, size, map_state); if (map_result.Failed()) { return map_result.Code(); } @@ -54,7 +62,7 @@ ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermissio return RESULT_SUCCESS; } -ResultCode TransferMemory::UnmapMemory(VAddr address, size_t size) { +ResultCode TransferMemory::UnmapMemory(VAddr address, u64 size) { if (memory_size != size) { return ERR_INVALID_SIZE; } diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h index ec294951e..a140b1e2b 100644 --- a/src/core/hle/kernel/transfer_memory.h +++ b/src/core/hle/kernel/transfer_memory.h @@ -4,6 +4,9 @@ #pragma once +#include +#include + #include "core/hle/kernel/object.h" union ResultCode; @@ -25,7 +28,7 @@ class TransferMemory final : public Object { public: static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; - static SharedPtr Create(KernelCore& kernel, VAddr base_address, size_t size, + static SharedPtr Create(KernelCore& kernel, VAddr base_address, u64 size, MemoryPermission permissions); TransferMemory(const TransferMemory&) = delete; @@ -46,6 +49,12 @@ public: return HANDLE_TYPE; } + /// Gets a pointer to the backing block of this instance. + const u8* GetPointer() const; + + /// Gets the size of the memory backing this instance in bytes. + u64 GetSize() const; + /// Attempts to map transfer memory with the given range and memory permissions. /// /// @param address The base address to being mapping memory at. @@ -56,7 +65,7 @@ public: /// the same values that were given when creating the transfer memory /// instance. /// - ResultCode MapMemory(VAddr address, size_t size, MemoryPermission permissions); + ResultCode MapMemory(VAddr address, u64 size, MemoryPermission permissions); /// Unmaps the transfer memory with the given range /// @@ -66,17 +75,20 @@ public: /// @pre The given address and size must be the same as the ones used /// to create the transfer memory instance. /// - ResultCode UnmapMemory(VAddr address, size_t size); + ResultCode UnmapMemory(VAddr address, u64 size); private: explicit TransferMemory(KernelCore& kernel); ~TransferMemory() override; + /// Memory block backing this instance. + std::shared_ptr> backing_block; + /// The base address for the memory managed by this instance. VAddr base_address = 0; /// Size of the memory, in bytes, that this instance manages. - size_t memory_size = 0; + u64 memory_size = 0; /// The memory permissions that are applied to this instance. MemoryPermission owner_permissions{}; From ea8f633dc088ca5e40d3391d1b826c753a94bf26 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 3 Apr 2019 16:35:14 -0400 Subject: [PATCH 2/2] service/am: Correct behavior of CreateTransferMemoryStorage() For whatever reason, shared memory was being used here instead of transfer memory, which (quite clearly) will not work based off the name of the function. This corrects this wonky usage of shared memory. --- src/core/hle/service/am/am.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 9c44e27c6..7d3e0e545 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -13,7 +13,7 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/readable_event.h" -#include "core/hle/kernel/shared_memory.h" +#include "core/hle/kernel/transfer_memory.h" #include "core/hle/kernel/writable_event.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/am/am.h" @@ -907,19 +907,19 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex rp.SetCurrentOffset(3); const auto handle{rp.Pop()}; - const auto shared_mem = - Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get( + const auto transfer_mem = + Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get( handle); - if (shared_mem == nullptr) { + if (transfer_mem == nullptr) { LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultCode(-1)); return; } - const u8* mem_begin = shared_mem->GetPointer(); - const u8* mem_end = mem_begin + shared_mem->GetSize(); + const u8* const mem_begin = transfer_mem->GetPointer(); + const u8* const mem_end = mem_begin + transfer_mem->GetSize(); std::vector memory{mem_begin, mem_end}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};