From 9f061763346787806990aabb57b1a1bfb69860ce Mon Sep 17 00:00:00 2001 From: Swastik-51 Date: Fri, 9 Oct 2026 01:27:29 +0530 Subject: [PATCH] fix(agc): cache Linux describePages results --- .../Execution/src/GuestMemory.cpp | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp index de2fb32eb..77e3ac3e9 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp @@ -423,6 +423,17 @@ struct PageStates { arena.forget(address, bytes); image.forget(address, bytes); } + + void record(std::uintptr_t base, std::uintptr_t regionEnd, bool readable, bool writable, std::uint64_t generation) { + for (PageSpan* span : {&arena, &image}) { + if (!readable || span->size == 0 || regionEnd <= span->base || base >= span->base + span->size) continue; + const std::uint8_t value = PageReadable | (writable ? PageWritable : 0u); + const auto first = std::max(base, span->base); + const auto last = std::min(regionEnd, span->base + span->size); + for (auto at = first; at < last; at += PageBytes) span->store(at, value); + if (GuestAllocations::GuestAllocationsGeneration_nid_postfix() != generation) span->forget(first, static_cast(last - first)); + } + } }; PageStates& Pages() { @@ -533,18 +544,12 @@ bool describePages(std::uintptr_t address, std::size_t bytes, Emit&& emit) { const bool committed = memory.State == MEM_COMMIT && (memory.Protect & (PAGE_GUARD | PAGE_NOACCESS)) == 0; const bool readable = committed && readableProtection(protection); const bool writable = readable && writableProtection(protection); - for (PageSpan* span : {&pages.arena, &pages.image}) { - if (!readable || span->size == 0 || regionEnd <= span->base || base >= span->base + span->size) continue; - const std::uint8_t value = PageReadable | (writable ? PageWritable : 0u); - const auto first = std::max(base, span->base); - const auto last = std::min(regionEnd, span->base + span->size); - for (auto at = first; at < last; at += PageBytes) span->store(at, value); - if (GuestAllocations::GuestAllocationsGeneration_nid_postfix() != generation) span->forget(first, static_cast(last - first)); - } + pages.record(base, regionEnd, readable, writable, generation); const auto next = std::min(end, regionEnd); if (!emit(PageRun{cursor, next, readable, writable})) return true; cursor = next; #else + const auto generation = GuestAllocations::GuestAllocationsGeneration_nid_postfix(); if (const int fd = HostMapping::QueryFd(); fd >= 0) { procmap_query query{}; query.size = sizeof(query); @@ -558,9 +563,13 @@ bool describePages(std::uintptr_t address, std::size_t bytes, Emit&& emit) { cursor = gapEnd; continue; } + const auto base = static_cast(query.vma_start); + const auto regionEnd = static_cast(query.vma_end); const bool readable = (query.vma_flags & PROCMAP_QUERY_VMA_READABLE) != 0; + const bool writable = readable && (query.vma_flags & PROCMAP_QUERY_VMA_WRITABLE) != 0; + pages.record(base, regionEnd, readable, writable, generation); const auto next = std::min(end, query.vma_end); - if (!emit(PageRun{cursor, next, readable, readable && (query.vma_flags & PROCMAP_QUERY_VMA_WRITABLE) != 0})) return true; + if (!emit(PageRun{cursor, next, readable, writable})) return true; cursor = next; continue; } @@ -589,8 +598,11 @@ bool describePages(std::uintptr_t address, std::size_t bytes, Emit&& emit) { found = true; break; } + const bool readable = permissions[0] == 'r'; + const bool writable = readable && permissions[1] == 'w'; + pages.record(first, last, readable, writable, generation); const auto next = std::min(end, last); - if (!emit(PageRun{cursor, next, permissions[0] == 'r', permissions[0] == 'r' && permissions[1] == 'w'})) return true; + if (!emit(PageRun{cursor, next, readable, writable})) return true; cursor = next; found = true; break;