Merge pull request #2194 from lioncash/mem
svc: Move memory range checking functions to the VMManager class
This commit is contained in:
commit
234f00bdd4
3 changed files with 66 additions and 30 deletions
|
@ -47,23 +47,6 @@ constexpr bool IsValidAddressRange(VAddr address, u64 size) {
|
||||||
return address + size > address;
|
return address + size > address;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if a given address range lies within a larger address range.
|
|
||||||
constexpr bool IsInsideAddressRange(VAddr address, u64 size, VAddr address_range_begin,
|
|
||||||
VAddr address_range_end) {
|
|
||||||
const VAddr end_address = address + size - 1;
|
|
||||||
return address_range_begin <= address && end_address <= address_range_end - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsInsideAddressSpace(const VMManager& vm, VAddr address, u64 size) {
|
|
||||||
return IsInsideAddressRange(address, size, vm.GetAddressSpaceBaseAddress(),
|
|
||||||
vm.GetAddressSpaceEndAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsInsideNewMapRegion(const VMManager& vm, VAddr address, u64 size) {
|
|
||||||
return IsInsideAddressRange(address, size, vm.GetNewMapRegionBaseAddress(),
|
|
||||||
vm.GetNewMapRegionEndAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8 GiB
|
// 8 GiB
|
||||||
constexpr u64 MAIN_MEMORY_SIZE = 0x200000000;
|
constexpr u64 MAIN_MEMORY_SIZE = 0x200000000;
|
||||||
|
|
||||||
|
@ -105,14 +88,14 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add
|
||||||
return ERR_INVALID_ADDRESS_STATE;
|
return ERR_INVALID_ADDRESS_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsInsideAddressSpace(vm_manager, src_addr, size)) {
|
if (!vm_manager.IsWithinAddressSpace(src_addr, size)) {
|
||||||
LOG_ERROR(Kernel_SVC,
|
LOG_ERROR(Kernel_SVC,
|
||||||
"Source is not within the address space, addr=0x{:016X}, size=0x{:016X}",
|
"Source is not within the address space, addr=0x{:016X}, size=0x{:016X}",
|
||||||
src_addr, size);
|
src_addr, size);
|
||||||
return ERR_INVALID_ADDRESS_STATE;
|
return ERR_INVALID_ADDRESS_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsInsideNewMapRegion(vm_manager, dst_addr, size)) {
|
if (!vm_manager.IsWithinNewMapRegion(dst_addr, size)) {
|
||||||
LOG_ERROR(Kernel_SVC,
|
LOG_ERROR(Kernel_SVC,
|
||||||
"Destination is not within the new map region, addr=0x{:016X}, size=0x{:016X}",
|
"Destination is not within the new map region, addr=0x{:016X}, size=0x{:016X}",
|
||||||
dst_addr, size);
|
dst_addr, size);
|
||||||
|
@ -238,7 +221,7 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {
|
||||||
auto* const current_process = Core::CurrentProcess();
|
auto* const current_process = Core::CurrentProcess();
|
||||||
auto& vm_manager = current_process->VMManager();
|
auto& vm_manager = current_process->VMManager();
|
||||||
|
|
||||||
if (!IsInsideAddressSpace(vm_manager, addr, size)) {
|
if (!vm_manager.IsWithinAddressSpace(addr, size)) {
|
||||||
LOG_ERROR(Kernel_SVC,
|
LOG_ERROR(Kernel_SVC,
|
||||||
"Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr,
|
"Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr,
|
||||||
size);
|
size);
|
||||||
|
@ -299,7 +282,7 @@ static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attr
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& vm_manager = Core::CurrentProcess()->VMManager();
|
auto& vm_manager = Core::CurrentProcess()->VMManager();
|
||||||
if (!IsInsideAddressSpace(vm_manager, address, size)) {
|
if (!vm_manager.IsWithinAddressSpace(address, size)) {
|
||||||
LOG_ERROR(Kernel_SVC,
|
LOG_ERROR(Kernel_SVC,
|
||||||
"Given address (0x{:016X}) is outside the bounds of the address space.", address);
|
"Given address (0x{:016X}) is outside the bounds of the address space.", address);
|
||||||
return ERR_INVALID_ADDRESS_STATE;
|
return ERR_INVALID_ADDRESS_STATE;
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
#include "core/memory_setup.h"
|
#include "core/memory_setup.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
namespace {
|
||||||
static const char* GetMemoryStateName(MemoryState state) {
|
const char* GetMemoryStateName(MemoryState state) {
|
||||||
static constexpr const char* names[] = {
|
static constexpr const char* names[] = {
|
||||||
"Unmapped", "Io",
|
"Unmapped", "Io",
|
||||||
"Normal", "CodeStatic",
|
"Normal", "CodeStatic",
|
||||||
|
@ -35,6 +35,14 @@ static const char* GetMemoryStateName(MemoryState state) {
|
||||||
return names[ToSvcMemoryState(state)];
|
return names[ToSvcMemoryState(state)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if a given address range lies within a larger address range.
|
||||||
|
constexpr bool IsInsideAddressRange(VAddr address, u64 size, VAddr address_range_begin,
|
||||||
|
VAddr address_range_end) {
|
||||||
|
const VAddr end_address = address + size - 1;
|
||||||
|
return address_range_begin <= address && end_address <= address_range_end - 1;
|
||||||
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
|
bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
|
||||||
ASSERT(base + size == next.base);
|
ASSERT(base + size == next.base);
|
||||||
if (permissions != next.permissions || state != next.state || attribute != next.attribute ||
|
if (permissions != next.permissions || state != next.state || attribute != next.attribute ||
|
||||||
|
@ -249,8 +257,7 @@ ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_p
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<VAddr> VMManager::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
|
ResultVal<VAddr> VMManager::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
|
||||||
if (target < GetHeapRegionBaseAddress() || target + size > GetHeapRegionEndAddress() ||
|
if (!IsWithinHeapRegion(target, size)) {
|
||||||
target + size < target) {
|
|
||||||
return ERR_INVALID_ADDRESS;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,8 +292,7 @@ ResultVal<VAddr> VMManager::HeapAllocate(VAddr target, u64 size, VMAPermission p
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode VMManager::HeapFree(VAddr target, u64 size) {
|
ResultCode VMManager::HeapFree(VAddr target, u64 size) {
|
||||||
if (target < GetHeapRegionBaseAddress() || target + size > GetHeapRegionEndAddress() ||
|
if (!IsWithinHeapRegion(target, size)) {
|
||||||
target + size < target) {
|
|
||||||
return ERR_INVALID_ADDRESS;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,6 +712,11 @@ u64 VMManager::GetAddressSpaceWidth() const {
|
||||||
return address_space_width;
|
return address_space_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMManager::IsWithinAddressSpace(VAddr address, u64 size) const {
|
||||||
|
return IsInsideAddressRange(address, size, GetAddressSpaceBaseAddress(),
|
||||||
|
GetAddressSpaceEndAddress());
|
||||||
|
}
|
||||||
|
|
||||||
VAddr VMManager::GetASLRRegionBaseAddress() const {
|
VAddr VMManager::GetASLRRegionBaseAddress() const {
|
||||||
return aslr_region_base;
|
return aslr_region_base;
|
||||||
}
|
}
|
||||||
|
@ -750,6 +761,11 @@ u64 VMManager::GetCodeRegionSize() const {
|
||||||
return code_region_end - code_region_base;
|
return code_region_end - code_region_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMManager::IsWithinCodeRegion(VAddr address, u64 size) const {
|
||||||
|
return IsInsideAddressRange(address, size, GetCodeRegionBaseAddress(),
|
||||||
|
GetCodeRegionEndAddress());
|
||||||
|
}
|
||||||
|
|
||||||
VAddr VMManager::GetHeapRegionBaseAddress() const {
|
VAddr VMManager::GetHeapRegionBaseAddress() const {
|
||||||
return heap_region_base;
|
return heap_region_base;
|
||||||
}
|
}
|
||||||
|
@ -762,6 +778,11 @@ u64 VMManager::GetHeapRegionSize() const {
|
||||||
return heap_region_end - heap_region_base;
|
return heap_region_end - heap_region_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMManager::IsWithinHeapRegion(VAddr address, u64 size) const {
|
||||||
|
return IsInsideAddressRange(address, size, GetHeapRegionBaseAddress(),
|
||||||
|
GetHeapRegionEndAddress());
|
||||||
|
}
|
||||||
|
|
||||||
VAddr VMManager::GetMapRegionBaseAddress() const {
|
VAddr VMManager::GetMapRegionBaseAddress() const {
|
||||||
return map_region_base;
|
return map_region_base;
|
||||||
}
|
}
|
||||||
|
@ -774,6 +795,10 @@ u64 VMManager::GetMapRegionSize() const {
|
||||||
return map_region_end - map_region_base;
|
return map_region_end - map_region_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMManager::IsWithinMapRegion(VAddr address, u64 size) const {
|
||||||
|
return IsInsideAddressRange(address, size, GetMapRegionBaseAddress(), GetMapRegionEndAddress());
|
||||||
|
}
|
||||||
|
|
||||||
VAddr VMManager::GetNewMapRegionBaseAddress() const {
|
VAddr VMManager::GetNewMapRegionBaseAddress() const {
|
||||||
return new_map_region_base;
|
return new_map_region_base;
|
||||||
}
|
}
|
||||||
|
@ -786,6 +811,11 @@ u64 VMManager::GetNewMapRegionSize() const {
|
||||||
return new_map_region_end - new_map_region_base;
|
return new_map_region_end - new_map_region_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMManager::IsWithinNewMapRegion(VAddr address, u64 size) const {
|
||||||
|
return IsInsideAddressRange(address, size, GetNewMapRegionBaseAddress(),
|
||||||
|
GetNewMapRegionEndAddress());
|
||||||
|
}
|
||||||
|
|
||||||
VAddr VMManager::GetTLSIORegionBaseAddress() const {
|
VAddr VMManager::GetTLSIORegionBaseAddress() const {
|
||||||
return tls_io_region_base;
|
return tls_io_region_base;
|
||||||
}
|
}
|
||||||
|
@ -798,4 +828,9 @@ u64 VMManager::GetTLSIORegionSize() const {
|
||||||
return tls_io_region_end - tls_io_region_base;
|
return tls_io_region_end - tls_io_region_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMManager::IsWithinTLSIORegion(VAddr address, u64 size) const {
|
||||||
|
return IsInsideAddressRange(address, size, GetTLSIORegionBaseAddress(),
|
||||||
|
GetTLSIORegionEndAddress());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -432,18 +432,21 @@ public:
|
||||||
/// Gets the address space width in bits.
|
/// Gets the address space width in bits.
|
||||||
u64 GetAddressSpaceWidth() const;
|
u64 GetAddressSpaceWidth() const;
|
||||||
|
|
||||||
|
/// Determines whether or not the given address range lies within the address space.
|
||||||
|
bool IsWithinAddressSpace(VAddr address, u64 size) const;
|
||||||
|
|
||||||
/// Gets the base address of the ASLR region.
|
/// Gets the base address of the ASLR region.
|
||||||
VAddr GetASLRRegionBaseAddress() const;
|
VAddr GetASLRRegionBaseAddress() const;
|
||||||
|
|
||||||
/// Gets the end address of the ASLR region.
|
/// Gets the end address of the ASLR region.
|
||||||
VAddr GetASLRRegionEndAddress() const;
|
VAddr GetASLRRegionEndAddress() const;
|
||||||
|
|
||||||
/// Determines whether or not the specified address range is within the ASLR region.
|
|
||||||
bool IsWithinASLRRegion(VAddr address, u64 size) const;
|
|
||||||
|
|
||||||
/// Gets the size of the ASLR region
|
/// Gets the size of the ASLR region
|
||||||
u64 GetASLRRegionSize() const;
|
u64 GetASLRRegionSize() const;
|
||||||
|
|
||||||
|
/// Determines whether or not the specified address range is within the ASLR region.
|
||||||
|
bool IsWithinASLRRegion(VAddr address, u64 size) const;
|
||||||
|
|
||||||
/// Gets the base address of the code region.
|
/// Gets the base address of the code region.
|
||||||
VAddr GetCodeRegionBaseAddress() const;
|
VAddr GetCodeRegionBaseAddress() const;
|
||||||
|
|
||||||
|
@ -453,6 +456,9 @@ public:
|
||||||
/// Gets the total size of the code region in bytes.
|
/// Gets the total size of the code region in bytes.
|
||||||
u64 GetCodeRegionSize() const;
|
u64 GetCodeRegionSize() const;
|
||||||
|
|
||||||
|
/// Determines whether or not the specified range is within the code region.
|
||||||
|
bool IsWithinCodeRegion(VAddr address, u64 size) const;
|
||||||
|
|
||||||
/// Gets the base address of the heap region.
|
/// Gets the base address of the heap region.
|
||||||
VAddr GetHeapRegionBaseAddress() const;
|
VAddr GetHeapRegionBaseAddress() const;
|
||||||
|
|
||||||
|
@ -462,6 +468,9 @@ public:
|
||||||
/// Gets the total size of the heap region in bytes.
|
/// Gets the total size of the heap region in bytes.
|
||||||
u64 GetHeapRegionSize() const;
|
u64 GetHeapRegionSize() const;
|
||||||
|
|
||||||
|
/// Determines whether or not the specified range is within the heap region.
|
||||||
|
bool IsWithinHeapRegion(VAddr address, u64 size) const;
|
||||||
|
|
||||||
/// Gets the base address of the map region.
|
/// Gets the base address of the map region.
|
||||||
VAddr GetMapRegionBaseAddress() const;
|
VAddr GetMapRegionBaseAddress() const;
|
||||||
|
|
||||||
|
@ -471,6 +480,9 @@ public:
|
||||||
/// Gets the total size of the map region in bytes.
|
/// Gets the total size of the map region in bytes.
|
||||||
u64 GetMapRegionSize() const;
|
u64 GetMapRegionSize() const;
|
||||||
|
|
||||||
|
/// Determines whether or not the specified range is within the map region.
|
||||||
|
bool IsWithinMapRegion(VAddr address, u64 size) const;
|
||||||
|
|
||||||
/// Gets the base address of the new map region.
|
/// Gets the base address of the new map region.
|
||||||
VAddr GetNewMapRegionBaseAddress() const;
|
VAddr GetNewMapRegionBaseAddress() const;
|
||||||
|
|
||||||
|
@ -480,6 +492,9 @@ public:
|
||||||
/// Gets the total size of the new map region in bytes.
|
/// Gets the total size of the new map region in bytes.
|
||||||
u64 GetNewMapRegionSize() const;
|
u64 GetNewMapRegionSize() const;
|
||||||
|
|
||||||
|
/// Determines whether or not the given address range is within the new map region
|
||||||
|
bool IsWithinNewMapRegion(VAddr address, u64 size) const;
|
||||||
|
|
||||||
/// Gets the base address of the TLS IO region.
|
/// Gets the base address of the TLS IO region.
|
||||||
VAddr GetTLSIORegionBaseAddress() const;
|
VAddr GetTLSIORegionBaseAddress() const;
|
||||||
|
|
||||||
|
@ -489,6 +504,9 @@ public:
|
||||||
/// Gets the total size of the TLS IO region in bytes.
|
/// Gets the total size of the TLS IO region in bytes.
|
||||||
u64 GetTLSIORegionSize() const;
|
u64 GetTLSIORegionSize() const;
|
||||||
|
|
||||||
|
/// Determines if the given address range is within the TLS IO region.
|
||||||
|
bool IsWithinTLSIORegion(VAddr address, u64 size) const;
|
||||||
|
|
||||||
/// Each VMManager has its own page table, which is set as the main one when the owning process
|
/// Each VMManager has its own page table, which is set as the main one when the owning process
|
||||||
/// is scheduled.
|
/// is scheduled.
|
||||||
Memory::PageTable page_table;
|
Memory::PageTable page_table;
|
||||||
|
|
Loading…
Reference in a new issue