summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/svc.cpp8
-rw-r--r--src/core/hle/kernel/svc_wrap.h56
-rw-r--r--src/core/hle/kernel/thread.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp13
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp72
5 files changed, 107 insertions, 47 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 0b12d5ae9..e406df829 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -370,15 +370,15 @@ static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
370 370
371struct BreakReason { 371struct BreakReason {
372 union { 372 union {
373 u64 raw; 373 u32 raw;
374 BitField<31, 1, u64> dont_kill_application; 374 BitField<31, 1, u32> signal_debugger;
375 }; 375 };
376}; 376};
377 377
378/// Break program execution 378/// Break program execution
379static void Break(u64 reason, u64 info1, u64 info2) { 379static void Break(u32 reason, u64 info1, u64 info2) {
380 BreakReason break_reason{reason}; 380 BreakReason break_reason{reason};
381 if (break_reason.dont_kill_application) { 381 if (break_reason.signal_debugger) {
382 LOG_ERROR( 382 LOG_ERROR(
383 Debug_Emulated, 383 Debug_Emulated,
384 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}", 384 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 22712e64f..cbb80c3c4 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -35,18 +35,18 @@ void SvcWrap() {
35 35
36template <ResultCode func(u32)> 36template <ResultCode func(u32)>
37void SvcWrap() { 37void SvcWrap() {
38 FuncReturn(func((u32)Param(0)).raw); 38 FuncReturn(func(static_cast<u32>(Param(0))).raw);
39} 39}
40 40
41template <ResultCode func(u32, u32)> 41template <ResultCode func(u32, u32)>
42void SvcWrap() { 42void SvcWrap() {
43 FuncReturn(func((u32)Param(0), (u32)Param(1)).raw); 43 FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1))).raw);
44} 44}
45 45
46template <ResultCode func(u32*, u32)> 46template <ResultCode func(u32*, u32)>
47void SvcWrap() { 47void SvcWrap() {
48 u32 param_1 = 0; 48 u32 param_1 = 0;
49 u32 retval = func(&param_1, (u32)Param(1)).raw; 49 u32 retval = func(&param_1, static_cast<u32>(Param(1))).raw;
50 Core::CurrentArmInterface().SetReg(1, param_1); 50 Core::CurrentArmInterface().SetReg(1, param_1);
51 FuncReturn(retval); 51 FuncReturn(retval);
52} 52}
@@ -61,7 +61,7 @@ void SvcWrap() {
61 61
62template <ResultCode func(u64, s32)> 62template <ResultCode func(u64, s32)>
63void SvcWrap() { 63void SvcWrap() {
64 FuncReturn(func(Param(0), (s32)Param(1)).raw); 64 FuncReturn(func(Param(0), static_cast<s32>(Param(1))).raw);
65} 65}
66 66
67template <ResultCode func(u64, u32)> 67template <ResultCode func(u64, u32)>
@@ -79,19 +79,19 @@ void SvcWrap() {
79 79
80template <ResultCode func(u32, u64)> 80template <ResultCode func(u32, u64)>
81void SvcWrap() { 81void SvcWrap() {
82 FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), Param(1)).raw); 82 FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw);
83} 83}
84 84
85template <ResultCode func(u32, u32, u64)> 85template <ResultCode func(u32, u32, u64)>
86void SvcWrap() { 86void SvcWrap() {
87 FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), (u32)(Param(1) & 0xFFFFFFFF), Param(2)).raw); 87 FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1)), Param(2)).raw);
88} 88}
89 89
90template <ResultCode func(u32, u32*, u64*)> 90template <ResultCode func(u32, u32*, u64*)>
91void SvcWrap() { 91void SvcWrap() {
92 u32 param_1 = 0; 92 u32 param_1 = 0;
93 u64 param_2 = 0; 93 u64 param_2 = 0;
94 ResultCode retval = func((u32)(Param(2) & 0xFFFFFFFF), &param_1, &param_2); 94 ResultCode retval = func(static_cast<u32>(Param(2)), &param_1, &param_2);
95 Core::CurrentArmInterface().SetReg(1, param_1); 95 Core::CurrentArmInterface().SetReg(1, param_1);
96 Core::CurrentArmInterface().SetReg(2, param_2); 96 Core::CurrentArmInterface().SetReg(2, param_2);
97 FuncReturn(retval.raw); 97 FuncReturn(retval.raw);
@@ -100,12 +100,12 @@ void SvcWrap() {
100template <ResultCode func(u64, u64, u32, u32)> 100template <ResultCode func(u64, u64, u32, u32)>
101void SvcWrap() { 101void SvcWrap() {
102 FuncReturn( 102 FuncReturn(
103 func(Param(0), Param(1), (u32)(Param(3) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw); 103 func(Param(0), Param(1), static_cast<u32>(Param(3)), static_cast<u32>(Param(3))).raw);
104} 104}
105 105
106template <ResultCode func(u32, u64, u32)> 106template <ResultCode func(u32, u64, u32)>
107void SvcWrap() { 107void SvcWrap() {
108 FuncReturn(func((u32)Param(0), Param(1), (u32)Param(2)).raw); 108 FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw);
109} 109}
110 110
111template <ResultCode func(u64, u64, u64)> 111template <ResultCode func(u64, u64, u64)>
@@ -115,25 +115,28 @@ void SvcWrap() {
115 115
116template <ResultCode func(u32, u64, u64, u32)> 116template <ResultCode func(u32, u64, u64, u32)>
117void SvcWrap() { 117void SvcWrap() {
118 FuncReturn(func((u32)Param(0), Param(1), Param(2), (u32)Param(3)).raw); 118 FuncReturn(
119 func(static_cast<u32>(Param(0)), Param(1), Param(2), static_cast<u32>(Param(3))).raw);
119} 120}
120 121
121template <ResultCode func(u32, u64, u64)> 122template <ResultCode func(u32, u64, u64)>
122void SvcWrap() { 123void SvcWrap() {
123 FuncReturn(func((u32)Param(0), Param(1), Param(2)).raw); 124 FuncReturn(func(static_cast<u32>(Param(0)), Param(1), Param(2)).raw);
124} 125}
125 126
126template <ResultCode func(u32*, u64, u64, s64)> 127template <ResultCode func(u32*, u64, u64, s64)>
127void SvcWrap() { 128void SvcWrap() {
128 u32 param_1 = 0; 129 u32 param_1 = 0;
129 ResultCode retval = func(&param_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (s64)Param(3)); 130 ResultCode retval =
131 func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3)));
130 Core::CurrentArmInterface().SetReg(1, param_1); 132 Core::CurrentArmInterface().SetReg(1, param_1);
131 FuncReturn(retval.raw); 133 FuncReturn(retval.raw);
132} 134}
133 135
134template <ResultCode func(u64, u64, u32, s64)> 136template <ResultCode func(u64, u64, u32, s64)>
135void SvcWrap() { 137void SvcWrap() {
136 FuncReturn(func(Param(0), Param(1), (u32)Param(2), (s64)Param(3)).raw); 138 FuncReturn(
139 func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3))).raw);
137} 140}
138 141
139template <ResultCode func(u64*, u64, u64, u64)> 142template <ResultCode func(u64*, u64, u64, u64)>
@@ -147,9 +150,9 @@ void SvcWrap() {
147template <ResultCode func(u32*, u64, u64, u64, u32, s32)> 150template <ResultCode func(u32*, u64, u64, u64, u32, s32)>
148void SvcWrap() { 151void SvcWrap() {
149 u32 param_1 = 0; 152 u32 param_1 = 0;
150 u32 retval = 153 u32 retval = func(&param_1, Param(1), Param(2), Param(3), static_cast<u32>(Param(4)),
151 func(&param_1, Param(1), Param(2), Param(3), (u32)Param(4), (s32)(Param(5) & 0xFFFFFFFF)) 154 static_cast<s32>(Param(5)))
152 .raw; 155 .raw;
153 Core::CurrentArmInterface().SetReg(1, param_1); 156 Core::CurrentArmInterface().SetReg(1, param_1);
154 FuncReturn(retval); 157 FuncReturn(retval);
155} 158}
@@ -172,7 +175,7 @@ void SvcWrap() {
172template <ResultCode func(u32*, u64, u64, u32)> 175template <ResultCode func(u32*, u64, u64, u32)>
173void SvcWrap() { 176void SvcWrap() {
174 u32 param_1 = 0; 177 u32 param_1 = 0;
175 u32 retval = func(&param_1, Param(1), Param(2), (u32)(Param(3) & 0xFFFFFFFF)).raw; 178 u32 retval = func(&param_1, Param(1), Param(2), static_cast<u32>(Param(3))).raw;
176 Core::CurrentArmInterface().SetReg(1, param_1); 179 Core::CurrentArmInterface().SetReg(1, param_1);
177 FuncReturn(retval); 180 FuncReturn(retval);
178} 181}
@@ -181,22 +184,22 @@ template <ResultCode func(Handle*, u64, u32, u32)>
181void SvcWrap() { 184void SvcWrap() {
182 u32 param_1 = 0; 185 u32 param_1 = 0;
183 u32 retval = 186 u32 retval =
184 func(&param_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw; 187 func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw;
185 Core::CurrentArmInterface().SetReg(1, param_1); 188 Core::CurrentArmInterface().SetReg(1, param_1);
186 FuncReturn(retval); 189 FuncReturn(retval);
187} 190}
188 191
189template <ResultCode func(u64, u32, s32, s64)> 192template <ResultCode func(u64, u32, s32, s64)>
190void SvcWrap() { 193void SvcWrap() {
191 FuncReturn( 194 FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)),
192 func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF), (s64)Param(3)) 195 static_cast<s64>(Param(3)))
193 .raw); 196 .raw);
194} 197}
195 198
196template <ResultCode func(u64, u32, s32, s32)> 199template <ResultCode func(u64, u32, s32, s32)>
197void SvcWrap() { 200void SvcWrap() {
198 FuncReturn(func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF), 201 FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)),
199 (s32)(Param(3) & 0xFFFFFFFF)) 202 static_cast<s32>(Param(3)))
200 .raw); 203 .raw);
201} 204}
202 205
@@ -226,7 +229,7 @@ void SvcWrap() {
226 229
227template <void func(s64)> 230template <void func(s64)>
228void SvcWrap() { 231void SvcWrap() {
229 func((s64)Param(0)); 232 func(static_cast<s64>(Param(0)));
230} 233}
231 234
232template <void func(u64, u64 len)> 235template <void func(u64, u64 len)>
@@ -239,4 +242,9 @@ void SvcWrap() {
239 func(Param(0), Param(1), Param(2)); 242 func(Param(0), Param(1), Param(2));
240} 243}
241 244
245template <void func(u32, u64, u64)>
246void SvcWrap() {
247 func(static_cast<u32>(Param(0)), Param(1), Param(2));
248}
249
242} // namespace Kernel 250} // namespace Kernel
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 33aed8c23..352ce1725 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -183,13 +183,10 @@ void Thread::ResumeFromWait() {
183 */ 183 */
184static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top, 184static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top,
185 VAddr entry_point, u64 arg) { 185 VAddr entry_point, u64 arg) {
186 memset(&context, 0, sizeof(Core::ARM_Interface::ThreadContext)); 186 context = {};
187
188 context.cpu_registers[0] = arg; 187 context.cpu_registers[0] = arg;
189 context.pc = entry_point; 188 context.pc = entry_point;
190 context.sp = stack_top; 189 context.sp = stack_top;
191 context.pstate = 0;
192 context.fpcr = 0;
193} 190}
194 191
195ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point, 192ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point,
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 8d194e175..c41ef7058 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -15,6 +15,11 @@
15#include "video_core/renderer_base.h" 15#include "video_core/renderer_base.h"
16 16
17namespace Service::Nvidia::Devices { 17namespace Service::Nvidia::Devices {
18namespace NvErrCodes {
19enum {
20 InvalidNmapHandle = -22,
21};
22}
18 23
19nvhost_as_gpu::nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {} 24nvhost_as_gpu::nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {}
20nvhost_as_gpu::~nvhost_as_gpu() = default; 25nvhost_as_gpu::~nvhost_as_gpu() = default;
@@ -79,14 +84,16 @@ u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output)
79 std::memcpy(entries.data(), input.data(), input.size()); 84 std::memcpy(entries.data(), input.data(), input.size());
80 85
81 auto& gpu = Core::System::GetInstance().GPU(); 86 auto& gpu = Core::System::GetInstance().GPU();
82
83 for (const auto& entry : entries) { 87 for (const auto& entry : entries) {
84 LOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}", 88 LOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}",
85 entry.offset, entry.nvmap_handle, entry.pages); 89 entry.offset, entry.nvmap_handle, entry.pages);
86 Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10; 90 Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10;
87
88 auto object = nvmap_dev->GetObject(entry.nvmap_handle); 91 auto object = nvmap_dev->GetObject(entry.nvmap_handle);
89 ASSERT(object); 92 if (!object) {
93 LOG_CRITICAL(Service_NVDRV, "nvmap {} is an invalid handle!", entry.nvmap_handle);
94 std::memcpy(output.data(), entries.data(), output.size());
95 return static_cast<u32>(NvErrCodes::InvalidNmapHandle);
96 }
90 97
91 ASSERT(object->status == nvmap::Object::Status::Allocated); 98 ASSERT(object->status == nvmap::Object::Status::Allocated);
92 99
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index a2287cc1b..43651d8a6 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -11,6 +11,13 @@
11 11
12namespace Service::Nvidia::Devices { 12namespace Service::Nvidia::Devices {
13 13
14namespace NvErrCodes {
15enum {
16 OperationNotPermitted = -1,
17 InvalidValue = -22,
18};
19}
20
14nvmap::nvmap() = default; 21nvmap::nvmap() = default;
15nvmap::~nvmap() = default; 22nvmap::~nvmap() = default;
16 23
@@ -44,7 +51,11 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o
44u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { 51u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
45 IocCreateParams params; 52 IocCreateParams params;
46 std::memcpy(&params, input.data(), sizeof(params)); 53 std::memcpy(&params, input.data(), sizeof(params));
54 LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
47 55
56 if (!params.size) {
57 return static_cast<u32>(NvErrCodes::InvalidValue);
58 }
48 // Create a new nvmap object and obtain a handle to it. 59 // Create a new nvmap object and obtain a handle to it.
49 auto object = std::make_shared<Object>(); 60 auto object = std::make_shared<Object>();
50 object->id = next_id++; 61 object->id = next_id++;
@@ -55,8 +66,6 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
55 u32 handle = next_handle++; 66 u32 handle = next_handle++;
56 handles[handle] = std::move(object); 67 handles[handle] = std::move(object);
57 68
58 LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
59
60 params.handle = handle; 69 params.handle = handle;
61 70
62 std::memcpy(output.data(), &params, sizeof(params)); 71 std::memcpy(output.data(), &params, sizeof(params));
@@ -66,9 +75,29 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
66u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { 75u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
67 IocAllocParams params; 76 IocAllocParams params;
68 std::memcpy(&params, input.data(), sizeof(params)); 77 std::memcpy(&params, input.data(), sizeof(params));
78 LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
79
80 if (!params.handle) {
81 return static_cast<u32>(NvErrCodes::InvalidValue);
82 }
83
84 if ((params.align - 1) & params.align) {
85 return static_cast<u32>(NvErrCodes::InvalidValue);
86 }
87
88 const u32 min_alignment = 0x1000;
89 if (params.align < min_alignment) {
90 params.align = min_alignment;
91 }
69 92
70 auto object = GetObject(params.handle); 93 auto object = GetObject(params.handle);
71 ASSERT(object); 94 if (!object) {
95 return static_cast<u32>(NvErrCodes::InvalidValue);
96 }
97
98 if (object->status == Object::Status::Allocated) {
99 return static_cast<u32>(NvErrCodes::OperationNotPermitted);
100 }
72 101
73 object->flags = params.flags; 102 object->flags = params.flags;
74 object->align = params.align; 103 object->align = params.align;
@@ -76,8 +105,6 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
76 object->addr = params.addr; 105 object->addr = params.addr;
77 object->status = Object::Status::Allocated; 106 object->status = Object::Status::Allocated;
78 107
79 LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
80
81 std::memcpy(output.data(), &params, sizeof(params)); 108 std::memcpy(output.data(), &params, sizeof(params));
82 return 0; 109 return 0;
83} 110}
@@ -88,8 +115,14 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
88 115
89 LOG_WARNING(Service_NVDRV, "called"); 116 LOG_WARNING(Service_NVDRV, "called");
90 117
118 if (!params.handle) {
119 return static_cast<u32>(NvErrCodes::InvalidValue);
120 }
121
91 auto object = GetObject(params.handle); 122 auto object = GetObject(params.handle);
92 ASSERT(object); 123 if (!object) {
124 return static_cast<u32>(NvErrCodes::OperationNotPermitted);
125 }
93 126
94 params.id = object->id; 127 params.id = object->id;
95 128
@@ -105,7 +138,14 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
105 138
106 auto itr = std::find_if(handles.begin(), handles.end(), 139 auto itr = std::find_if(handles.begin(), handles.end(),
107 [&](const auto& entry) { return entry.second->id == params.id; }); 140 [&](const auto& entry) { return entry.second->id == params.id; });
108 ASSERT(itr != handles.end()); 141 if (itr == handles.end()) {
142 return static_cast<u32>(NvErrCodes::InvalidValue);
143 }
144
145 auto& object = itr->second;
146 if (object->status != Object::Status::Allocated) {
147 return static_cast<u32>(NvErrCodes::InvalidValue);
148 }
109 149
110 itr->second->refcount++; 150 itr->second->refcount++;
111 151
@@ -125,8 +165,13 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
125 LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param); 165 LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
126 166
127 auto object = GetObject(params.handle); 167 auto object = GetObject(params.handle);
128 ASSERT(object); 168 if (!object) {
129 ASSERT(object->status == Object::Status::Allocated); 169 return static_cast<u32>(NvErrCodes::InvalidValue);
170 }
171
172 if (object->status != Object::Status::Allocated) {
173 return static_cast<u32>(NvErrCodes::OperationNotPermitted);
174 }
130 175
131 switch (static_cast<ParamTypes>(params.param)) { 176 switch (static_cast<ParamTypes>(params.param)) {
132 case ParamTypes::Size: 177 case ParamTypes::Size:
@@ -163,9 +208,12 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
163 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 208 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
164 209
165 auto itr = handles.find(params.handle); 210 auto itr = handles.find(params.handle);
166 ASSERT(itr != handles.end()); 211 if (itr == handles.end()) {
167 212 return static_cast<u32>(NvErrCodes::InvalidValue);
168 ASSERT(itr->second->refcount > 0); 213 }
214 if (!itr->second->refcount) {
215 return static_cast<u32>(NvErrCodes::InvalidValue);
216 }
169 217
170 itr->second->refcount--; 218 itr->second->refcount--;
171 219