1. 13 8月, 2016 2 次提交
    • M
      arm64: hibernate: handle allocation failures · dfbca61a
      Mark Rutland 提交于
      In create_safe_exec_page(), we create a copy of the hibernate exit text,
      along with some page tables to map this via TTBR0. We then install the
      new tables in TTBR0.
      
      In swsusp_arch_resume() we call create_safe_exec_page() before trying a
      number of operations which may fail (e.g. copying the linear map page
      tables). If these fail, we bail out of swsusp_arch_resume() and return
      an error code, but leave TTBR0 as-is. Subsequently, the core hibernate
      code will call free_basic_memory_bitmaps(), which will free all of the
      memory allocations we made, including the page tables installed in
      TTBR0.
      
      Thus, we may have TTBR0 pointing at dangling freed memory for some
      period of time. If the hibernate attempt was triggered by a user
      requesting a hibernate test via the reboot syscall, we may return to
      userspace with the clobbered TTBR0 value.
      
      Avoid these issues by reorganising swsusp_arch_resume() such that we
      have no failure paths after create_safe_exec_page(). We also add a check
      that the zero page allocation succeeded, matching what we have for other
      allocations.
      
      Fixes: 82869ac5 ("arm64: kernel: Add support for hibernate/suspend-to-disk")
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Acked-by: NJames Morse <james.morse@arm.com>
      Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: <stable@vger.kernel.org> # 4.7+
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      dfbca61a
    • M
      arm64: hibernate: avoid potential TLB conflict · 0194e760
      Mark Rutland 提交于
      In create_safe_exec_page we install a set of global mappings in TTBR0,
      then subsequently invalidate TLBs. While TTBR0 points at the zero page,
      and the TLBs should be free of stale global entries, we may have stale
      ASID-tagged entries (e.g. from the EFI runtime services mappings) for
      the same VAs. Per the ARM ARM these ASID-tagged entries may conflict
      with newly-allocated global entries, and we must follow a
      Break-Before-Make approach to avoid issues resulting from this.
      
      This patch reworks create_safe_exec_page to invalidate TLBs while the
      zero page is still in place, ensuring that there are no potential
      conflicts when the new TTBR0 value is installed. As a single CPU is
      online while this code executes, we do not need to perform broadcast TLB
      maintenance, and can call local_flush_tlb_all(), which also subsumes
      some barriers. The remaining assembly is converted to use write_sysreg()
      and isb().
      
      Other than this, we safely manipulate TTBRs in the hibernate dance. The
      code we install as part of the new TTBR0 mapping (the hibernated
      kernel's swsusp_arch_suspend_exit) installs a zero page into TTBR1,
      invalidates TLBs, then installs its preferred value. Upon being restored
      to the middle of swsusp_arch_suspend, the new image will call
      __cpu_suspend_exit, which will call cpu_uninstall_idmap, installing the
      zero page in TTBR0 and invalidating all TLB entries.
      
      Fixes: 82869ac5 ("arm64: kernel: Add support for hibernate/suspend-to-disk")
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Acked-by: NJames Morse <james.morse@arm.com>
      Tested-by: NJames Morse <james.morse@arm.com>
      Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: <stable@vger.kernel.org> # 4.7+
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      0194e760
  2. 22 6月, 2016 1 次提交
  3. 28 4月, 2016 2 次提交
    • J
      arm64: hibernate: Refuse to hibernate if the boot cpu is offline · 1fe492ce
      James Morse 提交于
      Hibernation represents a system state save/restore through
      a system reboot; this implies that the logical cpus carrying
      out hibernation/thawing must be the same, so that the context
      saved in the snapshot image on hibernation is consistent with
      the state of the system on resume. If resume from hibernation
      is driven through kernel command line parameter, the cpu responsible
      for thawing the system will be whatever CPU firmware boots the system
      on upon cold-boot (ie logical cpu 0); this means that in order to
      keep system context consistent between the hibernate snapshot image
      and system state on kernel resume from hibernate, logical cpu 0 must
      be online on hibernation and must be the logical cpu that creates
      the snapshot image.
      
      This patch adds a PM notifier that enforces logical cpu 0 is online
      when the hibernation is started (and prevents hibernation if it is
      not), which is sufficient to guarantee it will be the one creating
      the snapshot image therefore providing the resume cpu a consistent
      snapshot of the system to resume to.
      Signed-off-by: NJames Morse <james.morse@arm.com>
      Acked-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Acked-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      1fe492ce
    • J
      arm64: kernel: Add support for hibernate/suspend-to-disk · 82869ac5
      James Morse 提交于
      Add support for hibernate/suspend-to-disk.
      
      Suspend borrows code from cpu_suspend() to write cpu state onto the stack,
      before calling swsusp_save() to save the memory image.
      
      Restore creates a set of temporary page tables, covering only the
      linear map, copies the restore code to a 'safe' page, then uses the copy to
      restore the memory image. The copied code executes in the lower half of the
      address space, and once complete, restores the original kernel's page
      tables. It then calls into cpu_resume(), and follows the normal
      cpu_suspend() path back into the suspend code.
      
      To restore a kernel using KASLR, the address of the page tables, and
      cpu_resume() are stored in the hibernate arch-header and the el2
      vectors are pivotted via the 'safe' page in low memory.
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Tested-by: Kevin Hilman <khilman@baylibre.com> # Tested on Juno R2
      Signed-off-by: NJames Morse <james.morse@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      82869ac5