diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/ioctl_serialization.h | 107 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdevice.h | 12 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 78 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 20 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 6 |
5 files changed, 152 insertions, 71 deletions
diff --git a/src/core/hle/service/nvdrv/devices/ioctl_serialization.h b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h new file mode 100644 index 000000000..c560974f1 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/ioctl_serialization.h | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <span> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "common/concepts.h" | ||
| 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||
| 11 | |||
| 12 | namespace Service::Nvidia::Devices { | ||
| 13 | |||
| 14 | struct Ioctl1Traits { | ||
| 15 | template <typename T, typename R, typename A> | ||
| 16 | static T GetClassImpl(R (T::*)(A)); | ||
| 17 | |||
| 18 | template <typename T, typename R, typename A> | ||
| 19 | static A GetArgImpl(R (T::*)(A)); | ||
| 20 | }; | ||
| 21 | |||
| 22 | struct Ioctl23Traits { | ||
| 23 | template <typename T, typename R, typename A, typename B> | ||
| 24 | static T GetClassImpl(R (T::*)(A, B)); | ||
| 25 | |||
| 26 | template <typename T, typename R, typename A, typename B> | ||
| 27 | static A GetArgImpl(R (T::*)(A, B)); | ||
| 28 | }; | ||
| 29 | |||
| 30 | template <typename T> | ||
| 31 | struct ContainerType { | ||
| 32 | using ValueType = T; | ||
| 33 | }; | ||
| 34 | |||
| 35 | template <Common::IsContiguousContainer T> | ||
| 36 | struct ContainerType<T> { | ||
| 37 | using ValueType = T::value_type; | ||
| 38 | }; | ||
| 39 | |||
| 40 | template <typename InnerArg, typename F, typename Self, typename... Rest> | ||
| 41 | NvResult Wrap(std::span<const u8> input, std::span<u8> output, Self* self, F&& callable, | ||
| 42 | Rest&&... rest) { | ||
| 43 | using Arg = ContainerType<InnerArg>::ValueType; | ||
| 44 | constexpr bool ArgumentIsContainer = Common::IsContiguousContainer<InnerArg>; | ||
| 45 | |||
| 46 | // Verify that the input and output sizes are valid. | ||
| 47 | const size_t in_params = input.size() / sizeof(Arg); | ||
| 48 | const size_t out_params = output.size() / sizeof(Arg); | ||
| 49 | if (in_params * sizeof(Arg) != input.size()) { | ||
| 50 | return NvResult::InvalidSize; | ||
| 51 | } | ||
| 52 | if (out_params * sizeof(Arg) != output.size()) { | ||
| 53 | return NvResult::InvalidSize; | ||
| 54 | } | ||
| 55 | if (in_params == 0 && out_params == 0 && !ArgumentIsContainer) { | ||
| 56 | return NvResult::InvalidSize; | ||
| 57 | } | ||
| 58 | |||
| 59 | // Copy inputs, if needed. | ||
| 60 | std::vector<Arg> params(std::max(in_params, out_params)); | ||
| 61 | if (in_params > 0) { | ||
| 62 | std::memcpy(params.data(), input.data(), input.size()); | ||
| 63 | } | ||
| 64 | |||
| 65 | // Perform the call. | ||
| 66 | NvResult result; | ||
| 67 | if constexpr (ArgumentIsContainer) { | ||
| 68 | result = (self->*callable)(params, std::forward<Rest>(rest)...); | ||
| 69 | } else { | ||
| 70 | result = (self->*callable)(params.front(), std::forward<Rest>(rest)...); | ||
| 71 | } | ||
| 72 | |||
| 73 | // Copy outputs, if needed. | ||
| 74 | if (out_params > 0) { | ||
| 75 | std::memcpy(output.data(), params.data(), output.size()); | ||
| 76 | } | ||
| 77 | |||
| 78 | return result; | ||
| 79 | } | ||
| 80 | |||
| 81 | template <typename F> | ||
| 82 | NvResult nvdevice::Wrap1(F&& callable, std::span<const u8> input, std::span<u8> output) { | ||
| 83 | using Self = decltype(Ioctl1Traits::GetClassImpl(callable)); | ||
| 84 | using InnerArg = std::remove_reference_t<decltype(Ioctl1Traits::GetArgImpl(callable))>; | ||
| 85 | |||
| 86 | return Wrap<InnerArg>(input, output, static_cast<Self*>(this), callable); | ||
| 87 | } | ||
| 88 | |||
| 89 | template <typename F> | ||
| 90 | NvResult nvdevice::Wrap2(F&& callable, std::span<const u8> input, std::span<const u8> inline_input, | ||
| 91 | std::span<u8> output) { | ||
| 92 | using Self = decltype(Ioctl23Traits::GetClassImpl(callable)); | ||
| 93 | using InnerArg = std::remove_reference_t<decltype(Ioctl23Traits::GetArgImpl(callable))>; | ||
| 94 | |||
| 95 | return Wrap<InnerArg>(input, output, static_cast<Self*>(this), callable, inline_input); | ||
| 96 | } | ||
| 97 | |||
| 98 | template <typename F> | ||
| 99 | NvResult nvdevice::Wrap3(F&& callable, std::span<const u8> input, std::span<u8> output, | ||
| 100 | std::span<u8> inline_output) { | ||
| 101 | using Self = decltype(Ioctl23Traits::GetClassImpl(callable)); | ||
| 102 | using InnerArg = std::remove_reference_t<decltype(Ioctl23Traits::GetArgImpl(callable))>; | ||
| 103 | |||
| 104 | return Wrap<InnerArg>(input, output, static_cast<Self*>(this), callable, inline_output); | ||
| 105 | } | ||
| 106 | |||
| 107 | } // namespace Service::Nvidia::Devices | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index a04538d5d..af766f320 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h | |||
| @@ -75,6 +75,18 @@ public: | |||
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | protected: | 77 | protected: |
| 78 | template <typename F> | ||
| 79 | NvResult Wrap1(F&& callable, std::span<const u8> input, std::span<u8> output); | ||
| 80 | |||
| 81 | template <typename F> | ||
| 82 | NvResult Wrap2(F&& callable, std::span<const u8> input, std::span<const u8> inline_input, | ||
| 83 | std::span<u8> output); | ||
| 84 | |||
| 85 | template <typename F> | ||
| 86 | NvResult Wrap3(F&& callable, std::span<const u8> input, std::span<u8> output, | ||
| 87 | std::span<u8> inline_output); | ||
| 88 | |||
| 89 | protected: | ||
| 78 | Core::System& system; | 90 | Core::System& system; |
| 79 | }; | 91 | }; |
| 80 | 92 | ||
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 7d7bb8687..484001071 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/hle/service/nvdrv/core/container.h" | 12 | #include "core/hle/service/nvdrv/core/container.h" |
| 13 | #include "core/hle/service/nvdrv/core/nvmap.h" | 13 | #include "core/hle/service/nvdrv/core/nvmap.h" |
| 14 | #include "core/hle/service/nvdrv/devices/ioctl_serialization.h" | ||
| 14 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | 15 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" |
| 15 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" | 16 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" |
| 16 | #include "core/hle/service/nvdrv/nvdrv.h" | 17 | #include "core/hle/service/nvdrv/nvdrv.h" |
| @@ -33,21 +34,21 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 33 | case 'A': | 34 | case 'A': |
| 34 | switch (command.cmd) { | 35 | switch (command.cmd) { |
| 35 | case 0x1: | 36 | case 0x1: |
| 36 | return BindChannel(input, output); | 37 | return Wrap1(&nvhost_as_gpu::BindChannel, input, output); |
| 37 | case 0x2: | 38 | case 0x2: |
| 38 | return AllocateSpace(input, output); | 39 | return Wrap1(&nvhost_as_gpu::AllocateSpace, input, output); |
| 39 | case 0x3: | 40 | case 0x3: |
| 40 | return FreeSpace(input, output); | 41 | return Wrap1(&nvhost_as_gpu::FreeSpace, input, output); |
| 41 | case 0x5: | 42 | case 0x5: |
| 42 | return UnmapBuffer(input, output); | 43 | return Wrap1(&nvhost_as_gpu::UnmapBuffer, input, output); |
| 43 | case 0x6: | 44 | case 0x6: |
| 44 | return MapBufferEx(input, output); | 45 | return Wrap1(&nvhost_as_gpu::MapBufferEx, input, output); |
| 45 | case 0x8: | 46 | case 0x8: |
| 46 | return GetVARegions(input, output); | 47 | return Wrap1(&nvhost_as_gpu::GetVARegions1, input, output); |
| 47 | case 0x9: | 48 | case 0x9: |
| 48 | return AllocAsEx(input, output); | 49 | return Wrap1(&nvhost_as_gpu::AllocAsEx, input, output); |
| 49 | case 0x14: | 50 | case 0x14: |
| 50 | return Remap(input, output); | 51 | return Wrap1(&nvhost_as_gpu::Remap, input, output); |
| 51 | default: | 52 | default: |
| 52 | break; | 53 | break; |
| 53 | } | 54 | } |
| @@ -72,7 +73,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 72 | case 'A': | 73 | case 'A': |
| 73 | switch (command.cmd) { | 74 | switch (command.cmd) { |
| 74 | case 0x8: | 75 | case 0x8: |
| 75 | return GetVARegions(input, output, inline_output); | 76 | return Wrap3(&nvhost_as_gpu::GetVARegions3, input, output, inline_output); |
| 76 | default: | 77 | default: |
| 77 | break; | 78 | break; |
| 78 | } | 79 | } |
| @@ -87,10 +88,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i | |||
| 87 | void nvhost_as_gpu::OnOpen(DeviceFD fd) {} | 88 | void nvhost_as_gpu::OnOpen(DeviceFD fd) {} |
| 88 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} | 89 | void nvhost_as_gpu::OnClose(DeviceFD fd) {} |
| 89 | 90 | ||
| 90 | NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> output) { | 91 | NvResult nvhost_as_gpu::AllocAsEx(IoctlAllocAsEx& params) { |
| 91 | IoctlAllocAsEx params{}; | ||
| 92 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 93 | |||
| 94 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); | 92 | LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size); |
| 95 | 93 | ||
| 96 | std::scoped_lock lock(mutex); | 94 | std::scoped_lock lock(mutex); |
| @@ -141,10 +139,7 @@ NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> outpu | |||
| 141 | return NvResult::Success; | 139 | return NvResult::Success; |
| 142 | } | 140 | } |
| 143 | 141 | ||
| 144 | NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> output) { | 142 | NvResult nvhost_as_gpu::AllocateSpace(IoctlAllocSpace& params) { |
| 145 | IoctlAllocSpace params{}; | ||
| 146 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 147 | |||
| 148 | LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, | 143 | LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, |
| 149 | params.page_size, params.flags); | 144 | params.page_size, params.flags); |
| 150 | 145 | ||
| @@ -194,7 +189,6 @@ NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> o | |||
| 194 | .big_pages = params.page_size != VM::YUZU_PAGESIZE, | 189 | .big_pages = params.page_size != VM::YUZU_PAGESIZE, |
| 195 | }; | 190 | }; |
| 196 | 191 | ||
| 197 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 198 | return NvResult::Success; | 192 | return NvResult::Success; |
| 199 | } | 193 | } |
| 200 | 194 | ||
| @@ -222,10 +216,7 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) { | |||
| 222 | mapping_map.erase(offset); | 216 | mapping_map.erase(offset); |
| 223 | } | 217 | } |
| 224 | 218 | ||
| 225 | NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> output) { | 219 | NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { |
| 226 | IoctlFreeSpace params{}; | ||
| 227 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 228 | |||
| 229 | LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset, | 220 | LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset, |
| 230 | params.pages, params.page_size); | 221 | params.pages, params.page_size); |
| 231 | 222 | ||
| @@ -264,18 +255,11 @@ NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> outpu | |||
| 264 | return NvResult::BadValue; | 255 | return NvResult::BadValue; |
| 265 | } | 256 | } |
| 266 | 257 | ||
| 267 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 268 | return NvResult::Success; | 258 | return NvResult::Success; |
| 269 | } | 259 | } |
| 270 | 260 | ||
| 271 | NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) { | 261 | NvResult nvhost_as_gpu::Remap(std::span<IoctlRemapEntry> entries) { |
| 272 | const auto num_entries = input.size() / sizeof(IoctlRemapEntry); | 262 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", entries.size()); |
| 273 | |||
| 274 | LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries); | ||
| 275 | |||
| 276 | std::scoped_lock lock(mutex); | ||
| 277 | entries.resize_destructive(num_entries); | ||
| 278 | std::memcpy(entries.data(), input.data(), input.size()); | ||
| 279 | 263 | ||
| 280 | if (!vm.initialised) { | 264 | if (!vm.initialised) { |
| 281 | return NvResult::BadValue; | 265 | return NvResult::BadValue; |
| @@ -317,14 +301,10 @@ NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) { | |||
| 317 | } | 301 | } |
| 318 | } | 302 | } |
| 319 | 303 | ||
| 320 | std::memcpy(output.data(), entries.data(), output.size()); | ||
| 321 | return NvResult::Success; | 304 | return NvResult::Success; |
| 322 | } | 305 | } |
| 323 | 306 | ||
| 324 | NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> output) { | 307 | NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) { |
| 325 | IoctlMapBufferEx params{}; | ||
| 326 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 327 | |||
| 328 | LOG_DEBUG(Service_NVDRV, | 308 | LOG_DEBUG(Service_NVDRV, |
| 329 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" | 309 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" |
| 330 | ", offset={}", | 310 | ", offset={}", |
| @@ -421,14 +401,10 @@ NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> out | |||
| 421 | mapping_map[params.offset] = mapping; | 401 | mapping_map[params.offset] = mapping; |
| 422 | } | 402 | } |
| 423 | 403 | ||
| 424 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 425 | return NvResult::Success; | 404 | return NvResult::Success; |
| 426 | } | 405 | } |
| 427 | 406 | ||
| 428 | NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> output) { | 407 | NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { |
| 429 | IoctlUnmapBuffer params{}; | ||
| 430 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 431 | |||
| 432 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); | 408 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); |
| 433 | 409 | ||
| 434 | std::scoped_lock lock(mutex); | 410 | std::scoped_lock lock(mutex); |
| @@ -464,9 +440,7 @@ NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> out | |||
| 464 | return NvResult::Success; | 440 | return NvResult::Success; |
| 465 | } | 441 | } |
| 466 | 442 | ||
| 467 | NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::span<u8> output) { | 443 | NvResult nvhost_as_gpu::BindChannel(IoctlBindChannel& params) { |
| 468 | IoctlBindChannel params{}; | ||
| 469 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 470 | LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); | 444 | LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); |
| 471 | 445 | ||
| 472 | auto gpu_channel_device = module.GetDevice<nvhost_gpu>(params.fd); | 446 | auto gpu_channel_device = module.GetDevice<nvhost_gpu>(params.fd); |
| @@ -493,10 +467,7 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) { | |||
| 493 | }; | 467 | }; |
| 494 | } | 468 | } |
| 495 | 469 | ||
| 496 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output) { | 470 | NvResult nvhost_as_gpu::GetVARegions1(IoctlGetVaRegions& params) { |
| 497 | IoctlGetVaRegions params{}; | ||
| 498 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 499 | |||
| 500 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, | 471 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, |
| 501 | params.buf_size); | 472 | params.buf_size); |
| 502 | 473 | ||
| @@ -508,15 +479,10 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> ou | |||
| 508 | 479 | ||
| 509 | GetVARegionsImpl(params); | 480 | GetVARegionsImpl(params); |
| 510 | 481 | ||
| 511 | std::memcpy(output.data(), ¶ms, output.size()); | ||
| 512 | return NvResult::Success; | 482 | return NvResult::Success; |
| 513 | } | 483 | } |
| 514 | 484 | ||
| 515 | NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output, | 485 | NvResult nvhost_as_gpu::GetVARegions3(IoctlGetVaRegions& params, std::span<u8> inline_output) { |
| 516 | std::span<u8> inline_output) { | ||
| 517 | IoctlGetVaRegions params{}; | ||
| 518 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 519 | |||
| 520 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, | 486 | LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr, |
| 521 | params.buf_size); | 487 | params.buf_size); |
| 522 | 488 | ||
| @@ -528,9 +494,7 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> ou | |||
| 528 | 494 | ||
| 529 | GetVARegionsImpl(params); | 495 | GetVARegionsImpl(params); |
| 530 | 496 | ||
| 531 | std::memcpy(output.data(), ¶ms, output.size()); | 497 | std::memcpy(inline_output.data(), params.regions.data(), 2 * sizeof(VaRegion)); |
| 532 | std::memcpy(inline_output.data(), ¶ms.regions[0], sizeof(VaRegion)); | ||
| 533 | std::memcpy(inline_output.data() + sizeof(VaRegion), ¶ms.regions[1], sizeof(VaRegion)); | ||
| 534 | 498 | ||
| 535 | return NvResult::Success; | 499 | return NvResult::Success; |
| 536 | } | 500 | } |
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 2af3e1260..bc041f215 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -139,18 +139,17 @@ private: | |||
| 139 | static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, | 139 | static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, |
| 140 | "IoctlGetVaRegions is incorrect size"); | 140 | "IoctlGetVaRegions is incorrect size"); |
| 141 | 141 | ||
| 142 | NvResult AllocAsEx(std::span<const u8> input, std::span<u8> output); | 142 | NvResult AllocAsEx(IoctlAllocAsEx& params); |
| 143 | NvResult AllocateSpace(std::span<const u8> input, std::span<u8> output); | 143 | NvResult AllocateSpace(IoctlAllocSpace& params); |
| 144 | NvResult Remap(std::span<const u8> input, std::span<u8> output); | 144 | NvResult Remap(std::span<IoctlRemapEntry> params); |
| 145 | NvResult MapBufferEx(std::span<const u8> input, std::span<u8> output); | 145 | NvResult MapBufferEx(IoctlMapBufferEx& params); |
| 146 | NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output); | 146 | NvResult UnmapBuffer(IoctlUnmapBuffer& params); |
| 147 | NvResult FreeSpace(std::span<const u8> input, std::span<u8> output); | 147 | NvResult FreeSpace(IoctlFreeSpace& params); |
| 148 | NvResult BindChannel(std::span<const u8> input, std::span<u8> output); | 148 | NvResult BindChannel(IoctlBindChannel& params); |
| 149 | 149 | ||
| 150 | void GetVARegionsImpl(IoctlGetVaRegions& params); | 150 | void GetVARegionsImpl(IoctlGetVaRegions& params); |
| 151 | NvResult GetVARegions(std::span<const u8> input, std::span<u8> output); | 151 | NvResult GetVARegions1(IoctlGetVaRegions& params); |
| 152 | NvResult GetVARegions(std::span<const u8> input, std::span<u8> output, | 152 | NvResult GetVARegions3(IoctlGetVaRegions& params, std::span<u8> inline_output); |
| 153 | std::span<u8> inline_output); | ||
| 154 | 153 | ||
| 155 | void FreeMappingLocked(u64 offset); | 154 | void FreeMappingLocked(u64 offset); |
| 156 | 155 | ||
| @@ -213,7 +212,6 @@ private: | |||
| 213 | bool initialised{}; | 212 | bool initialised{}; |
| 214 | } vm; | 213 | } vm; |
| 215 | std::shared_ptr<Tegra::MemoryManager> gmmu; | 214 | std::shared_ptr<Tegra::MemoryManager> gmmu; |
| 216 | Common::ScratchBuffer<IoctlRemapEntry> entries; | ||
| 217 | 215 | ||
| 218 | // s32 channel{}; | 216 | // s32 channel{}; |
| 219 | // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; | 217 | // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 46a25fcab..804157ce3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -134,7 +134,7 @@ NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::span<u8> outp | |||
| 134 | LOG_DEBUG(Service_NVDRV, "called"); | 134 | LOG_DEBUG(Service_NVDRV, "called"); |
| 135 | 135 | ||
| 136 | IoctlClientData params{}; | 136 | IoctlClientData params{}; |
| 137 | std::memcpy(¶ms, input.data(), input.size()); | 137 | std::memcpy(¶ms, input.data(), std::min(sizeof(IoctlClientData), input.size())); |
| 138 | user_data = params.data; | 138 | user_data = params.data; |
| 139 | return NvResult::Success; | 139 | return NvResult::Success; |
| 140 | } | 140 | } |
| @@ -143,9 +143,9 @@ NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::span<u8> outp | |||
| 143 | LOG_DEBUG(Service_NVDRV, "called"); | 143 | LOG_DEBUG(Service_NVDRV, "called"); |
| 144 | 144 | ||
| 145 | IoctlClientData params{}; | 145 | IoctlClientData params{}; |
| 146 | std::memcpy(¶ms, input.data(), input.size()); | 146 | std::memcpy(¶ms, input.data(), std::min(sizeof(IoctlClientData), input.size())); |
| 147 | params.data = user_data; | 147 | params.data = user_data; |
| 148 | std::memcpy(output.data(), ¶ms, output.size()); | 148 | std::memcpy(output.data(), ¶ms, std::min(sizeof(IoctlClientData), output.size())); |
| 149 | return NvResult::Success; | 149 | return NvResult::Success; |
| 150 | } | 150 | } |
| 151 | 151 | ||