Merge pull request #2328 from lioncash/transfer
service/am: Correct behavior of CreateTransferMemoryStorage()
This commit is contained in:
		@@ -14,8 +14,8 @@ namespace Kernel {
 | 
			
		||||
TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
 | 
			
		||||
TransferMemory::~TransferMemory() = default;
 | 
			
		||||
 | 
			
		||||
SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address,
 | 
			
		||||
                                                 size_t size, MemoryPermission permissions) {
 | 
			
		||||
SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size,
 | 
			
		||||
                                                 MemoryPermission permissions) {
 | 
			
		||||
    SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)};
 | 
			
		||||
 | 
			
		||||
    transfer_memory->base_address = base_address;
 | 
			
		||||
@@ -26,7 +26,15 @@ SharedPtr<TransferMemory> 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<std::vector<u8>>(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<std::vector<u8>>(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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,9 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#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<TransferMemory> Create(KernelCore& kernel, VAddr base_address, size_t size,
 | 
			
		||||
    static SharedPtr<TransferMemory> 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<std::vector<u8>> 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{};
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
@@ -931,19 +931,19 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
 | 
			
		||||
    rp.SetCurrentOffset(3);
 | 
			
		||||
    const auto handle{rp.Pop<Kernel::Handle>()};
 | 
			
		||||
 | 
			
		||||
    const auto shared_mem =
 | 
			
		||||
        Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::SharedMemory>(
 | 
			
		||||
    const auto transfer_mem =
 | 
			
		||||
        Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(
 | 
			
		||||
            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<u8> memory{mem_begin, mem_end};
 | 
			
		||||
 | 
			
		||||
    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user