diff options
author | bunnei <bunneidev@gmail.com> | 2020-10-30 05:13:48 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2020-11-01 09:52:38 +0100 |
commit | c6e1c46ac70bf31b54f756f9611b1cf086b63fb0 (patch) | |
tree | edf5e2a33941aba44f11c5ed42b1d658cc6bf20e | |
parent | video_core: dma_pusher: Add support for prefetched command lists. (diff) | |
download | yuzu-c6e1c46ac70bf31b54f756f9611b1cf086b63fb0.tar yuzu-c6e1c46ac70bf31b54f756f9611b1cf086b63fb0.tar.gz yuzu-c6e1c46ac70bf31b54f756f9611b1cf086b63fb0.tar.bz2 yuzu-c6e1c46ac70bf31b54f756f9611b1cf086b63fb0.tar.lz yuzu-c6e1c46ac70bf31b54f756f9611b1cf086b63fb0.tar.xz yuzu-c6e1c46ac70bf31b54f756f9611b1cf086b63fb0.tar.zst yuzu-c6e1c46ac70bf31b54f756f9611b1cf086b63fb0.zip |
-rw-r--r-- | src/video_core/dma_pusher.cpp | 24 | ||||
-rw-r--r-- | src/video_core/dma_pusher.h | 3 |
2 files changed, 27 insertions, 0 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 9c49c6153..105b85a92 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/cityhash.h" #include "common/microprofile.h" #include "core/core.h" #include "core/memory.h" @@ -12,6 +13,20 @@ namespace Tegra { +void CommandList::RefreshIntegrityChecks(GPU& gpu) { + command_list_hashes.resize(command_lists.size()); + + for (std::size_t index = 0; index < command_lists.size(); ++index) { + const CommandListHeader command_list_header = command_lists[index]; + std::vector<CommandHeader> command_headers(command_list_header.size); + gpu.MemoryManager().ReadBlockUnsafe(command_list_header.addr, command_headers.data(), + command_list_header.size * sizeof(u32)); + command_list_hashes[index] = + Common::CityHash64(reinterpret_cast<char*>(command_headers.data()), + command_list_header.size * sizeof(u32)); + } +} + DmaPusher::DmaPusher(Core::System& system, GPU& gpu) : gpu{gpu}, system{system} {} DmaPusher::~DmaPusher() = default; @@ -80,6 +95,15 @@ bool DmaPusher::Step() { command_headers.resize(command_list_header.size); gpu.MemoryManager().ReadBlockUnsafe(dma_get, command_headers.data(), command_list_header.size * sizeof(u32)); + + // Integrity check + const u64 new_hash = Common::CityHash64(reinterpret_cast<char*>(command_headers.data()), + command_list_header.size * sizeof(u32)); + if (new_hash != next_hash) { + LOG_CRITICAL(HW_GPU, "CommandList at addr=0x{:X} is corrupt, skipping!", dma_get); + dma_pushbuffer.pop(); + return true; + } } for (std::size_t index = 0; index < command_headers.size();) { const CommandHeader& command_header = command_headers[index]; diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index 99b30ca0d..8496ba2da 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h @@ -91,7 +91,10 @@ struct CommandList final { explicit CommandList(std::vector<Tegra::CommandHeader>&& prefetch_command_list) : prefetch_command_list{std::move(prefetch_command_list)} {} + void RefreshIntegrityChecks(GPU& gpu); + std::vector<Tegra::CommandListHeader> command_lists; + std::vector<u64> command_list_hashes; std::vector<Tegra::CommandHeader> prefetch_command_list; }; |