Skip to content

Commit

Permalink
check address in sys_rsx_context_iomap
Browse files Browse the repository at this point in the history
* Fix 0 vm page flags to behave like 1m flags, follows c8a681e
* check if address exists and valid for rsx io allcations (must be allocated on 1m pages)
  • Loading branch information
elad335 committed Mar 4, 2019
1 parent c5908a7 commit 8afdc71
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 23 deletions.
35 changes: 23 additions & 12 deletions rpcs3/Emu/Cell/Modules/cellGcmSys.cpp
@@ -1,11 +1,13 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/IdManager.h"
#include "Emu/Cell/PPUModule.h"

#include "Emu/Memory/vm.h"
#include "Emu/RSX/GSRender.h"
#include "Emu/Cell/lv2/sys_ppu_thread.h"
#include "Emu/Cell/lv2/sys_rsx.h"

#include "cellGcmSys.h"
#include "sysPrxForUser.h"

Expand Down Expand Up @@ -951,21 +953,26 @@ s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr<u32> address)

s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict)
{
if (!size || (ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)
|| rsx::get_current_renderer()->main_mem_size < io + size)
if (!size || (ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF))
{
return CELL_GCM_ERROR_FAILURE;
}

// TODO: Pass correct flags and context
if (s32 error = sys_rsx_context_iomap(0, io, ea, size, 0))
{
return CELL_GCM_ERROR_FAILURE;
return error;
}

ea >>=20, io >>= 20, size >>= 20;
ea >>= 20, io >>= 20, size >>= 20;

IoMapTable[ea] = size;

// Fill the offset table and map memory
// Fill the offset table
for (u32 i = 0; i < size; i++)
{
RSXIOMem.io[ea + i] = offsetTable.ioAddress[ea + i] = io + i;
RSXIOMem.ea[io + i] = offsetTable.eaAddress[io + i] = ea + i;
offsetTable.ioAddress[ea + i] = io + i;
offsetTable.eaAddress[io + i] = ea + i;
}

return CELL_OK;
Expand Down Expand Up @@ -1018,19 +1025,23 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
{
if (unmap_count >= (size >> 20))
{
*offset = io << 20;
if (s32 error = sys_rsx_context_iomap(0, io << 20, ea, size, 0))
{
return error;
}

ea >>= 20, size >>= 20;

IoMapTable[ea] = size;

// Fill the offset table and map memory
// Fill the offset table
for (u32 i = 0; i < size; i++)
{
RSXIOMem.io[ea + i] = offsetTable.ioAddress[ea + i] = io + i;
RSXIOMem.ea[io + i] = offsetTable.eaAddress[io + i] = ea + i;
offsetTable.ioAddress[ea + i] = io + i;
offsetTable.eaAddress[io + i] = ea + i;
}

*offset = io << 20;
return CELL_OK;
}
}
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/lv2/sys_mmapper.cpp
Expand Up @@ -283,7 +283,7 @@ error_code sys_mmapper_map_shared_memory(u32 addr, u32 mem_id, u64 flags)

const auto mem = idm::get<lv2_obj, lv2_memory>(mem_id, [&](lv2_memory& mem) -> CellError
{
const u32 page_alignment = area->flags & SYS_MEMORY_PAGE_SIZE_1M ? 0x100000 : 0x10000;
const u32 page_alignment = area->flags & SYS_MEMORY_PAGE_SIZE_64K ? 0x10000 : 0x100000;

if (mem.align < page_alignment)
{
Expand Down
12 changes: 11 additions & 1 deletion rpcs3/Emu/Cell/lv2/sys_rsx.cpp
Expand Up @@ -176,12 +176,22 @@ s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
{
sys_rsx.warning("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags);

if (!size || io & 0xFFFFF || ea & 0xFFFFF || size & 0xFFFFF ||
if (!size || io & 0xFFFFF || ea >= 0xC0000000 || ea & 0xFFFFF || size & 0xFFFFF ||
rsx::get_current_renderer()->main_mem_size < io + size)
{
return CELL_EINVAL;
}

vm::reader_lock rlock;

for (u32 addr = ea, end = ea + size; addr < end; addr += 0x100000)
{
if (!vm::check_addr(addr, 1, vm::page_allocated | vm::page_1m_size))
{
return CELL_EINVAL;
}
}

io >>= 20, ea >>= 20, size >>= 20;

for (u32 i = 0; i < size; i++)
Expand Down
18 changes: 9 additions & 9 deletions rpcs3/Emu/Memory/vm.cpp
Expand Up @@ -689,13 +689,13 @@ namespace vm

u8 pflags = page_readable | page_writable;

if (align >= 0x100000)
if ((flags & SYS_MEMORY_PAGE_SIZE_64K) == SYS_MEMORY_PAGE_SIZE_64K)
{
pflags |= page_1m_size;
pflags |= page_64k_size;
}
else if (align >= 0x10000)
else if (!(flags & (SYS_MEMORY_PAGE_SIZE_MASK & ~SYS_MEMORY_PAGE_SIZE_1M)))
{
pflags |= page_64k_size;
pflags |= page_1m_size;
}

// Create or import shared memory object
Expand Down Expand Up @@ -738,13 +738,13 @@ namespace vm

u8 pflags = page_readable | page_writable;

if ((flags & SYS_MEMORY_PAGE_SIZE_1M) == SYS_MEMORY_PAGE_SIZE_1M)
if ((flags & SYS_MEMORY_PAGE_SIZE_64K) == SYS_MEMORY_PAGE_SIZE_64K)
{
pflags |= page_1m_size;
pflags |= page_64k_size;
}
else if ((flags & SYS_MEMORY_PAGE_SIZE_64K) == SYS_MEMORY_PAGE_SIZE_64K)
else if (!(flags & (SYS_MEMORY_PAGE_SIZE_MASK & ~SYS_MEMORY_PAGE_SIZE_1M)))
{
pflags |= page_64k_size;
pflags |= page_1m_size;
}

// Create or import shared memory object
Expand Down Expand Up @@ -1027,7 +1027,7 @@ namespace vm
{
g_locations =
{
std::make_shared<block_t>(0x00010000, 0x1FFF0000), // main
std::make_shared<block_t>(0x00010000, 0x1FFF0000, 0x200), // main
std::make_shared<block_t>(0x20000000, 0x10000000, 0x201), // user 64k pages
nullptr, // user 1m pages
std::make_shared<block_t>(0xC0000000, 0x10000000), // video
Expand Down

0 comments on commit 8afdc71

Please sign in to comment.