Merge pull request #2677 from lioncash/assert

kernel/vm_manager: Handle stack/TLS IO region placement a little better
master
Zach Hilman 2019-07-06 21:25:27 +07:00 committed by GitHub
commit fb9124b6cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 43 deletions

@ -98,9 +98,9 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add
return ERR_INVALID_ADDRESS_STATE; return ERR_INVALID_ADDRESS_STATE;
} }
if (!vm_manager.IsWithinNewMapRegion(dst_addr, size)) { if (!vm_manager.IsWithinStackRegion(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 stack region, addr=0x{:016X}, size=0x{:016X}",
dst_addr, size); dst_addr, size);
return ERR_INVALID_MEMORY_RANGE; return ERR_INVALID_MEMORY_RANGE;
} }
@ -726,8 +726,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
// 2.0.0+ // 2.0.0+
ASLRRegionBaseAddr = 12, ASLRRegionBaseAddr = 12,
ASLRRegionSize = 13, ASLRRegionSize = 13,
NewMapRegionBaseAddr = 14, StackRegionBaseAddr = 14,
NewMapRegionSize = 15, StackRegionSize = 15,
// 3.0.0+ // 3.0.0+
IsVirtualAddressMemoryEnabled = 16, IsVirtualAddressMemoryEnabled = 16,
PersonalMmHeapUsage = 17, PersonalMmHeapUsage = 17,
@ -752,8 +752,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
case GetInfoType::HeapRegionSize: case GetInfoType::HeapRegionSize:
case GetInfoType::ASLRRegionBaseAddr: case GetInfoType::ASLRRegionBaseAddr:
case GetInfoType::ASLRRegionSize: case GetInfoType::ASLRRegionSize:
case GetInfoType::NewMapRegionBaseAddr: case GetInfoType::StackRegionBaseAddr:
case GetInfoType::NewMapRegionSize: case GetInfoType::StackRegionSize:
case GetInfoType::TotalPhysicalMemoryAvailable: case GetInfoType::TotalPhysicalMemoryAvailable:
case GetInfoType::TotalPhysicalMemoryUsed: case GetInfoType::TotalPhysicalMemoryUsed:
case GetInfoType::IsVirtualAddressMemoryEnabled: case GetInfoType::IsVirtualAddressMemoryEnabled:
@ -806,12 +806,12 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
*result = process->VMManager().GetASLRRegionSize(); *result = process->VMManager().GetASLRRegionSize();
return RESULT_SUCCESS; return RESULT_SUCCESS;
case GetInfoType::NewMapRegionBaseAddr: case GetInfoType::StackRegionBaseAddr:
*result = process->VMManager().GetNewMapRegionBaseAddress(); *result = process->VMManager().GetStackRegionBaseAddress();
return RESULT_SUCCESS; return RESULT_SUCCESS;
case GetInfoType::NewMapRegionSize: case GetInfoType::StackRegionSize:
*result = process->VMManager().GetNewMapRegionSize(); *result = process->VMManager().GetStackRegionSize();
return RESULT_SUCCESS; return RESULT_SUCCESS;
case GetInfoType::TotalPhysicalMemoryAvailable: case GetInfoType::TotalPhysicalMemoryAvailable:

