k_process.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <random>
  4. #include "common/scope_exit.h"
  5. #include "common/settings.h"
  6. #include "core/arm/dynarmic/arm_dynarmic.h"
  7. #include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
  8. #include "core/core.h"
  9. #include "core/hle/kernel/k_process.h"
  10. #include "core/hle/kernel/k_scoped_resource_reservation.h"
  11. #include "core/hle/kernel/k_shared_memory.h"
  12. #include "core/hle/kernel/k_shared_memory_info.h"
  13. #include "core/hle/kernel/k_thread_local_page.h"
  14. #include "core/hle/kernel/k_thread_queue.h"
  15. #include "core/hle/kernel/k_worker_task_manager.h"
  16. #include "core/arm/dynarmic/arm_dynarmic_32.h"
  17. #include "core/arm/dynarmic/arm_dynarmic_64.h"
  18. #ifdef HAS_NCE
  19. #include "core/arm/nce/arm_nce.h"
  20. #endif
  21. namespace Kernel {
  22. namespace {
  23. Result TerminateChildren(KernelCore& kernel, KProcess* process,
  24. const KThread* thread_to_not_terminate) {
  25. // Request that all children threads terminate.
  26. {
  27. KScopedLightLock proc_lk(process->GetListLock());
  28. KScopedSchedulerLock sl(kernel);
  29. if (thread_to_not_terminate != nullptr &&
  30. process->GetPinnedThread(GetCurrentCoreId(kernel)) == thread_to_not_terminate) {
  31. // NOTE: Here Nintendo unpins the current thread instead of the thread_to_not_terminate.
  32. // This is valid because the only caller which uses non-nullptr as argument uses
  33. // GetCurrentThreadPointer(), but it's still notable because it seems incorrect at
  34. // first glance.
  35. process->UnpinCurrentThread();
  36. }
  37. auto& thread_list = process->GetThreadList();
  38. for (auto it = thread_list.begin(); it != thread_list.end(); ++it) {
  39. if (KThread* thread = std::addressof(*it); thread != thread_to_not_terminate) {
  40. if (thread->GetState() != ThreadState::Terminated) {
  41. thread->RequestTerminate();
  42. }
  43. }
  44. }
  45. }
  46. // Wait for all children threads to terminate.
  47. while (true) {
  48. // Get the next child.
  49. KThread* cur_child = nullptr;
  50. {
  51. KScopedLightLock proc_lk(process->GetListLock());
  52. auto& thread_list = process->GetThreadList();
  53. for (auto it = thread_list.begin(); it != thread_list.end(); ++it) {
  54. if (KThread* thread = std::addressof(*it); thread != thread_to_not_terminate) {
  55. if (thread->GetState() != ThreadState::Terminated) {
  56. if (thread->Open()) {
  57. cur_child = thread;
  58. break;
  59. }
  60. }
  61. }
  62. }
  63. }
  64. // If we didn't find any non-terminated children, we're done.
  65. if (cur_child == nullptr) {
  66. break;
  67. }
  68. // Terminate and close the thread.
  69. SCOPE_EXIT {
  70. cur_child->Close();
  71. };
  72. if (const Result terminate_result = cur_child->Terminate();
  73. ResultTerminationRequested == terminate_result) {
  74. R_THROW(terminate_result);
  75. }
  76. }
  77. R_SUCCEED();
  78. }
  79. class ThreadQueueImplForKProcessEnterUserException final : public KThreadQueue {
  80. private:
  81. KThread** m_exception_thread;
  82. public:
  83. explicit ThreadQueueImplForKProcessEnterUserException(KernelCore& kernel, KThread** t)
  84. : KThreadQueue(kernel), m_exception_thread(t) {}
  85. virtual void EndWait(KThread* waiting_thread, Result wait_result) override {
  86. // Set the exception thread.
  87. *m_exception_thread = waiting_thread;
  88. // Invoke the base end wait handler.
  89. KThreadQueue::EndWait(waiting_thread, wait_result);
  90. }
  91. virtual void CancelWait(KThread* waiting_thread, Result wait_result,
  92. bool cancel_timer_task) override {
  93. // Remove the thread as a waiter on its mutex owner.
  94. waiting_thread->GetLockOwner()->RemoveWaiter(waiting_thread);
  95. // Invoke the base cancel wait handler.
  96. KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task);
  97. }
  98. };
  99. void GenerateRandom(std::span<u64> out_random) {
  100. std::mt19937 rng(Settings::values.rng_seed_enabled ? Settings::values.rng_seed.GetValue()
  101. : static_cast<u32>(std::time(nullptr)));
  102. std::uniform_int_distribution<u64> distribution;
  103. std::generate(out_random.begin(), out_random.end(), [&] { return distribution(rng); });
  104. }
  105. } // namespace
  106. void KProcess::Finalize() {
  107. // Delete the process local region.
  108. this->DeleteThreadLocalRegion(m_plr_address);
  109. // Get the used memory size.
  110. const size_t used_memory_size = this->GetUsedNonSystemUserPhysicalMemorySize();
  111. // Finalize the page table.
  112. m_page_table.Finalize();
  113. // Finish using our system resource.
  114. if (m_system_resource) {
  115. if (m_system_resource->IsSecureResource()) {
  116. // Finalize optimized memory. If memory wasn't optimized, this is a no-op.
  117. m_kernel.MemoryManager().FinalizeOptimizedMemory(this->GetId(), m_memory_pool);
  118. }
  119. m_system_resource->Close();
  120. m_system_resource = nullptr;
  121. }
  122. // Free all shared memory infos.
  123. {
  124. auto it = m_shared_memory_list.begin();
  125. while (it != m_shared_memory_list.end()) {
  126. KSharedMemoryInfo* info = std::addressof(*it);
  127. KSharedMemory* shmem = info->GetSharedMemory();
  128. while (!info->Close()) {
  129. shmem->Close();
  130. }
  131. shmem->Close();
  132. it = m_shared_memory_list.erase(it);
  133. KSharedMemoryInfo::Free(m_kernel, info);
  134. }
  135. }
  136. // Our thread local page list must be empty at this point.
  137. ASSERT(m_partially_used_tlp_tree.empty());
  138. ASSERT(m_fully_used_tlp_tree.empty());
  139. // Release memory to the resource limit.
  140. if (m_resource_limit != nullptr) {
  141. ASSERT(used_memory_size >= m_memory_release_hint);
  142. m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, used_memory_size,
  143. used_memory_size - m_memory_release_hint);
  144. m_resource_limit->Close();
  145. }
  146. // Clear expensive resources, as the destructor is not called for guest objects.
  147. for (auto& interface : m_arm_interfaces) {
  148. interface.reset();
  149. }
  150. m_exclusive_monitor.reset();
  151. // Perform inherited finalization.
  152. KSynchronizationObject::Finalize();
  153. }
  154. Result KProcess::Initialize(const Svc::CreateProcessParameter& params, KResourceLimit* res_limit,
  155. bool is_real) {
  156. // TODO: remove this special case
  157. if (is_real) {
  158. // Create and clear the process local region.
  159. R_TRY(this->CreateThreadLocalRegion(std::addressof(m_plr_address)));
  160. this->GetMemory().ZeroBlock(m_plr_address, Svc::ThreadLocalRegionSize);
  161. }
  162. // Copy in the name from parameters.
  163. static_assert(sizeof(params.name) < sizeof(m_name));
  164. std::memcpy(m_name.data(), params.name.data(), sizeof(params.name));
  165. m_name[sizeof(params.name)] = 0;
  166. // Set misc fields.
  167. m_state = State::Created;
  168. m_main_thread_stack_size = 0;
  169. m_used_kernel_memory_size = 0;
  170. m_ideal_core_id = 0;
  171. m_flags = params.flags;
  172. m_version = params.version;
  173. m_program_id = params.program_id;
  174. m_code_address = params.code_address;
  175. m_code_size = params.code_num_pages * PageSize;
  176. m_is_application = True(params.flags & Svc::CreateProcessFlag::IsApplication);
  177. // Set thread fields.
  178. for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
  179. m_running_threads[i] = nullptr;
  180. m_pinned_threads[i] = nullptr;
  181. m_running_thread_idle_counts[i] = 0;
  182. m_running_thread_switch_counts[i] = 0;
  183. }
  184. // Set max memory based on address space type.
  185. switch ((params.flags & Svc::CreateProcessFlag::AddressSpaceMask)) {
  186. case Svc::CreateProcessFlag::AddressSpace32Bit:
  187. case Svc::CreateProcessFlag::AddressSpace64BitDeprecated:
  188. case Svc::CreateProcessFlag::AddressSpace64Bit:
  189. m_max_process_memory = m_page_table.GetHeapRegionSize();
  190. break;
  191. case Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias:
  192. m_max_process_memory = m_page_table.GetHeapRegionSize() + m_page_table.GetAliasRegionSize();
  193. break;
  194. default:
  195. UNREACHABLE();
  196. }
  197. // Generate random entropy.
  198. GenerateRandom(m_entropy);
  199. // Clear remaining fields.
  200. m_num_running_threads = 0;
  201. m_num_process_switches = 0;
  202. m_num_thread_switches = 0;
  203. m_num_fpu_switches = 0;
  204. m_num_supervisor_calls = 0;
  205. m_num_ipc_messages = 0;
  206. m_is_signaled = false;
  207. m_exception_thread = nullptr;
  208. m_is_suspended = false;
  209. m_memory_release_hint = 0;
  210. m_schedule_count = 0;
  211. m_is_handle_table_initialized = false;
  212. // Open a reference to our resource limit.
  213. m_resource_limit = res_limit;
  214. m_resource_limit->Open();
  215. // We're initialized!
  216. m_is_initialized = true;
  217. R_SUCCEED();
  218. }
  219. Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPageGroup& pg,
  220. std::span<const u32> caps, KResourceLimit* res_limit,
  221. KMemoryManager::Pool pool, bool immortal) {
  222. ASSERT(res_limit != nullptr);
  223. ASSERT((params.code_num_pages * PageSize) / PageSize ==
  224. static_cast<size_t>(params.code_num_pages));
  225. // Set members.
  226. m_memory_pool = pool;
  227. m_is_default_application_system_resource = false;
  228. m_is_immortal = immortal;
  229. // Setup our system resource.
  230. if (const size_t system_resource_num_pages = params.system_resource_num_pages;
  231. system_resource_num_pages != 0) {
  232. // Create a secure system resource.
  233. KSecureSystemResource* secure_resource = KSecureSystemResource::Create(m_kernel);
  234. R_UNLESS(secure_resource != nullptr, ResultOutOfResource);
  235. ON_RESULT_FAILURE {
  236. secure_resource->Close();
  237. };
  238. // Initialize the secure resource.
  239. R_TRY(secure_resource->Initialize(system_resource_num_pages * PageSize, res_limit,
  240. m_memory_pool));
  241. // Set our system resource.
  242. m_system_resource = secure_resource;
  243. } else {
  244. // Use the system-wide system resource.
  245. const bool is_app = True(params.flags & Svc::CreateProcessFlag::IsApplication);
  246. m_system_resource = std::addressof(is_app ? m_kernel.GetAppSystemResource()
  247. : m_kernel.GetSystemSystemResource());
  248. m_is_default_application_system_resource = is_app;
  249. // Open reference to the system resource.
  250. m_system_resource->Open();
  251. }
  252. // Ensure we clean up our secure resource, if we fail.
  253. ON_RESULT_FAILURE {
  254. m_system_resource->Close();
  255. m_system_resource = nullptr;
  256. };
  257. // Setup page table.
  258. {
  259. const auto as_type = params.flags & Svc::CreateProcessFlag::AddressSpaceMask;
  260. const bool enable_aslr = True(params.flags & Svc::CreateProcessFlag::EnableAslr);
  261. const bool enable_das_merge =
  262. False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
  263. R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
  264. params.code_address, params.code_num_pages * PageSize,
  265. m_system_resource, res_limit, m_memory, 0));
  266. }
  267. ON_RESULT_FAILURE_2 {
  268. m_page_table.Finalize();
  269. };
  270. // Ensure our memory is initialized.
  271. m_memory.SetCurrentPageTable(*this);
  272. m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager());
  273. // Ensure we can insert the code region.
  274. R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize,
  275. KMemoryState::Code),
  276. ResultInvalidMemoryRegion);
  277. // Map the code region.
  278. R_TRY(m_page_table.MapPageGroup(params.code_address, pg, KMemoryState::Code,
  279. KMemoryPermission::KernelRead));
  280. // Initialize capabilities.
  281. R_TRY(m_capabilities.InitializeForKip(caps, std::addressof(m_page_table)));
  282. // Initialize the process id.
  283. m_process_id = m_kernel.CreateNewUserProcessID();
  284. ASSERT(InitialProcessIdMin <= m_process_id);
  285. ASSERT(m_process_id <= InitialProcessIdMax);
  286. // Initialize the rest of the process.
  287. R_TRY(this->Initialize(params, res_limit, true));
  288. // We succeeded!
  289. R_SUCCEED();
  290. }
  291. Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
  292. std::span<const u32> user_caps, KResourceLimit* res_limit,
  293. KMemoryManager::Pool pool, KProcessAddress aslr_space_start) {
  294. ASSERT(res_limit != nullptr);
  295. // Set members.
  296. m_memory_pool = pool;
  297. m_is_default_application_system_resource = false;
  298. m_is_immortal = false;
  299. // Get the memory sizes.
  300. const size_t code_num_pages = params.code_num_pages;
  301. const size_t system_resource_num_pages = params.system_resource_num_pages;
  302. const size_t code_size = code_num_pages * PageSize;
  303. const size_t system_resource_size = system_resource_num_pages * PageSize;
  304. // Reserve memory for our code resource.
  305. KScopedResourceReservation memory_reservation(
  306. res_limit, Svc::LimitableResource::PhysicalMemoryMax, code_size);
  307. R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
  308. // Setup our system resource.
  309. if (system_resource_num_pages != 0) {
  310. // Create a secure system resource.
  311. KSecureSystemResource* secure_resource = KSecureSystemResource::Create(m_kernel);
  312. R_UNLESS(secure_resource != nullptr, ResultOutOfResource);
  313. ON_RESULT_FAILURE {
  314. secure_resource->Close();
  315. };
  316. // Initialize the secure resource.
  317. R_TRY(secure_resource->Initialize(system_resource_size, res_limit, m_memory_pool));
  318. // Set our system resource.
  319. m_system_resource = secure_resource;
  320. } else {
  321. // Use the system-wide system resource.
  322. const bool is_app = True(params.flags & Svc::CreateProcessFlag::IsApplication);
  323. m_system_resource = std::addressof(is_app ? m_kernel.GetAppSystemResource()
  324. : m_kernel.GetSystemSystemResource());
  325. m_is_default_application_system_resource = is_app;
  326. // Open reference to the system resource.
  327. m_system_resource->Open();
  328. }
  329. // Ensure we clean up our secure resource, if we fail.
  330. ON_RESULT_FAILURE {
  331. m_system_resource->Close();
  332. m_system_resource = nullptr;
  333. };
  334. // Setup page table.
  335. {
  336. const auto as_type = params.flags & Svc::CreateProcessFlag::AddressSpaceMask;
  337. const bool enable_aslr = True(params.flags & Svc::CreateProcessFlag::EnableAslr);
  338. const bool enable_das_merge =
  339. False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
  340. R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
  341. params.code_address, code_size, m_system_resource, res_limit,
  342. m_memory, aslr_space_start));
  343. }
  344. ON_RESULT_FAILURE_2 {
  345. m_page_table.Finalize();
  346. };
  347. // Ensure our memory is initialized.
  348. m_memory.SetCurrentPageTable(*this);
  349. m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager());
  350. // Ensure we can insert the code region.
  351. R_UNLESS(m_page_table.CanContain(params.code_address, code_size, KMemoryState::Code),
  352. ResultInvalidMemoryRegion);
  353. // Map the code region.
  354. R_TRY(m_page_table.MapPages(params.code_address, code_num_pages, KMemoryState::Code,
  355. KMemoryPermission::KernelRead | KMemoryPermission::NotMapped));
  356. // Initialize capabilities.
  357. R_TRY(m_capabilities.InitializeForUser(user_caps, std::addressof(m_page_table)));
  358. // Initialize the process id.
  359. m_process_id = m_kernel.CreateNewUserProcessID();
  360. ASSERT(ProcessIdMin <= m_process_id);
  361. ASSERT(m_process_id <= ProcessIdMax);
  362. // If we should optimize memory allocations, do so.
  363. if (m_system_resource->IsSecureResource() &&
  364. True(params.flags & Svc::CreateProcessFlag::OptimizeMemoryAllocation)) {
  365. R_TRY(m_kernel.MemoryManager().InitializeOptimizedMemory(m_process_id, pool));
  366. }
  367. // Initialize the rest of the process.
  368. R_TRY(this->Initialize(params, res_limit, true));
  369. // We succeeded, so commit our memory reservation.
  370. memory_reservation.Commit();
  371. R_SUCCEED();
  372. }
  373. void KProcess::DoWorkerTaskImpl() {
  374. // Terminate child threads.
  375. TerminateChildren(m_kernel, this, nullptr);
  376. // Finalize the handle table, if we're not immortal.
  377. if (!m_is_immortal && m_is_handle_table_initialized) {
  378. this->FinalizeHandleTable();
  379. }
  380. // Finish termination.
  381. this->FinishTermination();
  382. }
  383. Result KProcess::StartTermination() {
  384. // Finalize the handle table when we're done, if the process isn't immortal.
  385. SCOPE_EXIT {
  386. if (!m_is_immortal) {
  387. this->FinalizeHandleTable();
  388. }
  389. };
  390. // Terminate child threads other than the current one.
  391. R_RETURN(TerminateChildren(m_kernel, this, GetCurrentThreadPointer(m_kernel)));
  392. }
  393. void KProcess::FinishTermination() {
  394. // Only allow termination to occur if the process isn't immortal.
  395. if (!m_is_immortal) {
  396. // Release resource limit hint.
  397. if (m_resource_limit != nullptr) {
  398. m_memory_release_hint = this->GetUsedNonSystemUserPhysicalMemorySize();
  399. m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, 0,
  400. m_memory_release_hint);
  401. }
  402. // Change state.
  403. {
  404. KScopedSchedulerLock sl(m_kernel);
  405. this->ChangeState(State::Terminated);
  406. }
  407. // Close.
  408. this->Close();
  409. }
  410. }
  411. void KProcess::Exit() {
  412. // Determine whether we need to start terminating
  413. bool needs_terminate = false;
  414. {
  415. KScopedLightLock lk(m_state_lock);
  416. KScopedSchedulerLock sl(m_kernel);
  417. ASSERT(m_state != State::Created);
  418. ASSERT(m_state != State::CreatedAttached);
  419. ASSERT(m_state != State::Crashed);
  420. ASSERT(m_state != State::Terminated);
  421. if (m_state == State::Running || m_state == State::RunningAttached ||
  422. m_state == State::DebugBreak) {
  423. this->ChangeState(State::Terminating);
  424. needs_terminate = true;
  425. }
  426. }
  427. // If we need to start termination, do so.
  428. if (needs_terminate) {
  429. this->StartTermination();
  430. // Register the process as a work task.
  431. m_kernel.WorkerTaskManager().AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit, this);
  432. }
  433. // Exit the current thread.
  434. GetCurrentThread(m_kernel).Exit();
  435. }
  436. Result KProcess::Terminate() {
  437. // Determine whether we need to start terminating.
  438. bool needs_terminate = false;
  439. {
  440. KScopedLightLock lk(m_state_lock);
  441. // Check whether we're allowed to terminate.
  442. R_UNLESS(m_state != State::Created, ResultInvalidState);
  443. R_UNLESS(m_state != State::CreatedAttached, ResultInvalidState);
  444. KScopedSchedulerLock sl(m_kernel);
  445. if (m_state == State::Running || m_state == State::RunningAttached ||
  446. m_state == State::Crashed || m_state == State::DebugBreak) {
  447. this->ChangeState(State::Terminating);
  448. needs_terminate = true;
  449. }
  450. }
  451. // If we need to terminate, do so.
  452. if (needs_terminate) {
  453. // Start termination.
  454. if (R_SUCCEEDED(this->StartTermination())) {
  455. // Finish termination.
  456. this->FinishTermination();
  457. } else {
  458. // Register the process as a work task.
  459. m_kernel.WorkerTaskManager().AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit,
  460. this);
  461. }
  462. }
  463. R_SUCCEED();
  464. }
  465. Result KProcess::AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size) {
  466. // Lock ourselves, to prevent concurrent access.
  467. KScopedLightLock lk(m_state_lock);
  468. // Try to find an existing info for the memory.
  469. KSharedMemoryInfo* info = nullptr;
  470. for (auto it = m_shared_memory_list.begin(); it != m_shared_memory_list.end(); ++it) {
  471. if (it->GetSharedMemory() == shmem) {
  472. info = std::addressof(*it);
  473. break;
  474. }
  475. }
  476. // If we didn't find an info, create one.
  477. if (info == nullptr) {
  478. // Allocate a new info.
  479. info = KSharedMemoryInfo::Allocate(m_kernel);
  480. R_UNLESS(info != nullptr, ResultOutOfResource);
  481. // Initialize the info and add it to our list.
  482. info->Initialize(shmem);
  483. m_shared_memory_list.push_back(*info);
  484. }
  485. // Open a reference to the shared memory and its info.
  486. shmem->Open();
  487. info->Open();
  488. R_SUCCEED();
  489. }
  490. void KProcess::RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size) {
  491. // Lock ourselves, to prevent concurrent access.
  492. KScopedLightLock lk(m_state_lock);
  493. // Find an existing info for the memory.
  494. KSharedMemoryInfo* info = nullptr;
  495. auto it = m_shared_memory_list.begin();
  496. for (; it != m_shared_memory_list.end(); ++it) {
  497. if (it->GetSharedMemory() == shmem) {
  498. info = std::addressof(*it);
  499. break;
  500. }
  501. }
  502. ASSERT(info != nullptr);
  503. // Close a reference to the info and its memory.
  504. if (info->Close()) {
  505. m_shared_memory_list.erase(it);
  506. KSharedMemoryInfo::Free(m_kernel, info);
  507. }
  508. shmem->Close();
  509. }
  510. Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) {
  511. KThreadLocalPage* tlp = nullptr;
  512. KProcessAddress tlr = 0;
  513. // See if we can get a region from a partially used TLP.
  514. {
  515. KScopedSchedulerLock sl(m_kernel);
  516. if (auto it = m_partially_used_tlp_tree.begin(); it != m_partially_used_tlp_tree.end()) {
  517. tlr = it->Reserve();
  518. ASSERT(tlr != 0);
  519. if (it->IsAllUsed()) {
  520. tlp = std::addressof(*it);
  521. m_partially_used_tlp_tree.erase(it);
  522. m_fully_used_tlp_tree.insert(*tlp);
  523. }
  524. *out = tlr;
  525. R_SUCCEED();
  526. }
  527. }
  528. // Allocate a new page.
  529. tlp = KThreadLocalPage::Allocate(m_kernel);
  530. R_UNLESS(tlp != nullptr, ResultOutOfMemory);
  531. ON_RESULT_FAILURE {
  532. KThreadLocalPage::Free(m_kernel, tlp);
  533. };
  534. // Initialize the new page.
  535. R_TRY(tlp->Initialize(m_kernel, this));
  536. // Reserve a TLR.
  537. tlr = tlp->Reserve();
  538. ASSERT(tlr != 0);
  539. // Insert into our tree.
  540. {
  541. KScopedSchedulerLock sl(m_kernel);
  542. if (tlp->IsAllUsed()) {
  543. m_fully_used_tlp_tree.insert(*tlp);
  544. } else {
  545. m_partially_used_tlp_tree.insert(*tlp);
  546. }
  547. }
  548. // We succeeded!
  549. *out = tlr;
  550. R_SUCCEED();
  551. }
  552. Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) {
  553. KThreadLocalPage* page_to_free = nullptr;
  554. // Release the region.
  555. {
  556. KScopedSchedulerLock sl(m_kernel);
  557. // Try to find the page in the partially used list.
  558. auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize));
  559. if (it == m_partially_used_tlp_tree.end()) {
  560. // If we don't find it, it has to be in the fully used list.
  561. it = m_fully_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize));
  562. R_UNLESS(it != m_fully_used_tlp_tree.end(), ResultInvalidAddress);
  563. // Release the region.
  564. it->Release(addr);
  565. // Move the page out of the fully used list.
  566. KThreadLocalPage* tlp = std::addressof(*it);
  567. m_fully_used_tlp_tree.erase(it);
  568. if (tlp->IsAllFree()) {
  569. page_to_free = tlp;
  570. } else {
  571. m_partially_used_tlp_tree.insert(*tlp);
  572. }
  573. } else {
  574. // Release the region.
  575. it->Release(addr);
  576. // Handle the all-free case.
  577. KThreadLocalPage* tlp = std::addressof(*it);
  578. if (tlp->IsAllFree()) {
  579. m_partially_used_tlp_tree.erase(it);
  580. page_to_free = tlp;
  581. }
  582. }
  583. }
  584. // If we should free the page it was in, do so.
  585. if (page_to_free != nullptr) {
  586. page_to_free->Finalize();
  587. KThreadLocalPage::Free(m_kernel, page_to_free);
  588. }
  589. R_SUCCEED();
  590. }
  591. bool KProcess::ReserveResource(Svc::LimitableResource which, s64 value) {
  592. if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
  593. return rl->Reserve(which, value);
  594. } else {
  595. return true;
  596. }
  597. }
  598. bool KProcess::ReserveResource(Svc::LimitableResource which, s64 value, s64 timeout) {
  599. if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
  600. return rl->Reserve(which, value, timeout);
  601. } else {
  602. return true;
  603. }
  604. }
  605. void KProcess::ReleaseResource(Svc::LimitableResource which, s64 value) {
  606. if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
  607. rl->Release(which, value);
  608. }
  609. }
  610. void KProcess::ReleaseResource(Svc::LimitableResource which, s64 value, s64 hint) {
  611. if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) {
  612. rl->Release(which, value, hint);
  613. }
  614. }
  615. void KProcess::IncrementRunningThreadCount() {
  616. ASSERT(m_num_running_threads.load() >= 0);
  617. ++m_num_running_threads;
  618. }
  619. void KProcess::DecrementRunningThreadCount() {
  620. ASSERT(m_num_running_threads.load() > 0);
  621. if (const auto prev = m_num_running_threads--; prev == 1) {
  622. this->Terminate();
  623. }
  624. }
  625. bool KProcess::EnterUserException() {
  626. // Get the current thread.
  627. KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
  628. ASSERT(this == cur_thread->GetOwnerProcess());
  629. // Check that we haven't already claimed the exception thread.
  630. if (m_exception_thread == cur_thread) {
  631. return false;
  632. }
  633. // Create the wait queue we'll be using.
  634. ThreadQueueImplForKProcessEnterUserException wait_queue(m_kernel,
  635. std::addressof(m_exception_thread));
  636. // Claim the exception thread.
  637. {
  638. // Lock the scheduler.
  639. KScopedSchedulerLock sl(m_kernel);
  640. // Check that we're not terminating.
  641. if (cur_thread->IsTerminationRequested()) {
  642. return false;
  643. }
  644. // If we don't have an exception thread, we can just claim it directly.
  645. if (m_exception_thread == nullptr) {
  646. m_exception_thread = cur_thread;
  647. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  648. return true;
  649. }
  650. // Otherwise, we need to wait until we don't have an exception thread.
  651. // Add the current thread as a waiter on the current exception thread.
  652. cur_thread->SetKernelAddressKey(
  653. reinterpret_cast<uintptr_t>(std::addressof(m_exception_thread)) | 1);
  654. m_exception_thread->AddWaiter(cur_thread);
  655. // Wait to claim the exception thread.
  656. cur_thread->BeginWait(std::addressof(wait_queue));
  657. }
  658. // If our wait didn't end due to thread termination, we succeeded.
  659. return ResultTerminationRequested != cur_thread->GetWaitResult();
  660. }
  661. bool KProcess::LeaveUserException() {
  662. return this->ReleaseUserException(GetCurrentThreadPointer(m_kernel));
  663. }
  664. bool KProcess::ReleaseUserException(KThread* thread) {
  665. KScopedSchedulerLock sl(m_kernel);
  666. if (m_exception_thread == thread) {
  667. m_exception_thread = nullptr;
  668. // Remove waiter thread.
  669. bool has_waiters;
  670. if (KThread* next = thread->RemoveKernelWaiterByKey(
  671. std::addressof(has_waiters),
  672. reinterpret_cast<uintptr_t>(std::addressof(m_exception_thread)) | 1);
  673. next != nullptr) {
  674. next->EndWait(ResultSuccess);
  675. }
  676. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  677. return true;
  678. } else {
  679. return false;
  680. }
  681. }
  682. void KProcess::RegisterThread(KThread* thread) {
  683. KScopedLightLock lk(m_list_lock);
  684. m_thread_list.push_back(*thread);
  685. }
  686. void KProcess::UnregisterThread(KThread* thread) {
  687. KScopedLightLock lk(m_list_lock);
  688. m_thread_list.erase(m_thread_list.iterator_to(*thread));
  689. }
  690. size_t KProcess::GetUsedUserPhysicalMemorySize() const {
  691. const size_t norm_size = m_page_table.GetNormalMemorySize();
  692. const size_t other_size = m_code_size + m_main_thread_stack_size;
  693. const size_t sec_size = this->GetRequiredSecureMemorySizeNonDefault();
  694. return norm_size + other_size + sec_size;
  695. }
  696. size_t KProcess::GetTotalUserPhysicalMemorySize() const {
  697. // Get the amount of free and used size.
  698. const size_t free_size =
  699. m_resource_limit->GetFreeValue(Svc::LimitableResource::PhysicalMemoryMax);
  700. const size_t max_size = m_max_process_memory;
  701. // Determine used size.
  702. // NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike
  703. // GetUsedUserPhysicalMemorySize().
  704. const size_t norm_size = m_page_table.GetNormalMemorySize();
  705. const size_t other_size = m_code_size + m_main_thread_stack_size;
  706. const size_t sec_size = this->GetRequiredSecureMemorySize();
  707. const size_t used_size = norm_size + other_size + sec_size;
  708. // NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo
  709. // does it this way.
  710. if (used_size + free_size > max_size) {
  711. return max_size;
  712. } else {
  713. return free_size + this->GetUsedUserPhysicalMemorySize();
  714. }
  715. }
  716. size_t KProcess::GetUsedNonSystemUserPhysicalMemorySize() const {
  717. const size_t norm_size = m_page_table.GetNormalMemorySize();
  718. const size_t other_size = m_code_size + m_main_thread_stack_size;
  719. return norm_size + other_size;
  720. }
  721. size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const {
  722. // Get the amount of free and used size.
  723. const size_t free_size =
  724. m_resource_limit->GetFreeValue(Svc::LimitableResource::PhysicalMemoryMax);
  725. const size_t max_size = m_max_process_memory;
  726. // Determine used size.
  727. // NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike
  728. // GetUsedUserPhysicalMemorySize().
  729. const size_t norm_size = m_page_table.GetNormalMemorySize();
  730. const size_t other_size = m_code_size + m_main_thread_stack_size;
  731. const size_t sec_size = this->GetRequiredSecureMemorySize();
  732. const size_t used_size = norm_size + other_size + sec_size;
  733. // NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo
  734. // does it this way.
  735. if (used_size + free_size > max_size) {
  736. return max_size - this->GetRequiredSecureMemorySizeNonDefault();
  737. } else {
  738. return free_size + this->GetUsedNonSystemUserPhysicalMemorySize();
  739. }
  740. }
  741. Result KProcess::Run(s32 priority, size_t stack_size) {
  742. // Lock ourselves, to prevent concurrent access.
  743. KScopedLightLock lk(m_state_lock);
  744. // Validate that we're in a state where we can initialize.
  745. const auto state = m_state;
  746. R_UNLESS(state == State::Created || state == State::CreatedAttached, ResultInvalidState);
  747. // Place a tentative reservation of a thread for this process.
  748. KScopedResourceReservation thread_reservation(this, Svc::LimitableResource::ThreadCountMax);
  749. R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached);
  750. // Ensure that we haven't already allocated stack.
  751. ASSERT(m_main_thread_stack_size == 0);
  752. // Ensure that we're allocating a valid stack.
  753. stack_size = Common::AlignUp(stack_size, PageSize);
  754. R_UNLESS(stack_size + m_code_size <= m_max_process_memory, ResultOutOfMemory);
  755. R_UNLESS(stack_size + m_code_size >= m_code_size, ResultOutOfMemory);
  756. // Place a tentative reservation of memory for our new stack.
  757. KScopedResourceReservation mem_reservation(this, Svc::LimitableResource::PhysicalMemoryMax,
  758. stack_size);
  759. R_UNLESS(mem_reservation.Succeeded(), ResultLimitReached);
  760. // Allocate and map our stack.
  761. KProcessAddress stack_top = 0;
  762. if (stack_size) {
  763. KProcessAddress stack_bottom;
  764. R_TRY(m_page_table.MapPages(std::addressof(stack_bottom), stack_size / PageSize,
  765. KMemoryState::Stack, KMemoryPermission::UserReadWrite));
  766. stack_top = stack_bottom + stack_size;
  767. m_main_thread_stack_size = stack_size;
  768. }
  769. // Ensure our stack is safe to clean up on exit.
  770. ON_RESULT_FAILURE {
  771. if (m_main_thread_stack_size) {
  772. ASSERT(R_SUCCEEDED(m_page_table.UnmapPages(stack_top - m_main_thread_stack_size,
  773. m_main_thread_stack_size / PageSize,
  774. KMemoryState::Stack)));
  775. m_main_thread_stack_size = 0;
  776. }
  777. };
  778. // Set our maximum heap size.
  779. R_TRY(m_page_table.SetMaxHeapSize(m_max_process_memory -
  780. (m_main_thread_stack_size + m_code_size)));
  781. // Initialize our handle table.
  782. R_TRY(this->InitializeHandleTable(m_capabilities.GetHandleTableSize()));
  783. ON_RESULT_FAILURE_2 {
  784. this->FinalizeHandleTable();
  785. };
  786. // Create a new thread for the process.
  787. KThread* main_thread = KThread::Create(m_kernel);
  788. R_UNLESS(main_thread != nullptr, ResultOutOfResource);
  789. SCOPE_EXIT {
  790. main_thread->Close();
  791. };
  792. // Initialize the thread.
  793. R_TRY(KThread::InitializeUserThread(m_kernel.System(), main_thread, this->GetEntryPoint(), 0,
  794. stack_top, priority, m_ideal_core_id, this));
  795. // Register the thread, and commit our reservation.
  796. KThread::Register(m_kernel, main_thread);
  797. thread_reservation.Commit();
  798. // Add the thread to our handle table.
  799. Handle thread_handle;
  800. R_TRY(m_handle_table.Add(std::addressof(thread_handle), main_thread));
  801. // Set the thread arguments.
  802. main_thread->GetContext().r[0] = 0;
  803. main_thread->GetContext().r[1] = thread_handle;
  804. // Update our state.
  805. this->ChangeState((state == State::Created) ? State::Running : State::RunningAttached);
  806. ON_RESULT_FAILURE_2 {
  807. this->ChangeState(state);
  808. };
  809. // Suspend for debug, if we should.
  810. if (m_kernel.System().DebuggerEnabled()) {
  811. main_thread->RequestSuspend(SuspendType::Debug);
  812. }
  813. // Run our thread.
  814. R_TRY(main_thread->Run());
  815. // Open a reference to represent that we're running.
  816. this->Open();
  817. // We succeeded! Commit our memory reservation.
  818. mem_reservation.Commit();
  819. R_SUCCEED();
  820. }
  821. Result KProcess::Reset() {
  822. // Lock the process and the scheduler.
  823. KScopedLightLock lk(m_state_lock);
  824. KScopedSchedulerLock sl(m_kernel);
  825. // Validate that we're in a state that we can reset.
  826. R_UNLESS(m_state != State::Terminated, ResultInvalidState);
  827. R_UNLESS(m_is_signaled, ResultInvalidState);
  828. // Clear signaled.
  829. m_is_signaled = false;
  830. R_SUCCEED();
  831. }
  832. Result KProcess::SetActivity(Svc::ProcessActivity activity) {
  833. // Lock ourselves and the scheduler.
  834. KScopedLightLock lk(m_state_lock);
  835. KScopedLightLock list_lk(m_list_lock);
  836. KScopedSchedulerLock sl(m_kernel);
  837. // Validate our state.
  838. R_UNLESS(m_state != State::Terminating, ResultInvalidState);
  839. R_UNLESS(m_state != State::Terminated, ResultInvalidState);
  840. // Either pause or resume.
  841. if (activity == Svc::ProcessActivity::Paused) {
  842. // Verify that we're not suspended.
  843. R_UNLESS(!m_is_suspended, ResultInvalidState);
  844. // Suspend all threads.
  845. auto end = this->GetThreadList().end();
  846. for (auto it = this->GetThreadList().begin(); it != end; ++it) {
  847. it->RequestSuspend(SuspendType::Process);
  848. }
  849. // Set ourselves as suspended.
  850. this->SetSuspended(true);
  851. } else {
  852. ASSERT(activity == Svc::ProcessActivity::Runnable);
  853. // Verify that we're suspended.
  854. R_UNLESS(m_is_suspended, ResultInvalidState);
  855. // Resume all threads.
  856. auto end = this->GetThreadList().end();
  857. for (auto it = this->GetThreadList().begin(); it != end; ++it) {
  858. it->Resume(SuspendType::Process);
  859. }
  860. // Set ourselves as resumed.
  861. this->SetSuspended(false);
  862. }
  863. R_SUCCEED();
  864. }
  865. void KProcess::PinCurrentThread() {
  866. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  867. // Get the current thread.
  868. const s32 core_id = GetCurrentCoreId(m_kernel);
  869. KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
  870. // If the thread isn't terminated, pin it.
  871. if (!cur_thread->IsTerminationRequested()) {
  872. // Pin it.
  873. this->PinThread(core_id, cur_thread);
  874. cur_thread->Pin(core_id);
  875. // An update is needed.
  876. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  877. }
  878. }
  879. void KProcess::UnpinCurrentThread() {
  880. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  881. // Get the current thread.
  882. const s32 core_id = GetCurrentCoreId(m_kernel);
  883. KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
  884. // Unpin it.
  885. cur_thread->Unpin();
  886. this->UnpinThread(core_id, cur_thread);
  887. // An update is needed.
  888. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  889. }
  890. void KProcess::UnpinThread(KThread* thread) {
  891. ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
  892. // Get the thread's core id.
  893. const auto core_id = thread->GetActiveCore();
  894. // Unpin it.
  895. this->UnpinThread(core_id, thread);
  896. thread->Unpin();
  897. // An update is needed.
  898. KScheduler::SetSchedulerUpdateNeeded(m_kernel);
  899. }
  900. Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids,
  901. s32 max_out_count) {
  902. auto& memory = this->GetMemory();
  903. // Lock the list.
  904. KScopedLightLock lk(m_list_lock);
  905. // Iterate over the list.
  906. s32 count = 0;
  907. auto end = this->GetThreadList().end();
  908. for (auto it = this->GetThreadList().begin(); it != end; ++it) {
  909. // If we're within array bounds, write the id.
  910. if (count < max_out_count) {
  911. // Get the thread id.
  912. KThread* thread = std::addressof(*it);
  913. const u64 id = thread->GetId();
  914. // Copy the id to userland.
  915. memory.Write64(out_thread_ids + count * sizeof(u64), id);
  916. }
  917. // Increment the count.
  918. ++count;
  919. }
  920. // We successfully iterated the list.
  921. *out_num_threads = count;
  922. R_SUCCEED();
  923. }
  924. void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
  925. KProcess::KProcess(KernelCore& kernel)
  926. : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel},
  927. m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
  928. m_handle_table{kernel}, m_exclusive_monitor{}, m_memory{kernel.System()} {}
  929. KProcess::~KProcess() = default;
  930. Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
  931. KProcessAddress aslr_space_start, bool is_hbl) {
  932. // Create a resource limit for the process.
  933. const auto pool = static_cast<KMemoryManager::Pool>(metadata.GetPoolPartition());
  934. const auto physical_memory_size = m_kernel.MemoryManager().GetSize(pool);
  935. auto* res_limit =
  936. Kernel::CreateResourceLimitForProcess(m_kernel.System(), physical_memory_size);
  937. // Ensure we maintain a clean state on exit.
  938. SCOPE_EXIT {
  939. res_limit->Close();
  940. };
  941. // Declare flags and code address.
  942. Svc::CreateProcessFlag flag{};
  943. u64 code_address{};
  944. // Determine if we are an application.
  945. if (pool == KMemoryManager::Pool::Application) {
  946. flag |= Svc::CreateProcessFlag::IsApplication;
  947. }
  948. // If we are 64-bit, create as such.
  949. if (metadata.Is64BitProgram()) {
  950. flag |= Svc::CreateProcessFlag::Is64Bit;
  951. }
  952. // Set the address space type and code address.
  953. switch (metadata.GetAddressSpaceType()) {
  954. case FileSys::ProgramAddressSpaceType::Is39Bit:
  955. flag |= Svc::CreateProcessFlag::AddressSpace64Bit;
  956. // For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large.
  957. // However, some (buggy) programs/libraries like skyline incorrectly depend on the
  958. // existence of ASLR pages before the entry point, so we will adjust the load address
  959. // to point to about 2GiB into the ASLR region.
  960. code_address = 0x8000'0000;
  961. break;
  962. case FileSys::ProgramAddressSpaceType::Is36Bit:
  963. flag |= Svc::CreateProcessFlag::AddressSpace64BitDeprecated;
  964. code_address = 0x800'0000;
  965. break;
  966. case FileSys::ProgramAddressSpaceType::Is32Bit:
  967. flag |= Svc::CreateProcessFlag::AddressSpace32Bit;
  968. code_address = 0x20'0000;
  969. break;
  970. case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
  971. flag |= Svc::CreateProcessFlag::AddressSpace32BitWithoutAlias;
  972. code_address = 0x20'0000;
  973. break;
  974. }
  975. Svc::CreateProcessParameter params{
  976. .name = {},
  977. .version = {},
  978. .program_id = metadata.GetTitleID(),
  979. .code_address = code_address + GetInteger(aslr_space_start),
  980. .code_num_pages = static_cast<s32>(code_size / PageSize),
  981. .flags = flag,
  982. .reslimit = Svc::InvalidHandle,
  983. .system_resource_num_pages = static_cast<s32>(metadata.GetSystemResourceSize() / PageSize),
  984. };
  985. // Set the process name.
  986. const auto& name = metadata.GetName();
  987. static_assert(sizeof(params.name) <= sizeof(name));
  988. std::memcpy(params.name.data(), name.data(), sizeof(params.name));
  989. // Initialize for application process.
  990. R_TRY(this->Initialize(params, metadata.GetKernelCapabilities(), res_limit, pool,
  991. aslr_space_start));
  992. // Assign remaining properties.
  993. m_is_hbl = is_hbl;
  994. m_ideal_core_id = metadata.GetMainThreadCore();
  995. // Set up emulation context.
  996. this->InitializeInterfaces();
  997. // We succeeded.
  998. R_SUCCEED();
  999. }
  1000. void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
  1001. const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
  1002. Svc::MemoryPermission permission) {
  1003. m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
  1004. };
  1005. this->GetMemory().WriteBlock(base_addr, code_set.memory.data(), code_set.memory.size());
  1006. ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute);
  1007. ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read);
  1008. ReprotectSegment(code_set.DataSegment(), Svc::MemoryPermission::ReadWrite);
  1009. #ifdef HAS_NCE
  1010. const auto& patch = code_set.PatchSegment();
  1011. if (this->IsApplication() && Settings::IsNceEnabled() && patch.size != 0) {
  1012. auto& buffer = m_kernel.System().DeviceMemory().buffer;
  1013. const auto& code = code_set.CodeSegment();
  1014. buffer.Protect(GetInteger(base_addr + code.addr), code.size,
  1015. Common::MemoryPermission::Read | Common::MemoryPermission::Execute);
  1016. buffer.Protect(GetInteger(base_addr + patch.addr), patch.size,
  1017. Common::MemoryPermission::Read | Common::MemoryPermission::Execute);
  1018. ReprotectSegment(code_set.PatchSegment(), Svc::MemoryPermission::None);
  1019. }
  1020. #endif
  1021. }
  1022. void KProcess::InitializeInterfaces() {
  1023. m_exclusive_monitor =
  1024. Core::MakeExclusiveMonitor(this->GetMemory(), Core::Hardware::NUM_CPU_CORES);
  1025. #ifdef HAS_NCE
  1026. if (this->IsApplication() && Settings::IsNceEnabled()) {
  1027. // Register the scoped JIT handler before creating any NCE instances
  1028. // so that its signal handler will appear first in the signal chain.
  1029. Core::ScopedJitExecution::RegisterHandler();
  1030. for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
  1031. m_arm_interfaces[i] = std::make_unique<Core::ArmNce>(m_kernel.System(), true, i);
  1032. }
  1033. } else
  1034. #endif
  1035. if (this->Is64Bit()) {
  1036. for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
  1037. m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic64>(
  1038. m_kernel.System(), m_kernel.IsMulticore(), this,
  1039. static_cast<Core::DynarmicExclusiveMonitor&>(*m_exclusive_monitor), i);
  1040. }
  1041. } else {
  1042. for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
  1043. m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic32>(
  1044. m_kernel.System(), m_kernel.IsMulticore(), this,
  1045. static_cast<Core::DynarmicExclusiveMonitor&>(*m_exclusive_monitor), i);
  1046. }
  1047. }
  1048. }
  1049. bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) {
  1050. const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
  1051. return wp.type == DebugWatchpointType::None;
  1052. })};
  1053. if (watch == m_watchpoints.end()) {
  1054. return false;
  1055. }
  1056. watch->start_address = addr;
  1057. watch->end_address = addr + size;
  1058. watch->type = type;
  1059. for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
  1060. page += PageSize) {
  1061. m_debug_page_refcounts[page]++;
  1062. this->GetMemory().MarkRegionDebug(page, PageSize, true);
  1063. }
  1064. return true;
  1065. }
  1066. bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) {
  1067. const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) {
  1068. return wp.start_address == addr && wp.end_address == addr + size && wp.type == type;
  1069. })};
  1070. if (watch == m_watchpoints.end()) {
  1071. return false;
  1072. }
  1073. watch->start_address = 0;
  1074. watch->end_address = 0;
  1075. watch->type = DebugWatchpointType::None;
  1076. for (KProcessAddress page = Common::AlignDown(GetInteger(addr), PageSize); page < addr + size;
  1077. page += PageSize) {
  1078. m_debug_page_refcounts[page]--;
  1079. if (!m_debug_page_refcounts[page]) {
  1080. this->GetMemory().MarkRegionDebug(page, PageSize, false);
  1081. }
  1082. }
  1083. return true;
  1084. }
  1085. } // namespace Kernel