diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 6456ae6346..f598bd6348 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -804,6 +804,8 @@ add_library(core STATIC
     hle/service/nvnflinger/graphic_buffer_producer.h
     hle/service/nvnflinger/hos_binder_driver_server.cpp
     hle/service/nvnflinger/hos_binder_driver_server.h
+    hle/service/nvnflinger/hos_binder_driver.cpp
+    hle/service/nvnflinger/hos_binder_driver.h
     hle/service/nvnflinger/hardware_composer.cpp
     hle/service/nvnflinger/hardware_composer.h
     hle/service/nvnflinger/hwc_layer.h
@@ -961,8 +963,6 @@ add_library(core STATIC
     hle/service/vi/application_display_service.h
     hle/service/vi/application_root_service.cpp
     hle/service/vi/application_root_service.h
-    hle/service/vi/hos_binder_driver.cpp
-    hle/service/vi/hos_binder_driver.h
     hle/service/vi/manager_display_service.cpp
     hle/service/vi/manager_display_service.h
     hle/service/vi/manager_root_service.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index bd5f11d535..60e2efddcc 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -458,11 +458,9 @@ struct System::Impl {
             gpu_core->NotifyShutdown();
         }
 
+        core_timing.SyncPause(false);
         Network::CancelPendingSocketOperations();
         kernel.SuspendEmulation(true);
-        if (services) {
-            services->KillNVNFlinger();
-        }
         kernel.CloseServices();
         kernel.ShutdownCores();
         applet_manager.Reset();
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 9dc710ba90..8c4e14f08c 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -8,13 +8,13 @@
 
 namespace Service::AM {
 
-void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
+void LoopProcess(Core::System& system) {
     auto server_manager = std::make_unique<ServerManager>(system);
 
-    server_manager->RegisterNamedService(
-        "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, nvnflinger));
-    server_manager->RegisterNamedService(
-        "appletOE", std::make_shared<IApplicationProxyService>(system, nvnflinger));
+    server_manager->RegisterNamedService("appletAE",
+                                         std::make_shared<IAllSystemAppletProxiesService>(system));
+    server_manager->RegisterNamedService("appletOE",
+                                         std::make_shared<IApplicationProxyService>(system));
     ServerManager::RunServer(std::move(server_manager));
 }
 
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 4a2d797bd5..1afe253aed 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -7,12 +7,8 @@ namespace Core {
 class System;
 }
 
-namespace Service::Nvnflinger {
-class Nvnflinger;
-}
-
 namespace Service::AM {
 
-void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system);
+void LoopProcess(Core::System& system);
 
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/display_layer_manager.cpp b/src/core/hle/service/am/display_layer_manager.cpp
index 50674c3259..6cf3c369c3 100644
--- a/src/core/hle/service/am/display_layer_manager.cpp
+++ b/src/core/hle/service/am/display_layer_manager.cpp
@@ -1,9 +1,12 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#include "core/core.h"
 #include "core/hle/service/am/display_layer_manager.h"
 #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
+#include "core/hle/service/nvnflinger/hos_binder_driver.h"
 #include "core/hle/service/nvnflinger/nvnflinger.h"
+#include "core/hle/service/sm/sm.h"
 #include "core/hle/service/vi/vi_results.h"
 
 namespace Service::AM {
@@ -13,10 +16,12 @@ DisplayLayerManager::~DisplayLayerManager() {
     this->Finalize();
 }
 
-void DisplayLayerManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process,
+void DisplayLayerManager::Initialize(Core::System& system, Kernel::KProcess* process,
                                      AppletId applet_id, LibraryAppletMode mode) {
     m_process = process;
-    m_nvnflinger = nvnflinger;
+    m_surface_flinger = system.ServiceManager()
+                            .GetService<Nvnflinger::IHOSBinderDriver>("dispdrv", true)
+                            ->GetSurfaceFlinger();
     m_system_shared_buffer_id = 0;
     m_system_shared_layer_id = 0;
     m_applet_id = applet_id;
@@ -26,36 +31,36 @@ void DisplayLayerManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel:
 }
 
 void DisplayLayerManager::Finalize() {
-    if (!m_nvnflinger) {
+    if (!m_surface_flinger) {
         return;
     }
 
     // Clean up managed layers.
     for (const auto& layer : m_managed_display_layers) {
-        m_nvnflinger->DestroyLayer(layer);
+        m_surface_flinger->DestroyLayer(layer);
     }
 
     for (const auto& layer : m_managed_display_recording_layers) {
-        m_nvnflinger->DestroyLayer(layer);
+        m_surface_flinger->DestroyLayer(layer);
     }
 
     // Clean up shared layers.
     if (m_buffer_sharing_enabled) {
-        m_nvnflinger->GetSystemBufferManager().Finalize(m_process);
+        m_surface_flinger->GetSystemBufferManager().Finalize(m_process);
     }
 
-    m_nvnflinger = nullptr;
+    m_surface_flinger = nullptr;
 }
 
 Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer) {
-    R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed);
+    R_UNLESS(m_surface_flinger != nullptr, VI::ResultOperationFailed);
 
     // TODO(Subv): Find out how AM determines the display to use, for now just
     // create the layer in the Default display.
-    const auto display_id = m_nvnflinger->OpenDisplay("Default");
-    const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
+    const auto display_id = m_surface_flinger->OpenDisplay("Default");
+    const auto layer_id = m_surface_flinger->CreateLayer(*display_id);
 
-    m_nvnflinger->SetLayerVisibility(*layer_id, m_visible);
+    m_surface_flinger->SetLayerVisibility(*layer_id, m_visible);
     m_managed_display_layers.emplace(*layer_id);
 
     *out_layer = *layer_id;
@@ -65,7 +70,7 @@ Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer) {
 
 Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer,
                                                                u64* out_recording_layer) {
-    R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed);
+    R_UNLESS(m_surface_flinger != nullptr, VI::ResultOperationFailed);
 
     // TODO(Subv): Find out how AM determines the display to use, for now just
     // create the layer in the Default display.
@@ -74,10 +79,10 @@ Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer,
     // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
     // side effects.
     // TODO: Support multiple layers
-    const auto display_id = m_nvnflinger->OpenDisplay("Default");
-    const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
+    const auto display_id = m_surface_flinger->OpenDisplay("Default");
+    const auto layer_id = m_surface_flinger->CreateLayer(*display_id);
 
-    m_nvnflinger->SetLayerVisibility(*layer_id, m_visible);
+    m_surface_flinger->SetLayerVisibility(*layer_id, m_visible);
     m_managed_display_layers.emplace(*layer_id);
 
     *out_layer = *layer_id;
@@ -91,19 +96,19 @@ Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
     R_SUCCEED_IF(m_buffer_sharing_enabled);
 
     // Ensure we can access shared layers.
-    R_UNLESS(m_nvnflinger != nullptr, VI::ResultOperationFailed);
+    R_UNLESS(m_surface_flinger != nullptr, VI::ResultOperationFailed);
     R_UNLESS(m_applet_id != AppletId::Application, VI::ResultPermissionDenied);
 
     // Create the shared layer.
     const auto blend =
         m_blending_enabled ? Nvnflinger::LayerBlending::Coverage : Nvnflinger::LayerBlending::None;
-    const auto display_id = m_nvnflinger->OpenDisplay("Default").value();
-    R_TRY(m_nvnflinger->GetSystemBufferManager().Initialize(
+    const auto display_id = m_surface_flinger->OpenDisplay("Default").value();
+    R_TRY(m_surface_flinger->GetSystemBufferManager().Initialize(
         m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blend));
 
     // We succeeded, so set up remaining state.
     m_buffer_sharing_enabled = true;
-    m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
+    m_surface_flinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
     R_SUCCEED();
 }
 
@@ -124,13 +129,13 @@ void DisplayLayerManager::SetWindowVisibility(bool visible) {
 
     m_visible = visible;
 
-    if (m_nvnflinger) {
+    if (m_surface_flinger) {
         if (m_system_shared_layer_id) {
-            m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
+            m_surface_flinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
         }
 
         for (const auto layer_id : m_managed_display_layers) {
-            m_nvnflinger->SetLayerVisibility(layer_id, m_visible);
+            m_surface_flinger->SetLayerVisibility(layer_id, m_visible);
         }
     }
 }
@@ -142,7 +147,7 @@ bool DisplayLayerManager::GetWindowVisibility() const {
 Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written,
                                                      s32* out_fbshare_layer_index) {
     R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied);
-    R_RETURN(m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer(
+    R_RETURN(m_surface_flinger->GetSystemBufferManager().WriteAppletCaptureBuffer(
         out_was_written, out_fbshare_layer_index));
 }
 
diff --git a/src/core/hle/service/am/display_layer_manager.h b/src/core/hle/service/am/display_layer_manager.h
index 45023a88c4..92ab9399fa 100644
--- a/src/core/hle/service/am/display_layer_manager.h
+++ b/src/core/hle/service/am/display_layer_manager.h
@@ -9,6 +9,10 @@
 #include "core/hle/result.h"
 #include "core/hle/service/am/am_types.h"
 
+namespace Core {
+class System;
+}
+
 namespace Kernel {
 class KProcess;
 }
@@ -24,8 +28,8 @@ public:
     explicit DisplayLayerManager();
     ~DisplayLayerManager();
 
-    void Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process,
-                    AppletId applet_id, LibraryAppletMode mode);
+    void Initialize(Core::System& system, Kernel::KProcess* process, AppletId applet_id,
+                    LibraryAppletMode mode);
     void Finalize();
 
     Result CreateManagedDisplayLayer(u64* out_layer);
@@ -42,7 +46,7 @@ public:
 
 private:
     Kernel::KProcess* m_process{};
-    Nvnflinger::Nvnflinger* m_nvnflinger{};
+    std::shared_ptr<Nvnflinger::Nvnflinger> m_surface_flinger{};
     std::set<u64> m_managed_display_layers{};
     std::set<u64> m_managed_display_recording_layers{};
     u64 m_system_shared_buffer_id{};
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
index eebd90ba2f..21747783ae 100644
--- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
+++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
@@ -10,9 +10,8 @@
 
 namespace Service::AM {
 
-IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_,
-                                                               Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "appletAE"}, m_nvnflinger{nvnflinger} {
+IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_)
+    : ServiceFramework{system_, "appletAE"} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
@@ -37,8 +36,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(
     LOG_DEBUG(Service_AM, "called");
 
     if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
-        *out_system_applet_proxy = std::make_shared<ISystemAppletProxy>(
-            system, applet, process_handle.Get(), m_nvnflinger);
+        *out_system_applet_proxy =
+            std::make_shared<ISystemAppletProxy>(system, applet, process_handle.Get());
         R_SUCCEED();
     } else {
         UNIMPLEMENTED();
@@ -53,8 +52,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
     LOG_DEBUG(Service_AM, "called");
 
     if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
-        *out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>(
-            system, applet, process_handle.Get(), m_nvnflinger);
+        *out_library_applet_proxy =
+            std::make_shared<ILibraryAppletProxy>(system, applet, process_handle.Get());
         R_SUCCEED();
     } else {
         UNIMPLEMENTED();
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h
index 38b1ca2eac..0e2dcb86d9 100644
--- a/src/core/hle/service/am/service/all_system_applet_proxies_service.h
+++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h
@@ -8,10 +8,6 @@
 
 namespace Service {
 
-namespace Nvnflinger {
-class Nvnflinger;
-}
-
 namespace AM {
 
 struct Applet;
@@ -22,8 +18,7 @@ class ISystemAppletProxy;
 class IAllSystemAppletProxiesService final
     : public ServiceFramework<IAllSystemAppletProxiesService> {
 public:
-    explicit IAllSystemAppletProxiesService(Core::System& system_,
-                                            Nvnflinger::Nvnflinger& nvnflinger);
+    explicit IAllSystemAppletProxiesService(Core::System& system_);
     ~IAllSystemAppletProxiesService() override;
 
 private:
@@ -40,7 +35,6 @@ private:
 
 private:
     std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
-    Nvnflinger::Nvnflinger& m_nvnflinger;
 };
 
 } // namespace AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 776f4552b3..19d6a3b89c 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -17,9 +17,9 @@
 namespace Service::AM {
 
 IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
-                                     Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "IApplicationProxy"},
-      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+                                     Kernel::KProcess* process)
+    : ServiceFramework{system_, "IApplicationProxy"}, m_process{process}, m_applet{
+                                                                              std::move(applet)} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@@ -77,8 +77,7 @@ Result IApplicationProxy::GetWindowController(
 Result IApplicationProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller =
-        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
+    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/application_proxy.h b/src/core/hle/service/am/service/application_proxy.h
index 1ebc593ba8..6da350df72 100644
--- a/src/core/hle/service/am/service/application_proxy.h
+++ b/src/core/hle/service/am/service/application_proxy.h
@@ -22,7 +22,7 @@ class IWindowController;
 class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
 public:
     explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
-                               Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+                               Kernel::KProcess* process);
     ~IApplicationProxy();
 
 private:
@@ -40,7 +40,6 @@ private:
         Out<SharedPointer<IApplicationFunctions>> out_application_functions);
 
 private:
-    Nvnflinger::Nvnflinger& m_nvnflinger;
     Kernel::KProcess* const m_process;
     const std::shared_ptr<Applet> m_applet;
 };
diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp
index 36d4478df7..fd66e77b96 100644
--- a/src/core/hle/service/am/service/application_proxy_service.cpp
+++ b/src/core/hle/service/am/service/application_proxy_service.cpp
@@ -10,9 +10,8 @@
 
 namespace Service::AM {
 
-IApplicationProxyService::IApplicationProxyService(Core::System& system_,
-                                                   Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "appletOE"}, m_nvnflinger{nvnflinger} {
+IApplicationProxyService::IApplicationProxyService(Core::System& system_)
+    : ServiceFramework{system_, "appletOE"} {
     static const FunctionInfo functions[] = {
         {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"},
     };
@@ -28,7 +27,7 @@ Result IApplicationProxyService::OpenApplicationProxy(
 
     if (const auto applet = this->GetAppletFromProcessId(pid)) {
         *out_application_proxy =
-            std::make_shared<IApplicationProxy>(system, applet, process_handle.Get(), m_nvnflinger);
+            std::make_shared<IApplicationProxy>(system, applet, process_handle.Get());
         R_SUCCEED();
     } else {
         UNIMPLEMENTED();
diff --git a/src/core/hle/service/am/service/application_proxy_service.h b/src/core/hle/service/am/service/application_proxy_service.h
index 1c1d32d0b9..8efafa31ac 100644
--- a/src/core/hle/service/am/service/application_proxy_service.h
+++ b/src/core/hle/service/am/service/application_proxy_service.h
@@ -8,10 +8,6 @@
 
 namespace Service {
 
-namespace Nvnflinger {
-class Nvnflinger;
-}
-
 namespace AM {
 
 struct Applet;
@@ -19,7 +15,7 @@ class IApplicationProxy;
 
 class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> {
 public:
-    explicit IApplicationProxyService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger);
+    explicit IApplicationProxyService(Core::System& system_);
     ~IApplicationProxyService() override;
 
 private:
@@ -28,7 +24,6 @@ private:
 
 private:
     std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
-    Nvnflinger::Nvnflinger& m_nvnflinger;
 };
 
 } // namespace AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index bcb44a71cb..58e7093470 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -19,10 +19,9 @@
 namespace Service::AM {
 
 ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
-                                         Kernel::KProcess* process,
-                                         Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "ILibraryAppletProxy"},
-      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+                                         Kernel::KProcess* process)
+    : ServiceFramework{system_, "ILibraryAppletProxy"}, m_process{process}, m_applet{
+                                                                                std::move(applet)} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@@ -83,8 +82,7 @@ Result ILibraryAppletProxy::GetWindowController(
 Result ILibraryAppletProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller =
-        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
+    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/library_applet_proxy.h b/src/core/hle/service/am/service/library_applet_proxy.h
index 23e64e2959..7d0714b851 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.h
+++ b/src/core/hle/service/am/service/library_applet_proxy.h
@@ -25,7 +25,7 @@ class IWindowController;
 class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
 public:
     explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
-                                 Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+                                 Kernel::KProcess* process);
     ~ILibraryAppletProxy();
 
 private:
@@ -47,7 +47,6 @@ private:
     Result GetGlobalStateController(
         Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
 
-    Nvnflinger::Nvnflinger& m_nvnflinger;
     Kernel::KProcess* const m_process;
     const std::shared_ptr<Applet> m_applet;
 };
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp
index 6b77e423a4..06314407c5 100644
--- a/src/core/hle/service/am/service/self_controller.cpp
+++ b/src/core/hle/service/am/service/self_controller.cpp
@@ -15,9 +15,9 @@
 namespace Service::AM {
 
 ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
-                                 Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "ISelfController"}, m_nvnflinger{nvnflinger}, m_process{process},
-      m_applet{std::move(applet)} {
+                                 Kernel::KProcess* process)
+    : ServiceFramework{system_, "ISelfController"}, m_process{process}, m_applet{
+                                                                            std::move(applet)} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, D<&ISelfController::Exit>, "Exit"},
@@ -74,7 +74,7 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet>
     RegisterHandlers(functions);
 
     std::scoped_lock lk{m_applet->lock};
-    m_applet->display_layer_manager.Initialize(&m_nvnflinger, m_process, m_applet->applet_id,
+    m_applet->display_layer_manager.Initialize(system, m_process, m_applet->applet_id,
                                                m_applet->library_applet_mode);
 }
 
diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h
index 01fa381a35..eca083cfe5 100644
--- a/src/core/hle/service/am/service/self_controller.h
+++ b/src/core/hle/service/am/service/self_controller.h
@@ -23,7 +23,7 @@ struct Applet;
 class ISelfController final : public ServiceFramework<ISelfController> {
 public:
     explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
-                             Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+                             Kernel::KProcess* process);
     ~ISelfController() override;
 
 private:
@@ -64,7 +64,6 @@ private:
     Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
     Result SetRecordVolumeMuted(bool muted);
 
-    Nvnflinger::Nvnflinger& m_nvnflinger;
     Kernel::KProcess* const m_process;
     const std::shared_ptr<Applet> m_applet;
 };
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 5ec509d2e0..d1871ef9b7 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -19,10 +19,9 @@
 namespace Service::AM {
 
 ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
-                                       Kernel::KProcess* process,
-                                       Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "ISystemAppletProxy"},
-      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+                                       Kernel::KProcess* process)
+    : ServiceFramework{system_, "ISystemAppletProxy"}, m_process{process}, m_applet{
+                                                                               std::move(applet)} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@@ -83,8 +82,7 @@ Result ISystemAppletProxy::GetWindowController(
 Result ISystemAppletProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller =
-        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
+    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/system_applet_proxy.h b/src/core/hle/service/am/service/system_applet_proxy.h
index 3d50403158..67cd50e035 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.h
+++ b/src/core/hle/service/am/service/system_applet_proxy.h
@@ -25,7 +25,7 @@ class IWindowController;
 class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
 public:
     explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet,
-                                Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+                                Kernel::KProcess* process);
     ~ISystemAppletProxy();
 
 private:
@@ -46,7 +46,6 @@ private:
     Result GetGlobalStateController(
         Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
 
-    Nvnflinger::Nvnflinger& m_nvnflinger;
     Kernel::KProcess* const m_process;
     const std::shared_ptr<Applet> m_applet;
 };
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index cb256e5b49..03eb507b98 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -42,7 +42,7 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) {
     module.service_context.CloseEvent(event);
 }
 
-void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
+void LoopProcess(Core::System& system) {
     auto server_manager = std::make_unique<ServerManager>(system);
     auto module = std::make_shared<Module>(system);
     const auto NvdrvInterfaceFactoryForApplication = [&, module] {
@@ -62,7 +62,6 @@ void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
     server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules);
     server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactoryForTesting);
     server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system));
-    nvnflinger.SetNVDrvInstance(module);
     ServerManager::RunServer(std::move(server_manager));
 }
 
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index c594f0e5e1..154c389515 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -118,6 +118,6 @@ private:
     std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
 };
 
-void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system);
+void LoopProcess(Core::System& system);
 
 } // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
