X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/4d15aeb193b2c68f1d38666c317f8d3734f5f083..5ba3f43ea354af8ad55bea84372a2bc834d8757c:/osfmk/i386/hibernate_i386.c diff --git a/osfmk/i386/hibernate_i386.c b/osfmk/i386/hibernate_i386.c index a16994234..21322b751 100644 --- a/osfmk/i386/hibernate_i386.c +++ b/osfmk/i386/hibernate_i386.c @@ -43,6 +43,7 @@ #include #include #include +#include extern ppnum_t max_ppnum; @@ -65,6 +66,7 @@ hibernate_page_list_allocate(boolean_t log) hibernate_bitmap_t dram_ranges[MAX_BANKS]; boot_args * args = (boot_args *) PE_state.bootArgs; uint32_t non_os_pagecount; + ppnum_t pnmax = max_ppnum; mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap); if (args->MemoryMapDescriptorSize == 0) @@ -72,6 +74,13 @@ hibernate_page_list_allocate(boolean_t log) msize = args->MemoryMapDescriptorSize; mcount = args->MemoryMapSize / msize; +#if KASAN + /* adjust max page number to include stolen memory */ + if (atop(shadow_ptop) > pnmax) { + pnmax = (ppnum_t)atop(shadow_ptop); + } +#endif + num_banks = 0; non_os_pagecount = 0; for (i = 0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) @@ -79,10 +88,20 @@ hibernate_page_list_allocate(boolean_t log) base = (ppnum_t) (mptr->PhysicalStart >> I386_PGSHIFT); num = (ppnum_t) mptr->NumberOfPages; - if (base > max_ppnum) +#if KASAN + if (i == shadow_stolen_idx) { + /* + * Add all stolen pages to the bitmap. Later we will prune the unused + * pages. + */ + num += shadow_pages_total; + } +#endif + + if (base > pnmax) continue; - if ((base + num - 1) > max_ppnum) - num = max_ppnum - base + 1; + if ((base + num - 1) > pnmax) + num = pnmax - base + 1; if (!num) continue; @@ -225,14 +244,40 @@ hibernate_processor_setup(IOHibernateImageHeader * header) return (KERN_SUCCESS); } +static boolean_t hibernate_vm_locks_safe; + void hibernate_vm_lock(void) { - if (current_cpu_datap()->cpu_hibernate) hibernate_vm_lock_queues(); + if (current_cpu_datap()->cpu_hibernate) { + hibernate_vm_lock_queues(); + hibernate_vm_locks_safe = TRUE; + } } void hibernate_vm_unlock(void) { + assert(FALSE == ml_get_interrupts_enabled()); if (current_cpu_datap()->cpu_hibernate) hibernate_vm_unlock_queues(); + ml_set_is_quiescing(TRUE); +} + +// ACPI calls hibernate_vm_lock(), interrupt disable, hibernate_vm_unlock() on sleep, +// hibernate_vm_lock_end() and interrupt enable on wake. +// VM locks are safely single threaded between hibernate_vm_lock() and hibernate_vm_lock_end(). + +void +hibernate_vm_lock_end(void) +{ + assert(FALSE == ml_get_interrupts_enabled()); + hibernate_vm_locks_safe = FALSE; + ml_set_is_quiescing(FALSE); +} + +boolean_t +hibernate_vm_locks_are_safe(void) +{ + assert(FALSE == ml_get_interrupts_enabled()); + return (hibernate_vm_locks_safe); }