Introduce page size constants and replace all usages of PAGE_SIZE

Avoids using macros and results in code which looks slightly cleaner.
This commit is contained in:
Billy Laws 2022-08-31 13:08:28 +01:00
parent 30ec844a1b
commit 6359852652
11 changed files with 30 additions and 26 deletions

View File

@ -42,6 +42,12 @@ namespace skyline {
constexpr i64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second constexpr i64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second
constexpr i64 NsInMillisecond{1000000}; //!< The amount of nanoseconds in a millisecond constexpr i64 NsInMillisecond{1000000}; //!< The amount of nanoseconds in a millisecond
constexpr i64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day constexpr i64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
constexpr size_t AddressSpaceSize{1ULL << 39}; //!< The size of the host CPU AS in bytes
constexpr size_t PageSize{0x1000}; //!< The size of a host page
constexpr size_t PageSizeBits{12}; //!< log2(PageSize)
static_assert(PageSize == PAGE_SIZE);
} }
namespace util { namespace util {

View File

@ -115,7 +115,7 @@ namespace skyline::util {
template<typename TypeVal> template<typename TypeVal>
requires IsPointerOrUnsignedIntegral<TypeVal> requires IsPointerOrUnsignedIntegral<TypeVal>
constexpr bool IsPageAligned(TypeVal value) { constexpr bool IsPageAligned(TypeVal value) {
return IsAligned(value, PAGE_SIZE); return IsAligned(value, constant::PageSize);
} }
template<typename TypeVal> template<typename TypeVal>

View File

@ -9,8 +9,8 @@
namespace skyline::gpu { namespace skyline::gpu {
void Buffer::SetupGuestMappings() { void Buffer::SetupGuestMappings() {
u8 *alignedData{util::AlignDown(guest->data(), PAGE_SIZE)}; u8 *alignedData{util::AlignDown(guest->data(), constant::PageSize)};
size_t alignedSize{static_cast<size_t>(util::AlignUp(guest->data() + guest->size(), PAGE_SIZE) - alignedData)}; size_t alignedSize{static_cast<size_t>(util::AlignUp(guest->data() + guest->size(), constant::PageSize) - alignedData)};
alignedMirror = gpu.state.process->memory.CreateMirror(span<u8>{alignedData, alignedSize}); alignedMirror = gpu.state.process->memory.CreateMirror(span<u8>{alignedData, alignedSize});
mirror = alignedMirror.subspan(static_cast<size_t>(guest->data() - alignedData), guest->size()); mirror = alignedMirror.subspan(static_cast<size_t>(guest->data() - alignedData), guest->size());

View File

@ -16,10 +16,8 @@ namespace skyline::gpu {
std::mutex mutex; //!< Synchronizes access to the buffer mappings std::mutex mutex; //!< Synchronizes access to the buffer mappings
std::vector<std::shared_ptr<Buffer>> bufferMappings; //!< A sorted vector of all buffer mappings std::vector<std::shared_ptr<Buffer>> bufferMappings; //!< A sorted vector of all buffer mappings
static constexpr size_t AddressSpaceSize{1ULL << 39}; //!< The size of the guest CPU AS in bytes
static constexpr size_t PageSizeBits{12}; //!< The size of a single page of the guest CPU AS as a power of two (4 KiB == 1 << 12)
static constexpr size_t L2EntryGranularity{19}; //!< The amount of AS (in bytes) a single L2 PTE covers (512 KiB == 1 << 19) static constexpr size_t L2EntryGranularity{19}; //!< The amount of AS (in bytes) a single L2 PTE covers (512 KiB == 1 << 19)
SegmentTable<Buffer*, AddressSpaceSize, PageSizeBits, L2EntryGranularity> bufferTable; //!< A page table of all buffer mappings for O(1) lookups on full matches SegmentTable<Buffer *, constant::AddressSpaceSize, constant::PageSizeBits, L2EntryGranularity> bufferTable; //!< A page table of all buffer mappings for O(1) lookups on full matches
/** /**
* @brief A wrapper around a Buffer which locks it with the specified ContextTag * @brief A wrapper around a Buffer which locks it with the specified ContextTag

View File

@ -116,8 +116,8 @@ namespace skyline::gpu {
auto &mappings{guest->mappings}; auto &mappings{guest->mappings};
if (mappings.size() == 1) { if (mappings.size() == 1) {
auto mapping{mappings.front()}; auto mapping{mappings.front()};
u8 *alignedData{util::AlignDown(mapping.data(), PAGE_SIZE)}; u8 *alignedData{util::AlignDown(mapping.data(), constant::PageSize)};
size_t alignedSize{static_cast<size_t>(util::AlignUp(mapping.data() + mapping.size(), PAGE_SIZE) - alignedData)}; size_t alignedSize{static_cast<size_t>(util::AlignUp(mapping.data() + mapping.size(), constant::PageSize) - alignedData)};
alignedMirror = gpu.state.process->memory.CreateMirror(span<u8>{alignedData, alignedSize}); alignedMirror = gpu.state.process->memory.CreateMirror(span<u8>{alignedData, alignedSize});
mirror = alignedMirror.subspan(static_cast<size_t>(mapping.data() - alignedData), mapping.size()); mirror = alignedMirror.subspan(static_cast<size_t>(mapping.data() - alignedData), mapping.size());
@ -125,7 +125,7 @@ namespace skyline::gpu {
std::vector<span<u8>> alignedMappings; std::vector<span<u8>> alignedMappings;
const auto &frontMapping{mappings.front()}; const auto &frontMapping{mappings.front()};
u8 *alignedData{util::AlignDown(frontMapping.data(), PAGE_SIZE)}; u8 *alignedData{util::AlignDown(frontMapping.data(), constant::PageSize)};
alignedMappings.emplace_back(alignedData, (frontMapping.data() + frontMapping.size()) - alignedData); alignedMappings.emplace_back(alignedData, (frontMapping.data() + frontMapping.size()) - alignedData);
size_t totalSize{frontMapping.size()}; size_t totalSize{frontMapping.size()};
@ -137,7 +137,7 @@ namespace skyline::gpu {
const auto &backMapping{mappings.back()}; const auto &backMapping{mappings.back()};
totalSize += backMapping.size(); totalSize += backMapping.size();
alignedMappings.emplace_back(backMapping.data(), util::AlignUp(backMapping.size(), PAGE_SIZE)); alignedMappings.emplace_back(backMapping.data(), util::AlignUp(backMapping.size(), constant::PageSize));
alignedMirror = gpu.state.process->memory.CreateMirrors(alignedMappings); alignedMirror = gpu.state.process->memory.CreateMirrors(alignedMappings);
mirror = alignedMirror.subspan(static_cast<size_t>(frontMapping.data() - alignedData), totalSize); mirror = alignedMirror.subspan(static_cast<size_t>(frontMapping.data() - alignedData), totalSize);

View File

@ -266,6 +266,6 @@ namespace skyline::kernel {
size_t MemoryManager::GetSystemResourceUsage() { size_t MemoryManager::GetSystemResourceUsage() {
std::shared_lock lock(mutex); std::shared_lock lock(mutex);
constexpr size_t KMemoryBlockSize{0x40}; constexpr size_t KMemoryBlockSize{0x40};
return std::min(static_cast<size_t>(state.process->npdm.meta.systemResourceSize), util::AlignUp(chunks.size() * KMemoryBlockSize, PAGE_SIZE)); return std::min(static_cast<size_t>(state.process->npdm.meta.systemResourceSize), util::AlignUp(chunks.size() * KMemoryBlockSize, constant::PageSize));
} }
} }

View File

@ -12,7 +12,7 @@
namespace skyline { namespace skyline {
namespace constant { namespace constant {
constexpr u16 TlsSlotSize{0x200}; //!< The size of a single TLS slot constexpr u16 TlsSlotSize{0x200}; //!< The size of a single TLS slot
constexpr u8 TlsSlots{PAGE_SIZE / TlsSlotSize}; //!< The amount of TLS slots in a single page constexpr u8 TlsSlots{constant::PageSize / TlsSlotSize}; //!< The amount of TLS slots in a single page
constexpr KHandle BaseHandleIndex{0xD000}; //!< The index of the base handle constexpr KHandle BaseHandleIndex{0xD000}; //!< The index of the base handle
} }

View File

@ -38,18 +38,18 @@ namespace skyline::loader {
Executable executable{}; Executable executable{};
executable.text.contents = GetSegment(backing, header.text, header.flags.textCompressed ? header.textCompressedSize : 0); executable.text.contents = GetSegment(backing, header.text, header.flags.textCompressed ? header.textCompressedSize : 0);
executable.text.contents.resize(util::AlignUp(executable.text.contents.size(), PAGE_SIZE)); executable.text.contents.resize(util::AlignUp(executable.text.contents.size(), constant::PageSize));
executable.text.offset = header.text.memoryOffset; executable.text.offset = header.text.memoryOffset;
executable.ro.contents = GetSegment(backing, header.ro, header.flags.roCompressed ? header.roCompressedSize : 0); executable.ro.contents = GetSegment(backing, header.ro, header.flags.roCompressed ? header.roCompressedSize : 0);
executable.ro.contents.resize(util::AlignUp(executable.ro.contents.size(), PAGE_SIZE)); executable.ro.contents.resize(util::AlignUp(executable.ro.contents.size(), constant::PageSize));
executable.ro.offset = header.ro.memoryOffset; executable.ro.offset = header.ro.memoryOffset;
executable.data.contents = GetSegment(backing, header.data, header.flags.dataCompressed ? header.dataCompressedSize : 0); executable.data.contents = GetSegment(backing, header.data, header.flags.dataCompressed ? header.dataCompressedSize : 0);
executable.data.offset = header.data.memoryOffset; executable.data.offset = header.data.memoryOffset;
// Data and BSS are aligned together // Data and BSS are aligned together
executable.bssSize = util::AlignUp(executable.data.contents.size() + header.bssSize, PAGE_SIZE) - executable.data.contents.size(); executable.bssSize = util::AlignUp(executable.data.contents.size() + header.bssSize, constant::PageSize) - executable.data.contents.size();
if (header.dynsym.offset + header.dynsym.size <= header.ro.decompressedSize && header.dynstr.offset + header.dynstr.size <= header.ro.decompressedSize) { if (header.dynsym.offset + header.dynsym.size <= header.ro.decompressedSize && header.dynstr.offset + header.dynstr.size <= header.ro.decompressedSize) {
executable.dynsym = {header.dynsym.offset, header.dynsym.size}; executable.dynsym = {header.dynsym.offset, header.dynsym.size};

View File

@ -243,7 +243,7 @@ namespace skyline::nce {
offsets.push_back(instructionOffset); offsets.push_back(instructionOffset);
} }
} }
return {util::AlignUp(size * sizeof(u32), PAGE_SIZE), offsets}; return {util::AlignUp(size * sizeof(u32), constant::PageSize), offsets};
} }
void NCE::PatchCode(std::vector<u8> &text, u32 *patch, size_t patchSize, const std::vector<size_t> &offsets) { void NCE::PatchCode(std::vector<u8> &text, u32 *patch, size_t patchSize, const std::vector<size_t> &offsets) {
@ -413,7 +413,7 @@ namespace skyline::nce {
auto reprotectIntervalsWithFunction = [&intervals](auto getProtection) { auto reprotectIntervalsWithFunction = [&intervals](auto getProtection) {
for (auto region : intervals) { for (auto region : intervals) {
region = region.Align(PAGE_SIZE); region = region.Align(constant::PageSize);
mprotect(region.start, region.Size(), getProtection(region)); mprotect(region.start, region.Size(), getProtection(region));
} }
}; };
@ -472,7 +472,7 @@ namespace skyline::nce {
std::scoped_lock lock(trapMutex); std::scoped_lock lock(trapMutex);
// Retrieve any callbacks for the page that was faulted // Retrieve any callbacks for the page that was faulted
auto[entries, intervals]{trapMap.GetAlignedRecursiveRange<PAGE_SIZE>(address)}; auto[entries, intervals]{trapMap.GetAlignedRecursiveRange<constant::PageSize>(address)};
if (entries.empty()) if (entries.empty())
return false; // There's no callbacks associated with this page return false; // There's no callbacks associated with this page
@ -543,10 +543,10 @@ namespace skyline::nce {
TRACE_EVENT("host", "NCE::PageOutRegions"); TRACE_EVENT("host", "NCE::PageOutRegions");
std::scoped_lock lock{trapMutex}; std::scoped_lock lock{trapMutex};
for (auto region : handle->intervals) { for (auto region : handle->intervals) {
auto freeStart{util::AlignUp(region.start, PAGE_SIZE)}, freeEnd{util::AlignDown(region.end, PAGE_SIZE)}; // We want to avoid the first and last page as they may contain unrelated data auto freeStart{util::AlignUp(region.start, constant::PageSize)}, freeEnd{util::AlignDown(region.end, constant::PageSize)}; // We want to avoid the first and last page as they may contain unrelated data
ssize_t freeSize{freeEnd - freeStart}; ssize_t freeSize{freeEnd - freeStart};
constexpr ssize_t MinimumPageoutSize{PAGE_SIZE}; //!< The minimum size to page out, we don't want to page out small intervals for performance reasons constexpr ssize_t MinimumPageoutSize{constant::PageSize}; //!< The minimum size to page out, we don't want to page out small intervals for performance reasons
if (freeSize > MinimumPageoutSize) if (freeSize > MinimumPageoutSize)
state.process->memory.FreeMemory(span<u8>{freeStart, static_cast<size_t>(freeSize)}); state.process->memory.FreeMemory(span<u8>{freeStart, static_cast<size_t>(freeSize)});
} }

View File

@ -22,7 +22,7 @@ namespace skyline::service::nvdrv::core {
flags = pFlags; flags = pFlags;
kind = pKind; kind = pKind;
align = pAlign < PAGE_SIZE ? PAGE_SIZE : pAlign; align = pAlign < constant::PageSize ? constant::PageSize : pAlign;
// This flag is only applicable for handles with an address passed // This flag is only applicable for handles with an address passed
if (pAddress) if (pAddress)
@ -30,7 +30,7 @@ namespace skyline::service::nvdrv::core {
else else
throw exception("Mapping nvmap handles without a CPU side address is unimplemented!"); throw exception("Mapping nvmap handles without a CPU side address is unimplemented!");
size = util::AlignUp(size, PAGE_SIZE); size = util::AlignUp(size, constant::PageSize);
alignedSize = util::AlignUp(size, align); alignedSize = util::AlignUp(size, align);
address = pAddress; address = pAddress;
@ -56,7 +56,7 @@ namespace skyline::service::nvdrv::core {
return PosixResult::Success; return PosixResult::Success;
} }
NvMap::NvMap(const DeviceState &state) : state(state), smmuAllocator(PAGE_SIZE) {} NvMap::NvMap(const DeviceState &state) : state(state), smmuAllocator(soc::SmmuPageSize) {}
void NvMap::AddHandle(std::shared_ptr<Handle> handleDesc) { void NvMap::AddHandle(std::shared_ptr<Handle> handleDesc) {
std::scoped_lock lock(handlesLock); std::scoped_lock lock(handlesLock);

View File

@ -9,7 +9,7 @@ namespace skyline::service::nvdrv::device {
NvMap::NvMap(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx) : NvDevice(state, driver, core, ctx) {} NvMap::NvMap(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx) : NvDevice(state, driver, core, ctx) {}
PosixResult NvMap::Create(In<u32> size, Out<NvMapCore::Handle::Id> handle) { PosixResult NvMap::Create(In<u32> size, Out<NvMapCore::Handle::Id> handle) {
auto handleDesc{core.nvMap.CreateHandle(util::AlignUp(static_cast<u32>(size), PAGE_SIZE))}; auto handleDesc{core.nvMap.CreateHandle(util::AlignUp(static_cast<u32>(size), constant::PageSize))};
if (handleDesc) { if (handleDesc) {
(*handleDesc)->origSize = size; // Orig size is the unaligned size (*handleDesc)->origSize = size; // Orig size is the unaligned size
handle = (*handleDesc)->id; handle = (*handleDesc)->id;
@ -51,8 +51,8 @@ namespace skyline::service::nvdrv::device {
return PosixResult::InvalidArgument; return PosixResult::InvalidArgument;
// Force page size alignment at a minimum // Force page size alignment at a minimum
if (align < PAGE_SIZE) [[unlikely]] if (align < constant::PageSize) [[unlikely]]
align = PAGE_SIZE; align = constant::PageSize;
auto handleDesc{core.nvMap.GetHandle(handle)}; auto handleDesc{core.nvMap.GetHandle(handle)};
if (!handleDesc) [[unlikely]] if (!handleDesc) [[unlikely]]