Line 319: |
Line 319: |
| | | |
| The anti-downgrade fuses were [[Fuses#Anti-downgrade|updated]]. | | The anti-downgrade fuses were [[Fuses#Anti-downgrade|updated]]. |
| + | |
| + | ==== Kernel ==== |
| + | * Compiler/libc changes: |
| + | ** The kernel is now linked using RELR for relocations instead of RELA (see compiler support in lld for .relr.dyn). |
| + | ** This greatly reduces the relocations segment size; it has decreased from 0x3A50 bytes in 16.0.0 to 0x90 in 17.0.0. |
| + | ** Many minor optimization changes, e.g. mul+add -> madd, madd -> smaddl/umaddl, (a + b - 1) >> 36 is now (a + b) > 0x1000000000, various reordering. |
| + | * crt0 changes: |
| + | ** crt0 is no longer located at _start, instead _start is `b crt0` followed by 0x7FC of zeroes. |
| + | ** crt0 is now located at the start of .rodata. |
| + | *** The crt0 page is now identity-mapped R-X in .rodata instead of RWX at start-of-text. |
| + | ** Many system registers which were previously set from KInitArguments are now set using a register constants table in the crt0 .rodata segment. |
| + | *** These are ttbr0_el1, ttbr1_el1, tcr_el1, mair_el1, and sctlr_el1. |
| + | *** This table is initially zeroes, and is initialized to the correct values by KernelLdr before returning to Kernel/setting permissions. |
| + | ** Kernel Map now stores offsets relative to itself rather than relative to _start. |
| + | *** Kernel map also now stores an additional offset (to the "register constants"). |
| + | ** The big idea here is to make the crt0 page no longer executable after init. |
| + | *** This mitigates the ability to execute gadgets (via ROP/etc) to set TTBR1_EL1 (and other important registers) to user-controlled values. |
| + | **** The *only* ttbr1_el1 gadget in all of kernel now sets it to the constant in .rodata, which can't be modified after KernelLdr finishes. |
| + | *** This also enables setting the WXN bit while still identity-mapped, instead of having to do it later in boot. |
| + | * KernelLdr changes: |
| + | ** INI1 is now used in-place, if KSystemControl does not have a preferred layout. |
| + | * Initialize0 changes: |
| + | ** Initialize0 now receives the initial process binary size from KernelLdr and stores it in a global. |
| + | *** Initialize1 forwards this to the rest of the kernel as with the address. |
| + | ** Initialize0 no longer memsets the slab region to zero before calling the ifdef'd out function for the unknown debug region. |
| + | *** This is now done by InitializeSlabHeaps(). |
| + | * All exception returns now migitate post-eret speculative execution. |
| + | ** All "eret" instructions are now "eret; dsb nsh; isb;" |
| + | * KInitialPageAllocator::Allocate(Aligned) now memsets the pages to zero before returning them to the caller. |
| + | ** Correspondingly, KInitialPageTable no longer memsets those pages to zero after allocating them. |
| + | * KInitialProcessReader::CreateProcessParameter now ands sizes with 0x1FFFFF000 before overflow checking. |
| + | ** This may actually just be compiler-garbage due to the types being u32-cast-to-higher-width? |
| + | * CreateAndStartInitialProcesses changes: |
| + | ** A difference check is now an != when allocating page group. |
| + | ** Segment loading/uncompressing has now been refactored: |
| + | *** The entire page group is no longer mapped while loading the segments. |
| + | *** KInitialProcessReader::Load is now responsible; it now takes the page group as argument, clears bss (using linear map), and then calls a helper to load each segment. |
| + | **** This helper creates a page group for just the pages relevant to the segment, copies the data (using linear map), and then if compressed maps the page group, uncompresses, and unmaps. |
| + | * KMemoryRegionType had a number of large changes: |
| + | ** A new memory type is now inserted after the SecureAppletMemory region (id is 0xC200028E). |
| + | ** Low 0x2 ID derivations changed to accommodate this. |
| + | ** As a knock-on effect(?) type IDs for pool partitions changed substantially (likely due to derivation changes elsewhere). |
| + | * New KProcess field ("has application system resource"). |
| + | ** This is set to 1 when initializing a KProcess with CreateProcessFlag_IsApplication and system_resource_num_pages == 0. |
| + | ** When this is true, svc::GetInfo() always returns 0 for InfoType_SystemResourceSizeTotal and InfoType_SystemResourceSizeUsed. |
| + | *** This also modifies the calculations for various SystemResourceSize calculations. |
| + | *** MapPhysicalMemory() and UnmapPhysicalMemory() will also now return svc::ResultInvalidState(). |
| + | * The KProcess::Initialize() overload used by initial processes now supports system_resource_num_pages != 0 (and allocates a system resource in this case). |
| + | ** NOTE: KInitialProcessReader::CreateProcessParameter still hardcodes param->system_resource_num_pages = 0 for all KIPs. |
| + | * Changes to KPageTable(Base) around KMemoryState: |
| + | ** There is no longer a bijective mapping between svc::MemoryState and kern::KMemoryState. |
| + | ** In particular, KMemoryState_Io has been split into two memory states: |
| + | *** KMemoryState_Io(Register) no longer has bit 13 (0x2000) set (new value is 0x180001). |
| + | *** For memory mapped with SvcMapIoRegion called with svc::MemoryMapping_Memory, KMemoryState_Io(Memory) retains that bit set (value is 0x182001). |
| + | *** KPageTableBase functions dealing with Io mappings now take in MemoryState arguments, and/or MemoryMapping arguments (for the IoRegion functions). |
| + | ** KMemoryState_ThreadLocal no longer has bit 13 (0x2000) set (new value is 0x400000C). |
| + | ** KMemoryState_Kernel no longer has bit 13 (0x2000) set (new value is 0x13). |
| + | ** KMemoryState_Static no longer has bit 13 (0x2000) set (new value is 0x40002). |
| + | ** KMemoryState_Insecure now supports FlagCanQueryPhysical (new value is 0x55C3817). |
| + | ** To accommodate this, KPageTableBase::QueryMapping/Contains/GetRegionAddress/GetRegionSize now take an svc::MemoryState (u8) instead of the full KMemoryState. |
| + | *** In a (presumably) happy accident, this produces much, much better assembly for the switch statement. |
| + | ** KPageTableBase::CheckMemoryState was made ALWAYS_INLINE and now calls an impl-func which takes KMemoryBlock * as argument. |
| + | * KPageTableBase::MapPageGroup no longer sets the io bit in page properties. |
| + | ** This is the overload used by process creation. |
| + | * KMemoryBlockManager::UpdateIfMatch now takes set_disable_attr, clear_disable_attr. |
| + | ** KPageTableBase::MapPhysicalMemory passes true for set_disable_attr if the address is exactly the start of the alias region. |
| + | * KPageTableBase::UnmapPhysicalMemory now passes clear_disable_attr = 1 to KMemoryManager::Update if the address is exactly the start of the alias region. |
| + | * KProcessPageTable::Initialize no longer has an unused truncated-process-id argument. |
| + | * Changes to KPageTable(Base) mapping for first-reference: |
| + | ** KPageTable::Operate is no longer allowed to take MapFirst as operation. |
| + | ** KPageTable::MapContiguousWithBaseAttribute no longer supports not_first argument, always calls OpenAdditionalReference. |
| + | ** KPageTable::OperateOnPageGroup is now allowed to take MapFirst as operation, and MapWithPageGroup can now call OpenFirst or OpenAdditional for page group references. |
| + | ** KPageTableBase::AllocatePageGroupAndOperate now passes MapFirst. |
| + | * Miscellaneous page table changes: |
| + | ** KSupervisorPageTable::Initialize now checks that the WXN bit is set in sctlr_el1 instead of setting it. |
| + | ** KPageTable::Finalize now calls a second OnFinalize() stub after NoteUpdated(). |
| + | * KPageTableBase::MapStatic alignment checks were loosened/changed. |
| + | * New KMemoryAttribute bit 0x10 ("PermissionLocked"). |
| + | ** This can be set via SvcSetMemoryAttribute. |
| + | *** NOTE: Once set, this bit is irrevocable and can never be unset. |
| + | **** This is to enable relro (read only relocations). |
| + | *** This requires a new KMemoryStateFlag (bit 27) "FlagCanPermissionLock", which is set only on CodeData and AliasCodeData. |
| + | ** KPageTable::SetMemoryAttribute now calls a new KMemoryBlockManager::UpdateAttributes function specifically for updating the attributes. |
| + | ** This bit is allowed to be set when unmapped CodeMemory (as it can be set on (Alias)CodeData). |
| + | * HandleException now uses UserspaceAccess functions to retrieve the instruction when EsrEc is Unknown, IllegalState, Bkpt, or Brk. |
| + | * InvalidateProcessDataCache now special-cases being called on the current process, with a simpler (new) KPageTableBase function. |
| + | * Changes around signaling/thread termination. |
| + | ** KThread::BeginTerminate no longer calls NotifyAvailable on the thread. |
| + | ** KThread::DoWorkerTask now acquires the scheduler lock and calls NotifyAvailable on the thread. |
| + | ** KThread and KProcess exit now use separate KWorkerTaskManagers (0 = Thread, 1 = Process). |
| + | *** Main() now initializes the two KWorkerTaskManagers, and now aborts if their priorities (both constant 11) are zero. |
| + | * KSleepManager's no longer saves and restores tcr_el1 when saving/restoring system registers. |
| + | |
| | | |
| ==See Also== | | ==See Also== |