mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 04:04:18 +02:00
Fix the guest page size at compile time for the Steam Frame build
Every translated guest load and store tests RequiresCheckedAccess(). On x86-64 and Windows that is a compile-time false, but on AArch64 it read a global flag, which under PIE is a GOT load plus a byte load and a branch on every access, re-read after every guest store. The flag is only true on kernels with pages larger than 4 KiB. The Steam Frame's SteamOS kernel uses 4 KiB pages (getconf PAGESIZE on the headset reports 4096), so the native --headset steam_frame build now folds the test away like x86-64 does. GuestFlat::Initialize checks the page size at startup in that build and refuses to start with a clear message if it is ever anything else. Android and other AArch64 builds still probe at runtime. Checked with clang --target=aarch64-linux-gnu -O2 -fPIE: a FlatRead32 loop loses both flag loads and the checked Memory::Read32 fallback. Follows the finding from nx-mod/wiicompiled-nx 18ef16f6, which made the flag hidden instead; a compile-time constant removes it entirely. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018NKSMYZU43wUfYtm1sxGsC
This commit is contained in:
2 files changed
+18
-4
No files matched your search
@@ -71,10 +71,15 @@ bool IsActive();
|
||||
// accesses must use the checked Memory::* path.
|
||||
// Windows user mode and x86-64 always use a 4 KiB base page, so those builds
|
||||
// fold this to a compile-time false: it appears in every flat access and must
|
||||
// not become a hot-path load. Only AArch64, where the page size is a kernel
|
||||
// configuration (4/16/64 KiB), has to probe it at runtime.
|
||||
// not become a hot-path load. On AArch64 the page size is a kernel
|
||||
// configuration (4/16/64 KiB), so it is probed at runtime, except in the native
|
||||
// Steam Frame build: that build only runs on the headset, whose SteamOS kernel
|
||||
// uses 4 KiB pages, and Initialize() refuses to start on any other page size.
|
||||
#if defined(_WIN32) || defined(__x86_64__)
|
||||
#define MKW_GUEST_FLAT_FIXED_PAGE_SIZE 1
|
||||
#elif defined(MKW_HEADSET_STEAM_FRAME) && !defined(__ANDROID__)
|
||||
#define MKW_GUEST_FLAT_FIXED_PAGE_SIZE 1
|
||||
#define MKW_GUEST_FLAT_VERIFY_PAGE_SIZE 1
|
||||
#endif
|
||||
|
||||
#if defined(MKW_GUEST_FLAT_FIXED_PAGE_SIZE)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "memory.h"
|
||||
@@ -61,8 +62,9 @@ constexpr size_t kAllocationGranularity = 0x10000; // 64 KiB
|
||||
constexpr size_t kHostPageSize = 0x1000;
|
||||
|
||||
// Only hosts that can expose a page larger than 4 KiB need to discover their
|
||||
// size at runtime; see RequiresCheckedAccess() in guest_flat_memory.h.
|
||||
#if !defined(MKW_GUEST_FLAT_FIXED_PAGE_SIZE)
|
||||
// size at runtime, or check it when the build assumes 4 KiB; see
|
||||
// RequiresCheckedAccess() in guest_flat_memory.h.
|
||||
#if !defined(MKW_GUEST_FLAT_FIXED_PAGE_SIZE) || defined(MKW_GUEST_FLAT_VERIFY_PAGE_SIZE)
|
||||
size_t HostPageSize()
|
||||
{
|
||||
const long size = sysconf(_SC_PAGESIZE);
|
||||
@@ -521,6 +523,13 @@ void Initialize(const std::vector<RegionRequest>& regions) {
|
||||
|
||||
#if !defined(MKW_GUEST_FLAT_FIXED_PAGE_SIZE)
|
||||
g_requiresCheckedAccess = HostPageSize() > kGuestPageSize;
|
||||
#elif defined(MKW_GUEST_FLAT_VERIFY_PAGE_SIZE)
|
||||
if (HostPageSize() != kGuestPageSize) {
|
||||
throw std::runtime_error(
|
||||
"This is a Steam Frame build, which assumes the headset's 4 KiB memory pages, but this "
|
||||
"kernel uses " + std::to_string(HostPageSize()) + "-byte pages. Build without "
|
||||
"--headset steam_frame for this device.");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_initialized) {
|
||||
|
||||
Reference in new issue
Block a user