Merge pull request #4434 from wwylele/shared-memory-state
Kernel/SharedMemory: set and reset source memory state
This commit is contained in:
		| @@ -136,6 +136,7 @@ void SoftwareKeyboard::Finalize() { | |||||||
|     SendParameter(message); |     SendParameter(message); | ||||||
|  |  | ||||||
|     is_running = false; |     is_running = false; | ||||||
|  |     text_memory = nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| Frontend::KeyboardConfig SoftwareKeyboard::ToFrontendConfig( | Frontend::KeyboardConfig SoftwareKeyboard::ToFrontendConfig( | ||||||
|   | |||||||
| @@ -170,12 +170,12 @@ public: | |||||||
|      * linear heap. |      * linear heap. | ||||||
|      * @param name Optional object name, used for debugging purposes. |      * @param name Optional object name, used for debugging purposes. | ||||||
|      */ |      */ | ||||||
|     SharedPtr<SharedMemory> CreateSharedMemory(Process* owner_process, u32 size, |     ResultVal<SharedPtr<SharedMemory>> CreateSharedMemory(Process* owner_process, u32 size, | ||||||
|                                                MemoryPermission permissions, |                                                           MemoryPermission permissions, | ||||||
|                                                MemoryPermission other_permissions, |                                                           MemoryPermission other_permissions, | ||||||
|                                                VAddr address = 0, |                                                           VAddr address = 0, | ||||||
|                                                MemoryRegion region = MemoryRegion::BASE, |                                                           MemoryRegion region = MemoryRegion::BASE, | ||||||
|                                                std::string name = "Unknown"); |                                                           std::string name = "Unknown"); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Creates a shared memory object from a block of memory managed by an HLE applet. |      * Creates a shared memory object from a block of memory managed by an HLE applet. | ||||||
|   | |||||||
| @@ -17,13 +17,16 @@ SharedMemory::~SharedMemory() { | |||||||
|         kernel.GetMemoryRegion(MemoryRegion::SYSTEM) |         kernel.GetMemoryRegion(MemoryRegion::SYSTEM) | ||||||
|             ->Free(interval.lower(), interval.upper() - interval.lower()); |             ->Free(interval.lower(), interval.upper() - interval.lower()); | ||||||
|     } |     } | ||||||
|  |     if (base_address != 0 && owner_process != nullptr) { | ||||||
|  |         owner_process->vm_manager.ChangeMemoryState(base_address, size, MemoryState::Locked, | ||||||
|  |                                                     VMAPermission::None, MemoryState::Private, | ||||||
|  |                                                     VMAPermission::ReadWrite); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| SharedPtr<SharedMemory> KernelSystem::CreateSharedMemory(Process* owner_process, u32 size, | ResultVal<SharedPtr<SharedMemory>> KernelSystem::CreateSharedMemory( | ||||||
|                                                          MemoryPermission permissions, |     Process* owner_process, u32 size, MemoryPermission permissions, | ||||||
|                                                          MemoryPermission other_permissions, |     MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { | ||||||
|                                                          VAddr address, MemoryRegion region, |  | ||||||
|                                                          std::string name) { |  | ||||||
|     SharedPtr<SharedMemory> shared_memory(new SharedMemory(*this)); |     SharedPtr<SharedMemory> shared_memory(new SharedMemory(*this)); | ||||||
|  |  | ||||||
|     shared_memory->owner_process = owner_process; |     shared_memory->owner_process = owner_process; | ||||||
| @@ -53,13 +56,17 @@ SharedPtr<SharedMemory> KernelSystem::CreateSharedMemory(Process* owner_process, | |||||||
|         auto& vm_manager = shared_memory->owner_process->vm_manager; |         auto& vm_manager = shared_memory->owner_process->vm_manager; | ||||||
|         // The memory is already available and mapped in the owner process. |         // The memory is already available and mapped in the owner process. | ||||||
|  |  | ||||||
|  |         CASCADE_CODE(vm_manager.ChangeMemoryState(address, size, MemoryState::Private, | ||||||
|  |                                                   VMAPermission::ReadWrite, MemoryState::Locked, | ||||||
|  |                                                   SharedMemory::ConvertPermissions(permissions))); | ||||||
|  |  | ||||||
|         auto backing_blocks = vm_manager.GetBackingBlocksForRange(address, size); |         auto backing_blocks = vm_manager.GetBackingBlocksForRange(address, size); | ||||||
|         ASSERT_MSG(backing_blocks.Succeeded(), "Trying to share freed memory"); |         ASSERT(backing_blocks.Succeeded()); // should success after verifying memory state above | ||||||
|         shared_memory->backing_blocks = std::move(backing_blocks).Unwrap(); |         shared_memory->backing_blocks = std::move(backing_blocks).Unwrap(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     shared_memory->base_address = address; |     shared_memory->base_address = address; | ||||||
|     return shared_memory; |     return MakeResult(shared_memory); | ||||||
| } | } | ||||||
|  |  | ||||||
| SharedPtr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet( | SharedPtr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet( | ||||||
|   | |||||||
| @@ -1250,9 +1250,10 @@ ResultCode SVC::CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my | |||||||
|     if (addr == 0 && current_process->flags.shared_device_mem) |     if (addr == 0 && current_process->flags.shared_device_mem) | ||||||
|         region = current_process->flags.memory_region; |         region = current_process->flags.memory_region; | ||||||
|  |  | ||||||
|     shared_memory = kernel.CreateSharedMemory( |     CASCADE_RESULT(shared_memory, | ||||||
|         current_process.get(), size, static_cast<MemoryPermission>(my_permission), |                    kernel.CreateSharedMemory( | ||||||
|         static_cast<MemoryPermission>(other_permission), addr, region); |                        current_process.get(), size, static_cast<MemoryPermission>(my_permission), | ||||||
|  |                        static_cast<MemoryPermission>(other_permission), addr, region)); | ||||||
|     CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(shared_memory))); |     CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(shared_memory))); | ||||||
|  |  | ||||||
|     LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr); |     LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr); | ||||||
|   | |||||||
| @@ -861,10 +861,11 @@ Module::Module(Core::System& system) : system(system) { | |||||||
|     applet_manager = std::make_shared<AppletManager>(system); |     applet_manager = std::make_shared<AppletManager>(system); | ||||||
|  |  | ||||||
|     using Kernel::MemoryPermission; |     using Kernel::MemoryPermission; | ||||||
|     shared_font_mem = |     shared_font_mem = system.Kernel() | ||||||
|         system.Kernel().CreateSharedMemory(nullptr, 0x332000, // 3272 KB |                           .CreateSharedMemory(nullptr, 0x332000, // 3272 KB | ||||||
|                                            MemoryPermission::ReadWrite, MemoryPermission::Read, 0, |                                               MemoryPermission::ReadWrite, MemoryPermission::Read, | ||||||
|                                            Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); |                                               0, Kernel::MemoryRegion::SYSTEM, "APT:SharedFont") | ||||||
|  |                           .Unwrap(); | ||||||
|  |  | ||||||
|     lock = system.Kernel().CreateMutex(false, "APT_U:Lock"); |     lock = system.Kernel().CreateMutex(false, "APT_U:Lock"); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,9 +20,11 @@ void CSND_SND::Initialize(Kernel::HLERequestContext& ctx) { | |||||||
|  |  | ||||||
|     using Kernel::MemoryPermission; |     using Kernel::MemoryPermission; | ||||||
|     mutex = system.Kernel().CreateMutex(false, "CSND:mutex"); |     mutex = system.Kernel().CreateMutex(false, "CSND:mutex"); | ||||||
|     shared_memory = system.Kernel().CreateSharedMemory( |     shared_memory = system.Kernel() | ||||||
|         nullptr, size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0, |                         .CreateSharedMemory(nullptr, size, MemoryPermission::ReadWrite, | ||||||
|         Kernel::MemoryRegion::BASE, "CSND:SharedMemory"); |                                             MemoryPermission::ReadWrite, 0, | ||||||
|  |                                             Kernel::MemoryRegion::BASE, "CSND:SharedMemory") | ||||||
|  |                         .Unwrap(); | ||||||
|  |  | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|   | |||||||
| @@ -810,9 +810,11 @@ GSP_GPU::GSP_GPU(Core::System& system) : ServiceFramework("gsp::Gpu", 2), system | |||||||
|     RegisterHandlers(functions); |     RegisterHandlers(functions); | ||||||
|  |  | ||||||
|     using Kernel::MemoryPermission; |     using Kernel::MemoryPermission; | ||||||
|     shared_memory = system.Kernel().CreateSharedMemory( |     shared_memory = system.Kernel() | ||||||
|         nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0, |                         .CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, | ||||||
|         Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); |                                             MemoryPermission::ReadWrite, 0, | ||||||
|  |                                             Kernel::MemoryRegion::BASE, "GSP:SharedMemory") | ||||||
|  |                         .Unwrap(); | ||||||
|  |  | ||||||
|     first_initialization = true; |     first_initialization = true; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -360,9 +360,11 @@ std::shared_ptr<Module> Module::Interface::GetModule() const { | |||||||
| Module::Module(Core::System& system) : system(system) { | Module::Module(Core::System& system) : system(system) { | ||||||
|     using namespace Kernel; |     using namespace Kernel; | ||||||
|  |  | ||||||
|     shared_mem = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, |     shared_mem = | ||||||
|                                                     MemoryPermission::Read, 0, MemoryRegion::BASE, |         system.Kernel() | ||||||
|                                                     "HID:SharedMemory"); |             .CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, | ||||||
|  |                                 MemoryPermission::Read, 0, MemoryRegion::BASE, "HID:SharedMemory") | ||||||
|  |             .Unwrap(); | ||||||
|  |  | ||||||
|     // Create event handles |     // Create event handles | ||||||
|     event_pad_or_touch_1 = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventPadOrTouch1"); |     event_pad_or_touch_1 = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventPadOrTouch1"); | ||||||
|   | |||||||
| @@ -443,6 +443,17 @@ void HTTP_C::CloseClientCertContext(Kernel::HLERequestContext& ctx) { | |||||||
|     LOG_DEBUG(Service_HTTP, "called, cert_handle={}", cert_handle); |     LOG_DEBUG(Service_HTTP, "called, cert_handle={}", cert_handle); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void HTTP_C::Finalize(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx, 0x39, 0, 0); | ||||||
|  |  | ||||||
|  |     shared_memory = nullptr; | ||||||
|  |  | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |  | ||||||
|  |     LOG_WARNING(Service_HTTP, "(STUBBED) called"); | ||||||
|  | } | ||||||
|  |  | ||||||
| void HTTP_C::DecryptClCertA() { | void HTTP_C::DecryptClCertA() { | ||||||
|     static constexpr u32 iv_length = 16; |     static constexpr u32 iv_length = 16; | ||||||
|  |  | ||||||
| @@ -575,7 +586,7 @@ HTTP_C::HTTP_C() : ServiceFramework("http:C", 32) { | |||||||
|         {0x00360000, nullptr, "ClearDNSCache"}, |         {0x00360000, nullptr, "ClearDNSCache"}, | ||||||
|         {0x00370080, nullptr, "SetKeepAlive"}, |         {0x00370080, nullptr, "SetKeepAlive"}, | ||||||
|         {0x003800C0, nullptr, "SetPostDataTypeSize"}, |         {0x003800C0, nullptr, "SetPostDataTypeSize"}, | ||||||
|         {0x00390000, nullptr, "Finalize"}, |         {0x00390000, &HTTP_C::Finalize, "Finalize"}, | ||||||
|     }; |     }; | ||||||
|     RegisterHandlers(functions); |     RegisterHandlers(functions); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -240,6 +240,13 @@ private: | |||||||
|      */ |      */ | ||||||
|     void CloseClientCertContext(Kernel::HLERequestContext& ctx); |     void CloseClientCertContext(Kernel::HLERequestContext& ctx); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * HTTP_C::Finalize service function | ||||||
|  |      *  Outputs: | ||||||
|  |      *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |      */ | ||||||
|  |     void Finalize(Kernel::HLERequestContext& ctx); | ||||||
|  |  | ||||||
|     void DecryptClCertA(); |     void DecryptClCertA(); | ||||||
|  |  | ||||||
|     Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr; |     Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr; | ||||||
|   | |||||||
| @@ -149,9 +149,11 @@ IR_RST::IR_RST(Core::System& system) : ServiceFramework("ir:rst", 1), system(sys | |||||||
|     using namespace Kernel; |     using namespace Kernel; | ||||||
|     // Note: these two kernel objects are even available before Initialize service function is |     // Note: these two kernel objects are even available before Initialize service function is | ||||||
|     // called. |     // called. | ||||||
|     shared_memory = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, |     shared_memory = | ||||||
|                                                        MemoryPermission::Read, 0, |         system.Kernel() | ||||||
|                                                        MemoryRegion::BASE, "IRRST:SharedMemory"); |             .CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, | ||||||
|  |                                 MemoryPermission::Read, 0, MemoryRegion::BASE, "IRRST:SharedMemory") | ||||||
|  |             .Unwrap(); | ||||||
|     update_event = system.Kernel().CreateEvent(ResetType::OneShot, "IRRST:UpdateEvent"); |     update_event = system.Kernel().CreateEvent(ResetType::OneShot, "IRRST:UpdateEvent"); | ||||||
|  |  | ||||||
|     update_callback_id = system.CoreTiming().RegisterEvent( |     update_callback_id = system.CoreTiming().RegisterEvent( | ||||||
|   | |||||||
| @@ -52,6 +52,7 @@ struct MIC_U::Impl { | |||||||
|     void UnmapSharedMem(Kernel::HLERequestContext& ctx) { |     void UnmapSharedMem(Kernel::HLERequestContext& ctx) { | ||||||
|         IPC::RequestParser rp{ctx, 0x02, 0, 0}; |         IPC::RequestParser rp{ctx, 0x02, 0, 0}; | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  |         shared_memory = nullptr; | ||||||
|         rb.Push(RESULT_SUCCESS); |         rb.Push(RESULT_SUCCESS); | ||||||
|         LOG_WARNING(Service_MIC, "called"); |         LOG_WARNING(Service_MIC, "called"); | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user