Line 511: |
Line 511: |
| | | |
| The anti-downgrade fuses were [[Fuses#Anti-downgrade|updated]]. | | The anti-downgrade fuses were [[Fuses#Anti-downgrade|updated]]. |
− |
| |
− | ==== Kernel ====
| |
− | * KMemoryManager now supports per-pool-partition minimum page alignments.
| |
− | ** KMemoryManager::Initialize now aborts unless a valid pool index is chosen.
| |
− | ** KMemoryManager::Initialize now takes an additional array argument of minimum-page alignments (one array entry per pool partition).
| |
− | *** This array is currently all-zero, which corresponds to minimum allocation alignment of 0x1000 (1 page).
| |
− | ** Allocation functions now check that alignment is valid for the pool's minimum.
| |
− | ** MapPhysicalMemory now checks alignment based on the mm min-pages.
| |
− | ** UnmapPhysicalMemory now checks alignment based on the mm min-pages.
| |
− | ** StartProcess() now checks alignment/aligns up based on the mm min-pages.
| |
− | ** KProcess::Run no longer aligns the input stack-size up to page size when checking that stack + code size does not exceed m_max_process_memory.
| |
− | * KMemoryBlock was refactored:
| |
− | ** Fields were shuffled around, optimizing the storage layout.
| |
− | *** The last field now ends @ +0x3A, instead of +0x40 before, coming close to but not actually saving 8 bytes per block.
| |
− | **** This presumably makes space for fields which are ifdef'd out on NX.
| |
− | ** DisableMergeAttribute_(Device)Right is now 0x20, instead of 0x10.
| |
− | *** Bit 0x10 appears nowhere in entire kernel now, and code which previously did & 0xF to get the Left disable attrs still does & 0xF.
| |
− | **** Bit 0x10 is presumably ifdef'd out on NX.
| |
− | ** KMemoryInfo is essentially no longer used at all any more.
| |
− | *** All cases where GetMemoryInfo was called now use the fields from the KMemoryBlock directly.
| |
− | *** The one exception to this is KPageTableBase::QueryInfo, which still returns a KMemoryInfo as output variable.
| |
− | * The kernel now handles ttbr0 management completely differently:
| |
− | ** The kernel now stores an array of 0x51 TTBR0 pages (Kernel + 0x50 KProcesses, matching the slab heap size) in .rodata.
| |
− | *** Initialize1 now calls a new function prior to unmapping the identity mapping which allocates these pages from the InitialPageAllocator (using paddr lookup + the identity mapping to write to the read-only array in .rodata).
| |
− | ** KSleepSystemRegisters::Save no longer saves TTBR0_EL1; ::Restore sets ttbr0_el1 to g_Ttbr0Pages[0].
| |
− | ** KProcess::InitializeUser now checks that the KProcess is within the slabheap; the KProcess's slab heap index is now passed to KProcessPageTable::Initialize.
| |
− | ** KPageTable no longer has any globals to track ASID management; ASID is now just the KProcess's slab heap index + 1.
| |
− | * KTargetSystem refactor:
| |
− | ** KTargetSystem is now located in .rodata, and no longer 4-byte aligns the bools.
| |
− | ** new .init_array function initializes all the KTargetSystem values in .rodata (before the region is write-protected) using values-from-smc.
| |
− | ** KSystemControl::Initialize() now sets new bool (g_HasKTargetSystem) to true.
| |
− | *** Instead of setting values, KSystemControl now does ABORT_UNLESS(value_from_smc == (g_HasKTargetSystem && g_KTargetSystem.value)) for all values.
| |
− | *** This essentially just checks that the previous .init call worked as expected.
| |
− | ** All KTargetSystem::Is*() calls now return g_HasKTargetSystem && g_KTargetSystem.value instead of just returning g_KTargetSystem.value
| |
− | *** Note: these are still fully inlined in all cases.
| |
− | * KAddressSpaceInfo::GetBegin/GetSize now take in CreateProcess flags instead of bit-width.
| |
− | * svc::WaitForAddress now supports a new ArbitrationType (ArbitrationType_WaitIfEqual64, value=3).
| |
− | ** svc::WaitForAddress's "value" parameter is now an int64_t, instead of an int32_t.
| |
− | ** When ArbitrationType_WaitIfEqual64 is passed, address is now checked for 8-byte alignment instead of 4-byte alignment, and 64-bit value is read/compared from userspace instead of 32-bit.
| |
− | * New InfoType 0x22: "InfoType_TransferMemoryHint"
| |
− | ** This returns a hint for the transfer memory's process address.
| |
− | ** InfoType values 0x1D-0x21 are presumably ifdef'd out on NX.
| |
− | * KProcess->max_process_memory is now set to GetHeapRegionSize() in all cases.
| |
− | ** Previously, this was GetHeapRegionSize() + GetAliasRegionSize() for processes with AddressSpace32BitWithoutAlias.
| |
− | * The kernel now supports execute-only memory (--X).
| |
− | ** SetProcessMemoryPermission now supports MemoryPermission_Execute.
| |
− | *** KPageTableBase::SetProcessMemoryPermission now acquires and immediately releases the scheduler lock prior to operating, if the Execute bit is set on the input permissions.
| |
− | ** KPageTable::GetEntryTemplate now checks for the MemoryPermission_Execute bit instead of checking directly against ReadExecute.
| |
− | ** HandleException now supports using supervisor-mode access to read the failing instruction on Unknown/IllegalState/Bkpt/Brk.
| |
− | *** Supervisor-mode access is used only if user-access fails, KTargetSystem::IsDebugMode() returns true, pc is 4-byte aligned, and 0x200000 <= PC <= (1 << 39).
| |
− | ** HandleException now no longer forces processing when accessing MemoryState_Code without KMemoryPermission_UserRead.
| |
− | * The way DebugFlags capabilities works was changed:
| |
− | ** Previously, bit0=AllowDebug, bit1=ForceDebug.
| |
− | ** Now, bit0=AllowDebug, bit1=ForceDebugProd, bit2=ForceDebug.
| |
− | *** Processes may now only have one of the above bits set, previously both AllowDebug and ForceDebug were allowed simultaneously.
| |
− | ** New function requires KTargetSystem::IsDebugMode():
| |
− | *** GetProcessList,
| |
− | ** Many functions now require (KTargetSystem::IsDebugMode() || GetCurrentProcess().IsForceDebugProd()):
| |
− | *** DebugActiveProcess, GetDebugEvent, QueryDebugProcessMemory, ReadDebugMemory, GetThreadList, GetDebugThreadContext, GetDebugThreadParam,
| |
− | ** KDebug now has a member which tracks whether the owner process is ForceDebugProd.
| |
− | ** KDebugBase::Attach now requires !ForceDebugProd when attaching to a process in the Created/Running states.
| |
− | *** Crashed may still be attached to when ForceDebugProd.
| |
− | ** KDebugBase::GetDebugEventInfo now always sets instruction = 0 when creating info for an UndefinedInstruction exception when ForceDebugProd.
| |
− | ** KDebugBase::(Read/Write)Memory no longer allow reading/writing Io memory when ForceDebugProd is set.
| |
− | ** KPageTableBase::(Read/Write)DebugMemory now check memory state differently:
| |
− | *** Previously: either memory had to be UserRead/UserReadWrite (no state flags check) or KMemoryState_FlagCanDebug had to be set.
| |
− | *** Now: memory has to be UserRead/UserReadWrite (no state flags check) or (memory has to be UserRead AND KMemoryState_FlagCanDebug has to be set) or (IsDebugMode() && !ForceDebugProd && memory has to have KernelRead|UserExecute bits && KMemoryState_FlagCanDebug has to be set)
| |
− | **** This renders the original flag check completely pointless for ReadDebugMemory (but still allows writing to UserRead memory).
| |
− | **** Memory which was previously readable despite not-user-read is no longer readable.
| |
− | **** Execute-only memory is readable, but only when running under debug mode and using a KDebug created by a process which does not have ForceDebugProd set.
| |
− | **** The ForceDebugProd check is not present for WriteDebugMemory.
| |
− | ** GetThreadList() no longer functions in non-debug mode even with ForceDebugProd
| |
− | ** KDebugBase::TerminateProcess no longer detaches from the target process.
| |
− | * Changes relevant to debugging the kernel:
| |
− | ** EL1SynchronousExceptionHandler now infinite loops instead of calling HandleException.
| |
− | ** SupervisorModeThreadStarter now sets X30 to 0 + creates a stack frame + invokes the thread function with "BLR X1" instead of "BR X1".
| |
− | *** This guarantees validity if walking kernel stack frames.
| |
− | * KPageTable implementation was heavily rewritten.
| |
− | ** Too many changes to summarize here; the fundamental implementation is now based on iteration over levels using TraversalContext instead of separate per-level logic.
| |
− | * KPageTableBase::SetupForIpcClient now validates that the unused (on nx) upper memory attribute bits are all unset.
| |
− | * Many heavy K(Initial)PageTable changes, including:
| |
− | ** KInitialPageTable's table entries no longer have bit 58 (0x0400000000000000) set; previously this was used to indicate/determine whether a mapping was present even if the entry was NotMapped.
| |
− | *** Bit0 (0x1) is now used to check for mapping existence again in many places.
| |
− | ** KPageTableImpl::InitializeForKernel now iterates over mappings created by KInitialPageTable, setting PageAttribute=#used entries for tables and setting bit 58 on blocks.
| |
− | * KInterruptController::Finalize() now sets m_gicd and m_gicc to nullptr if core id == 0.
| |
− |
| |
| | | |
| === [[SSL_services|ssl]] === | | === [[SSL_services|ssl]] === |