diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 7140d0db8b..6f98fbc082 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -218,6 +218,7 @@ add_library(core STATIC
     hle/kernel/k_session.h
     hle/kernel/k_shared_memory.cpp
     hle/kernel/k_shared_memory.h
+    hle/kernel/k_shared_memory_info.h
     hle/kernel/k_slab_heap.h
     hle/kernel/k_spin_lock.cpp
     hle/kernel/k_spin_lock.h
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 8ead1a769d..211157ccc6 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -23,6 +23,7 @@
 #include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/k_scoped_resource_reservation.h"
 #include "core/hle/kernel/k_shared_memory.h"
+#include "core/hle/kernel/k_shared_memory_info.h"
 #include "core/hle/kernel/k_slab_heap.h"
 #include "core/hle/kernel/k_thread.h"
 #include "core/hle/kernel/kernel.h"
@@ -254,10 +255,26 @@ ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAdd
     // Lock ourselves, to prevent concurrent access.
     KScopedLightLock lk(state_lock);
 
-    // TODO(bunnei): Manage KSharedMemoryInfo list here.
+    // Try to find an existing info for the memory.
+    KSharedMemoryInfo* shemen_info = nullptr;
+    const auto iter = std::find_if(
+        shared_memory_list.begin(), shared_memory_list.end(),
+        [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
+    if (iter != shared_memory_list.end()) {
+        shemen_info = *iter;
+    }
 
-    // Open a reference to the shared memory.
+    if (shemen_info == nullptr) {
+        shemen_info = KSharedMemoryInfo::Allocate(kernel);
+        R_UNLESS(shemen_info != nullptr, ResultOutOfMemory);
+
+        shemen_info->Initialize(shmem);
+        shared_memory_list.push_back(shemen_info);
+    }
+
+    // Open a reference to the shared memory and its info.
     shmem->Open();
+    shemen_info->Open();
 
     return ResultSuccess;
 }
@@ -267,7 +284,20 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a
     // Lock ourselves, to prevent concurrent access.
     KScopedLightLock lk(state_lock);
 
-    // TODO(bunnei): Manage KSharedMemoryInfo list here.
+    KSharedMemoryInfo* shemen_info = nullptr;
+    const auto iter = std::find_if(
+        shared_memory_list.begin(), shared_memory_list.end(),
+        [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; });
+    if (iter != shared_memory_list.end()) {
+        shemen_info = *iter;
+    }
+
+    ASSERT(shemen_info != nullptr);
+
+    if (shemen_info->Close()) {
+        shared_memory_list.erase(iter);
+        KSharedMemoryInfo::Free(kernel, shemen_info);
+    }
 
     // Close a reference to the shared memory.
     shmem->Close();
@@ -412,6 +442,24 @@ void KProcess::Finalize() {
     // Finalize the handle table and close any open handles.
     handle_table.Finalize();
 
+    // Free all shared memory infos.
+    {
+        auto it = shared_memory_list.begin();
+        while (it != shared_memory_list.end()) {
+            KSharedMemoryInfo* info = *it;
+            KSharedMemory* shmem = info->GetSharedMemory();
+
+            while (!info->Close()) {
+                shmem->Close();
+            }
+
+            shmem->Close();
+
+            it = shared_memory_list.erase(it);
+            KSharedMemoryInfo::Free(kernel, info);
+        }
+    }
+
     // Perform inherited finalization.
     KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize();
 }
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index a03c074fb8..1a53e2be75 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -34,6 +34,7 @@ class KernelCore;
 class KPageTable;
 class KResourceLimit;
 class KThread;
+class KSharedMemoryInfo;
 class TLSPage;
 
 struct CodeSet;
@@ -448,6 +449,9 @@ private:
     /// List of threads that are running with this process as their owner.
     std::list<const KThread*> thread_list;
 
+    /// List of shared memory that are running with this process as their owner.
+    std::list<KSharedMemoryInfo*> shared_memory_list;
+
     /// Address of the top of the main thread's stack
     VAddr main_thread_stack_top{};
 
diff --git a/src/core/hle/kernel/k_shared_memory_info.h b/src/core/hle/kernel/k_shared_memory_info.h
new file mode 100644
index 0000000000..bf97a01841
--- /dev/null
+++ b/src/core/hle/kernel/k_shared_memory_info.h
@@ -0,0 +1,46 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include <boost/intrusive/list.hpp>
+
+#include "common/assert.h"
+#include "core/hle/kernel/slab_helpers.h"
+
+namespace Kernel {
+
+class KSharedMemory;
+
+class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>,
+                                public boost::intrusive::list_base_hook<> {
+
+public:
+    explicit KSharedMemoryInfo() = default;
+
+    constexpr void Initialize(KSharedMemory* shmem) {
+        shared_memory = shmem;
+    }
+
+    constexpr KSharedMemory* GetSharedMemory() const {
+        return shared_memory;
+    }
+
+    constexpr void Open() {
+        ++reference_count;
+    }
+
+    constexpr bool Close() {
+        return (--reference_count) == 0;
+    }
+
+private:
+    KSharedMemory* shared_memory{};
+    size_t reference_count{};
+};
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 901d43da9c..b6658b4374 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -49,6 +49,7 @@ class KScheduler;
 class KServerSession;
 class KSession;
 class KSharedMemory;
+class KSharedMemoryInfo;
 class KThread;
 class KTransferMemory;
 class KWritableEvent;
@@ -309,6 +310,8 @@ public:
             return slab_heap_container->session;
         } else if constexpr (std::is_same_v<T, KSharedMemory>) {
             return slab_heap_container->shared_memory;
+        } else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) {
+            return slab_heap_container->shared_memory_info;
         } else if constexpr (std::is_same_v<T, KThread>) {
             return slab_heap_container->thread;
         } else if constexpr (std::is_same_v<T, KTransferMemory>) {
@@ -362,6 +365,7 @@ private:
         KSlabHeap<KResourceLimit> resource_limit;
         KSlabHeap<KSession> session;
         KSlabHeap<KSharedMemory> shared_memory;
+        KSlabHeap<KSharedMemoryInfo> shared_memory_info;
         KSlabHeap<KThread> thread;
         KSlabHeap<KTransferMemory> transfer_memory;
         KSlabHeap<KWritableEvent> writeable_event;