index ffe72f2817..241006cc89 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
@@ -263,8 +263,10 @@ NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char*
 }
 
 NVDRV::~NVDRV() {
-    auto& container = nvdrv->GetContainer();
-    container.CloseSession(session_id);
+    if (is_initialized) {
+        auto& container = nvdrv->GetContainer();
+        container.CloseSession(session_id);
+    }
 }
 
 } // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index f2195ae1e1..c72f925979 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
@@ -16,6 +16,10 @@ public:
     explicit NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name);
     ~NVDRV() override;
 
+    std::shared_ptr<Module> GetModule() const {
+        return nvdrv;
+    }
+
 private:
     void Open(HLERequestContext& ctx);
     void Ioctl1(HLERequestContext& ctx);
diff --git a/src/core/hle/service/vi/hos_binder_driver.cpp b/src/core/hle/service/nvnflinger/hos_binder_driver.cpp
similarity index 78%
rename from src/core/hle/service/vi/hos_binder_driver.cpp
rename to src/core/hle/service/nvnflinger/hos_binder_driver.cpp
index ba03172456..e09d720477 100644
--- a/src/core/hle/service/vi/hos_binder_driver.cpp
+++ b/src/core/hle/service/nvnflinger/hos_binder_driver.cpp
@@ -3,13 +3,16 @@
 
 #include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/nvnflinger/binder.h"