@ -625,9 +625,11 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType type) { void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType type) {
u64 map_region_size = 0; u64 map_region_size = 0;
u64 heap_region_size = 0; u64 heap_region_size = 0;
u64 new_map_region_size = 0; u64 stack_region_size = 0;
u64 tls_io_region_size = 0; u64 tls_io_region_size = 0;
u64 stack_and_tls_io_end = 0;
switch (type) { switch (type) {
case FileSys::ProgramAddressSpaceType::Is32Bit: case FileSys::ProgramAddressSpaceType::Is32Bit:
case FileSys::ProgramAddressSpaceType::Is32BitNoMap: case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
@ -643,6 +645,7 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
map_region_size = 0; map_region_size = 0;
heap_region_size = 0x80000000; heap_region_size = 0x80000000;
} }
stack_and_tls_io_end = 0x40000000;
break; break;
case FileSys::ProgramAddressSpaceType::Is36Bit: case FileSys::ProgramAddressSpaceType::Is36Bit:
address_space_width = 36; address_space_width = 36;
@ -652,6 +655,7 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
aslr_region_end = aslr_region_base + 0xFF8000000; aslr_region_end = aslr_region_base + 0xFF8000000;
map_region_size = 0x180000000; map_region_size = 0x180000000;
heap_region_size = 0x180000000; heap_region_size = 0x180000000;
stack_and_tls_io_end = 0x80000000;
break; break;
case FileSys::ProgramAddressSpaceType::Is39Bit: case FileSys::ProgramAddressSpaceType::Is39Bit:
address_space_width = 39; address_space_width = 39;
@ -661,7 +665,7 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
aslr_region_end = aslr_region_base + 0x7FF8000000; aslr_region_end = aslr_region_base + 0x7FF8000000;
map_region_size = 0x1000000000; map_region_size = 0x1000000000;
heap_region_size = 0x180000000; heap_region_size = 0x180000000;
new_map_region_size = 0x80000000; stack_region_size = 0x80000000;
tls_io_region_size = 0x1000000000; tls_io_region_size = 0x1000000000;
break; break;
default: default:
@ -669,6 +673,8 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
return; return;
} }
const u64 stack_and_tls_io_begin = aslr_region_base;
address_space_base = 0; address_space_base = 0;
address_space_end = 1ULL << address_space_width; address_space_end = 1ULL << address_space_width;
@ -679,15 +685,20 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
heap_region_end = heap_region_base + heap_region_size; heap_region_end = heap_region_base + heap_region_size;
heap_end = heap_region_base; heap_end = heap_region_base;
new_map_region_base = heap_region_end; stack_region_base = heap_region_end;
new_map_region_end = new_map_region_base + new_map_region_size; stack_region_end = stack_region_base + stack_region_size;
tls_io_region_base = new_map_region_end; tls_io_region_base = stack_region_end;
tls_io_region_end = tls_io_region_base + tls_io_region_size; tls_io_region_end = tls_io_region_base + tls_io_region_size;
if (new_map_region_size == 0) { if (stack_region_size == 0) {
new_map_region_base = address_space_base; stack_region_base = stack_and_tls_io_begin;
new_map_region_end = address_space_end; stack_region_end = stack_and_tls_io_end;
}
if (tls_io_region_size == 0) {
tls_io_region_base = stack_and_tls_io_begin;
tls_io_region_end = stack_and_tls_io_end;
} }
} }
@ -879,21 +890,21 @@ bool VMManager::IsWithinMapRegion(VAddr address, u64 size) const {
return IsInsideAddressRange(address, size, GetMapRegionBaseAddress(), GetMapRegionEndAddress()); return IsInsideAddressRange(address, size, GetMapRegionBaseAddress(), GetMapRegionEndAddress());
} }
VAddr VMManager::GetNewMapRegionBaseAddress() const { VAddr VMManager::GetStackRegionBaseAddress() const {
return new_map_region_base; return stack_region_base;
} }
VAddr VMManager::GetNewMapRegionEndAddress() const { VAddr VMManager::GetStackRegionEndAddress() const {
return new_map_region_end; return stack_region_end;
} }
u64 VMManager::GetNewMapRegionSize() const { u64 VMManager::GetStackRegionSize() const {
return new_map_region_end - new_map_region_base; return stack_region_end - stack_region_base;
} }
bool VMManager::IsWithinNewMapRegion(VAddr address, u64 size) const { bool VMManager::IsWithinStackRegion(VAddr address, u64 size) const {
return IsInsideAddressRange(address, size, GetNewMapRegionBaseAddress(), return IsInsideAddressRange(address, size, GetStackRegionBaseAddress(),
GetNewMapRegionEndAddress()); GetStackRegionEndAddress());
} }
VAddr VMManager::GetTLSIORegionBaseAddress() const { VAddr VMManager::GetTLSIORegionBaseAddress() const {

@ -596,17 +596,17 @@ public:
/// Determines whether or not the specified range is within the map region. /// Determines whether or not the specified range is within the map region.
bool IsWithinMapRegion(VAddr address, u64 size) const; bool IsWithinMapRegion(VAddr address, u64 size) const;
/// Gets the base address of the new map region. /// Gets the base address of the stack region.
VAddr GetNewMapRegionBaseAddress() const; VAddr GetStackRegionBaseAddress() const;
/// Gets the end address of the new map region. /// Gets the end address of the stack region.
VAddr GetNewMapRegionEndAddress() const; VAddr GetStackRegionEndAddress() const;
/// Gets the total size of the new map region in bytes. /// Gets the total size of the stack region in bytes.
u64 GetNewMapRegionSize() const; u64 GetStackRegionSize() const;
/// Determines whether or not the given address range is within the new map region /// Determines whether or not the given address range is within the stack region
bool IsWithinNewMapRegion(VAddr address, u64 size) const; bool IsWithinStackRegion(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;
@ -726,8 +726,8 @@ private:
VAddr map_region_base = 0; VAddr map_region_base = 0;
VAddr map_region_end = 0; VAddr map_region_end = 0;
VAddr new_map_region_base = 0; VAddr stack_region_base = 0;
VAddr new_map_region_end = 0; VAddr stack_region_end = 0;
VAddr tls_io_region_base = 0; VAddr tls_io_region_base = 0;
VAddr tls_io_region_end = 0; VAddr tls_io_region_end = 0;

@ -16,11 +16,9 @@
#include "core/core.h" #include "core/core.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/vm_manager.h" #include "core/hle/kernel/vm_manager.h"
#include "core/hle/lock.h"
#include "core/memory.h" #include "core/memory.h"
#include "core/memory_setup.h" #include "core/memory_setup.h"
#include "video_core/gpu.h" #include "video_core/gpu.h"
#include "video_core/renderer_base.h"
namespace Memory { namespace Memory {

@ -8,10 +8,6 @@
#include <string> #include <string>
#include "common/common_types.h" #include "common/common_types.h"
namespace Common {
struct PageTable;
}
namespace Kernel { namespace Kernel {
class Process; class Process;
} }