mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 08:22:04 +00:00
kern: SvcSetMemoryPermission
This commit is contained in:
parent
d87a9f011c
commit
c622539b95
2 changed files with 60 additions and 3 deletions
|
@ -1021,7 +1021,35 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTableBase::SetMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission svc_perm) {
|
Result KPageTableBase::SetMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission svc_perm) {
|
||||||
MESOSPHERE_UNIMPLEMENTED();
|
const size_t num_pages = size / PageSize;
|
||||||
|
|
||||||
|
/* Lock the table. */
|
||||||
|
KScopedLightLock lk(this->general_lock);
|
||||||
|
|
||||||
|
/* Verify we can change the memory permission. */
|
||||||
|
KMemoryState old_state;
|
||||||
|
KMemoryPermission old_perm;
|
||||||
|
R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), nullptr, addr, size, KMemoryState_FlagCanReprotect, KMemoryState_FlagCanReprotect, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None));
|
||||||
|
|
||||||
|
/* Determine new perm. */
|
||||||
|
const KMemoryPermission new_perm = ConvertToKMemoryPermission(svc_perm);
|
||||||
|
R_SUCCEED_IF(old_perm == new_perm);
|
||||||
|
|
||||||
|
/* Create an update allocator. */
|
||||||
|
KMemoryBlockManagerUpdateAllocator allocator(this->memory_block_slab_manager);
|
||||||
|
R_TRY(allocator.GetResult());
|
||||||
|
|
||||||
|
/* We're going to perform an update, so create a helper. */
|
||||||
|
KScopedPageTableUpdater updater(this);
|
||||||
|
|
||||||
|
/* Perform mapping operation. */
|
||||||
|
const KPageProperties properties = { new_perm, false, false, false };
|
||||||
|
R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null<KPhysicalAddress>, false, properties, OperationType_ChangePermissions, false));
|
||||||
|
|
||||||
|
/* Update the blocks. */
|
||||||
|
this->memory_block_manager.Update(&allocator, addr, num_pages, old_state, new_perm, KMemoryAttribute_None);
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KPageTableBase::SetProcessMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission svc_perm) {
|
Result KPageTableBase::SetProcessMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission svc_perm) {
|
||||||
|
|
|
@ -21,6 +21,35 @@ namespace ams::kern::svc {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr bool IsValidSetMemoryPermission(ams::svc::MemoryPermission perm) {
|
||||||
|
switch (perm) {
|
||||||
|
case ams::svc::MemoryPermission_None:
|
||||||
|
case ams::svc::MemoryPermission_Read:
|
||||||
|
case ams::svc::MemoryPermission_ReadWrite:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result SetMemoryPermission(uintptr_t address, size_t size, ams::svc::MemoryPermission perm) {
|
||||||
|
/* Validate address / size. */
|
||||||
|
R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress());
|
||||||
|
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||||
|
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||||
|
R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory());
|
||||||
|
|
||||||
|
/* Validate the permission. */
|
||||||
|
R_UNLESS(IsValidSetMemoryPermission(perm), svc::ResultInvalidNewMemoryPermission());
|
||||||
|
|
||||||
|
/* Validate that the region is in range for the current process. */
|
||||||
|
auto &page_table = GetCurrentProcess().GetPageTable();
|
||||||
|
R_UNLESS(page_table.Contains(address, size), svc::ResultInvalidCurrentMemory());
|
||||||
|
|
||||||
|
/* Set the memory attribute. */
|
||||||
|
return page_table.SetMemoryPermission(address, size, perm);
|
||||||
|
}
|
||||||
|
|
||||||
Result SetMemoryAttribute(uintptr_t address, size_t size, uint32_t mask, uint32_t attr) {
|
Result SetMemoryAttribute(uintptr_t address, size_t size, uint32_t mask, uint32_t attr) {
|
||||||
/* Validate address / size. */
|
/* Validate address / size. */
|
||||||
R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress());
|
R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress());
|
||||||
|
@ -97,7 +126,7 @@ namespace ams::kern::svc {
|
||||||
/* ============================= 64 ABI ============================= */
|
/* ============================= 64 ABI ============================= */
|
||||||
|
|
||||||
Result SetMemoryPermission64(ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission perm) {
|
Result SetMemoryPermission64(ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission perm) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcSetMemoryPermission64 was called.");
|
return SetMemoryPermission(address, size, perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetMemoryAttribute64(ams::svc::Address address, ams::svc::Size size, uint32_t mask, uint32_t attr) {
|
Result SetMemoryAttribute64(ams::svc::Address address, ams::svc::Size size, uint32_t mask, uint32_t attr) {
|
||||||
|
@ -115,7 +144,7 @@ namespace ams::kern::svc {
|
||||||
/* ============================= 64From32 ABI ============================= */
|
/* ============================= 64From32 ABI ============================= */
|
||||||
|
|
||||||
Result SetMemoryPermission64From32(ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission perm) {
|
Result SetMemoryPermission64From32(ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission perm) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcSetMemoryPermission64From32 was called.");
|
return SetMemoryPermission(address, size, perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetMemoryAttribute64From32(ams::svc::Address address, ams::svc::Size size, uint32_t mask, uint32_t attr) {
|
Result SetMemoryAttribute64From32(ams::svc::Address address, ams::svc::Size size, uint32_t mask, uint32_t attr) {
|
||||||
|
|
Loading…
Reference in a new issue