Added Mtyprotect and moved Mprotect to ORBIS_KERNEL_MAP_OP_PROTECT
This commit is contained in:
parent
4914809672
commit
9ad6317f01
|
@ -216,6 +216,23 @@ int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot) {
|
|||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelMTypeProtect(void* addr, size_t size, int mtype, int prot) {
|
||||
LOG_INFO(Kernel_Vmm, "called addr = {}, size = {:#x}, mtype = {:#x}, prot = {:#x}",
|
||||
fmt::ptr(addr), size, mtype, prot);
|
||||
Core::MemoryManager* memory_manager = Core::Memory::Instance();
|
||||
if (!memory_manager) {
|
||||
LOG_ERROR(Kernel_Vmm, "Failed to get MemoryManager instance");
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
int result = memory_manager->MTypeProtect(std::bit_cast<VAddr>(addr), size,
|
||||
static_cast<Core::VMAType>(mtype), prot);
|
||||
if (result != ORBIS_OK) {
|
||||
LOG_ERROR(Kernel_Vmm, "MTypeProtect failed with result {}", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info,
|
||||
size_t infoSize) {
|
||||
LOG_WARNING(Kernel_Vmm, "called offset = {:#x}, flags = {:#x}", offset, flags);
|
||||
|
@ -284,8 +301,8 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn
|
|||
processed++;
|
||||
} else if (entries[i].operation ==
|
||||
MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT) { // MPROTECT
|
||||
result =
|
||||
sceKernelMProtect(entries[i].start, entries[i].length, entries[i].protection);
|
||||
result = sceKernelMTypeProtect(entries[i].start, entries[i].length, entries[i].type,
|
||||
entries[i].protection);
|
||||
LOG_INFO(Kernel_Vmm,
|
||||
"BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}", i,
|
||||
entries[i].operation, entries[i].length, result);
|
||||
|
@ -296,6 +313,19 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn
|
|||
if (result == 0) {
|
||||
processed++;
|
||||
}
|
||||
} else if (entries[i].operation ==
|
||||
MemoryOpTypes::ORBIS_KERNEL_MAP_OP_PROTECT) { // MPROTECT
|
||||
result = sceKernelMProtect(entries[i].start, entries[i].length,
|
||||
entries[i].protection);
|
||||
LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}",
|
||||
i, entries[i].operation, entries[i].length, result);
|
||||
if (result != ORBIS_OK) {
|
||||
LOG_ERROR(Kernel_Vmm, "BatchMap: MProtect failed on entry {} with result {}", i,
|
||||
result);
|
||||
}
|
||||
if (result == 0) {
|
||||
processed++;
|
||||
}
|
||||
} else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE) {
|
||||
result = sceKernelMapNamedFlexibleMemory(&entries[i].start, entries[i].length,
|
||||
entries[i].protection, flags, "");
|
||||
|
|
|
@ -95,6 +95,10 @@ s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len,
|
|||
int flags);
|
||||
int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** end, u32* prot);
|
||||
|
||||
int PS4_SYSV_ABI sceKernelMProtect(void* addr, size_t size, int prot);
|
||||
|
||||
int PS4_SYSV_ABI sceKernelMTypeProtect(void* addr, size_t size, int mtype, int prot);
|
||||
|
||||
int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info,
|
||||
size_t infoSize);
|
||||
s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut);
|
||||
|
|
|
@ -315,6 +315,58 @@ int MemoryManager::MProtect(VAddr addr, size_t size, int prot) {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot) {
|
||||
std::scoped_lock lk{mutex};
|
||||
|
||||
// Find the virtual memory area that contains the specified address range.
|
||||
auto it = FindVMA(addr);
|
||||
if (it == vma_map.end() || !it->second.Contains(addr, size)) {
|
||||
LOG_ERROR(Core, "Address range not mapped");
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
VirtualMemoryArea& vma = it->second;
|
||||
if (vma.type == VMAType::Free) {
|
||||
LOG_ERROR(Core, "Cannot change protection on free memory region");
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
// Check if the new protection flags are valid.
|
||||
if ((static_cast<int>(prot) &
|
||||
~(static_cast<int>(MemoryProt::NoAccess) | static_cast<int>(MemoryProt::CpuRead) |
|
||||
static_cast<int>(MemoryProt::CpuReadWrite) | static_cast<int>(MemoryProt::GpuRead) |
|
||||
static_cast<int>(MemoryProt::GpuWrite) | static_cast<int>(MemoryProt::GpuReadWrite))) !=
|
||||
0) {
|
||||
LOG_ERROR(Core, "Invalid protection flags, prot: {:#x}, GpuWrite: {:#x}",
|
||||
static_cast<uint32_t>(prot), static_cast<uint32_t>(MemoryProt::GpuWrite));
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
// Change the type and protection on the specified address range.
|
||||
vma.type = mtype;
|
||||
vma.prot = static_cast<MemoryProt>(prot);
|
||||
|
||||
// Use the Protect function from the AddressSpace class.
|
||||
Core::MemoryPermission perms;
|
||||
if ((static_cast<int>(prot) & static_cast<int>(MemoryProt::CpuRead)) != 0)
|
||||
perms |= Core::MemoryPermission::Read;
|
||||
if ((static_cast<int>(prot) & static_cast<int>(MemoryProt::CpuReadWrite)) != 0)
|
||||
perms |= Core::MemoryPermission::ReadWrite;
|
||||
if ((static_cast<int>(prot) & static_cast<int>(MemoryProt::GpuRead)) != 0)
|
||||
perms |= Core::MemoryPermission::Read;
|
||||
if ((static_cast<int>(prot) & static_cast<int>(MemoryProt::GpuWrite)) != 0)
|
||||
perms |= Core::MemoryPermission::Write;
|
||||
if ((static_cast<int>(prot) & static_cast<int>(MemoryProt::GpuReadWrite)) != 0)
|
||||
perms |= Core::MemoryPermission::ReadWrite;
|
||||
impl.Protect(addr, size, perms);
|
||||
|
||||
LOG_INFO(Core, "Changed type and protection on range {:#x}-{:#x} to {:#x} {:#x}", addr,
|
||||
addr + size, mtype, prot);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int MemoryManager::VirtualQuery(VAddr addr, int flags,
|
||||
Libraries::Kernel::OrbisVirtualQueryInfo* info) {
|
||||
|
|
|
@ -167,6 +167,8 @@ public:
|
|||
|
||||
int MProtect(VAddr addr, size_t size, int prot);
|
||||
|
||||
int MTypeProtect(VAddr addr, size_t size, VMAType mtype, int prot);
|
||||
|
||||
int VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info);
|
||||
|
||||
int DirectMemoryQuery(PAddr addr, bool find_next, Libraries::Kernel::OrbisQueryInfo* out_info);
|
||||
|
|
Loading…
Reference in New Issue