mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +00:00
Validate requested dmem range in MapMemory
Handles a rare edge case that only comes up when modding Driveclub
This commit is contained in:
parent
e389d03601
commit
607bd59a9c
@ -320,6 +320,28 @@ s32 MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, u64 size, Memo
|
|||||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate the requested physical address range
|
||||||
|
if (phys_addr != -1) {
|
||||||
|
auto validated_size = 0;
|
||||||
|
do {
|
||||||
|
auto dmem_area = FindDmemArea(phys_addr + validated_size)->second;
|
||||||
|
// If any requested dmem area is not allocated, return an error.
|
||||||
|
if (dmem_area.is_free) {
|
||||||
|
LOG_ERROR(Kernel_Vmm, "Unable to map {:#x} bytes at physical address {:#x}", size,
|
||||||
|
phys_addr);
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
// Track how much we've validated.
|
||||||
|
validated_size += dmem_area.size - (phys_addr + validated_size - dmem_area.base);
|
||||||
|
} while (validated_size < size && phys_addr + validated_size < GetTotalDirectSize());
|
||||||
|
// If the requested range goes outside the dmem map, return an error.
|
||||||
|
if (validated_size < size) {
|
||||||
|
LOG_ERROR(Kernel_Vmm, "Unable to map {:#x} bytes at physical address {:#x}", size,
|
||||||
|
phys_addr);
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Limit the minumum address to SystemManagedVirtualBase to prevent hardware-specific issues.
|
// Limit the minumum address to SystemManagedVirtualBase to prevent hardware-specific issues.
|
||||||
VAddr mapped_addr = (virtual_addr == 0) ? impl.SystemManagedVirtualBase() : virtual_addr;
|
VAddr mapped_addr = (virtual_addr == 0) ? impl.SystemManagedVirtualBase() : virtual_addr;
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ enum class VMAType : u32 {
|
|||||||
|
|
||||||
struct DirectMemoryArea {
|
struct DirectMemoryArea {
|
||||||
PAddr base = 0;
|
PAddr base = 0;
|
||||||
size_t size = 0;
|
u64 size = 0;
|
||||||
int memory_type = 0;
|
s32 memory_type = 0;
|
||||||
bool is_pooled = false;
|
bool is_pooled = false;
|
||||||
bool is_free = true;
|
bool is_free = true;
|
||||||
|
|
||||||
@ -72,6 +72,10 @@ struct DirectMemoryArea {
|
|||||||
return base + size;
|
return base + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Contains(PAddr addr, u64 size) const {
|
||||||
|
return addr >= base && (addr + size) <= (base + this->size);
|
||||||
|
}
|
||||||
|
|
||||||
bool CanMergeWith(const DirectMemoryArea& next) const {
|
bool CanMergeWith(const DirectMemoryArea& next) const {
|
||||||
if (base + size != next.base) {
|
if (base + size != next.base) {
|
||||||
return false;
|
return false;
|
||||||
@ -88,7 +92,7 @@ struct DirectMemoryArea {
|
|||||||
|
|
||||||
struct VirtualMemoryArea {
|
struct VirtualMemoryArea {
|
||||||
VAddr base = 0;
|
VAddr base = 0;
|
||||||
size_t size = 0;
|
u64 size = 0;
|
||||||
PAddr phys_base = 0;
|
PAddr phys_base = 0;
|
||||||
VMAType type = VMAType::Free;
|
VMAType type = VMAType::Free;
|
||||||
MemoryProt prot = MemoryProt::NoAccess;
|
MemoryProt prot = MemoryProt::NoAccess;
|
||||||
|
Loading…
Reference in New Issue
Block a user