mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +00:00
Reserve fixes
ReserveVirtualRange seems to follow the 0x200000000 base address like MemoryPoolReserve does. Both also need checks in their flags Fixed path to ensure we're mapping in-bounds. If we're not in mapping to our address space, we'll end up reserving and returning the wrong address, which could lead to weird memory issues in games. I'll need to test on real hardware to verify if such changes are appropriate.
This commit is contained in:
parent
1c0945e4ae
commit
c59bb4f1f1
@ -223,9 +223,9 @@ int MemoryManager::PoolReserve(void** out_addr, VAddr virtual_addr, size_t size,
|
|||||||
|
|
||||||
// Fixed mapping means the virtual address must exactly match the provided one.
|
// Fixed mapping means the virtual address must exactly match the provided one.
|
||||||
if (True(flags & MemoryMapFlags::Fixed)) {
|
if (True(flags & MemoryMapFlags::Fixed)) {
|
||||||
// Make sure we're mapping to a valid address
|
|
||||||
mapped_addr = mapped_addr > min_address ? mapped_addr : min_address;
|
|
||||||
auto vma = FindVMA(mapped_addr)->second;
|
auto vma = FindVMA(mapped_addr)->second;
|
||||||
|
// If the found vma doesn't contain our address, then it's not in the vma map.
|
||||||
|
ASSERT_MSG(vma.Contains(mapped_addr, 0), "Requested address is out of bounds!");
|
||||||
size_t remaining_size = vma.base + vma.size - mapped_addr;
|
size_t remaining_size = vma.base + vma.size - mapped_addr;
|
||||||
// If the VMA is mapped or there's not enough space, unmap the region first.
|
// If the VMA is mapped or there's not enough space, unmap the region first.
|
||||||
if (vma.IsMapped() || remaining_size < size) {
|
if (vma.IsMapped() || remaining_size < size) {
|
||||||
@ -260,14 +260,15 @@ int MemoryManager::PoolReserve(void** out_addr, VAddr virtual_addr, size_t size,
|
|||||||
int MemoryManager::Reserve(void** out_addr, VAddr virtual_addr, size_t size, MemoryMapFlags flags,
|
int MemoryManager::Reserve(void** out_addr, VAddr virtual_addr, size_t size, MemoryMapFlags flags,
|
||||||
u64 alignment) {
|
u64 alignment) {
|
||||||
std::scoped_lock lk{mutex};
|
std::scoped_lock lk{mutex};
|
||||||
|
|
||||||
virtual_addr = (virtual_addr == 0) ? impl.SystemManagedVirtualBase() : virtual_addr;
|
|
||||||
alignment = alignment > 0 ? alignment : 16_KB;
|
alignment = alignment > 0 ? alignment : 16_KB;
|
||||||
VAddr mapped_addr = alignment > 0 ? Common::AlignUp(virtual_addr, alignment) : virtual_addr;
|
VAddr min_address = Common::AlignUp(impl.SystemManagedVirtualBase(), alignment);
|
||||||
|
VAddr mapped_addr = Common::AlignUp(virtual_addr, alignment);
|
||||||
|
|
||||||
// Fixed mapping means the virtual address must exactly match the provided one.
|
// Fixed mapping means the virtual address must exactly match the provided one.
|
||||||
if (True(flags & MemoryMapFlags::Fixed)) {
|
if (True(flags & MemoryMapFlags::Fixed)) {
|
||||||
auto vma = FindVMA(mapped_addr)->second;
|
auto vma = FindVMA(mapped_addr)->second;
|
||||||
|
// If the found vma doesn't contain our address, then it's not in the vma map.
|
||||||
|
ASSERT_MSG(vma.Contains(mapped_addr, 0), "Requested address is out of bounds!");
|
||||||
size_t remaining_size = vma.base + vma.size - mapped_addr;
|
size_t remaining_size = vma.base + vma.size - mapped_addr;
|
||||||
// If the VMA is mapped or there's not enough space, unmap the region first.
|
// If the VMA is mapped or there's not enough space, unmap the region first.
|
||||||
if (vma.IsMapped() || remaining_size < size) {
|
if (vma.IsMapped() || remaining_size < size) {
|
||||||
@ -278,6 +279,9 @@ int MemoryManager::Reserve(void** out_addr, VAddr virtual_addr, size_t size, Mem
|
|||||||
|
|
||||||
// Find the first free area starting with provided virtual address.
|
// Find the first free area starting with provided virtual address.
|
||||||
if (False(flags & MemoryMapFlags::Fixed)) {
|
if (False(flags & MemoryMapFlags::Fixed)) {
|
||||||
|
// When MemoryMapFlags::Fixed is not specified, and mapped_addr is 0,
|
||||||
|
// search from address 0x200000000 instead.
|
||||||
|
mapped_addr = mapped_addr == 0 ? 0x200000000 : mapped_addr;
|
||||||
mapped_addr = SearchFree(mapped_addr, size, alignment);
|
mapped_addr = SearchFree(mapped_addr, size, alignment);
|
||||||
if (mapped_addr == -1) {
|
if (mapped_addr == -1) {
|
||||||
// No suitable memory areas to map to
|
// No suitable memory areas to map to
|
||||||
|
Loading…
Reference in New Issue
Block a user