aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_page_table_base.cpp1
-rw-r--r--src/core/hle/kernel/k_page_table_base.h5
-rw-r--r--src/core/hle/kernel/k_process.cpp13
-rw-r--r--src/core/hle/kernel/k_process_page_table.h4
-rw-r--r--src/core/hle/kernel/k_thread.cpp38
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp9
-rw-r--r--src/core/hle/kernel/svc_version.h6
7 files changed, 53 insertions, 23 deletions
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp
index e5b2ed7041..3696f9f251 100644
--- a/src/core/hle/kernel/k_page_table_base.cpp
+++ b/src/core/hle/kernel/k_page_table_base.cpp
@@ -268,6 +268,7 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
// Set other basic fields.
m_enable_aslr = enable_aslr;
m_enable_device_address_space_merge = enable_das_merge;
+ m_allowed_exec_device_mapping = false;
m_address_space_start = start;
m_address_space_end = end;
m_is_kernel = false;
diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h
index 90f8124a24..726fad989f 100644
--- a/src/core/hle/kernel/k_page_table_base.h
+++ b/src/core/hle/kernel/k_page_table_base.h
@@ -223,6 +223,7 @@ private:
bool m_is_kernel{};
bool m_enable_aslr{};
bool m_enable_device_address_space_merge{};
+ bool m_allowed_exec_device_mapping{};
KMemoryBlockSlabManager* m_memory_block_slab_manager{};
KBlockInfoManager* m_block_info_manager{};
KResourceLimit* m_resource_limit{};
@@ -255,6 +256,10 @@ public:
return m_enable_aslr;
}
+ void AllowDeviceMappingOfExecPages() {
+ m_allowed_exec_device_mapping = true;
+ }
+
bool Contains(KProcessAddress addr) const {
return m_address_space_start <= addr && addr <= m_address_space_end - 1;
}
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index bd50f74c27..70e578f22a 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -341,6 +341,11 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
// Initialize capabilities.
R_TRY(m_capabilities.InitializeForKip(caps, std::addressof(m_page_table)));
+ // Enable mapping device pages as executable on legacy processes.
+ if (m_capabilities.GetIntendedKernelMajorVersion() < 26) {
+ m_page_table.AllowDeviceMappingOfExecPages();
+ }
+
// Initialize the process id.
m_process_id = m_kernel.CreateNewUserProcessID();
ASSERT(InitialProcessIdMin <= m_process_id);
@@ -437,6 +442,11 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
// Initialize capabilities.
R_TRY(m_capabilities.InitializeForUser(user_caps, std::addressof(m_page_table)));
+ // Enable mapping device pages as executable on legacy processes.
+ if (m_capabilities.GetIntendedKernelMajorVersion() < 26) {
+ m_page_table.AllowDeviceMappingOfExecPages();
+ }
+
// Initialize the process id.
m_process_id = m_kernel.CreateNewUserProcessID();
ASSERT(ProcessIdMin <= m_process_id);
@@ -989,6 +999,9 @@ Result KProcess::Run(s32 priority, size_t stack_size) {
main_thread->GetContext().r[0] = 0;
main_thread->GetContext().r[1] = thread_handle;
+ // Pass the thread handle to the thread local region.
+ this->GetMemory().Write32(GetInteger(main_thread->GetTlsAddress()) + 0x110, thread_handle);
+
// Update our state.
this->ChangeState((state == State::Created) ? State::Running : State::RunningAttached);
ON_RESULT_FAILURE_2 {
diff --git a/src/core/hle/kernel/k_process_page_table.h b/src/core/hle/kernel/k_process_page_table.h
index 6462e44a99..97c9238907 100644
--- a/src/core/hle/kernel/k_process_page_table.h
+++ b/src/core/hle/kernel/k_process_page_table.h
@@ -33,6 +33,10 @@ public:
m_page_table.Finalize();
}
+ void AllowDeviceMappingOfExecPages() {
+ m_page_table.AllowDeviceMappingOfExecPages();
+ }
+
[[nodiscard]] Core::Memory::Memory& GetMemory() noexcept { return m_page_table.GetMemory(); }
[[nodiscard]] Core::Memory::Memory const& GetMemory() const noexcept { return m_page_table.GetMemory(); }
[[nodiscard]] Common::PageTable& GetImpl() noexcept { return m_page_table.GetImpl(); }
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index ea9b7eb114..0af315d726 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -76,11 +76,13 @@ namespace Kernel {
std::atomic_uint16_t interrupt_flag;
std::atomic_uint8_t cache_maintenance_flag;
std::atomic_int64_t thread_cpu_time;
+ std::atomic_uint32_t current_thread_handle;
};
static_assert(offsetof(ThreadLocalRegion, disable_count) == 0x100);
static_assert(offsetof(ThreadLocalRegion, interrupt_flag) == 0x102);
static_assert(offsetof(ThreadLocalRegion, cache_maintenance_flag) == 0x104);
static_assert(offsetof(ThreadLocalRegion, thread_cpu_time) == 0x108);
+ static_assert(offsetof(ThreadLocalRegion, current_thread_handle) == 0x110);
class ThreadQueueImplForKThreadSleep final : public KThreadQueueWithoutEndWait {
public:
@@ -128,24 +130,24 @@ namespace Kernel {
// Next, assert things based on the type.
switch (type) {
- case ThreadType::Main:
- ASSERT(arg == 0);
- [[fallthrough]];
- case ThreadType::User:
- ASSERT(((owner == nullptr) ||
- (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
- ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
- (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
- break;
- case ThreadType::HighPriority:
- case ThreadType::Dummy:
- break;
- case ThreadType::Kernel:
- UNIMPLEMENTED();
- break;
- default:
- ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type));
- break;
+ case ThreadType::Main:
+ ASSERT(arg == 0);
+ [[fallthrough]];
+ case ThreadType::User:
+ ASSERT(((owner == nullptr) ||
+ (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask()));
+ ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) ||
+ (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask()));
+ break;
+ case ThreadType::HighPriority:
+ case ThreadType::Dummy:
+ break;
+ case ThreadType::Kernel:
+ UNIMPLEMENTED();
+ break;
+ default:
+ ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type));
+ break;
}
m_thread_type = type;
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index ca5ce6fe07..1aa6f87c04 100644
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -75,7 +75,12 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u
KThread::Register(kernel, thread);
// Add the thread to the handle table.
- R_RETURN(process.GetHandleTable().Add(out_handle, thread));
+ R_TRY(process.GetHandleTable().Add(out_handle, thread));
+
+ // Pass the thread handle to the thread local region.
+ process.GetMemory().Write32(GetInteger(thread->GetTlsAddress()) + 0x110, *out_handle);
+
+ R_SUCCEED();
}
/// Starts the thread for the provided handle
diff --git a/src/core/hle/kernel/svc_version.h b/src/core/hle/kernel/svc_version.h
index b47874dcde..ec5c5a006a 100644
--- a/src/core/hle/kernel/svc_version.h
+++ b/src/core/hle/kernel/svc_version.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
@@ -53,8 +53,8 @@ constexpr inline u32 RequiredKernelVersion =
// This is the highest SVC version supported, to be updated on new kernel releases.
// NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor.
-constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(20);
-constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(5);
+constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(22);
+constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(2);
constexpr inline u32 SupportedKernelVersion =
EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion);