mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-25 12:55:00 +00:00
Implemented sceKernelMTypeProtect and sceKernelMProtect (#387)
* Fixed ORBIS_KERNEL_MAP_OP_TYPE_PROTECT for batchmap2
* Fix merge
* Changed 4 to ORBIS_KERNEL_MAP_OP_TYPE_PROTECT
* Removed MProtect from AddressSpace
* Added Mtyprotect and moved Mprotect to ORBIS_KERNEL_MAP_OP_PROTECT
* Changed Protect for Windows
* reverted the previous function
* Fixed Mtypeprotect and MProtect
* ''
* ''
* Took out logs stopping build
* clang-format issues
* Fixed the order of mtypeprotect and mprotect in batchmap2
* ''
* update branch
* ''
* Fixed nits
* ''
* Update submodules to latest commits
* ''
* reverted ffmpeg
* ''
* Fixed the nits
* ''
* ''
* ''
* ''
* ''
* Fix clang formatting, DEBUG_ASSERT, and extra spacing
* Fix build issues
* Revert "Fix build issues"
This reverts commit 9185f96ec9
.
* ''
* ''
* ''
* Changes for MemoryProt Format
* ''
* ''
* ''
This commit is contained in:
parent
0dd6e257c5
commit
b9c6093717
6 changed files with 202 additions and 25 deletions
|
@ -7,6 +7,7 @@
|
|||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/memory_management.h"
|
||||
#include "core/memory.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
||||
|
||||
namespace Core {
|
||||
|
@ -292,6 +293,118 @@ int MemoryManager::QueryProtection(VAddr addr, void** start, void** end, u32* pr
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int MemoryManager::Protect(VAddr addr, size_t size, MemoryProt 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;
|
||||
}
|
||||
|
||||
// Validate protection flags
|
||||
constexpr static MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead |
|
||||
MemoryProt::CpuReadWrite | MemoryProt::GpuRead |
|
||||
MemoryProt::GpuWrite | MemoryProt::GpuReadWrite;
|
||||
|
||||
MemoryProt invalid_flags = prot & ~valid_flags;
|
||||
if (u32(invalid_flags) != 0 && u32(invalid_flags) != u32(MemoryProt::NoAccess)) {
|
||||
LOG_ERROR(Core, "Invalid protection flags: prot = {:#x}, invalid flags = {:#x}", u32(prot),
|
||||
u32(invalid_flags));
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
// Change protection
|
||||
vma.prot = prot;
|
||||
|
||||
// Set permissions
|
||||
Core::MemoryPermission perms{};
|
||||
|
||||
if (True(prot & MemoryProt::CpuRead)) {
|
||||
perms |= Core::MemoryPermission::Read;
|
||||
}
|
||||
if (True(prot & MemoryProt::CpuReadWrite)) {
|
||||
perms |= Core::MemoryPermission::ReadWrite;
|
||||
}
|
||||
if (True(prot & MemoryProt::GpuRead)) {
|
||||
perms |= Core::MemoryPermission::Read;
|
||||
}
|
||||
if (True(prot & MemoryProt::GpuWrite)) {
|
||||
perms |= Core::MemoryPermission::Write;
|
||||
}
|
||||
if (True(prot & MemoryProt::GpuReadWrite)) {
|
||||
perms |= Core::MemoryPermission::ReadWrite;
|
||||
}
|
||||
|
||||
impl.Protect(addr, size, perms);
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int MemoryManager::MTypeProtect(VAddr addr, size_t size, VMAType mtype, MemoryProt 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;
|
||||
}
|
||||
|
||||
// Validate protection flags
|
||||
constexpr static MemoryProt valid_flags = MemoryProt::NoAccess | MemoryProt::CpuRead |
|
||||
MemoryProt::CpuReadWrite | MemoryProt::GpuRead |
|
||||
MemoryProt::GpuWrite | MemoryProt::GpuReadWrite;
|
||||
|
||||
MemoryProt invalid_flags = prot & ~valid_flags;
|
||||
if (u32(invalid_flags) != 0 && u32(invalid_flags) != u32(MemoryProt::NoAccess)) {
|
||||
LOG_ERROR(Core, "Invalid protection flags: prot = {:#x}, invalid flags = {:#x}", u32(prot),
|
||||
u32(invalid_flags));
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
// Change type and protection
|
||||
vma.type = mtype;
|
||||
vma.prot = prot;
|
||||
|
||||
// Set permissions
|
||||
Core::MemoryPermission perms{};
|
||||
|
||||
if (True(prot & MemoryProt::CpuRead)) {
|
||||
perms |= Core::MemoryPermission::Read;
|
||||
}
|
||||
if (True(prot & MemoryProt::CpuReadWrite)) {
|
||||
perms |= Core::MemoryPermission::ReadWrite;
|
||||
}
|
||||
if (True(prot & MemoryProt::GpuRead)) {
|
||||
perms |= Core::MemoryPermission::Read;
|
||||
}
|
||||
if (True(prot & MemoryProt::GpuWrite)) {
|
||||
perms |= Core::MemoryPermission::Write;
|
||||
}
|
||||
if (True(prot & MemoryProt::GpuReadWrite)) {
|
||||
perms |= Core::MemoryPermission::ReadWrite;
|
||||
}
|
||||
|
||||
impl.Protect(addr, size, perms);
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int MemoryManager::VirtualQuery(VAddr addr, int flags,
|
||||
::Libraries::Kernel::OrbisVirtualQueryInfo* info) {
|
||||
std::scoped_lock lk{mutex};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue