kernel/process: Make data member variables private

Makes the public interface consistent in terms of how accesses are done
on a process object. It also makes it slightly nicer to reason about the
logic of the process class, as we don't want to expose everything to
external code.
This commit is contained in:
Lioncash 2018-09-29 18:47:00 -04:00
parent 16145e2f21
commit cf9d6c6f52
18 changed files with 120 additions and 75 deletions

View File

@ -130,7 +130,7 @@ public:
std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
auto& current_process = Core::CurrentProcess();
auto** const page_table = current_process->vm_manager.page_table.pointers.data();
auto** const page_table = current_process->VMManager().page_table.pointers.data();
Dynarmic::A64::UserConfig config;
@ -139,7 +139,7 @@ std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
// Memory
config.page_table = reinterpret_cast<void**>(page_table);
config.page_table_address_space_bits = current_process->vm_manager.GetAddressSpaceWidth();
config.page_table_address_space_bits = current_process->VMManager().GetAddressSpaceWidth();
config.silently_mirror_page_table = false;
// Multi-process state

View File

@ -34,7 +34,7 @@ ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() {
if (!updatable)
return MakeResult<VirtualFile>(file);
const PatchManager patch_manager(Core::CurrentProcess()->program_id);
const PatchManager patch_manager(Core::CurrentProcess()->GetTitleID());
return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file, ivfc_offset));
}

View File

@ -81,7 +81,7 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
// be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData && title_id == 0)
title_id = Core::CurrentProcess()->program_id;
title_id = Core::CurrentProcess()->GetTitleID();
std::string out;

View File

