From 96d15b28c6399e09375da0167b34ad4caab5a30a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 9 Mar 2020 23:23:38 -0700 Subject: [PATCH] kern: implement CallSecureMonitor, some of GetInfo/GetSystemInfo --- .../arch/arm64/kern_k_process_page_table.hpp | 15 +++ .../nintendo/nx/kern_k_system_control.hpp | 3 + .../mesosphere/kern_k_page_table_base.hpp | 8 +- .../include/mesosphere/kern_panic.hpp | 2 +- .../arch/arm64/kern_exception_handlers.cpp | 9 ++ .../nintendo/nx/kern_k_system_control.cpp | 49 ++++++++++ .../board/nintendo/nx/kern_secure_monitor.cpp | 40 ++++++++ .../board/nintendo/nx/kern_secure_monitor.hpp | 2 + .../source/kern_k_page_table_base.cpp | 23 +++++ .../source/svc/kern_svc_info.cpp | 92 ++++++++++++++++++- .../svc/kern_svc_secure_monitor_call.cpp | 2 +- .../include/vapours/svc/svc_common.hpp | 4 +- .../arch/arm64/kern_k_thread_context_asm.s | 48 +++++----- 13 files changed, 264 insertions(+), 33 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 1376a865f..2df7f508b 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -84,6 +84,10 @@ namespace ams::kern::arch::arm64 { return this->page_table.UnmapPages(addr, num_pages, state); } + Result MakeAndOpenPageGroup(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) { + return this->page_table.MakeAndOpenPageGroup(out, address, num_pages, state_mask, state, perm_mask, perm, attr_mask, attr); + } + bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const { return this->page_table.GetPhysicalAddress(out, address); } @@ -96,12 +100,23 @@ namespace ams::kern::arch::arm64 { KProcessAddress GetAliasRegionStart() const { return this->page_table.GetAliasRegionStart(); } KProcessAddress GetStackRegionStart() const { return this->page_table.GetStackRegionStart(); } KProcessAddress GetKernelMapRegionStart() const { return this->page_table.GetKernelMapRegionStart(); } + KProcessAddress GetAliasCodeRegionStart() const { return this->page_table.GetAliasCodeRegionStart(); } size_t GetAddressSpaceSize() const { return this->page_table.GetAddressSpaceSize(); } size_t GetHeapRegionSize() const { return this->page_table.GetHeapRegionSize(); } size_t GetAliasRegionSize() const { return this->page_table.GetAliasRegionSize(); } size_t GetStackRegionSize() const { return this->page_table.GetStackRegionSize(); } size_t GetKernelMapRegionSize() const { return this->page_table.GetKernelMapRegionSize(); } + size_t GetAliasCodeRegionSize() const { return this->page_table.GetAliasCodeRegionSize(); } + + KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const { + /* TODO: Better way to convert address type? */ + return this->page_table.GetHeapPhysicalAddress(address); + } + + KBlockInfoManager *GetBlockInfoManager() { + return this->page_table.GetBlockInfoManager(); + } }; } diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp index 499159bb7..45fa322a7 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp @@ -63,6 +63,9 @@ namespace ams::kern::board::nintendo::nx { /* Power management. */ static void SleepSystem(); static NORETURN void StopSystem(); + + /* User access. */ + static void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args); }; } \ No newline at end of file diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index aa121f6a0..e9630f52c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -191,8 +191,6 @@ namespace ams::kern { KPageTableImpl &GetImpl() { return this->impl; } const KPageTableImpl &GetImpl() const { return this->impl; } - KBlockInfoManager *GetBlockInfoManager() const { return this->block_info_manager; } - bool IsLockedByCurrentThread() const { return this->general_lock.IsLockedByCurrentThread(); } bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr) { @@ -245,6 +243,8 @@ namespace ams::kern { return this->GetImpl().GetPhysicalAddress(out, virt_addr); } + KBlockInfoManager *GetBlockInfoManager() const { return this->block_info_manager; } + Result SetMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission perm); Result SetProcessMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission perm); Result SetHeapSize(KProcessAddress *out, size_t size); @@ -270,18 +270,22 @@ namespace ams::kern { Result MapPageGroup(KProcessAddress *out_addr, const KPageGroup &pg, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm); Result MapPageGroup(KProcessAddress address, const KPageGroup &pg, KMemoryState state, KMemoryPermission perm); Result UnmapPageGroup(KProcessAddress address, const KPageGroup &pg, KMemoryState state); + + Result MakeAndOpenPageGroup(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr); public: KProcessAddress GetAddressSpaceStart() const { return this->address_space_start; } KProcessAddress GetHeapRegionStart() const { return this->heap_region_start; } KProcessAddress GetAliasRegionStart() const { return this->alias_region_start; } KProcessAddress GetStackRegionStart() const { return this->stack_region_start; } KProcessAddress GetKernelMapRegionStart() const { return this->kernel_map_region_start; } + KProcessAddress GetAliasCodeRegionStart() const { return this->alias_code_region_start; } size_t GetAddressSpaceSize() const { return this->address_space_end - this->address_space_start; } size_t GetHeapRegionSize() const { return this->heap_region_end - this->heap_region_start; } size_t GetAliasRegionSize() const { return this->alias_region_end - this->alias_region_start; } size_t GetStackRegionSize() const { return this->stack_region_end - this->stack_region_start; } size_t GetKernelMapRegionSize() const { return this->kernel_map_region_end - this->kernel_map_region_start; } + size_t GetAliasCodeRegionSize() const { return this->alias_code_region_end - this->alias_code_region_start; } public: static ALWAYS_INLINE KVirtualAddress GetLinearVirtualAddress(KPhysicalAddress addr) { return KMemoryLayout::GetLinearVirtualAddress(addr); diff --git a/libraries/libmesosphere/include/mesosphere/kern_panic.hpp b/libraries/libmesosphere/include/mesosphere/kern_panic.hpp index 3df06b178..2f31453ae 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_panic.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_panic.hpp @@ -32,7 +32,7 @@ namespace ams::kern { #define MESOSPHERE_UNUSED(...) ::ams::kern::UnusedImpl(__VA_ARGS__) #ifdef MESOSPHERE_ENABLE_DEBUG_PRINT -#define MESOSPHERE_PANIC(...) do { ::ams::kern::Panic(__FILE__, __LINE__, __VA_ARGS__); } while(0) +#define MESOSPHERE_PANIC(...) do { ::ams::kern::Panic(__FILE__, __LINE__, ## __VA_ARGS__); } while(0) #else #define MESOSPHERE_PANIC(...) do { MESOSPHERE_UNUSED(__VA_ARGS__); ::ams::kern::Panic(); } while(0) #endif diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index d284e3987..37fefefb4 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -150,6 +150,15 @@ namespace ams::kern::arch::arm64 { HandleUserException(context, esr, far, afsr0, afsr1, data); } } else { + MESOSPHERE_LOG("Unhandled Exception in Supervisor Mode\n"); + MESOSPHERE_LOG("Current Process = %s\n", GetCurrentProcess().GetName()); + + for (size_t i = 0; i < 31; i++) { + MESOSPHERE_LOG("X[%02zu] = %016lx\n", i, context->x[i]); + } + MESOSPHERE_LOG("PC = %016lx\n", context->pc); + MESOSPHERE_LOG("SP = %016lx\n", context->sp); + MESOSPHERE_PANIC("Unhandled Exception in Supervisor Mode\n"); } diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index 790022ffc..b22e1189e 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -327,4 +327,53 @@ namespace ams::kern::board::nintendo::nx { while (true) { /* ... */ } } + /* User access. */ + void KSystemControl::CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args) { + /* Get the function id for the current call. */ + u64 function_id = args->r[0]; + + MESOSPHERE_LOG("CallSecureMonitor(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx);\n", args->r[0], args->r[1], args->r[2], args->r[3], args->r[4], args->r[5], args->r[6], args->r[7]); + + /* We'll need to map in pages if arguments are pointers. Prepare page groups to do so. */ + auto &page_table = GetCurrentProcess().GetPageTable(); + auto *bim = page_table.GetBlockInfoManager(); + + constexpr size_t MaxMappedRegisters = 7; + std::array page_groups = { KPageGroup(bim), KPageGroup(bim), KPageGroup(bim), KPageGroup(bim), KPageGroup(bim), KPageGroup(bim), KPageGroup(bim), }; + + for (size_t i = 0; i < MaxMappedRegisters; i++) { + const size_t reg_id = i + 1; + if (function_id & (1ul << (8 + reg_id))) { + /* Create and open a new page group for the address. */ + KVirtualAddress virt_addr = args->r[reg_id]; + + if (R_SUCCEEDED(page_table.MakeAndOpenPageGroup(std::addressof(page_groups[i]), util::AlignDown(GetInteger(virt_addr), PageSize), 1, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None))) { + /* Translate the virtual address to a physical address. */ + const auto it = page_groups[i].begin(); + MESOSPHERE_ASSERT(it != page_groups[i].end()); + MESOSPHERE_ASSERT(it->GetNumPages() == 1); + + KPhysicalAddress phys_addr = page_table.GetHeapPhysicalAddress(it->GetAddress()); + + args->r[reg_id] = GetInteger(phys_addr) | (GetInteger(virt_addr) & (PageSize - 1)); + MESOSPHERE_LOG("Mapped arg %zu\n", reg_id); + } else { + /* If we couldn't map, we should clear the address. */ + MESOSPHERE_LOG("Failed to map arg %zu\n", reg_id); + args->r[reg_id] = 0; + } + } + } + + /* Invoke the secure monitor. */ + smc::CallSecureMonitorFromUser(args); + + MESOSPHERE_LOG("Secure Monitor Returned: (%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx);\n", args->r[0], args->r[1], args->r[2], args->r[3], args->r[4], args->r[5], args->r[6], args->r[7]); + + /* Make sure that we close any pages that we opened. */ + for (size_t i = 0; i < MaxMappedRegisters; i++) { + page_groups[i].Close(); + } + } + } \ No newline at end of file diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp index 49f2ac286..3ae375069 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp @@ -71,6 +71,42 @@ namespace ams::kern::board::nintendo::nx::smc { args.x[7] = x7; } + void CallUserSecureMonitorFunction(ams::svc::lp64::SecureMonitorArguments *args) { + /* Load arguments into registers. */ + register u64 x0 asm("x0") = args->r[0]; + register u64 x1 asm("x1") = args->r[1]; + register u64 x2 asm("x2") = args->r[2]; + register u64 x3 asm("x3") = args->r[3]; + register u64 x4 asm("x4") = args->r[4]; + register u64 x5 asm("x5") = args->r[5]; + register u64 x6 asm("x6") = args->r[6]; + register u64 x7 asm("x7") = args->r[7]; + + /* Actually make the call. */ + { + /* Disable interrupts while making the call. */ + KScopedInterruptDisable intr_disable; + __asm__ __volatile__("smc #0" + : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7) + : + : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory" + ); + + /* Restore the CoreLocalRegion into X18. */ + cpu::SetCoreLocalRegionAddress(cpu::GetTpidrEl1()); + } + + /* Store arguments to output. */ + args->r[0] = x0; + args->r[1] = x1; + args->r[2] = x2; + args->r[3] = x3; + args->r[4] = x4; + args->r[5] = x5; + args->r[6] = x6; + args->r[7] = x7; + } + void CallPrivilegedSecureMonitorFunctionForInit(SecureMonitorArguments &args) { /* Load arguments into registers. */ register u64 x0 asm("x0") = args.x[0]; @@ -188,4 +224,8 @@ namespace ams::kern::board::nintendo::nx::smc { while (true) { /* ... */ } } + void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args) { + CallUserSecureMonitorFunction(args); + } + } \ No newline at end of file diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp index fa78b0ee2..72abe5dee 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp @@ -91,6 +91,8 @@ namespace ams::kern::board::nintendo::nx::smc { void NORETURN Panic(u32 color); + void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args); + namespace init { void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 4b4eb1d3d..217a27213 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -1020,4 +1020,27 @@ namespace ams::kern { return ResultSuccess(); } + Result KPageTableBase::MakeAndOpenPageGroup(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) { + /* Ensure that the page group isn't null. */ + AMS_ASSERT(out != nullptr); + + /* Make sure that the region we're mapping is valid for the table. */ + const size_t size = num_pages * PageSize; + R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); + + /* Lock the table. */ + KScopedLightLock lk(this->general_lock); + + /* Check if state allows us to create the group. */ + R_TRY(this->CheckMemoryState(address, size, state_mask | KMemoryState_FlagReferenceCounted, state | KMemoryState_FlagReferenceCounted, perm_mask, perm, attr_mask, attr)); + + /* Create a new page group for the region. */ + R_TRY(this->MakePageGroup(*out, address, num_pages)); + + /* Open a new reference to the pages in the group. */ + out->Open(); + + return ResultSuccess(); + } + } diff --git a/libraries/libmesosphere/source/svc/kern_svc_info.cpp b/libraries/libmesosphere/source/svc/kern_svc_info.cpp index b1dc3a534..84f330e3b 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_info.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_info.cpp @@ -21,28 +21,112 @@ namespace ams::kern::svc { namespace { + Result GetInfo(u64 *out, ams::svc::InfoType info_type, ams::svc::Handle handle, u64 info_subtype) { + MESOSPHERE_LOG("GetInfo(%p, %u, %08x, %lu) was called\n", out, static_cast(info_type), static_cast(handle), info_subtype); + ON_SCOPE_EXIT{ MESOSPHERE_LOG("GetInfo returned %016lx\n", *out); }; + switch (info_type) { + case ams::svc::InfoType_AliasRegionAddress: + case ams::svc::InfoType_AliasRegionSize: + case ams::svc::InfoType_HeapRegionAddress: + case ams::svc::InfoType_HeapRegionSize: + case ams::svc::InfoType_AslrRegionAddress: + case ams::svc::InfoType_AslrRegionSize: + case ams::svc::InfoType_StackRegionAddress: + case ams::svc::InfoType_StackRegionSize: + { + /* These info types don't support non-zero subtypes. */ + R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination()); + + /* Get the process from its handle. */ + KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject(handle); + R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle()); + + switch (info_type) { + case ams::svc::InfoType_AliasRegionAddress: + *out = GetInteger(process->GetPageTable().GetAliasRegionStart()); + break; + case ams::svc::InfoType_AliasRegionSize: + *out = process->GetPageTable().GetAliasRegionSize(); + break; + case ams::svc::InfoType_HeapRegionAddress: + *out = GetInteger(process->GetPageTable().GetHeapRegionStart()); + break; + case ams::svc::InfoType_HeapRegionSize: + *out = process->GetPageTable().GetHeapRegionSize(); + break; + case ams::svc::InfoType_AslrRegionAddress: + *out = GetInteger(process->GetPageTable().GetAliasCodeRegionStart()); + break; + case ams::svc::InfoType_AslrRegionSize: + *out = process->GetPageTable().GetAliasCodeRegionSize(); + break; + case ams::svc::InfoType_StackRegionAddress: + *out = GetInteger(process->GetPageTable().GetStackRegionStart()); + break; + case ams::svc::InfoType_StackRegionSize: + *out = process->GetPageTable().GetStackRegionSize(); + break; + MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + } + } + break; + default: + return svc::ResultInvalidEnumValue(); + } + + return ResultSuccess(); + } + + Result GetSystemInfo(u64 *out, ams::svc::SystemInfoType info_type, ams::svc::Handle handle, u64 info_subtype) { + MESOSPHERE_LOG("GetSystemInfo(%p, %u, %08x, %lu) was called\n", out, static_cast(info_type), static_cast(handle), info_subtype); + ON_SCOPE_EXIT{ MESOSPHERE_LOG("GetSystemInfo returned %016lx\n", *out); }; + + switch (info_type) { + case ams::svc::SystemInfoType_InitialProcessIdRange: + { + R_UNLESS(handle == ams::svc::InvalidHandle, svc::ResultInvalidHandle()); + switch (static_cast(info_subtype)) { + case ams::svc::InitialProcessIdRangeInfo_Minimum: + MESOSPHERE_ABORT_UNLESS(GetInitialProcessIdMin() <= GetInitialProcessIdMax()); + *out = GetInitialProcessIdMin(); + break; + case ams::svc::InitialProcessIdRangeInfo_Maximum: + MESOSPHERE_ABORT_UNLESS(GetInitialProcessIdMin() <= GetInitialProcessIdMax()); + *out = GetInitialProcessIdMax(); + break; + default: + return svc::ResultInvalidCombination(); + } + } + break; + default: + return svc::ResultInvalidEnumValue(); + } + + return ResultSuccess(); + } } /* ============================= 64 ABI ============================= */ Result GetInfo64(uint64_t *out, ams::svc::InfoType info_type, ams::svc::Handle handle, uint64_t info_subtype) { - MESOSPHERE_PANIC("Stubbed SvcGetInfo64 was called."); + return GetInfo(out, info_type, handle, info_subtype); } Result GetSystemInfo64(uint64_t *out, ams::svc::SystemInfoType info_type, ams::svc::Handle handle, uint64_t info_subtype) { - MESOSPHERE_PANIC("Stubbed SvcGetSystemInfo64 was called."); + return GetSystemInfo(out, info_type, handle, info_subtype); } /* ============================= 64From32 ABI ============================= */ Result GetInfo64From32(uint64_t *out, ams::svc::InfoType info_type, ams::svc::Handle handle, uint64_t info_subtype) { - MESOSPHERE_PANIC("Stubbed SvcGetInfo64From32 was called."); + return GetInfo(out, info_type, handle, info_subtype); } Result GetSystemInfo64From32(uint64_t *out, ams::svc::SystemInfoType info_type, ams::svc::Handle handle, uint64_t info_subtype) { - MESOSPHERE_PANIC("Stubbed SvcGetSystemInfo64From32 was called."); + return GetSystemInfo(out, info_type, handle, info_subtype); } } diff --git a/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp b/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp index ccbb1b906..8c0034ff6 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_secure_monitor_call.cpp @@ -28,7 +28,7 @@ namespace ams::kern::svc { /* ============================= 64 ABI ============================= */ void CallSecureMonitor64(ams::svc::lp64::SecureMonitorArguments *args) { - MESOSPHERE_PANIC("Stubbed SvcCallSecureMonitor64 was called."); + KSystemControl::CallSecureMonitorFromUser(args); } /* ============================= 64From32 ABI ============================= */ diff --git a/libraries/libvapours/include/vapours/svc/svc_common.hpp b/libraries/libvapours/include/vapours/svc/svc_common.hpp index 49bd91327..b20680377 100644 --- a/libraries/libvapours/include/vapours/svc/svc_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_common.hpp @@ -28,13 +28,15 @@ namespace ams::svc { using Handle = u32; #endif - static constexpr size_t MaxWaitSynchronizationHandleCount = 0x40; + constexpr inline size_t MaxWaitSynchronizationHandleCount = 0x40; enum PseudoHandle : Handle { CurrentThread = 0xFFFF8000, CurrentProcess = 0xFFFF8001, }; + constexpr inline Handle InvalidHandle = Handle(0); + constexpr ALWAYS_INLINE bool operator==(const Handle &lhs, const PseudoHandle &rhs) { return static_cast(lhs) == static_cast(rhs); } diff --git a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s index b6867cb4e..c50e28dac 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s @@ -100,22 +100,22 @@ _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters64ERKS3_: msr fpsr, x1 /* Restore the FPU registers. */ - ldp q0, q1, [sp, #(16 * 0 + 0x80)] - ldp q2, q3, [sp, #(16 * 2 + 0x80)] - ldp q4, q5, [sp, #(16 * 4 + 0x80)] - ldp q6, q7, [sp, #(16 * 6 + 0x80)] - ldp q8, q9, [sp, #(16 * 8 + 0x80)] - ldp q10, q11, [sp, #(16 * 10 + 0x80)] - ldp q12, q13, [sp, #(16 * 12 + 0x80)] - ldp q14, q15, [sp, #(16 * 14 + 0x80)] - ldp q16, q17, [sp, #(16 * 16 + 0x80)] - ldp q18, q19, [sp, #(16 * 18 + 0x80)] - ldp q20, q21, [sp, #(16 * 20 + 0x80)] - ldp q22, q23, [sp, #(16 * 22 + 0x80)] - ldp q24, q25, [sp, #(16 * 24 + 0x80)] - ldp q26, q27, [sp, #(16 * 26 + 0x80)] - ldp q28, q29, [sp, #(16 * 28 + 0x80)] - ldp q30, q31, [sp, #(16 * 30 + 0x80)] + ldp q0, q1, [x0, #(16 * 0 + 0x80)] + ldp q2, q3, [x0, #(16 * 2 + 0x80)] + ldp q4, q5, [x0, #(16 * 4 + 0x80)] + ldp q6, q7, [x0, #(16 * 6 + 0x80)] + ldp q8, q9, [x0, #(16 * 8 + 0x80)] + ldp q10, q11, [x0, #(16 * 10 + 0x80)] + ldp q12, q13, [x0, #(16 * 12 + 0x80)] + ldp q14, q15, [x0, #(16 * 14 + 0x80)] + ldp q16, q17, [x0, #(16 * 16 + 0x80)] + ldp q18, q19, [x0, #(16 * 18 + 0x80)] + ldp q20, q21, [x0, #(16 * 20 + 0x80)] + ldp q22, q23, [x0, #(16 * 22 + 0x80)] + ldp q24, q25, [x0, #(16 * 24 + 0x80)] + ldp q26, q27, [x0, #(16 * 26 + 0x80)] + ldp q28, q29, [x0, #(16 * 28 + 0x80)] + ldp q30, q31, [x0, #(16 * 30 + 0x80)] ret @@ -131,13 +131,13 @@ _ZN3ams4kern4arch5arm6414KThreadContext21RestoreFpuRegisters32ERKS3_: msr fpsr, x1 /* Restore the FPU registers. */ - ldp q0, q1, [sp, #(16 * 0 + 0x80)] - ldp q2, q3, [sp, #(16 * 2 + 0x80)] - ldp q4, q5, [sp, #(16 * 4 + 0x80)] - ldp q6, q7, [sp, #(16 * 6 + 0x80)] - ldp q8, q9, [sp, #(16 * 8 + 0x80)] - ldp q10, q11, [sp, #(16 * 10 + 0x80)] - ldp q12, q13, [sp, #(16 * 12 + 0x80)] - ldp q14, q15, [sp, #(16 * 14 + 0x80)] + ldp q0, q1, [x0, #(16 * 0 + 0x80)] + ldp q2, q3, [x0, #(16 * 2 + 0x80)] + ldp q4, q5, [x0, #(16 * 4 + 0x80)] + ldp q6, q7, [x0, #(16 * 6 + 0x80)] + ldp q8, q9, [x0, #(16 * 8 + 0x80)] + ldp q10, q11, [x0, #(16 * 10 + 0x80)] + ldp q12, q13, [x0, #(16 * 12 + 0x80)] + ldp q14, q15, [x0, #(16 * 14 + 0x80)] ret