2019-09-24 22:54:27 +02:00
|
|
|
#include "KPrivateMemory.h"
|
2020-01-01 14:11:25 +01:00
|
|
|
#include "KProcess.h"
|
2019-10-13 10:04:47 +02:00
|
|
|
#include <nce.h>
|
2020-01-07 03:36:08 +01:00
|
|
|
#include <asm/unistd.h>
|
2019-09-24 22:54:27 +02:00
|
|
|
|
|
|
|
namespace skyline::kernel::type {
|
2020-01-07 03:36:08 +01:00
|
|
|
KPrivateMemory::KPrivateMemory(const DeviceState &state, u64 dstAddress, size_t size, memory::Permission permission, const memory::Type type, std::shared_ptr<KThread> thread) : state(state), address(dstAddress), size(size), permission(permission), type(type), KObject(state, KType::KPrivateMemory) {
|
|
|
|
Registers fregs{};
|
|
|
|
fregs.x0 = dstAddress;
|
|
|
|
fregs.x1 = size;
|
|
|
|
fregs.x2 = static_cast<u64>(permission.Get());
|
|
|
|
fregs.x3 = static_cast<u64>(MAP_PRIVATE | MAP_ANONYMOUS | ((dstAddress) ? MAP_FIXED : 0)); // NOLINT(hicpp-signed-bitwise)
|
|
|
|
fregs.x4 = static_cast<u64>(-1);
|
|
|
|
fregs.x8 = __NR_mmap;
|
|
|
|
state.nce->ExecuteFunction(ThreadCall::Syscall, fregs, thread);
|
|
|
|
if (fregs.x0 < 0)
|
2019-09-24 22:54:27 +02:00
|
|
|
throw exception("An error occurred while mapping private region in child process");
|
|
|
|
if (!this->address)
|
2020-01-07 03:36:08 +01:00
|
|
|
this->address = fregs.x0;
|
2019-09-24 22:54:27 +02:00
|
|
|
}
|
|
|
|
|
2019-11-17 21:19:01 +01:00
|
|
|
u64 RemapPrivateFunc(u64 address, size_t oldSize, size_t size, u64 flags) {
|
|
|
|
return reinterpret_cast<u64>(mremap(reinterpret_cast<void *>(address), oldSize, size, static_cast<int>(flags)));
|
2019-09-24 22:54:27 +02:00
|
|
|
}
|
|
|
|
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
u64 KPrivateMemory::Resize(size_t newSize, bool canMove) {
|
2020-01-07 03:36:08 +01:00
|
|
|
Registers fregs{};
|
|
|
|
fregs.x0 = address;
|
|
|
|
fregs.x1 = size;
|
|
|
|
fregs.x2 = newSize;
|
|
|
|
fregs.x3 = canMove ? MREMAP_MAYMOVE : 0;
|
|
|
|
fregs.x8 = __NR_mremap;
|
|
|
|
state.nce->ExecuteFunction(ThreadCall::Syscall, fregs, state.thread);
|
|
|
|
if (fregs.x0 < 0)
|
2019-09-24 22:54:27 +02:00
|
|
|
throw exception("An error occurred while remapping private region in child process");
|
2020-01-07 03:36:08 +01:00
|
|
|
address = fregs.x0;
|
2019-09-24 22:54:27 +02:00
|
|
|
size = newSize;
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
return address;
|
2019-09-24 22:54:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u64 UpdatePermissionPrivateFunc(u64 address, size_t size, u64 perms) {
|
|
|
|
return static_cast<u64>(mprotect(reinterpret_cast<void *>(address), size, static_cast<int>(perms)));
|
|
|
|
}
|
|
|
|
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
void KPrivateMemory::UpdatePermission(memory::Permission permission) {
|
2020-01-07 03:36:08 +01:00
|
|
|
Registers fregs{};
|
|
|
|
fregs.x0 = address;
|
|
|
|
fregs.x1 = size;
|
|
|
|
fregs.x2 = static_cast<u64>(permission.Get());
|
|
|
|
fregs.x8 = __NR_mprotect;
|
|
|
|
state.nce->ExecuteFunction(ThreadCall::Syscall, fregs, state.thread);
|
|
|
|
if (fregs.x0 < 0)
|
2019-09-24 22:54:27 +02:00
|
|
|
throw exception("An error occurred while updating private region's permissions in child process");
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
this->permission = permission;
|
2019-09-24 22:54:27 +02:00
|
|
|
}
|
|
|
|
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
memory::MemoryInfo KPrivateMemory::GetInfo(u64 address) {
|
2019-09-24 22:54:27 +02:00
|
|
|
memory::MemoryInfo info{};
|
|
|
|
info.baseAddress = address;
|
|
|
|
info.size = size;
|
2020-01-01 14:11:25 +01:00
|
|
|
info.type = static_cast<u32>(type);
|
|
|
|
for (const auto ®ion : regionInfoVec)
|
Framebuffer and NativeActivity
What was added:
* Framebuffer
* NativeActivity
* NV Services
* IOCTL Handler
* NV Devices:
* * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E
* * /dev/nvhost-as-gpu
* * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714
* * /dev/nvhost-ctrl
* * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714
* SVCs:
* * SetMemoryAttribute
* * CreateTransferMemory
* * ResetSignal
* * GetSystemTick
* Addition of Compact Logger
What was fixed:
* SVCs:
* * SetHeapSize
* * SetMemoryAttribute
* * QueryMemory
* A release build would not set CMAKE_BUILD_TYPE to "RELEASE"
* The logger code was simplified
2019-11-13 21:09:31 +01:00
|
|
|
if ((address >= region.address) && (address < (region.address + region.size)))
|
|
|
|
info.memoryAttribute.isUncached = region.isUncached;
|
2019-09-24 22:54:27 +02:00
|
|
|
info.memoryAttribute.isIpcLocked = (info.ipcRefCount > 0);
|
|
|
|
info.memoryAttribute.isDeviceShared = (info.deviceRefCount > 0);
|
2020-01-01 14:11:25 +01:00
|
|
|
info.r = permission.r;
|
|
|
|
info.w = permission.w;
|
|
|
|
info.x = permission.x;
|
2019-09-24 22:54:27 +02:00
|
|
|
info.ipcRefCount = ipcRefCount;
|
|
|
|
info.deviceRefCount = deviceRefCount;
|
|
|
|
return info;
|
|
|
|
}
|
2019-10-13 10:04:47 +02:00
|
|
|
|
|
|
|
u64 UnmapPrivateFunc(u64 address, size_t size) {
|
|
|
|
return static_cast<u64>(munmap(reinterpret_cast<void *>(address), size));
|
|
|
|
}
|
|
|
|
|
|
|
|
KPrivateMemory::~KPrivateMemory() {
|
|
|
|
try {
|
2020-01-07 03:36:08 +01:00
|
|
|
Registers fregs{};
|
|
|
|
fregs.x0 = address;
|
|
|
|
fregs.x1 = size;
|
|
|
|
fregs.x8 = __NR_munmap;
|
|
|
|
state.nce->ExecuteFunction(ThreadCall::Syscall, fregs, state.thread);
|
|
|
|
} catch (const std::exception &) {}
|
2019-10-13 10:04:47 +02:00
|
|
|
}
|
2019-09-24 22:54:27 +02:00
|
|
|
};
|