summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2023-12-24 18:20:02 +0100
committerGravatar Liam2024-01-18 21:12:30 -0500
commit7a9d1ad2f873003e6aad637e8749b77b91247da3 (patch)
treee167a5d5ad73dbd78dc4b5c165b12a1220a167f4 /src
parentCore: Initial implementation of device memory mapping (diff)
downloadyuzu-7a9d1ad2f873003e6aad637e8749b77b91247da3.tar.gz
yuzu-7a9d1ad2f873003e6aad637e8749b77b91247da3.tar.xz
yuzu-7a9d1ad2f873003e6aad637e8749b77b91247da3.zip
NVDRV: Implement sessions and initial implementation of SMMU
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/hle_ipc.h8
-rw-r--r--src/core/hle/service/nvdrv/core/container.cpp44
-rw-r--r--src/core/hle/service/nvdrv/core/container.h15
-rw-r--r--src/core/hle/service/nvdrv/core/nvmap.cpp58
-rw-r--r--src/core/hle/service/nvdrv/core/nvmap.h16
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdevice.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp10
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp31
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h7
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp27
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h6
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.cpp36
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.h1
-rw-r--r--src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp21
-rw-r--r--src/core/hle/service/nvnflinger/fb_share_buffer_manager.h5
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp2
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/gpu.cpp2
-rw-r--r--src/video_core/host1x/host1x.cpp3
-rw-r--r--src/video_core/host1x/host1x.h18
37 files changed, 260 insertions, 100 deletions
diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h
index 440737db5..d550a11b7 100644
--- a/src/core/hle/service/hle_ipc.h
+++ b/src/core/hle/service/hle_ipc.h
@@ -19,6 +19,8 @@
19#include "core/hle/ipc.h" 19#include "core/hle/ipc.h"
20#include "core/hle/kernel/k_handle_table.h" 20#include "core/hle/kernel/k_handle_table.h"
21#include "core/hle/kernel/svc_common.h" 21#include "core/hle/kernel/svc_common.h"
22#include "core/hle/kernel/k_auto_object.h"
23#include "core/hle/kernel/k_handle_table.h"
22 24
23union Result; 25union Result;
24 26
@@ -41,6 +43,8 @@ class KernelCore;
41class KHandleTable; 43class KHandleTable;
42class KProcess; 44class KProcess;
43class KServerSession; 45class KServerSession;
46template <typename T>
47class KScopedAutoObject;
44class KThread; 48class KThread;
45} // namespace Kernel 49} // namespace Kernel
46 50
@@ -373,6 +377,10 @@ public:
373 return nullptr; 377 return nullptr;
374 } 378 }
375 379
380 Kernel::KScopedAutoObject<Kernel::KAutoObject> GetObjectFromHandle(u32 handle) {
381 return GetClientHandleTable().GetObjectForIpc(handle, thread);
382 }
383
376 [[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const { 384 [[nodiscard]] std::shared_ptr<SessionRequestManager> GetManager() const {
377 return manager.lock(); 385 return manager.lock();
378 } 386 }
diff --git a/src/core/hle/service/nvdrv/core/container.cpp b/src/core/hle/service/nvdrv/core/container.cpp
index 37ca24f5d..7c2231fe6 100644
--- a/src/core/hle/service/nvdrv/core/container.cpp
+++ b/src/core/hle/service/nvdrv/core/container.cpp
@@ -2,19 +2,30 @@
2// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors 2// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors
3// SPDX-License-Identifier: GPL-3.0-or-later 3// SPDX-License-Identifier: GPL-3.0-or-later
4 4
5#include <atomic>
6#include <deque>
7#include <mutex>
8
9#include "core/hle/kernel/k_process.h"
5#include "core/hle/service/nvdrv/core/container.h" 10#include "core/hle/service/nvdrv/core/container.h"
6#include "core/hle/service/nvdrv/core/nvmap.h" 11#include "core/hle/service/nvdrv/core/nvmap.h"
7#include "core/hle/service/nvdrv/core/syncpoint_manager.h" 12#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
13#include "core/memory.h"
8#include "video_core/host1x/host1x.h" 14#include "video_core/host1x/host1x.h"
9 15
10namespace Service::Nvidia::NvCore { 16namespace Service::Nvidia::NvCore {
11 17
12struct ContainerImpl { 18struct ContainerImpl {
13 explicit ContainerImpl(Tegra::Host1x::Host1x& host1x_) 19 explicit ContainerImpl(Tegra::Host1x::Host1x& host1x_)
14 : file{host1x_}, manager{host1x_}, device_file_data{} {} 20 : host1x{host1x_}, file{host1x_}, manager{host1x_}, device_file_data{} {}
21 Tegra::Host1x::Host1x& host1x;
15 NvMap file; 22 NvMap file;
16 SyncpointManager manager; 23 SyncpointManager manager;
17 Container::Host1xDeviceFileData device_file_data; 24 Container::Host1xDeviceFileData device_file_data;
25 std::deque<Session> sessions;
26 size_t new_ids{};
27 std::deque<size_t> id_pool;
28 std::mutex session_guard;
18}; 29};
19 30
20Container::Container(Tegra::Host1x::Host1x& host1x_) { 31Container::Container(Tegra::Host1x::Host1x& host1x_) {
@@ -23,6 +34,37 @@ Container::Container(Tegra::Host1x::Host1x& host1x_) {
23 34
24Container::~Container() = default; 35Container::~Container() = default;
25 36
37size_t Container::OpenSession(Kernel::KProcess* process) {
38 std::scoped_lock lk(impl->session_guard);
39 size_t new_id{};
40 auto* memory_interface = &process->GetMemory();
41 auto& smmu = impl->host1x.MemoryManager();
42 auto smmu_id = smmu.RegisterProcess(memory_interface);
43 if (!impl->id_pool.empty()) {
44 new_id = impl->id_pool.front();
45 impl->id_pool.pop_front();
46 impl->sessions[new_id] = Session{new_id, process, smmu_id};
47 } else {
48 impl->sessions.emplace_back(new_id, process, smmu_id);
49 new_id = impl->new_ids++;
50 }
51 LOG_CRITICAL(Debug, "Created Session {}", new_id);
52 return new_id;
53}
54
55void Container::CloseSession(size_t id) {
56 std::scoped_lock lk(impl->session_guard);
57 auto& smmu = impl->host1x.MemoryManager();
58 smmu.UnregisterProcess(impl->sessions[id].smmu_id);
59 impl->id_pool.emplace_front(id);
60 LOG_CRITICAL(Debug, "Closed Session {}", id);
61}
62
63Session* Container::GetSession(size_t id) {
64 std::atomic_thread_fence(std::memory_order_acquire);
65 return &impl->sessions[id];
66}
67
26NvMap& Container::GetNvMapFile() { 68NvMap& Container::GetNvMapFile() {
27 return impl->file; 69 return impl->file;
28} 70}
diff --git a/src/core/hle/service/nvdrv/core/container.h b/src/core/hle/service/nvdrv/core/container.h
index b4b63ac90..a1fd20199 100644
--- a/src/core/hle/service/nvdrv/core/container.h
+++ b/src/core/hle/service/nvdrv/core/container.h
@@ -10,6 +10,10 @@
10 10
11#include "core/hle/service/nvdrv/nvdata.h" 11#include "core/hle/service/nvdrv/nvdata.h"
12 12
13namespace Kernel {
14class KProcess;
15}
16
13namespace Tegra::Host1x { 17namespace Tegra::Host1x {
14class Host1x; 18class Host1x;
15} // namespace Tegra::Host1x 19} // namespace Tegra::Host1x
@@ -21,11 +25,22 @@ class SyncpointManager;
21 25
22struct ContainerImpl; 26struct ContainerImpl;
23 27
28struct Session {
29 size_t id;
30 Kernel::KProcess* process;
31 size_t smmu_id;
32};
33
24class Container { 34class Container {
25public: 35public:
26 explicit Container(Tegra::Host1x::Host1x& host1x); 36 explicit Container(Tegra::Host1x::Host1x& host1x);
27 ~Container(); 37 ~Container();
28 38
39 size_t OpenSession(Kernel::KProcess* process);
40 void CloseSession(size_t id);
41
42 Session* GetSession(size_t id);
43
29 NvMap& GetNvMapFile(); 44 NvMap& GetNvMapFile();
30 45
31 const NvMap& GetNvMapFile() const; 46 const NvMap& GetNvMapFile() const;
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp
index 0ca05257e..fd6c9aa0c 100644
--- a/src/core/hle/service/nvdrv/core/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/core/nvmap.cpp
@@ -18,8 +18,6 @@ NvMap::Handle::Handle(u64 size_, Id id_)
18} 18}
19 19
20NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) { 20NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) {
21 std::scoped_lock lock(mutex);
22
23 // Handles cannot be allocated twice 21 // Handles cannot be allocated twice
24 if (allocated) { 22 if (allocated) {
25 return NvResult::AccessDenied; 23 return NvResult::AccessDenied;
@@ -79,10 +77,11 @@ void NvMap::UnmapHandle(Handle& handle_description) {
79 } 77 }
80 78
81 // Free and unmap the handle from the SMMU 79 // Free and unmap the handle from the SMMU
82 host1x.MemoryManager().Unmap(static_cast<GPUVAddr>(handle_description.pin_virt_address), 80 auto& smmu = host1x.MemoryManager();
83 handle_description.aligned_size); 81 smmu.Unmap(static_cast<DAddr>(handle_description.pin_virt_address),
84 host1x.Allocator().Free(handle_description.pin_virt_address, 82 handle_description.aligned_size);
85 static_cast<u32>(handle_description.aligned_size)); 83 smmu.Free(handle_description.pin_virt_address,
84 static_cast<size_t>(handle_description.aligned_size));
86 handle_description.pin_virt_address = 0; 85 handle_description.pin_virt_address = 0;
87} 86}
88 87
@@ -133,7 +132,32 @@ VAddr NvMap::GetHandleAddress(Handle::Id handle) {
133 } 132 }
134} 133}
135 134
136u32 NvMap::PinHandle(NvMap::Handle::Id handle) { 135NvResult NvMap::AllocateHandle(Handle::Id handle, Handle::Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t session_id) {
136 auto handle_description{GetHandle(handle)};
137 if (!handle_description) [[unlikely]] {
138 return NvResult::BadParameter;
139 }
140
141 if (handle_description->allocated) [[unlikely]] {
142 return NvResult::InsufficientMemory;
143 }
144
145 std::scoped_lock lock(handle_description->mutex);
146 NvResult result = handle_description->Alloc(pFlags, pAlign, pKind, pAddress);
147 if (result != NvResult::Success) {
148 return result;
149 }
150 auto& smmu = host1x.MemoryManager();
151 size_t total_size = static_cast<size_t>(handle_description->aligned_size);
152 handle_description->d_address = smmu.Allocate(total_size);
153 if (handle_description->d_address == 0) {
154 return NvResult::InsufficientMemory;
155 }
156 smmu.Map(handle_description->d_address, handle_description->address, total_size, session_id);
157 return NvResult::Success;
158}
159
160u32 NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id) {
137 auto handle_description{GetHandle(handle)}; 161 auto handle_description{GetHandle(handle)};
138 if (!handle_description) [[unlikely]] { 162 if (!handle_description) [[unlikely]] {
139 return 0; 163 return 0;
@@ -157,11 +181,10 @@ u32 NvMap::PinHandle(NvMap::Handle::Id handle) {
157 } 181 }
158 182
159 // If not then allocate some space and map it 183 // If not then allocate some space and map it
160 u32 address{}; 184 DAddr address{};
161 auto& smmu_allocator = host1x.Allocator(); 185 auto& smmu = host1x.MemoryManager();
162 auto& smmu_memory_manager = host1x.MemoryManager(); 186 while ((address = smmu.AllocatePinned(
163 while ((address = smmu_allocator.Allocate( 187 static_cast<size_t>(handle_description->aligned_size))) == 0) {
164 static_cast<u32>(handle_description->aligned_size))) == 0) {
165 // Free handles until the allocation succeeds 188 // Free handles until the allocation succeeds
166 std::scoped_lock queueLock(unmap_queue_lock); 189 std::scoped_lock queueLock(unmap_queue_lock);
167 if (auto freeHandleDesc{unmap_queue.front()}) { 190 if (auto freeHandleDesc{unmap_queue.front()}) {
@@ -175,9 +198,9 @@ u32 NvMap::PinHandle(NvMap::Handle::Id handle) {
175 } 198 }
176 } 199 }
177 200
178 smmu_memory_manager.Map(static_cast<GPUVAddr>(address), handle_description->address, 201 smmu.Map(address, handle_description->address, handle_description->aligned_size,
179 handle_description->aligned_size); 202 session_id);
180 handle_description->pin_virt_address = address; 203 handle_description->pin_virt_address = static_cast<u32>(address);
181 } 204 }
182 205
183 handle_description->pins++; 206 handle_description->pins++;
@@ -236,6 +259,11 @@ std::optional<NvMap::FreeInfo> NvMap::FreeHandle(Handle::Id handle, bool interna
236 std::scoped_lock queueLock(unmap_queue_lock); 259 std::scoped_lock queueLock(unmap_queue_lock);
237 UnmapHandle(*handle_description); 260 UnmapHandle(*handle_description);
238 } 261 }
262 if (handle_description->allocated) {
263 auto& smmu = host1x.MemoryManager();
264 smmu.Free(handle_description->d_address, handle_description->aligned_size);
265 smmu.Unmap(handle_description->d_address, handle_description->aligned_size);
266 }
239 267
240 handle_description->pins = 0; 268 handle_description->pins = 0;
241 } 269 }
diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h
index a8e573890..7c3110d91 100644
--- a/src/core/hle/service/nvdrv/core/nvmap.h
+++ b/src/core/hle/service/nvdrv/core/nvmap.h
@@ -61,8 +61,10 @@ public:
61 } flags{}; 61 } flags{};
62 static_assert(sizeof(Flags) == sizeof(u32)); 62 static_assert(sizeof(Flags) == sizeof(u32));
63 63
64 u64 address{}; //!< The memory location in the guest's AS that this handle corresponds to, 64 VAddr address{}; //!< The memory location in the guest's AS that this handle corresponds to,
65 //!< this can also be in the nvdrv tmem 65 //!< this can also be in the nvdrv tmem
66 DAddr d_address{}; //!< The memory location in the device's AS that this handle corresponds to,
67 //!< this can also be in the nvdrv tmem
66 bool is_shared_mem_mapped{}; //!< If this nvmap has been mapped with the MapSharedMem IPC 68 bool is_shared_mem_mapped{}; //!< If this nvmap has been mapped with the MapSharedMem IPC
67 //!< call 69 //!< call
68 70
@@ -125,7 +127,15 @@ public:
125 * number of calls to `UnpinHandle` 127 * number of calls to `UnpinHandle`
126 * @return The SMMU virtual address that the handle has been mapped to 128 * @return The SMMU virtual address that the handle has been mapped to
127 */ 129 */
128 u32 PinHandle(Handle::Id handle); 130 u32 PinHandle(Handle::Id handle, size_t session_id);
131
132 /**
133 * @brief Maps a handle into the SMMU address space
134 * @note This operation is refcounted, the number of calls to this must eventually match the
135 * number of calls to `UnpinHandle`
136 * @return The SMMU virtual address that the handle has been mapped to
137 */
138 NvResult AllocateHandle(Handle::Id handle, Handle::Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress, size_t session_id);
129 139
130 /** 140 /**
131 * @brief When this has been called an equal number of times to `PinHandle` for the supplied 141 * @brief When this has been called an equal number of times to `PinHandle` for the supplied
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h
index a04538d5d..ff91aabcb 100644
--- a/src/core/hle/service/nvdrv/devices/nvdevice.h
+++ b/src/core/hle/service/nvdrv/devices/nvdevice.h
@@ -62,7 +62,7 @@ public:
62 * Called once a device is opened 62 * Called once a device is opened
63 * @param fd The device fd 63 * @param fd The device fd
64 */ 64 */
65 virtual void OnOpen(DeviceFD fd) = 0; 65 virtual void OnOpen(size_t session_id, DeviceFD fd) = 0;
66 66
67 /** 67 /**
68 * Called once a device is closed 68 * Called once a device is closed
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 05a43d8dc..0ff41c6b2 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -35,7 +35,7 @@ NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in
35 return NvResult::NotImplemented; 35 return NvResult::NotImplemented;
36} 36}
37 37
38void nvdisp_disp0::OnOpen(DeviceFD fd) {} 38void nvdisp_disp0::OnOpen(size_t session_id, DeviceFD fd) {}
39void nvdisp_disp0::OnClose(DeviceFD fd) {} 39void nvdisp_disp0::OnClose(DeviceFD fd) {}
40 40
41void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat format, u32 width, 41void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat format, u32 width,
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index daee05fe8..4e32ec191 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -32,7 +32,7 @@ public:
32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
33 std::span<u8> inline_output) override; 33 std::span<u8> inline_output) override;
34 34
35 void OnOpen(DeviceFD fd) override; 35 void OnOpen(size_t session_id, DeviceFD fd) override;
36 void OnClose(DeviceFD fd) override; 36 void OnClose(DeviceFD fd) override;
37 37
38 /// Performs a screen flip, drawing the buffer pointed to by the handle. 38 /// Performs a screen flip, drawing the buffer pointed to by the handle.
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 6b3639008..c92a7b2f6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -86,7 +86,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i
86 return NvResult::NotImplemented; 86 return NvResult::NotImplemented;
87} 87}
88 88
89void nvhost_as_gpu::OnOpen(DeviceFD fd) {} 89void nvhost_as_gpu::OnOpen(size_t session_id, DeviceFD fd) {}
90void nvhost_as_gpu::OnClose(DeviceFD fd) {} 90void nvhost_as_gpu::OnClose(DeviceFD fd) {}
91 91
92NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { 92NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
index 79a21683d..0dd279f88 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -55,7 +55,7 @@ public:
55 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 55 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
56 std::span<u8> inline_output) override; 56 std::span<u8> inline_output) override;
57 57
58 void OnOpen(DeviceFD fd) override; 58 void OnOpen(size_t session_id, DeviceFD fd) override;
59 void OnClose(DeviceFD fd) override; 59 void OnClose(DeviceFD fd) override;
60 60
61 Kernel::KEvent* QueryEvent(u32 event_id) override; 61 Kernel::KEvent* QueryEvent(u32 event_id) override;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index b8dd34e24..c4033cf1b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -76,7 +76,7 @@ NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inp
76 return NvResult::NotImplemented; 76 return NvResult::NotImplemented;
77} 77}
78 78
79void nvhost_ctrl::OnOpen(DeviceFD fd) {} 79void nvhost_ctrl::OnOpen(size_t session_id, DeviceFD fd) {}
80 80
81void nvhost_ctrl::OnClose(DeviceFD fd) {} 81void nvhost_ctrl::OnClose(DeviceFD fd) {}
82 82
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index 992124b60..84f419f16 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -32,7 +32,7 @@ public:
32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
33 std::span<u8> inline_output) override; 33 std::span<u8> inline_output) override;
34 34
35 void OnOpen(DeviceFD fd) override; 35 void OnOpen(size_t session_id, DeviceFD fd) override;
36 void OnClose(DeviceFD fd) override; 36 void OnClose(DeviceFD fd) override;
37 37
38 Kernel::KEvent* QueryEvent(u32 event_id) override; 38 Kernel::KEvent* QueryEvent(u32 event_id) override;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 3e0c96456..75276c37c 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -82,7 +82,7 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8>
82 return NvResult::NotImplemented; 82 return NvResult::NotImplemented;
83} 83}
84 84
85void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} 85void nvhost_ctrl_gpu::OnOpen(size_t session_id, DeviceFD fd) {}
86void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} 86void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {}
87 87
88NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) { 88NvResult nvhost_ctrl_gpu::GetCharacteristics1(IoctlCharacteristics& params) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
index d170299bd..6147e37cc 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -28,7 +28,7 @@ public:
28 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 28 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
29 std::span<u8> inline_output) override; 29 std::span<u8> inline_output) override;
30 30
31 void OnOpen(DeviceFD fd) override; 31 void OnOpen(size_t session_id, DeviceFD fd) override;
32 void OnClose(DeviceFD fd) override; 32 void OnClose(DeviceFD fd) override;
33 33
34 Kernel::KEvent* QueryEvent(u32 event_id) override; 34 Kernel::KEvent* QueryEvent(u32 event_id) override;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index b0395c2f0..0929c7128 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -120,7 +120,7 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
120 return NvResult::NotImplemented; 120 return NvResult::NotImplemented;
121} 121}
122 122
123void nvhost_gpu::OnOpen(DeviceFD fd) {} 123void nvhost_gpu::OnOpen(size_t session_id, DeviceFD fd) {}
124void nvhost_gpu::OnClose(DeviceFD fd) {} 124void nvhost_gpu::OnClose(DeviceFD fd) {}
125 125
126NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { 126NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index 88fd228ff..f5a396c40 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -47,7 +47,7 @@ public:
47 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 47 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
48 std::span<u8> inline_output) override; 48 std::span<u8> inline_output) override;
49 49
50 void OnOpen(DeviceFD fd) override; 50 void OnOpen(size_t session_id, DeviceFD fd) override;
51 void OnClose(DeviceFD fd) override; 51 void OnClose(DeviceFD fd) override;
52 52
53 Kernel::KEvent* QueryEvent(u32 event_id) override; 53 Kernel::KEvent* QueryEvent(u32 event_id) override;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index f43914e1b..63228518e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -35,7 +35,7 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
35 case 0x7: 35 case 0x7:
36 return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output); 36 return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output);
37 case 0x9: 37 case 0x9:
38 return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output); 38 return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output, fd);
39 case 0xa: 39 case 0xa:
40 return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output); 40 return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output);
41 default: 41 default:
@@ -68,9 +68,10 @@ NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in
68 return NvResult::NotImplemented; 68 return NvResult::NotImplemented;
69} 69}
70 70
71void nvhost_nvdec::OnOpen(DeviceFD fd) { 71void nvhost_nvdec::OnOpen(size_t session_id, DeviceFD fd) {
72 LOG_INFO(Service_NVDRV, "NVDEC video stream started"); 72 LOG_INFO(Service_NVDRV, "NVDEC video stream started");
73 system.SetNVDECActive(true); 73 system.SetNVDECActive(true);
74 sessions[fd] = session_id;
74} 75}
75 76
76void nvhost_nvdec::OnClose(DeviceFD fd) { 77void nvhost_nvdec::OnClose(DeviceFD fd) {
@@ -81,6 +82,10 @@ void nvhost_nvdec::OnClose(DeviceFD fd) {
81 system.GPU().ClearCdmaInstance(iter->second); 82 system.GPU().ClearCdmaInstance(iter->second);
82 } 83 }
83 system.SetNVDECActive(false); 84 system.SetNVDECActive(false);
85 auto it = sessions.find(fd);
86 if (it != sessions.end()) {
87 sessions.erase(it);
88 }
84} 89}
85 90
86} // namespace Service::Nvidia::Devices 91} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index ad2233c49..1fb27b814 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -20,7 +20,7 @@ public:
20 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 20 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
21 std::span<u8> inline_output) override; 21 std::span<u8> inline_output) override;
22 22
23 void OnOpen(DeviceFD fd) override; 23 void OnOpen(size_t session_id, DeviceFD fd) override;
24 void OnClose(DeviceFD fd) override; 24 void OnClose(DeviceFD fd) override;
25}; 25};
26 26
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 74c701b95..9ab0ae4d8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -133,10 +133,10 @@ NvResult nvhost_nvdec_common::GetWaitbase(IoctlGetWaitbase& params) {
133 return NvResult::Success; 133 return NvResult::Success;
134} 134}
135 135
136NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries) { 136NvResult nvhost_nvdec_common::MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries, DeviceFD fd) {
137 const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size())); 137 const size_t num_entries = std::min(params.num_entries, static_cast<u32>(entries.size()));
138 for (size_t i = 0; i < num_entries; i++) { 138 for (size_t i = 0; i < num_entries; i++) {
139 entries[i].map_address = nvmap.PinHandle(entries[i].map_handle); 139 entries[i].map_address = nvmap.PinHandle(entries[i].map_handle, sessions[fd]);
140 } 140 }
141 141
142 return NvResult::Success; 142 return NvResult::Success;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 7ce748e18..b44b17a82 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -5,6 +5,8 @@
5 5
6#include <deque> 6#include <deque>
7#include <vector> 7#include <vector>
8#include <unordered_map>
9
8#include "common/common_types.h" 10#include "common/common_types.h"
9#include "common/swap.h" 11#include "common/swap.h"
10#include "core/hle/service/nvdrv/core/syncpoint_manager.h" 12#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
@@ -111,7 +113,7 @@ protected:
111 NvResult Submit(IoctlSubmit& params, std::span<u8> input, DeviceFD fd); 113 NvResult Submit(IoctlSubmit& params, std::span<u8> input, DeviceFD fd);
112 NvResult GetSyncpoint(IoctlGetSyncpoint& params); 114 NvResult GetSyncpoint(IoctlGetSyncpoint& params);
113 NvResult GetWaitbase(IoctlGetWaitbase& params); 115 NvResult GetWaitbase(IoctlGetWaitbase& params);
114 NvResult MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries); 116 NvResult MapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries, DeviceFD fd);
115 NvResult UnmapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries); 117 NvResult UnmapBuffer(IoctlMapBuffer& params, std::span<MapBufferEntry> entries);
116 NvResult SetSubmitTimeout(u32 timeout); 118 NvResult SetSubmitTimeout(u32 timeout);
117 119
@@ -125,6 +127,7 @@ protected:
125 NvCore::NvMap& nvmap; 127 NvCore::NvMap& nvmap;
126 NvCore::ChannelType channel_type; 128 NvCore::ChannelType channel_type;
127 std::array<u32, MaxSyncPoints> device_syncpoints{}; 129 std::array<u32, MaxSyncPoints> device_syncpoints{};
130 std::unordered_map<DeviceFD, size_t> sessions;
128}; 131};
129}; // namespace Devices 132}; // namespace Devices
130} // namespace Service::Nvidia 133} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
index 9e6b86458..1c88b39ab 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
@@ -44,7 +44,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in
44 return NvResult::NotImplemented; 44 return NvResult::NotImplemented;
45} 45}
46 46
47void nvhost_nvjpg::OnOpen(DeviceFD fd) {} 47void nvhost_nvjpg::OnOpen(size_t session_id, DeviceFD fd) {}
48void nvhost_nvjpg::OnClose(DeviceFD fd) {} 48void nvhost_nvjpg::OnClose(DeviceFD fd) {}
49 49
50NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) { 50NvResult nvhost_nvjpg::SetNVMAPfd(IoctlSetNvmapFD& params) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
index 790c97f6a..3e33dffef 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
@@ -22,7 +22,7 @@ public:
22 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 22 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
23 std::span<u8> inline_output) override; 23 std::span<u8> inline_output) override;
24 24
25 void OnOpen(DeviceFD fd) override; 25 void OnOpen(size_t session_id, DeviceFD fd) override;
26 void OnClose(DeviceFD fd) override; 26 void OnClose(DeviceFD fd) override;
27 27
28private: 28private:
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index 87f8d7c22..d4c93ea5d 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -33,7 +33,7 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
33 case 0x3: 33 case 0x3:
34 return WrapFixed(this, &nvhost_vic::GetWaitbase, input, output); 34 return WrapFixed(this, &nvhost_vic::GetWaitbase, input, output);
35 case 0x9: 35 case 0x9:
36 return WrapFixedVariable(this, &nvhost_vic::MapBuffer, input, output); 36 return WrapFixedVariable(this, &nvhost_vic::MapBuffer, input, output, fd);
37 case 0xa: 37 case 0xa:
38 return WrapFixedVariable(this, &nvhost_vic::UnmapBuffer, input, output); 38 return WrapFixedVariable(this, &nvhost_vic::UnmapBuffer, input, output);
39 default: 39 default:
@@ -68,7 +68,9 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
68 return NvResult::NotImplemented; 68 return NvResult::NotImplemented;
69} 69}
70 70
71void nvhost_vic::OnOpen(DeviceFD fd) {} 71void nvhost_vic::OnOpen(size_t session_id, DeviceFD fd) {
72 sessions[fd] = session_id;
73}
72 74
73void nvhost_vic::OnClose(DeviceFD fd) { 75void nvhost_vic::OnClose(DeviceFD fd) {
74 auto& host1x_file = core.Host1xDeviceFile(); 76 auto& host1x_file = core.Host1xDeviceFile();
@@ -76,6 +78,10 @@ void nvhost_vic::OnClose(DeviceFD fd) {
76 if (iter != host1x_file.fd_to_id.end()) { 78 if (iter != host1x_file.fd_to_id.end()) {
77 system.GPU().ClearCdmaInstance(iter->second); 79 system.GPU().ClearCdmaInstance(iter->second);
78 } 80 }
81 auto it = sessions.find(fd);
82 if (it != sessions.end()) {
83 sessions.erase(it);
84 }
79} 85}
80 86
81} // namespace Service::Nvidia::Devices 87} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index cadbcb0a5..d70df0f20 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -19,7 +19,7 @@ public:
19 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 19 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
20 std::span<u8> inline_output) override; 20 std::span<u8> inline_output) override;
21 21
22 void OnOpen(DeviceFD fd) override; 22 void OnOpen(size_t session_id, DeviceFD fd) override;
23 void OnClose(DeviceFD fd) override; 23 void OnClose(DeviceFD fd) override;
24}; 24};
25} // namespace Service::Nvidia::Devices 25} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 71b2e62ec..2b107f009 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -36,9 +36,9 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
36 case 0x3: 36 case 0x3:
37 return WrapFixed(this, &nvmap::IocFromId, input, output); 37 return WrapFixed(this, &nvmap::IocFromId, input, output);
38 case 0x4: 38 case 0x4:
39 return WrapFixed(this, &nvmap::IocAlloc, input, output); 39 return WrapFixed(this, &nvmap::IocAlloc, input, output, fd);
40 case 0x5: 40 case 0x5:
41 return WrapFixed(this, &nvmap::IocFree, input, output); 41 return WrapFixed(this, &nvmap::IocFree, input, output, fd);
42 case 0x9: 42 case 0x9:
43 return WrapFixed(this, &nvmap::IocParam, input, output); 43 return WrapFixed(this, &nvmap::IocParam, input, output);
44 case 0xe: 44 case 0xe:
@@ -67,8 +67,15 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, st
67 return NvResult::NotImplemented; 67 return NvResult::NotImplemented;
68} 68}
69 69
70void nvmap::OnOpen(DeviceFD fd) {} 70void nvmap::OnOpen(size_t session_id, DeviceFD fd) {
71void nvmap::OnClose(DeviceFD fd) {} 71 sessions[fd] = session_id;
72}
73void nvmap::OnClose(DeviceFD fd) {
74 auto it = sessions.find(fd);
75 if (it != sessions.end()) {
76 sessions.erase(it);
77 }
78}
72 79
73NvResult nvmap::IocCreate(IocCreateParams& params) { 80NvResult nvmap::IocCreate(IocCreateParams& params) {
74 LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); 81 LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size);
@@ -87,7 +94,7 @@ NvResult nvmap::IocCreate(IocCreateParams& params) {
87 return NvResult::Success; 94 return NvResult::Success;
88} 95}
89 96
90NvResult nvmap::IocAlloc(IocAllocParams& params) { 97NvResult nvmap::IocAlloc(IocAllocParams& params, DeviceFD fd) {
91 LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); 98 LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address);
92 99
93 if (!params.handle) { 100 if (!params.handle) {
@@ -116,15 +123,15 @@ NvResult nvmap::IocAlloc(IocAllocParams& params) {
116 return NvResult::InsufficientMemory; 123 return NvResult::InsufficientMemory;
117 } 124 }
118 125
119 const auto result = 126 const auto result = file.AllocateHandle(params.handle, params.flags, params.align, params.kind,
120 handle_description->Alloc(params.flags, params.align, params.kind, params.address); 127 params.address, sessions[fd]);
121 if (result != NvResult::Success) { 128 if (result != NvResult::Success) {
122 LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle); 129 LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle);
123 return result; 130 return result;
124 } 131 }
125 bool is_out_io{}; 132 bool is_out_io{};
126 ASSERT(system.ApplicationProcess() 133 auto process = container.GetSession(sessions[fd])->process;
127 ->GetPageTable() 134 ASSERT(process->GetPageTable()
128 .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address, 135 .LockForMapDeviceAddressSpace(&is_out_io, handle_description->address,
129 handle_description->size, 136 handle_description->size,
130 Kernel::KMemoryPermission::None, true, false) 137 Kernel::KMemoryPermission::None, true, false)
@@ -224,7 +231,7 @@ NvResult nvmap::IocParam(IocParamParams& params) {
224 return NvResult::Success; 231 return NvResult::Success;
225} 232}
226 233
227NvResult nvmap::IocFree(IocFreeParams& params) { 234NvResult nvmap::IocFree(IocFreeParams& params, DeviceFD fd) {
228 LOG_DEBUG(Service_NVDRV, "called"); 235 LOG_DEBUG(Service_NVDRV, "called");
229 236
230 if (!params.handle) { 237 if (!params.handle) {
@@ -233,9 +240,9 @@ NvResult nvmap::IocFree(IocFreeParams& params) {
233 } 240 }
234 241
235 if (auto freeInfo{file.FreeHandle(params.handle, false)}) { 242 if (auto freeInfo{file.FreeHandle(params.handle, false)}) {
243 auto process = container.GetSession(sessions[fd])->process;
236 if (freeInfo->can_unlock) { 244 if (freeInfo->can_unlock) {
237 ASSERT(system.ApplicationProcess() 245 ASSERT(process->GetPageTable()
238 ->GetPageTable()
239 .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size) 246 .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size)
240 .IsSuccess()); 247 .IsSuccess());
241 } 248 }
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index 049c11028..ea5df2a9c 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -33,7 +33,7 @@ public:
33 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output, 33 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
34 std::span<u8> inline_output) override; 34 std::span<u8> inline_output) override;
35 35
36 void OnOpen(DeviceFD fd) override; 36 void OnOpen(size_t session_id, DeviceFD fd) override;
37 void OnClose(DeviceFD fd) override; 37 void OnClose(DeviceFD fd) override;
38 38
39 enum class HandleParameterType : u32_le { 39 enum class HandleParameterType : u32_le {
@@ -100,11 +100,11 @@ public:
100 static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); 100 static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");
101 101
102 NvResult IocCreate(IocCreateParams& params); 102 NvResult IocCreate(IocCreateParams& params);
103 NvResult IocAlloc(IocAllocParams& params); 103 NvResult IocAlloc(IocAllocParams& params, DeviceFD fd);
104 NvResult IocGetId(IocGetIdParams& params); 104 NvResult IocGetId(IocGetIdParams& params);
105 NvResult IocFromId(IocFromIdParams& params); 105 NvResult IocFromId(IocFromIdParams& params);
106 NvResult IocParam(IocParamParams& params); 106 NvResult IocParam(IocParamParams& params);
107 NvResult IocFree(IocFreeParams& params); 107 NvResult IocFree(IocFreeParams& params, DeviceFD fd);
108 108
109private: 109private:
110 /// Id to use for the next handle that is created. 110 /// Id to use for the next handle that is created.
@@ -115,6 +115,7 @@ private:
115 115
116 NvCore::Container& container; 116 NvCore::Container& container;
117 NvCore::NvMap& file; 117 NvCore::NvMap& file;
118 std::unordered_map<DeviceFD, size_t> sessions;
118}; 119};
119 120
120} // namespace Service::Nvidia::Devices 121} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 9e46ee8dd..5191341db 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -45,13 +45,22 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) {
45void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { 45void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
46 auto server_manager = std::make_unique<ServerManager>(system); 46 auto server_manager = std::make_unique<ServerManager>(system);
47 auto module = std::make_shared<Module>(system); 47 auto module = std::make_shared<Module>(system);
48 server_manager->RegisterNamedService("nvdrv", std::make_shared<NVDRV>(system, module, "nvdrv")); 48 const auto NvdrvInterfaceFactoryForApplication = [&, module] {
49 server_manager->RegisterNamedService("nvdrv:a", 49 return std::make_shared<NVDRV>(system, module, "nvdrv");
50 std::make_shared<NVDRV>(system, module, "nvdrv:a")); 50 };
51 server_manager->RegisterNamedService("nvdrv:s", 51 const auto NvdrvInterfaceFactoryForApplets = [&, module] {
52 std::make_shared<NVDRV>(system, module, "nvdrv:s")); 52 return std::make_shared<NVDRV>(system, module, "nvdrv:a");
53 server_manager->RegisterNamedService("nvdrv:t", 53 };
54 std::make_shared<NVDRV>(system, module, "nvdrv:t")); 54 const auto NvdrvInterfaceFactoryForSysmodules = [&, module] {
55 return std::make_shared<NVDRV>(system, module, "nvdrv:a");
56 };
57 const auto NvdrvInterfaceFactory = [&, module] {
58 return std::make_shared<NVDRV>(system, module, "nvdrv:t");
59 };
60 server_manager->RegisterNamedService("nvdrv", NvdrvInterfaceFactoryForApplication);
61 server_manager->RegisterNamedService("nvdrv:a", NvdrvInterfaceFactoryForApplets);
62 server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules);
63 server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactory);
55 server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system)); 64 server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system));
56 nvnflinger.SetNVDrvInstance(module); 65 nvnflinger.SetNVDrvInstance(module);
57 ServerManager::RunServer(std::move(server_manager)); 66 ServerManager::RunServer(std::move(server_manager));
@@ -113,7 +122,7 @@ NvResult Module::VerifyFD(DeviceFD fd) const {
113 return NvResult::Success; 122 return NvResult::Success;
114} 123}
115 124
116DeviceFD Module::Open(const std::string& device_name) { 125DeviceFD Module::Open(const std::string& device_name, size_t session_id) {
117 auto it = builders.find(device_name); 126 auto it = builders.find(device_name);
118 if (it == builders.end()) { 127 if (it == builders.end()) {
119 LOG_ERROR(Service_NVDRV, "Trying to open unknown device {}", device_name); 128 LOG_ERROR(Service_NVDRV, "Trying to open unknown device {}", device_name);
@@ -124,7 +133,7 @@ DeviceFD Module::Open(const std::string& device_name) {
124 auto& builder = it->second; 133 auto& builder = it->second;
125 auto device = builder(fd)->second; 134 auto device = builder(fd)->second;
126 135
127 device->OnOpen(fd); 136 device->OnOpen(session_id, fd);
128 137
129 return fd; 138 return fd;
130} 139}
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index d8622b3ca..d7648fb15 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -77,7 +77,7 @@ public:
77 NvResult VerifyFD(DeviceFD fd) const; 77 NvResult VerifyFD(DeviceFD fd) const;
78 78
79 /// Opens a device node and returns a file descriptor to it. 79 /// Opens a device node and returns a file descriptor to it.
80 DeviceFD Open(const std::string& device_name); 80 DeviceFD Open(const std::string& device_name, size_t session_id);
81 81
82 /// Sends an ioctl command to the specified file descriptor. 82 /// Sends an ioctl command to the specified file descriptor.
83 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output); 83 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output);
@@ -93,6 +93,10 @@ public:
93 93
94 NvResult QueryEvent(DeviceFD fd, u32 event_id, Kernel::KEvent*& event); 94 NvResult QueryEvent(DeviceFD fd, u32 event_id, Kernel::KEvent*& event);
95 95
96 NvCore::Container& GetContainer() {
97 return container;
98 }
99
96private: 100private:
97 friend class EventInterface; 101 friend class EventInterface;
98 friend class Service::Nvnflinger::Nvnflinger; 102 friend class Service::Nvnflinger::Nvnflinger;
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
index c8a880e84..492ad849a 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
@@ -3,14 +3,18 @@
3// SPDX-License-Identifier: GPL-3.0-or-later 3// SPDX-License-Identifier: GPL-3.0-or-later
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "common/scope_exit.h"
6#include "core/core.h" 7#include "core/core.h"
7#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
9#include "core/hle/kernel/k_process.h"
8#include "core/hle/kernel/k_readable_event.h" 10#include "core/hle/kernel/k_readable_event.h"
9#include "core/hle/service/ipc_helpers.h" 11#include "core/hle/service/ipc_helpers.h"
10#include "core/hle/service/nvdrv/nvdata.h" 12#include "core/hle/service/nvdrv/nvdata.h"
11#include "core/hle/service/nvdrv/nvdrv.h" 13#include "core/hle/service/nvdrv/nvdrv.h"
12#include "core/hle/service/nvdrv/nvdrv_interface.h" 14#include "core/hle/service/nvdrv/nvdrv_interface.h"
13 15
16#pragma optimize("", off)
17
14namespace Service::Nvidia { 18namespace Service::Nvidia {
15 19
16void NVDRV::Open(HLERequestContext& ctx) { 20void NVDRV::Open(HLERequestContext& ctx) {
@@ -37,7 +41,7 @@ void NVDRV::Open(HLERequestContext& ctx) {
37 return; 41 return;
38 } 42 }
39 43
40 DeviceFD fd = nvdrv->Open(device_name); 44 DeviceFD fd = nvdrv->Open(device_name, session_id);
41 45
42 rb.Push<DeviceFD>(fd); 46 rb.Push<DeviceFD>(fd);
43 rb.PushEnum(fd != INVALID_NVDRV_FD ? NvResult::Success : NvResult::FileOperationFailed); 47 rb.PushEnum(fd != INVALID_NVDRV_FD ? NvResult::Success : NvResult::FileOperationFailed);
@@ -150,12 +154,29 @@ void NVDRV::Close(HLERequestContext& ctx) {
150 154
151void NVDRV::Initialize(HLERequestContext& ctx) { 155void NVDRV::Initialize(HLERequestContext& ctx) {
152 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 156 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
157 IPC::ResponseBuilder rb{ctx, 3};
158 SCOPE_EXIT({
159 rb.Push(ResultSuccess);
160 rb.PushEnum(NvResult::Success);
161 });
153 162
154 is_initialized = true; 163 if (is_initialized) {
164 // No need to initialize again
165 return;
166 }
155 167
156 IPC::ResponseBuilder rb{ctx, 3}; 168 IPC::RequestParser rp{ctx};
157 rb.Push(ResultSuccess); 169 const auto process_handle{ctx.GetCopyHandle(0)};
158 rb.PushEnum(NvResult::Success); 170 // The transfer memory is lent to nvdrv as a work buffer since nvdrv is
171 // unable to allocate as much memory on its own. For HLE it's unnecessary to handle it
172 [[maybe_unused]] const auto transfer_memory_handle{ctx.GetCopyHandle(1)};
173 [[maybe_unused]] const auto transfer_memory_size = rp.Pop<u32>();
174
175 auto& container = nvdrv->GetContainer();
176 auto process = ctx.GetObjectFromHandle(process_handle);
177 session_id = container.OpenSession(process->DynamicCast<Kernel::KProcess*>());
178
179 is_initialized = true;
159} 180}
160 181
161void NVDRV::QueryEvent(HLERequestContext& ctx) { 182void NVDRV::QueryEvent(HLERequestContext& ctx) {
@@ -242,6 +263,9 @@ NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char*
242 RegisterHandlers(functions); 263 RegisterHandlers(functions);
243} 264}
244 265
245NVDRV::~NVDRV() = default; 266NVDRV::~NVDRV() {
267 auto& container = nvdrv->GetContainer();
268 container.CloseSession(session_id);
269}
246 270
247} // namespace Service::Nvidia 271} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index 6e98115dc..e7237c881 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
@@ -35,6 +35,7 @@ private:
35 35
36 u64 pid{}; 36 u64 pid{};
37 bool is_initialized{}; 37 bool is_initialized{};
38 size_t session_id{};
38 Common::ScratchBuffer<u8> output_buffer; 39 Common::ScratchBuffer<u8> output_buffer;
39 Common::ScratchBuffer<u8> inline_output_buffer; 40 Common::ScratchBuffer<u8> inline_output_buffer;
40}; 41};
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp
index 2fef6cc1a..d36eff4ec 100644
--- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp
+++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp
@@ -87,19 +87,19 @@ Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap,
87 R_SUCCEED(); 87 R_SUCCEED();
88} 88}
89 89
90Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { 90Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Nvidia::DeviceFD nvmap_fd) {
91 // Free the handle. 91 // Free the handle.
92 Nvidia::Devices::nvmap::IocFreeParams free_params{ 92 Nvidia::Devices::nvmap::IocFreeParams free_params{
93 .handle = handle, 93 .handle = handle,
94 }; 94 };
95 R_UNLESS(nvmap.IocFree(free_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); 95 R_UNLESS(nvmap.IocFree(free_params, nvmap_fd) == Nvidia::NvResult::Success, VI::ResultOperationFailed);
96 96
97 // We succeeded. 97 // We succeeded.
98 R_SUCCEED(); 98 R_SUCCEED();
99} 99}
100 100
101Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer, 101Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer,
102 u32 size) { 102 u32 size, Nvidia::DeviceFD nvmap_fd) {
103 // Assign the allocated memory to the handle. 103 // Assign the allocated memory to the handle.
104 Nvidia::Devices::nvmap::IocAllocParams alloc_params{ 104 Nvidia::Devices::nvmap::IocAllocParams alloc_params{
105 .handle = handle, 105 .handle = handle,
@@ -109,16 +109,15 @@ Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::Proce
109 .kind = 0, 109 .kind = 0,
110 .address = GetInteger(buffer), 110 .address = GetInteger(buffer),
111 }; 111 };
112 R_UNLESS(nvmap.IocAlloc(alloc_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed); 112 R_UNLESS(nvmap.IocAlloc(alloc_params, nvmap_fd) == Nvidia::NvResult::Success, VI::ResultOperationFailed);
113 113
114 // We succeeded. 114 // We succeeded.
115 R_SUCCEED(); 115 R_SUCCEED();
116} 116}
117 117
118Result AllocateHandleForBuffer(u32* out_handle, Nvidia::Module& nvdrv, 118Result AllocateHandleForBuffer(u32* out_handle, Nvidia::Module& nvdrv, Nvidia::DeviceFD nvmap_fd,
119 Common::ProcessAddress buffer, u32 size) { 119 Common::ProcessAddress buffer, u32 size) {
120 // Get the nvmap device. 120 // Get the nvmap device.
121 auto nvmap_fd = nvdrv.Open("/dev/nvmap");
122 auto nvmap = nvdrv.GetDevice<Nvidia::Devices::nvmap>(nvmap_fd); 121 auto nvmap = nvdrv.GetDevice<Nvidia::Devices::nvmap>(nvmap_fd);
123 ASSERT(nvmap != nullptr); 122 ASSERT(nvmap != nullptr);
124 123
@@ -127,11 +126,11 @@ Result AllocateHandleForBuffer(u32* out_handle, Nvidia::Module& nvdrv,
127 126
128 // Ensure we maintain a clean state on failure. 127 // Ensure we maintain a clean state on failure.
129 ON_RESULT_FAILURE { 128 ON_RESULT_FAILURE {
130 ASSERT(R_SUCCEEDED(FreeNvMapHandle(*nvmap, *out_handle))); 129 ASSERT(R_SUCCEEDED(FreeNvMapHandle(*nvmap, *out_handle, nvmap_fd)));
131 }; 130 };
132 131
133 // Assign the allocated memory to the handle. 132 // Assign the allocated memory to the handle.
134 R_RETURN(AllocNvMapHandle(*nvmap, *out_handle, buffer, size)); 133 R_RETURN(AllocNvMapHandle(*nvmap, *out_handle, buffer, size, nvmap_fd));
135} 134}
136 135
137constexpr auto SharedBufferBlockLinearFormat = android::PixelFormat::Rgba8888; 136constexpr auto SharedBufferBlockLinearFormat = android::PixelFormat::Rgba8888;
@@ -197,8 +196,12 @@ Result FbShareBufferManager::Initialize(u64* out_buffer_id, u64* out_layer_id, u
197 std::addressof(m_buffer_page_group), m_system, 196 std::addressof(m_buffer_page_group), m_system,
198 SharedBufferSize)); 197 SharedBufferSize));
199 198
199 auto& container = m_nvdrv->GetContainer();
200 m_session_id = container.OpenSession(m_system.ApplicationProcess());
201 m_nvmap_fd = m_nvdrv->Open("/dev/nvmap", m_session_id);
202
200 // Create an nvmap handle for the buffer and assign the memory to it. 203 // Create an nvmap handle for the buffer and assign the memory to it.
201 R_TRY(AllocateHandleForBuffer(std::addressof(m_buffer_nvmap_handle), *m_nvdrv, map_address, 204 R_TRY(AllocateHandleForBuffer(std::addressof(m_buffer_nvmap_handle), *m_nvdrv, m_nvmap_fd, map_address,
202 SharedBufferSize)); 205 SharedBufferSize));
203 206
204 // Record the display id. 207 // Record the display id.
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h
index c809c01b4..4b1a3d430 100644
--- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h
+++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.h
@@ -6,6 +6,7 @@
6#include "common/math_util.h" 6#include "common/math_util.h"
7#include "core/hle/service/nvnflinger/nvnflinger.h" 7#include "core/hle/service/nvnflinger/nvnflinger.h"
8#include "core/hle/service/nvnflinger/ui/fence.h" 8#include "core/hle/service/nvnflinger/ui/fence.h"
9#include "core/hle/service/nvdrv/nvdata.h"
9 10
10namespace Kernel { 11namespace Kernel {
11class KPageGroup; 12class KPageGroup;
@@ -53,13 +54,15 @@ private:
53 u64 m_layer_id = 0; 54 u64 m_layer_id = 0;
54 u32 m_buffer_nvmap_handle = 0; 55 u32 m_buffer_nvmap_handle = 0;
55 SharedMemoryPoolLayout m_pool_layout = {}; 56 SharedMemoryPoolLayout m_pool_layout = {};
56 57 Nvidia::DeviceFD m_nvmap_fd = {};
58 size_t m_session_id = {};
57 std::unique_ptr<Kernel::KPageGroup> m_buffer_page_group; 59 std::unique_ptr<Kernel::KPageGroup> m_buffer_page_group;
58 60
59 std::mutex m_guard; 61 std::mutex m_guard;
60 Core::System& m_system; 62 Core::System& m_system;
61 Nvnflinger& m_flinger; 63 Nvnflinger& m_flinger;
62 std::shared_ptr<Nvidia::Module> m_nvdrv; 64 std::shared_ptr<Nvidia::Module> m_nvdrv;
65
63}; 66};
64 67
65} // namespace Service::Nvnflinger 68} // namespace Service::Nvnflinger
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index 0469110e8..e4b38ae0b 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -126,7 +126,7 @@ void Nvnflinger::ShutdownLayers() {
126 126
127void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { 127void Nvnflinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
128 nvdrv = std::move(instance); 128 nvdrv = std::move(instance);
129 disp_fd = nvdrv->Open("/dev/nvdisp_disp0"); 129 disp_fd = nvdrv->Open("/dev/nvdisp_disp0", 0);
130} 130}
131 131
132std::optional<u64> Nvnflinger::OpenDisplay(std::string_view name) { 132std::optional<u64> Nvnflinger::OpenDisplay(std::string_view name) {
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index c22c7631c..2dda8ebc2 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -71,6 +71,8 @@ add_library(video_core STATIC
71 host1x/ffmpeg/ffmpeg.h 71 host1x/ffmpeg/ffmpeg.h
72 host1x/control.cpp 72 host1x/control.cpp
73 host1x/control.h 73 host1x/control.h
74 host1x/gpu_device_memory_manager.cpp
75 host1x/gpu_device_memory_manager.h
74 host1x/host1x.cpp 76 host1x/host1x.cpp
75 host1x/host1x.h 77 host1x/host1x.h
76 host1x/nvdec.cpp 78 host1x/nvdec.cpp
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 11549d448..1e915682f 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -85,7 +85,7 @@ struct GPU::Impl {
85 void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) { 85 void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) {
86 renderer = std::move(renderer_); 86 renderer = std::move(renderer_);
87 rasterizer = renderer->ReadRasterizer(); 87 rasterizer = renderer->ReadRasterizer();
88 host1x.MemoryManager().BindRasterizer(rasterizer); 88 host1x.MemoryManager().BindInterface(rasterizer);
89 } 89 }
90 90
91 /// Flush all current written commands into the host GPU for execution. 91 /// Flush all current written commands into the host GPU for execution.
diff --git a/src/video_core/host1x/host1x.cpp b/src/video_core/host1x/host1x.cpp
index 7c317a85d..d05bcaf26 100644
--- a/src/video_core/host1x/host1x.cpp
+++ b/src/video_core/host1x/host1x.cpp
@@ -9,8 +9,7 @@ namespace Tegra {
9namespace Host1x { 9namespace Host1x {
10 10
11Host1x::Host1x(Core::System& system_) 11Host1x::Host1x(Core::System& system_)
12 : system{system_}, syncpoint_manager{}, memory_manager{system, 32, 12}, 12 : system{system_}, syncpoint_manager{}, memory_manager(system.DeviceMemory()) {}
13 allocator{std::make_unique<Common::FlatAllocator<u32, 0, 32>>(1 << 12)} {}
14 13
15} // namespace Host1x 14} // namespace Host1x
16 15
diff --git a/src/video_core/host1x/host1x.h b/src/video_core/host1x/host1x.h
index 57082ae54..18f7389f6 100644
--- a/src/video_core/host1x/host1x.h
+++ b/src/video_core/host1x/host1x.h
@@ -5,9 +5,8 @@
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7 7
8#include "common/address_space.h" 8#include "video_core/host1x/gpu_device_memory_manager.h"
9#include "video_core/host1x/syncpoint_manager.h" 9#include "video_core/host1x/syncpoint_manager.h"
10#include "video_core/memory_manager.h"
11 10
12namespace Core { 11namespace Core {
13class System; 12class System;
@@ -29,27 +28,18 @@ public:
29 return syncpoint_manager; 28 return syncpoint_manager;
30 } 29 }
31 30
32 Tegra::MemoryManager& MemoryManager() { 31 Tegra::MaxwellDeviceMemoryManager& MemoryManager() {
33 return memory_manager; 32 return memory_manager;
34 } 33 }
35 34
36 const Tegra::MemoryManager& MemoryManager() const { 35 const Tegra::MaxwellDeviceMemoryManager& MemoryManager() const {
37 return memory_manager; 36 return memory_manager;
38 } 37 }
39 38
40 Common::FlatAllocator<u32, 0, 32>& Allocator() {
41 return *allocator;
42 }
43
44 const Common::FlatAllocator<u32, 0, 32>& Allocator() const {
45 return *allocator;
46 }
47
48private: 39private:
49 Core::System& system; 40 Core::System& system;
50 SyncpointManager syncpoint_manager; 41 SyncpointManager syncpoint_manager;
51 Tegra::MemoryManager memory_manager; 42 Tegra::MaxwellDeviceMemoryManager memory_manager;
52 std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator;
53}; 43};
54 44
55} // namespace Host1x 45} // namespace Host1x