@ -587,7 +587,7 @@ static void HandleQuery() {
strlen("Xfer:features:read:target.xml:")) == 0) {
SendReply(target_xml);
} else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
const VAddr base_address = Core::CurrentProcess()->vm_manager.GetCodeRegionBaseAddress();
const VAddr base_address = Core::CurrentProcess()->VMManager().GetCodeRegionBaseAddress();
std::string buffer = fmt::format("TextSeg={:0x}", base_address);
SendReply(buffer.c_str());
} else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
@ -909,7 +909,7 @@ static void ReadMemory() {
SendReply("E01");
}
const auto& vm_manager = Core::CurrentProcess()->vm_manager;
const auto& vm_manager = Core::CurrentProcess()->VMManager();
if (addr < vm_manager.GetCodeRegionBaseAddress() ||
addr >= vm_manager.GetMapRegionEndAddress()) {
return SendReply("E00");

View File

@ -135,6 +135,16 @@ public:
return HANDLE_TYPE;
}
/// Gets a reference to the process' memory manager.
Kernel::VMManager& VMManager() {
return vm_manager;
}
/// Gets a const reference to the process' memory manager.
const Kernel::VMManager& VMManager() const {
return vm_manager;
}
/// Gets the current status of the process
ProcessStatus GetStatus() const {
return status;
@ -145,6 +155,40 @@ public:
return process_id;
}
/// Gets the title ID corresponding to this process.
u64 GetTitleID() const {
return program_id;
}
/// Gets the resource limit descriptor for this process
ResourceLimit& GetResourceLimit() {
return *resource_limit;
}
/// Gets the resource limit descriptor for this process
const ResourceLimit& GetResourceLimit() const {
return *resource_limit;
}
/// Gets the default CPU ID for this process
u8 GetDefaultProcessorID() const {
return ideal_processor;
}
/// Gets the bitmask of allowed CPUs that this process' threads can run on.
u32 GetAllowedProcessorMask() const {
return allowed_processor_mask;
}
/// Gets the bitmask of allowed thread priorities.
u32 GetAllowedThreadPriorityMask() const {
return allowed_thread_priority_mask;
}
u32 IsVirtualMemoryEnabled() const {
return is_virtual_address_memory_enabled;
}
/**
* Loads process-specifics configuration info with metadata provided
* by an executable.
@ -153,30 +197,6 @@ public:
*/
void LoadFromMetadata(const FileSys::ProgramMetadata& metadata);
/// Title ID corresponding to the process
u64 program_id;
/// Resource limit descriptor for this process
SharedPtr<ResourceLimit> resource_limit;
/// The process may only call SVCs which have the corresponding bit set.
std::bitset<0x80> svc_access_mask;
/// Maximum size of the handle table for the process.
unsigned int handle_table_size = 0x200;
/// Special memory ranges mapped into this processes address space. This is used to give
/// processes access to specific I/O regions and device memory.
boost::container::static_vector<AddressMapping, 8> address_mappings;
ProcessFlags flags;
/// Kernel compatibility version for this process
u16 kernel_version = 0;
/// The default CPU for this process, threads are scheduled on this cpu by default.
u8 ideal_processor = 0;
/// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
/// this value from the process header.
u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
u32 allowed_thread_priority_mask = 0xFFFFFFFF;
u32 is_virtual_address_memory_enabled = 0;
/**
* Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
* to this process.
@ -212,18 +232,43 @@ public:
ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
VMManager vm_manager;
private:
explicit Process(KernelCore& kernel);
~Process() override;
/// Memory manager for this process.
Kernel::VMManager vm_manager;
/// Current status of the process
ProcessStatus status;
/// The ID of this process
u32 process_id = 0;
/// Title ID corresponding to the process
u64 program_id;
/// Resource limit descriptor for this process
SharedPtr<ResourceLimit> resource_limit;
/// The process may only call SVCs which have the corresponding bit set.
std::bitset<0x80> svc_access_mask;
/// Maximum size of the handle table for the process.
u32 handle_table_size = 0x200;
/// Special memory ranges mapped into this processes address space. This is used to give
/// processes access to specific I/O regions and device memory.
boost::container::static_vector<AddressMapping, 8> address_mappings;
ProcessFlags flags;
/// Kernel compatibility version for this process
u16 kernel_version = 0;
/// The default CPU for this process, threads are scheduled on this cpu by default.
u8 ideal_processor = 0;
/// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
/// this value from the process header.
u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
u32 allowed_thread_priority_mask = 0xFFFFFFFF;
u32 is_virtual_address_memory_enabled = 0;
// Memory used to back the allocations in the regular heap. A single vector is used to cover
// the entire virtual address space extents that bound the allocations, including any holes.
// This makes deallocation and reallocation of holes fast and keeps process memory contiguous

View File

@ -88,7 +88,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
if (previous_process != current_thread->owner_process) {
Core::CurrentProcess() = current_thread->owner_process;
SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
SetCurrentPageTable(&Core::CurrentProcess()->VMManager().page_table);
}
cpu_core.LoadContext(new_thread->context);

View File

@ -35,11 +35,11 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, SharedPtr<Proce
// Refresh the address mappings for the current process.
if (Core::CurrentProcess() != nullptr) {
Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(
Core::CurrentProcess()->VMManager().RefreshMemoryBlockMappings(
shared_memory->backing_block.get());
}
} else {
auto& vm_manager = shared_memory->owner_process->vm_manager;
auto& vm_manager = shared_memory->owner_process->VMManager();
// The memory is already available and mapped in the owner process.
auto vma = vm_manager.FindVMA(address);
@ -73,7 +73,7 @@ SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
shared_memory->backing_block = std::move(heap_block);
shared_memory->backing_block_offset = offset;
shared_memory->base_address =
kernel.CurrentProcess()->vm_manager.GetHeapRegionBaseAddress() + offset;
kernel.CurrentProcess()->VMManager().GetHeapRegionBaseAddress() + offset;
return shared_memory;
}
@ -107,7 +107,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
VAddr target_address = address;
// Map the memory block into the target process
auto result = target_process->vm_manager.MapMemoryBlock(
auto result = target_process->VMManager().MapMemoryBlock(
target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
if (result.Failed()) {
LOG_ERROR(
@ -117,14 +117,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
return result.Code();
}
return target_process->vm_manager.ReprotectRange(target_address, size,
ConvertPermissions(permissions));
return target_process->VMManager().ReprotectRange(target_address, size,
ConvertPermissions(permissions));
}
ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) {
// TODO(Subv): Verify what happens if the application tries to unmap an address that is not
// mapped to a SharedMemory.
return target_process->vm_manager.UnmapRange(address, size);
return target_process->VMManager().UnmapRange(address, size);
}
VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) {

View File

@ -51,7 +51,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
}
auto& process = *Core::CurrentProcess();
const VAddr heap_base = process.vm_manager.GetHeapRegionBaseAddress();
const VAddr heap_base = process.VMManager().GetHeapRegionBaseAddress();
CASCADE_RESULT(*heap_addr,
process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite));
return RESULT_SUCCESS;
@ -327,14 +327,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
info_sub_id, handle);
const auto& current_process = Core::CurrentProcess();
const auto& vm_manager = current_process->vm_manager;
const auto& vm_manager = current_process->VMManager();
switch (static_cast<GetInfoType>(info_id)) {
case GetInfoType::AllowedCpuIdBitmask:
*result = current_process->allowed_processor_mask;
*result = current_process->GetAllowedProcessorMask();
break;
case GetInfoType::AllowedThreadPrioBitmask:
*result = current_process->allowed_thread_priority_mask;
*result = current_process->GetAllowedThreadPriorityMask();
break;
case GetInfoType::MapRegionBaseAddr:
*result = vm_manager.GetMapRegionBaseAddress();
@ -386,10 +386,10 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = vm_manager.GetNewMapRegionSize();
break;
case GetInfoType::IsVirtualAddressMemoryEnabled:
*result = current_process->is_virtual_address_memory_enabled;
*result = current_process->IsVirtualMemoryEnabled();
break;
case GetInfoType::TitleId:
*result = current_process->program_id;
*result = current_process->GetTitleID();
break;
case GetInfoType::PrivilegedProcessId:
LOG_WARNING(Kernel_SVC,
@ -444,8 +444,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
// Note: The kernel uses the current process's resource limit instead of
// the one from the thread owner's resource limit.
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) {
const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
return ERR_NOT_AUTHORIZED;
}
@ -519,9 +519,9 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
if (!process) {
return ERR_INVALID_HANDLE;
}
auto vma = process->vm_manager.FindVMA(addr);
auto vma = process->VMManager().FindVMA(addr);
memory_info->attributes = 0;
if (vma == Core::CurrentProcess()->vm_manager.vma_map.end()) {
if (vma == Core::CurrentProcess()->VMManager().vma_map.end()) {
memory_info->base_address = 0;
memory_info->permission = static_cast<u32>(VMAPermission::None);
memory_info->size = 0;
@ -568,14 +568,14 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
return ERR_INVALID_THREAD_PRIORITY;
}
SharedPtr<ResourceLimit>& resource_limit = Core::CurrentProcess()->resource_limit;
if (resource_limit->GetMaxResourceValue(ResourceType::Priority) > priority) {
const ResourceLimit& resource_limit = Core::CurrentProcess()->GetResourceLimit();
if (resource_limit.GetMaxResourceValue(ResourceType::Priority) > priority) {
return ERR_NOT_AUTHORIZED;
}
if (processor_id == THREADPROCESSORID_DEFAULT) {
// Set the target CPU to the one specified in the process' exheader.
processor_id = Core::CurrentProcess()->ideal_processor;
processor_id = Core::CurrentProcess()->GetDefaultProcessorID();
ASSERT(processor_id != THREADPROCESSORID_DEFAULT);
}
@ -902,10 +902,10 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
}
if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) {
ASSERT(thread->owner_process->ideal_processor !=
ASSERT(thread->owner_process->GetDefaultProcessorID() !=
static_cast<u8>(THREADPROCESSORID_DEFAULT));
// Set the target CPU to the one specified in the process' exheader.
core = thread->owner_process->ideal_processor;
core = thread->owner_process->GetDefaultProcessorID();
mask = 1ull << core;
}

View File

@ -259,10 +259,10 @@ void Thread::BoostPriority(u32 priority) {
SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority,
Process& owner_process) {
// Setup page table so we can write to memory
SetCurrentPageTable(&owner_process.vm_manager.page_table);
SetCurrentPageTable(&owner_process.VMManager().page_table);
// Initialize new "main" thread
const VAddr stack_top = owner_process.vm_manager.GetTLSIORegionEndAddress();
const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress();
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0,
stack_top, &owner_process);

View File

@ -51,7 +51,7 @@ enum class FatalType : u32 {
};
static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) {
const auto title_id = Core::CurrentProcess()->program_id;
const auto title_id = Core::CurrentProcess()->GetTitleID();
std::string crash_report =
fmt::format("Yuzu {}-{} crash report\n"
"Title ID: {:016x}\n"

View File

@ -317,9 +317,9 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) {
void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
// Map backing memory for the font data
Core::CurrentProcess()->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0,
SHARED_FONT_MEM_SIZE,
Kernel::MemoryState::Shared);
Core::CurrentProcess()->VMManager().MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0,
SHARED_FONT_MEM_SIZE,
Kernel::MemoryState::Shared);
// Create shared font memory object
auto& kernel = Core::System::GetInstance().Kernel();

View File

@ -132,7 +132,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process)
process.LoadFromMetadata(metadata);
// Load NSO modules
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress();
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
VAddr next_load_addr = base_address;
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
"subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {

View File

@ -395,7 +395,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::Process& process) {
if (buffer.size() != file->GetSize())
return ResultStatus::ErrorIncorrectELFFileSize;
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress();
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
ElfReader elf_reader(&buffer[0]);
SharedPtr<CodeSet> codeset = elf_reader.LoadInto(base_address);
codeset->name = file->GetName();

View File

@ -181,7 +181,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::Process& process) {
}
// Load NRO
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress();
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
if (!LoadNro(file, base_address)) {
return ResultStatus::ErrorLoadingNRO;

View File

@ -159,7 +159,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::Process& process) {
}
// Load module
const VAddr base_address = process.vm_manager.GetCodeRegionBaseAddress();
const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress();
LoadModule(file, base_address);
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address);

View File

@ -119,7 +119,7 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin
static u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) {
u8* direct_pointer = nullptr;
auto& vm_manager = process.vm_manager;
auto& vm_manager = process.VMManager();
auto it = vm_manager.FindVMA(vaddr);
ASSERT(it != vm_manager.vma_map.end());
@ -214,7 +214,7 @@ void Write(const VAddr vaddr, const T data) {
}
bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
auto& page_table = process.vm_manager.page_table;
const auto& page_table = process.VMManager().page_table;
const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
if (page_pointer)
@ -363,7 +363,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
}
};
const auto& vm_manager = Core::CurrentProcess()->vm_manager;
const auto& vm_manager = Core::CurrentProcess()->VMManager();
CheckRegion(vm_manager.GetCodeRegionBaseAddress(), vm_manager.GetCodeRegionEndAddress());
CheckRegion(vm_manager.GetHeapRegionBaseAddress(), vm_manager.GetHeapRegionEndAddress());
@ -387,7 +387,7 @@ u64 Read64(const VAddr addr) {
void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
const std::size_t size) {
auto& page_table = process.vm_manager.page_table;
const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size;
std::size_t page_index = src_addr >> PAGE_BITS;
@ -452,7 +452,7 @@ void Write64(const VAddr addr, const u64 data) {
void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
const std::size_t size) {
auto& page_table = process.vm_manager.page_table;
const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size;
std::size_t page_index = dest_addr >> PAGE_BITS;
std::size_t page_offset = dest_addr & PAGE_MASK;
@ -498,7 +498,7 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t
}
void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
auto& page_table = process.vm_manager.page_table;
const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size;
std::size_t page_index = dest_addr >> PAGE_BITS;
std::size_t page_offset = dest_addr & PAGE_MASK;
@ -540,7 +540,7 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std:
void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
const std::size_t size) {
auto& page_table = process.vm_manager.page_table;
const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size;
std::size_t page_index = src_addr >> PAGE_BITS;
std::size_t page_offset = src_addr & PAGE_MASK;

View File

@ -16,7 +16,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
Core::CurrentProcess() = Kernel::Process::Create(kernel, "");
page_table = &Core::CurrentProcess()->vm_manager.page_table;
page_table = &Core::CurrentProcess()->VMManager().page_table;
std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr);
page_table->special_regions.clear();

View File

@ -622,9 +622,9 @@ void GMainWindow::BootGame(const QString& filename) {
std::string title_name;
const auto res = Core::System::GetInstance().GetGameName(title_name);
if (res != Loader::ResultStatus::Success) {
const u64 program_id = Core::System::GetInstance().CurrentProcess()->program_id;
const u64 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
const auto [nacp, icon_file] = FileSys::PatchManager(program_id).GetControlMetadata();
const auto [nacp, icon_file] = FileSys::PatchManager(title_id).GetControlMetadata();
if (nacp != nullptr)
title_name = nacp->GetApplicationName();