+#include "core/hle/service/nvnflinger/hos_binder_driver.h"
 #include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
-#include "core/hle/service/vi/hos_binder_driver.h"
 
-namespace Service::VI {
+namespace Service::Nvnflinger {
 
-IHOSBinderDriver::IHOSBinderDriver(Core::System& system_, Nvnflinger::HosBinderDriverServer& server)
-    : ServiceFramework{system_, "IHOSBinderDriver"}, m_server(server) {
+IHOSBinderDriver::IHOSBinderDriver(Core::System& system_,
+                                   std::shared_ptr<HosBinderDriverServer> server,
+                                   std::shared_ptr<Nvnflinger> surface_flinger)
+    : ServiceFramework{system_, "IHOSBinderDriver"}, m_server(server),
+      m_surface_flinger(surface_flinger) {
     static const FunctionInfo functions[] = {
         {0, C<&IHOSBinderDriver::TransactParcel>, "TransactParcel"},
         {1, C<&IHOSBinderDriver::AdjustRefcount>, "AdjustRefcount"},
@@ -27,7 +30,7 @@ Result IHOSBinderDriver::TransactParcel(s32 binder_id, android::TransactionId tr
                                         u32 flags) {
     LOG_DEBUG(Service_VI, "called. id={} transaction={}, flags={}", binder_id, transaction_id,
               flags);
-    m_server.TryGetProducer(binder_id)->Transact(transaction_id, flags, parcel_data, parcel_reply);
+    m_server->TryGetProducer(binder_id)->Transact(transaction_id, flags, parcel_data, parcel_reply);
     R_SUCCEED();
 }
 
@@ -39,7 +42,7 @@ Result IHOSBinderDriver::AdjustRefcount(s32 binder_id, s32 addval, s32 type) {
 Result IHOSBinderDriver::GetNativeHandle(s32 binder_id, u32 type_id,
                                          OutCopyHandle<Kernel::KReadableEvent> out_handle) {
     LOG_WARNING(Service_VI, "(STUBBED) called id={}, type_id={}", binder_id, type_id);
-    *out_handle = &m_server.TryGetProducer(binder_id)->GetNativeHandle();
+    *out_handle = &m_server->TryGetProducer(binder_id)->GetNativeHandle();
     R_SUCCEED();
 }
 
@@ -50,4 +53,4 @@ Result IHOSBinderDriver::TransactParcelAuto(s32 binder_id, android::TransactionI
     R_RETURN(this->TransactParcel(binder_id, transaction_id, parcel_data, parcel_reply, flags));
 }
 
-} // namespace Service::VI
+} // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/vi/hos_binder_driver.h b/src/core/hle/service/nvnflinger/hos_binder_driver.h
similarity index 68%
rename from src/core/hle/service/vi/hos_binder_driver.h
rename to src/core/hle/service/nvnflinger/hos_binder_driver.h
index ed6e8cdbee..aa9e3121a8 100644
--- a/src/core/hle/service/vi/hos_binder_driver.h
+++ b/src/core/hle/service/nvnflinger/hos_binder_driver.h
@@ -5,13 +5,21 @@
 #include "core/hle/service/nvnflinger/binder.h"
 #include "core/hle/service/service.h"
 
-namespace Service::VI {
+namespace Service::Nvnflinger {
+
+class HosBinderDriverServer;
+class Nvnflinger;
 
 class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> {
 public:
-    explicit IHOSBinderDriver(Core::System& system_, Nvnflinger::HosBinderDriverServer& server);
+    explicit IHOSBinderDriver(Core::System& system_, std::shared_ptr<HosBinderDriverServer> server,
+                              std::shared_ptr<Nvnflinger> surface_flinger);
     ~IHOSBinderDriver() override;
 
+    std::shared_ptr<Nvnflinger> GetSurfaceFlinger() {
+        return m_surface_flinger;
+    }
+
 private:
     Result TransactParcel(s32 binder_id, android::TransactionId transaction_id,
                           InBuffer<BufferAttr_HipcMapAlias> parcel_data,
@@ -24,7 +32,8 @@ private:
                               OutBuffer<BufferAttr_HipcAutoSelect> parcel_reply, u32 flags);
 
 private:
-    Nvnflinger::HosBinderDriverServer& m_server;
+    const std::shared_ptr<HosBinderDriverServer> m_server;
+    const std::shared_ptr<Nvnflinger> m_surface_flinger;
 };
 
-} // namespace Service::VI
+} // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index 687ccc9f9e..cd8062a2b6 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -1,33 +1,24 @@
 // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-#include <algorithm>
-#include <optional>
-
-#include "common/assert.h"
-#include "common/logging/log.h"
 #include "common/microprofile.h"
 #include "common/scope_exit.h"
 #include "common/settings.h"
-#include "common/thread.h"
 #include "core/core.h"
 #include "core/core_timing.h"
-#include "core/hle/kernel/k_readable_event.h"
 #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
 #include "core/hle/service/nvdrv/nvdrv.h"
-#include "core/hle/service/nvnflinger/buffer_item_consumer.h"
-#include "core/hle/service/nvnflinger/buffer_queue_core.h"
+#include "core/hle/service/nvdrv/nvdrv_interface.h"
 #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
 #include "core/hle/service/nvnflinger/hardware_composer.h"
+#include "core/hle/service/nvnflinger/hos_binder_driver.h"
 #include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
 #include "core/hle/service/nvnflinger/nvnflinger.h"
-#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
+#include "core/hle/service/server_manager.h"
+#include "core/hle/service/sm/sm.h"
 #include "core/hle/service/vi/display/vi_display.h"
 #include "core/hle/service/vi/layer/vi_layer.h"
 #include "core/hle/service/vi/vi_results.h"
-#include "video_core/gpu.h"
-#include "video_core/host1x/host1x.h"
-#include "video_core/host1x/syncpoint_manager.h"
 
 namespace Service::Nvnflinger {
 
@@ -47,6 +38,11 @@ void Nvnflinger::SplitVSync(std::stop_token stop_token) {
     while (!stop_token.stop_requested()) {
         vsync_signal.Wait();
 
+        if (system.IsShuttingDown()) {
+            ShutdownLayers();
+            return;
+        }
+
         const auto lock_guard = Lock();
 
         if (!is_abandoned) {
@@ -65,6 +61,9 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
     displays.emplace_back(4, "Null", hos_binder_driver_server, service_context, system);
     guard = std::make_shared<std::mutex>();
 
+    nvdrv = system.ServiceManager().GetService<Nvidia::NVDRV>("nvdrv:s", true)->GetModule();
+    disp_fd = nvdrv->Open("/dev/nvdisp_disp0", {});
+
     // Schedule the screen composition events
     multi_composition_event = Core::Timing::CreateEvent(
         "ScreenComposition",
@@ -110,22 +109,12 @@ Nvnflinger::~Nvnflinger() {
 
 void Nvnflinger::ShutdownLayers() {
     // Abandon consumers.
-    {
-        const auto lock_guard = Lock();
-        for (auto& display : displays) {
-            display.Abandon();
-        }
-
-        is_abandoned = true;
+    const auto lock_guard = Lock();
+    for (auto& display : displays) {
+        display.Abandon();
     }
 
-    // Join the vsync thread, if it exists.
-    vsync_thread = {};
-}
-
-void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
-    nvdrv = std::move(instance);
-    disp_fd = nvdrv->Open("/dev/nvdisp_disp0", {});
+    is_abandoned = true;
 }
 
 std::optional<u64> Nvnflinger::OpenDisplay(std::string_view name) {
@@ -332,4 +321,14 @@ FbShareBufferManager& Nvnflinger::GetSystemBufferManager() {
     return *system_buffer_manager;
 }
 
+void LoopProcess(Core::System& system) {
+    const auto binder_server = std::make_shared<HosBinderDriverServer>(system);
+    const auto surface_flinger = std::make_shared<Nvnflinger>(system, *binder_server);
+
+    auto server_manager = std::make_unique<ServerManager>(system);
+    server_manager->RegisterNamedService(
+        "dispdrv", std::make_shared<IHOSBinderDriver>(system, binder_server, surface_flinger));
+    ServerManager::RunServer(std::move(server_manager));
+}
+
 } // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h
index 4cf4f069d7..5ed7dc3171 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.h
+++ b/src/core/hle/service/nvnflinger/nvnflinger.h
@@ -8,7 +8,6 @@
 #include <mutex>
 #include <optional>
 #include <thread>
-#include <vector>
 
 #include "common/common_types.h"
 #include "common/polyfill_thread.h"
@@ -57,9 +56,6 @@ public:
 
     void ShutdownLayers();
 
-    /// Sets the NVDrv module instance to use to send buffers to the GPU.
-    void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance);
-
     /// Opens the specified display and returns the ID.
     ///
     /// If an invalid display name is provided, then an empty optional is returned.
@@ -169,4 +165,6 @@ private:
     HosBinderDriverServer& hos_binder_driver_server;
 };
 
+void LoopProcess(Core::System& system);
+
 } // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index fbdf217ba5..0718df981d 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -49,7 +49,6 @@
 #include "core/hle/service/npns/npns.h"
 #include "core/hle/service/ns/ns.h"
 #include "core/hle/service/nvdrv/nvdrv.h"
-#include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
 #include "core/hle/service/nvnflinger/nvnflinger.h"
 #include "core/hle/service/olsc/olsc.h"
 #include "core/hle/service/omm/omm.h"
@@ -210,14 +209,9 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
 }
 
 /// Initialize Services
-Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system)
-    : hos_binder_driver_server{std::make_unique<Nvnflinger::HosBinderDriverServer>(system)},
-      nv_flinger{std::make_unique<Nvnflinger::Nvnflinger>(system, *hos_binder_driver_server)} {
-
+Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
     auto& kernel = system.Kernel();
 
-    // Nvnflinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
-    // here and pass it into the respective InstallInterfaces functions.
     system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
 
     // clang-format off
@@ -226,13 +220,14 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
     kernel.RunOnHostCoreProcess("jit",        [&] { JIT::LoopProcess(system); }).detach();
     kernel.RunOnHostCoreProcess("ldn",        [&] { LDN::LoopProcess(system); }).detach();
     kernel.RunOnHostCoreProcess("Loader",     [&] { LDR::LoopProcess(system); }).detach();
-    kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(*nv_flinger, system); }).detach();
+    kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(system); }).detach();
     kernel.RunOnHostCoreProcess("bsdsocket",  [&] { Sockets::LoopProcess(system); }).detach();
-    kernel.RunOnHostCoreProcess("vi",         [&] { VI::LoopProcess(system, *nv_flinger, *hos_binder_driver_server); }).detach();
+    kernel.RunOnHostCoreProcess("vi",         [&] { VI::LoopProcess(system); }).detach();
+    kernel.RunOnHostCoreProcess("nvnflinger", [&] { Nvnflinger::LoopProcess(system); }).detach();
 
     kernel.RunOnGuestCoreProcess("sm",         [&] { SM::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("account",    [&] { Account::LoopProcess(system); });
-    kernel.RunOnGuestCoreProcess("am",         [&] { AM::LoopProcess(*nv_flinger, system); });
+    kernel.RunOnGuestCoreProcess("am",         [&] { AM::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("aoc",        [&] { AOC::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("apm",        [&] { APM::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("bcat",       [&] { BCAT::LoopProcess(system); });
@@ -246,7 +241,6 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
     kernel.RunOnGuestCoreProcess("fatal",      [&] { Fatal::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("fgm",        [&] { FGM::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("friends",    [&] { Friend::LoopProcess(system); });
-    // glue depends on settings and psc, so they must come first
     kernel.RunOnGuestCoreProcess("settings",   [&] { Set::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("psc",        [&] { PSC::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("glue",       [&] { Glue::LoopProcess(system); });
@@ -283,8 +277,4 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
 
 Services::~Services() = default;
 
-void Services::KillNVNFlinger() {
-    nv_flinger->ShutdownLayers();
-}
-
 } // namespace Service
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 22d1343d5d..cf4a3e8beb 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -28,11 +28,6 @@ namespace FileSystem {
 class FileSystemController;
 }
 
-namespace Nvnflinger {
-class HosBinderDriverServer;
-class Nvnflinger;
-} // namespace Nvnflinger
-
 namespace SM {
 class ServiceManager;
 }
@@ -244,12 +239,6 @@ class Services final {
 public:
     explicit Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system);
     ~Services();
-
-    void KillNVNFlinger();
-
-private:
-    std::unique_ptr<Nvnflinger::HosBinderDriverServer> hos_binder_driver_server;
-    std::unique_ptr<Nvnflinger::Nvnflinger> nv_flinger;
 };
 
 } // namespace Service
diff --git a/src/core/hle/service/vi/application_display_service.cpp b/src/core/hle/service/vi/application_display_service.cpp
index 78229e30f1..a6e04bf602 100644
--- a/src/core/hle/service/vi/application_display_service.cpp
+++ b/src/core/hle/service/vi/application_display_service.cpp
@@ -2,10 +2,10 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/nvnflinger/hos_binder_driver.h"
 #include "core/hle/service/nvnflinger/nvnflinger.h"
 #include "core/hle/service/nvnflinger/parcel.h"
 #include "core/hle/service/vi/application_display_service.h"
-#include "core/hle/service/vi/hos_binder_driver.h"
 #include "core/hle/service/vi/manager_display_service.h"
 #include "core/hle/service/vi/system_display_service.h"
 #include "core/hle/service/vi/vi_results.h"
@@ -13,10 +13,10 @@
 namespace Service::VI {
 
 IApplicationDisplayService::IApplicationDisplayService(
-    Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-    Nvnflinger::HosBinderDriverServer& hos_binder_driver_server)
-    : ServiceFramework{system_, "IApplicationDisplayService"}, m_nvnflinger{nvnflinger},
-      m_hos_binder_driver_server{hos_binder_driver_server} {
+    Core::System& system_, std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service)
+    : ServiceFramework{system_, "IApplicationDisplayService"},
+      m_binder_service{std::move(binder_service)},
+      m_surface_flinger{m_binder_service->GetSurfaceFlinger()} {
 
     // clang-format off
     static const FunctionInfo functions[] = {
@@ -49,36 +49,37 @@ IApplicationDisplayService::IApplicationDisplayService(
 
 IApplicationDisplayService::~IApplicationDisplayService() {
     for (const auto layer_id : m_stray_layer_ids) {
-        m_nvnflinger.DestroyLayer(layer_id);
+        m_surface_flinger->DestroyLayer(layer_id);
     }
 }
 
 Result IApplicationDisplayService::GetRelayService(
-    Out<SharedPointer<IHOSBinderDriver>> out_relay_service) {
+    Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_relay_service) {
     LOG_WARNING(Service_VI, "(STUBBED) called");
-    *out_relay_service = std::make_shared<IHOSBinderDriver>(system, m_hos_binder_driver_server);
+    *out_relay_service = m_binder_service;
     R_SUCCEED();
 }
 
 Result IApplicationDisplayService::GetSystemDisplayService(
     Out<SharedPointer<ISystemDisplayService>> out_system_display_service) {
     LOG_WARNING(Service_VI, "(STUBBED) called");
-    *out_system_display_service = std::make_shared<ISystemDisplayService>(system, m_nvnflinger);
+    *out_system_display_service =
+        std::make_shared<ISystemDisplayService>(system, m_surface_flinger);
     R_SUCCEED();
 }
 
 Result IApplicationDisplayService::GetManagerDisplayService(
     Out<SharedPointer<IManagerDisplayService>> out_manager_display_service) {
     LOG_WARNING(Service_VI, "(STUBBED) called");
-    *out_manager_display_service = std::make_shared<IManagerDisplayService>(system, m_nvnflinger);
+    *out_manager_display_service =
+        std::make_shared<IManagerDisplayService>(system, m_surface_flinger);
     R_SUCCEED();
 }
 
 Result IApplicationDisplayService::GetIndirectDisplayTransactionService(
-    Out<SharedPointer<IHOSBinderDriver>> out_indirect_display_transaction_service) {
+    Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_indirect_display_transaction_service) {
     LOG_WARNING(Service_VI, "(STUBBED) called");
-    *out_indirect_display_transaction_service =
-        std::make_shared<IHOSBinderDriver>(system, m_hos_binder_driver_server);
+    *out_indirect_display_transaction_service = m_binder_service;
     R_SUCCEED();
 }
 
@@ -89,7 +90,7 @@ Result IApplicationDisplayService::OpenDisplay(Out<u64> out_display_id, DisplayN
     ASSERT_MSG(strcmp(display_name.data(), "Default") == 0,
                "Non-default displays aren't supported yet");
 
-    const auto display_id = m_nvnflinger.OpenDisplay(display_name.data());
+    const auto display_id = m_surface_flinger->OpenDisplay(display_name.data());
     if (!display_id) {
         LOG_ERROR(Service_VI, "Display not found! display_name={}", display_name.data());
         R_THROW(VI::ResultNotFound);
@@ -106,7 +107,7 @@ Result IApplicationDisplayService::OpenDefaultDisplay(Out<u64> out_display_id) {
 
 Result IApplicationDisplayService::CloseDisplay(u64 display_id) {
     LOG_DEBUG(Service_VI, "called");
-    R_SUCCEED_IF(m_nvnflinger.CloseDisplay(display_id));
+    R_SUCCEED_IF(m_surface_flinger->CloseDisplay(display_id));
     R_THROW(ResultUnknown);
 }
 
@@ -168,19 +169,19 @@ Result IApplicationDisplayService::OpenLayer(Out<u64> out_size,
 
     LOG_DEBUG(Service_VI, "called. layer_id={}, aruid={:#x}", layer_id, aruid.pid);
 
-    const auto display_id = m_nvnflinger.OpenDisplay(display_name.data());
+    const auto display_id = m_surface_flinger->OpenDisplay(display_name.data());
     if (!display_id) {
         LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id);
         R_THROW(VI::ResultNotFound);
     }
 
-    const auto buffer_queue_id = m_nvnflinger.FindBufferQueueId(*display_id, layer_id);
+    const auto buffer_queue_id = m_surface_flinger->FindBufferQueueId(*display_id, layer_id);
     if (!buffer_queue_id) {
         LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id);
         R_THROW(VI::ResultNotFound);
     }
 
-    if (!m_nvnflinger.OpenLayer(layer_id)) {
+    if (!m_surface_flinger->OpenLayer(layer_id)) {
         LOG_WARNING(Service_VI, "Tried to open layer which was already open");
         R_THROW(VI::ResultOperationFailed);
     }
@@ -199,7 +200,7 @@ Result IApplicationDisplayService::OpenLayer(Out<u64> out_size,
 Result IApplicationDisplayService::CloseLayer(u64 layer_id) {
     LOG_DEBUG(Service_VI, "called. layer_id={}", layer_id);
 
-    if (!m_nvnflinger.CloseLayer(layer_id)) {
+    if (!m_surface_flinger->CloseLayer(layer_id)) {
         LOG_WARNING(Service_VI, "Tried to close layer which was not open");
         R_THROW(VI::ResultOperationFailed);
     }
@@ -212,14 +213,14 @@ Result IApplicationDisplayService::CreateStrayLayer(
     u32 flags, u64 display_id) {
     LOG_DEBUG(Service_VI, "called. flags={}, display_id={}", flags, display_id);
 
-    const auto layer_id = m_nvnflinger.CreateLayer(display_id);
+    const auto layer_id = m_surface_flinger->CreateLayer(display_id);
     if (!layer_id) {
         LOG_ERROR(Service_VI, "Layer not found! display_id={}", display_id);
         R_THROW(VI::ResultNotFound);
     }
 
     m_stray_layer_ids.push_back(*layer_id);
-    const auto buffer_queue_id = m_nvnflinger.FindBufferQueueId(display_id, *layer_id);
+    const auto buffer_queue_id = m_surface_flinger->FindBufferQueueId(display_id, *layer_id);
     if (!buffer_queue_id) {
         LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id);
         R_THROW(VI::ResultNotFound);
@@ -240,7 +241,7 @@ Result IApplicationDisplayService::CreateStrayLayer(
 
 Result IApplicationDisplayService::DestroyStrayLayer(u64 layer_id) {
     LOG_WARNING(Service_VI, "(STUBBED) called. layer_id={}", layer_id);
-    m_nvnflinger.DestroyLayer(layer_id);
+    m_surface_flinger->DestroyLayer(layer_id);
     R_SUCCEED();
 }
 
@@ -248,7 +249,7 @@ Result IApplicationDisplayService::GetDisplayVsyncEvent(
     OutCopyHandle<Kernel::KReadableEvent> out_vsync_event, u64 display_id) {
     LOG_DEBUG(Service_VI, "called. display_id={}", display_id);
 
-    const auto result = m_nvnflinger.FindVsyncEvent(out_vsync_event, display_id);
+    const auto result = m_surface_flinger->FindVsyncEvent(out_vsync_event, display_id);
     if (result != ResultSuccess) {
         if (result == ResultNotFound) {
             LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
diff --git a/src/core/hle/service/vi/application_display_service.h b/src/core/hle/service/vi/application_display_service.h
index 5dff4bb31c..e56490f9fa 100644
--- a/src/core/hle/service/vi/application_display_service.h
+++ b/src/core/hle/service/vi/application_display_service.h
@@ -9,26 +9,30 @@ namespace Kernel {
 class KReadableEvent;
 }
 
+namespace Service::Nvnflinger {
+class Nvnflinger;
+class IHOSBinderDriver;
+} // namespace Service::Nvnflinger
+
 namespace Service::VI {
 
-class IHOSBinderDriver;
 class IManagerDisplayService;
 class ISystemDisplayService;
 
 class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {
 public:
-    IApplicationDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-                               Nvnflinger::HosBinderDriverServer& hos_binder_driver_server);
+    IApplicationDisplayService(Core::System& system_,
+                               std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service);
     ~IApplicationDisplayService() override;
 
 private:
-    Result GetRelayService(Out<SharedPointer<IHOSBinderDriver>> out_relay_service);
+    Result GetRelayService(Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_relay_service);
     Result GetSystemDisplayService(
         Out<SharedPointer<ISystemDisplayService>> out_system_display_service);
     Result GetManagerDisplayService(
         Out<SharedPointer<IManagerDisplayService>> out_manager_display_service);
     Result GetIndirectDisplayTransactionService(
-        Out<SharedPointer<IHOSBinderDriver>> out_indirect_display_transaction_service);
+        Out<SharedPointer<Nvnflinger::IHOSBinderDriver>> out_indirect_display_transaction_service);
     Result OpenDisplay(Out<u64> out_display_id, DisplayName display_name);
     Result OpenDefaultDisplay(Out<u64> out_display_id);
     Result CloseDisplay(u64 display_id);
@@ -56,8 +60,8 @@ private:
                                                    s64 width, s64 height);
 
 private:
-    Nvnflinger::Nvnflinger& m_nvnflinger;
-    Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server;
+    const std::shared_ptr<Nvnflinger::IHOSBinderDriver> m_binder_service;
+    const std::shared_ptr<Nvnflinger::Nvnflinger> m_surface_flinger;
     std::vector<u64> m_stray_layer_ids;
     bool m_vsync_event_fetched{false};
 };
diff --git a/src/core/hle/service/vi/application_root_service.cpp b/src/core/hle/service/vi/application_root_service.cpp
index 7af7f062c4..501fbdd6aa 100644
--- a/src/core/hle/service/vi/application_root_service.cpp
+++ b/src/core/hle/service/vi/application_root_service.cpp
@@ -11,10 +11,8 @@
 namespace Service::VI {
 
 IApplicationRootService::IApplicationRootService(
-    Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-    Nvnflinger::HosBinderDriverServer& hos_binder_driver_server)
-    : ServiceFramework{system_, "vi:u"}, m_nvnflinger{nvnflinger}, m_hos_binder_driver_server{
-                                                                       hos_binder_driver_server} {
+    Core::System& system_, std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service)
+    : ServiceFramework{system_, "vi:u"}, m_binder_service{std::move(binder_service)} {
     static const FunctionInfo functions[] = {
         {0, C<&IApplicationRootService::GetDisplayService>, "GetDisplayService"},
         {1, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -27,8 +25,8 @@ IApplicationRootService::~IApplicationRootService() = default;
 Result IApplicationRootService::GetDisplayService(
     Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) {
     LOG_DEBUG(Service_VI, "called");
-    R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_nvnflinger,
-                                          m_hos_binder_driver_server, Permission::User, policy));
+    R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_binder_service,
+                                          Permission::User, policy));
 }
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/application_root_service.h b/src/core/hle/service/vi/application_root_service.h
index 9dbf28cb4c..d1f023e9ec 100644
--- a/src/core/hle/service/vi/application_root_service.h
+++ b/src/core/hle/service/vi/application_root_service.h
@@ -11,8 +11,7 @@ class System;
 }
 
 namespace Service::Nvnflinger {
-class HosBinderDriverServer;
-class Nvnflinger;
+class IHOSBinderDriver;
 } // namespace Service::Nvnflinger
 
 namespace Service::VI {
@@ -22,8 +21,8 @@ enum class Policy : u32;
 
 class IApplicationRootService final : public ServiceFramework<IApplicationRootService> {
 public:
-    explicit IApplicationRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-                                     Nvnflinger::HosBinderDriverServer& hos_binder_driver_server);
+    explicit IApplicationRootService(Core::System& system_,
+                                     std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service);
     ~IApplicationRootService() override;
 
 private:
@@ -32,8 +31,7 @@ private:
         Policy policy);
 
 private:
-    Nvnflinger::Nvnflinger& m_nvnflinger;
-    Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server;
+    const std::shared_ptr<Nvnflinger::IHOSBinderDriver> m_binder_service;
 };
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/manager_display_service.cpp b/src/core/hle/service/vi/manager_display_service.cpp
index 17f2f3b8fe..22454ba61e 100644
--- a/src/core/hle/service/vi/manager_display_service.cpp
+++ b/src/core/hle/service/vi/manager_display_service.cpp
@@ -8,9 +8,10 @@
 
 namespace Service::VI {
 
-IManagerDisplayService::IManagerDisplayService(Core::System& system_,
-                                               Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "IManagerDisplayService"}, m_nvnflinger{nvnflinger} {
+IManagerDisplayService::IManagerDisplayService(
+    Core::System& system_, std::shared_ptr<Nvnflinger::Nvnflinger> surface_flinger)
+    : ServiceFramework{system_, "IManagerDisplayService"},
+      m_surface_flinger{std::move(surface_flinger)} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {200, nullptr, "AllocateProcessHeapBlock"},
@@ -107,7 +108,7 @@ Result IManagerDisplayService::CreateManagedLayer(Out<u64> out_layer_id, u32 unk
     LOG_WARNING(Service_VI, "(STUBBED) called. unknown={}, display={}, aruid={}", unknown,
                 display_id, aruid.pid);
 
-    const auto layer_id = m_nvnflinger.CreateLayer(display_id);
+    const auto layer_id = m_surface_flinger->CreateLayer(display_id);
     if (!layer_id) {
         LOG_ERROR(Service_VI, "Layer not found! display={}", display_id);
         R_THROW(VI::ResultNotFound);
diff --git a/src/core/hle/service/vi/manager_display_service.h b/src/core/hle/service/vi/manager_display_service.h
index 60e646ee04..4a3d53ff88 100644
--- a/src/core/hle/service/vi/manager_display_service.h
+++ b/src/core/hle/service/vi/manager_display_service.h
@@ -8,7 +8,8 @@ namespace Service::VI {
 
 class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> {
 public:
-    explicit IManagerDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger);
+    explicit IManagerDisplayService(Core::System& system_,
+                                    std::shared_ptr<Nvnflinger::Nvnflinger> surface_flinger);
     ~IManagerDisplayService() override;
 
 private:
@@ -18,7 +19,7 @@ private:
     Result SetLayerVisibility(bool visible, u64 layer_id);
 
 private:
-    Nvnflinger::Nvnflinger& m_nvnflinger;
+    const std::shared_ptr<Nvnflinger::Nvnflinger> m_surface_flinger;
 };
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/manager_root_service.cpp b/src/core/hle/service/vi/manager_root_service.cpp
index a7eee4f04f..36b84909a9 100644
--- a/src/core/hle/service/vi/manager_root_service.cpp
+++ b/src/core/hle/service/vi/manager_root_service.cpp
@@ -11,10 +11,8 @@
 namespace Service::VI {
 
 IManagerRootService::IManagerRootService(
-    Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-    Nvnflinger::HosBinderDriverServer& hos_binder_driver_server)
-    : ServiceFramework{system_, "vi:m"}, m_nvnflinger{nvnflinger}, m_hos_binder_driver_server{
-                                                                       hos_binder_driver_server} {
+    Core::System& system_, std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service)
+    : ServiceFramework{system_, "vi:m"}, m_binder_service{std::move(binder_service)} {
     static const FunctionInfo functions[] = {
         {2, C<&IManagerRootService::GetDisplayService>, "GetDisplayService"},
         {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -31,8 +29,8 @@ IManagerRootService::~IManagerRootService() = default;
 Result IManagerRootService::GetDisplayService(
     Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) {
     LOG_DEBUG(Service_VI, "called");
-    R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_nvnflinger,
-                                          m_hos_binder_driver_server, Permission::Manager, policy));
+    R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_binder_service,
+                                          Permission::Manager, policy));
 }
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/manager_root_service.h b/src/core/hle/service/vi/manager_root_service.h
index e6cb77aeb4..26aa95a884 100644
--- a/src/core/hle/service/vi/manager_root_service.h
+++ b/src/core/hle/service/vi/manager_root_service.h
@@ -11,8 +11,7 @@ class System;
 }
 
 namespace Service::Nvnflinger {
-class HosBinderDriverServer;
-class Nvnflinger;
+class IHOSBinderDriver;
 } // namespace Service::Nvnflinger
 
 namespace Service::VI {
@@ -22,8 +21,8 @@ enum class Policy : u32;
 
 class IManagerRootService final : public ServiceFramework<IManagerRootService> {
 public:
-    explicit IManagerRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-                                 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server);
+    explicit IManagerRootService(Core::System& system_,
+                                 std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service);
     ~IManagerRootService() override;
 
 private:
@@ -31,8 +30,7 @@ private:
         Out<SharedPointer<IApplicationDisplayService>> out_application_display_service,
         Policy policy);
 
-    Nvnflinger::Nvnflinger& m_nvnflinger;
-    Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server;
+    const std::shared_ptr<Nvnflinger::IHOSBinderDriver> m_binder_service;
 };
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/service_creator.cpp b/src/core/hle/service/vi/service_creator.cpp
index 1de9d61a4c..594e57398c 100644
--- a/src/core/hle/service/vi/service_creator.cpp
+++ b/src/core/hle/service/vi/service_creator.cpp
@@ -22,9 +22,8 @@ static bool IsValidServiceAccess(Permission permission, Policy policy) {
 
 Result GetApplicationDisplayService(
     std::shared_ptr<IApplicationDisplayService>* out_application_display_service,
-    Core::System& system, Nvnflinger::Nvnflinger& nvnflinger,
-    Nvnflinger::HosBinderDriverServer& hos_binder_driver_server, Permission permission,
-    Policy policy) {
+    Core::System& system, std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service,
+    Permission permission, Policy policy) {
 
     if (!IsValidServiceAccess(permission, policy)) {
         LOG_ERROR(Service_VI, "Permission denied for policy {}", policy);
@@ -32,7 +31,7 @@ Result GetApplicationDisplayService(
     }
 
     *out_application_display_service =
-        std::make_shared<IApplicationDisplayService>(system, nvnflinger, hos_binder_driver_server);
+        std::make_shared<IApplicationDisplayService>(system, binder_service);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/vi/service_creator.h b/src/core/hle/service/vi/service_creator.h
index 8963bcd269..bdfac8a08b 100644
--- a/src/core/hle/service/vi/service_creator.h
+++ b/src/core/hle/service/vi/service_creator.h
@@ -12,8 +12,7 @@ class System;
 }
 
 namespace Service::Nvnflinger {
-class HosBinderDriverServer;
-class Nvnflinger;
+class IHOSBinderDriver;
 } // namespace Service::Nvnflinger
 
 union Result;
@@ -26,8 +25,7 @@ enum class Policy : u32;
 
 Result GetApplicationDisplayService(
     std::shared_ptr<IApplicationDisplayService>* out_application_display_service,
-    Core::System& system, Nvnflinger::Nvnflinger& nvnflinger,
-    Nvnflinger::HosBinderDriverServer& hos_binder_driver_server, Permission permission,
-    Policy policy);
+    Core::System& system, std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service,
+    Permission permission, Policy policy);
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/system_display_service.cpp b/src/core/hle/service/vi/system_display_service.cpp
index 1e1cfc8179..8d6c3f04c5 100644
--- a/src/core/hle/service/vi/system_display_service.cpp
+++ b/src/core/hle/service/vi/system_display_service.cpp
@@ -9,9 +9,10 @@
 
 namespace Service::VI {
 
-ISystemDisplayService::ISystemDisplayService(Core::System& system_,
-                                             Nvnflinger::Nvnflinger& nvnflinger)
-    : ServiceFramework{system_, "ISystemDisplayService"}, m_nvnflinger{nvnflinger} {
+ISystemDisplayService::ISystemDisplayService(
+    Core::System& system_, std::shared_ptr<Nvnflinger::Nvnflinger> surface_flinger)
+    : ServiceFramework{system_, "ISystemDisplayService"},
+      m_surface_flinger{std::move(surface_flinger)} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {1200, nullptr, "GetZOrderCountMin"},
@@ -104,7 +105,7 @@ Result ISystemDisplayService::GetSharedBufferMemoryHandleId(
     u64 buffer_id, ClientAppletResourceUserId aruid) {
     LOG_INFO(Service_VI, "called. buffer_id={}, aruid={:#x}", buffer_id, aruid.pid);
 
-    R_RETURN(m_nvnflinger.GetSystemBufferManager().GetSharedBufferMemoryHandleId(
+    R_RETURN(m_surface_flinger->GetSystemBufferManager().GetSharedBufferMemoryHandleId(
         out_size, out_nvmap_handle, out_pool_layout, buffer_id, aruid.pid));
 }
 
@@ -122,7 +123,7 @@ Result ISystemDisplayService::AcquireSharedFrameBuffer(Out<android::Fence> out_f
                                                        Out<std::array<s32, 4>> out_slots,
                                                        Out<s64> out_target_slot, u64 layer_id) {
     LOG_DEBUG(Service_VI, "called");
-    R_RETURN(m_nvnflinger.GetSystemBufferManager().AcquireSharedFrameBuffer(
+    R_RETURN(m_surface_flinger->GetSystemBufferManager().AcquireSharedFrameBuffer(
         out_fence, *out_slots, out_target_slot, layer_id));
 }
 
@@ -131,15 +132,15 @@ Result ISystemDisplayService::PresentSharedFrameBuffer(android::Fence fence,
                                                        u32 window_transform, s32 swap_interval,
                                                        u64 layer_id, s64 surface_id) {
     LOG_DEBUG(Service_VI, "called");
-    R_RETURN(m_nvnflinger.GetSystemBufferManager().PresentSharedFrameBuffer(
+    R_RETURN(m_surface_flinger->GetSystemBufferManager().PresentSharedFrameBuffer(
         fence, crop_region, window_transform, swap_interval, layer_id, surface_id));
 }
 
 Result ISystemDisplayService::GetSharedFrameBufferAcquirableEvent(
     OutCopyHandle<Kernel::KReadableEvent> out_event, u64 layer_id) {
     LOG_DEBUG(Service_VI, "called");
-    R_RETURN(m_nvnflinger.GetSystemBufferManager().GetSharedFrameBufferAcquirableEvent(out_event,
-                                                                                       layer_id));
+    R_RETURN(m_surface_flinger->GetSystemBufferManager().GetSharedFrameBufferAcquirableEvent(
+        out_event, layer_id));
 }
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/system_display_service.h b/src/core/hle/service/vi/system_display_service.h
index cfcb196fd7..6c3f57ad75 100644
--- a/src/core/hle/service/vi/system_display_service.h
+++ b/src/core/hle/service/vi/system_display_service.h
@@ -7,14 +7,16 @@
 #include "core/hle/service/service.h"
 
 namespace Service::Nvnflinger {
+class Nvnflinger;
 struct SharedMemoryPoolLayout;
-}
+} // namespace Service::Nvnflinger
 
 namespace Service::VI {
 
 class ISystemDisplayService final : public ServiceFramework<ISystemDisplayService> {
 public:
-    explicit ISystemDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger);
+    explicit ISystemDisplayService(Core::System& system_,
+                                   std::shared_ptr<Nvnflinger::Nvnflinger> surface_flinger);
     ~ISystemDisplayService() override;
 
 private:
@@ -39,7 +41,7 @@ private:
                                     s64 surface_id);
 
 private:
-    Nvnflinger::Nvnflinger& m_nvnflinger;
+    const std::shared_ptr<Nvnflinger::Nvnflinger> m_surface_flinger;
 };
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/system_root_service.cpp b/src/core/hle/service/vi/system_root_service.cpp
index 8789b4cfb1..1d435ed6b4 100644
--- a/src/core/hle/service/vi/system_root_service.cpp
+++ b/src/core/hle/service/vi/system_root_service.cpp
@@ -10,10 +10,9 @@
 
 namespace Service::VI {
 
-ISystemRootService::ISystemRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-                                       Nvnflinger::HosBinderDriverServer& hos_binder_driver_server)
-    : ServiceFramework{system_, "vi:s"}, m_nvnflinger{nvnflinger}, m_hos_binder_driver_server{
-                                                                       hos_binder_driver_server} {
+ISystemRootService::ISystemRootService(Core::System& system_,
+                                       std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service)
+    : ServiceFramework{system_, "vi:s"}, m_binder_service{std::move(binder_service)} {
     static const FunctionInfo functions[] = {
         {1, C<&ISystemRootService::GetDisplayService>, "GetDisplayService"},
         {3, nullptr, "GetDisplayServiceWithProxyNameExchange"},
@@ -26,8 +25,8 @@ ISystemRootService::~ISystemRootService() = default;
 Result ISystemRootService::GetDisplayService(
     Out<SharedPointer<IApplicationDisplayService>> out_application_display_service, Policy policy) {
     LOG_DEBUG(Service_VI, "called");
-    R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_nvnflinger,
-                                          m_hos_binder_driver_server, Permission::System, policy));
+    R_RETURN(GetApplicationDisplayService(out_application_display_service, system, m_binder_service,
+                                          Permission::System, policy));
 }
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/system_root_service.h b/src/core/hle/service/vi/system_root_service.h
index 2c547faa50..6f07c39fd6 100644
--- a/src/core/hle/service/vi/system_root_service.h
+++ b/src/core/hle/service/vi/system_root_service.h
@@ -11,8 +11,7 @@ class System;
 }
 
 namespace Service::Nvnflinger {
-class HosBinderDriverServer;
-class Nvnflinger;
+class IHOSBinderDriver;
 } // namespace Service::Nvnflinger
 
 namespace Service::VI {
@@ -22,8 +21,8 @@ enum class Policy : u32;
 
 class ISystemRootService final : public ServiceFramework<ISystemRootService> {
 public:
-    explicit ISystemRootService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger,
-                                Nvnflinger::HosBinderDriverServer& hos_binder_driver_server);
+    explicit ISystemRootService(Core::System& system_,
+                                std::shared_ptr<Nvnflinger::IHOSBinderDriver> binder_service);
     ~ISystemRootService() override;
 
 private:
@@ -31,8 +30,7 @@ private:
         Out<SharedPointer<IApplicationDisplayService>> out_application_display_service,
         Policy policy);
 
-    Nvnflinger::Nvnflinger& m_nvnflinger;
-    Nvnflinger::HosBinderDriverServer& m_hos_binder_driver_server;
+    const std::shared_ptr<Nvnflinger::IHOSBinderDriver> m_binder_service;
 };
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 304e589b7f..d20f1fdea7 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -1,7 +1,10 @@
 // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#include "core/core.h"
+#include "core/hle/service/nvnflinger/hos_binder_driver.h"
 #include "core/hle/service/server_manager.h"
+#include "core/hle/service/sm/sm.h"
 #include "core/hle/service/vi/application_display_service.h"
 #include "core/hle/service/vi/application_root_service.h"
 #include "core/hle/service/vi/manager_root_service.h"
@@ -10,16 +13,17 @@
 
 namespace Service::VI {
 
-void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nvnflinger,
-                 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) {
+void LoopProcess(Core::System& system) {
+    const auto binder_service =
+        system.ServiceManager().GetService<Nvnflinger::IHOSBinderDriver>("dispdrv", true);
     auto server_manager = std::make_unique<ServerManager>(system);
 
-    server_manager->RegisterNamedService("vi:m", std::make_shared<IManagerRootService>(
-                                                     system, nvnflinger, hos_binder_driver_server));
     server_manager->RegisterNamedService(
-        "vi:s", std::make_shared<ISystemRootService>(system, nvnflinger, hos_binder_driver_server));
-    server_manager->RegisterNamedService("vi:u", std::make_shared<IApplicationRootService>(
-                                                     system, nvnflinger, hos_binder_driver_server));
+        "vi:m", std::make_shared<IManagerRootService>(system, binder_service));
+    server_manager->RegisterNamedService(
+        "vi:s", std::make_shared<ISystemRootService>(system, binder_service));
+    server_manager->RegisterNamedService(
+        "vi:u", std::make_shared<IApplicationRootService>(system, binder_service));
     ServerManager::RunServer(std::move(server_manager));
 }
 
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index 8e681370d2..0c3dc175d4 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -7,14 +7,8 @@ namespace Core {
 class System;
 }
 
-namespace Service::Nvnflinger {
-class HosBinderDriverServer;
-class Nvnflinger;
-} // namespace Service::Nvnflinger
-
 namespace Service::VI {
 
-void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nvnflinger,
-                 Nvnflinger::HosBinderDriverServer& hos_binder_driver_server);
+void LoopProcess(Core::System& system);
 
 } // namespace Service::VI