summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_hibernate.c
diff options
context:
space:
mode:
authormlarkin <mlarkin@openbsd.org>2018-06-21 07:33:30 +0000
committermlarkin <mlarkin@openbsd.org>2018-06-21 07:33:30 +0000
commit65052cac05ce177746c1301e1e06a60add3aee37 (patch)
treead39da169b88ed262c5d5c12f3d36ff9667f2591 /sys/kern/subr_hibernate.c
parentAdd missing comma. This fixes compilation if we enable VMM_DEBUG macro. (diff)
downloadwireguard-openbsd-65052cac05ce177746c1301e1e06a60add3aee37.tar.xz
wireguard-openbsd-65052cac05ce177746c1301e1e06a60add3aee37.zip
Save and restore retguard area during hibernate unpack. This copies the
original retguard data to the piglet and bcopys it back in place immediately before resuming via the ACPI Sx trampoline. ok deraadt, guenther, tested by many.
Diffstat (limited to 'sys/kern/subr_hibernate.c')
-rw-r--r--sys/kern/subr_hibernate.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c
index 3c946e8ea75..05dec26e810 100644
--- a/sys/kern/subr_hibernate.c
+++ b/sys/kern/subr_hibernate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_hibernate.c,v 1.123 2017/08/17 06:50:41 mlarkin Exp $ */
+/* $OpenBSD: subr_hibernate.c,v 1.124 2018/06/21 07:33:30 mlarkin Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@@ -55,6 +55,7 @@
* 29*PAGE_SIZE start of hiballoc area
* 30*PAGE_SIZE preserved entropy
* 110*PAGE_SIZE end of hiballoc area (80 pages)
+ * 366*PAGE_SIZE end of retguard preservation region (256 pages)
* ... unused
* HIBERNATE_CHUNK_SIZE start of hibernate chunk table
* 2*HIBERNATE_CHUNK_SIZE bounce area for chunks being unpacked
@@ -776,7 +777,7 @@ void
hibernate_inflate_region(union hibernate_info *hib, paddr_t dest,
paddr_t src, size_t size)
{
- int end_stream = 0, rle;
+ int end_stream = 0, rle, skip;
struct hibernate_zlib_state *hibernate_state;
hibernate_state =
@@ -790,10 +791,22 @@ hibernate_inflate_region(union hibernate_info *hib, paddr_t dest,
* Is this a special page? If yes, redirect the
* inflate output to a scratch page (eg, discard it)
*/
- if (hibernate_inflate_skip(hib, dest)) {
+ skip = hibernate_inflate_skip(hib, dest);
+ if (skip == HIB_SKIP) {
hibernate_enter_resume_mapping(
HIBERNATE_INFLATE_PAGE,
HIBERNATE_INFLATE_PAGE, 0);
+ } else if (skip == HIB_MOVE) {
+ /*
+ * Special case : retguard region. This gets moved
+ * temporarily into the piglet region and copied into
+ * place immediately before resume
+ */
+ hibernate_enter_resume_mapping(
+ HIBERNATE_INFLATE_PAGE,
+ hib->piglet_pa + (110 * PAGE_SIZE) +
+ hib->retguard_ofs, 0);
+ hib->retguard_ofs += PAGE_SIZE;
} else {
hibernate_enter_resume_mapping(
HIBERNATE_INFLATE_PAGE, dest, 0);
@@ -1230,6 +1243,7 @@ hibernate_unpack_image(union hibernate_info *hib)
/* Can't use hiber_info that's passed in after this point */
bcopy(hib, &local_hib, sizeof(union hibernate_info));
+ local_hib.retguard_ofs = 0;
/* VA == PA */
local_hib.piglet_va = local_hib.piglet_pa;
@@ -1262,9 +1276,18 @@ hibernate_unpack_image(union hibernate_info *hib)
/*
* Resume the loaded kernel by jumping to the MD resume vector.
- * We won't be returning from this call.
+ * We won't be returning from this call. We pass the location of
+ * the retguard save area so the MD code can replace it before
+ * resuming. See the piglet layout at the top of this file for
+ * more information on the layout of the piglet area.
+ *
+ * We use 'global_piglet_va' here since by the time we are at
+ * this point, we have already unpacked the image, and we want
+ * the suspended kernel's view of what the piglet was, before
+ * suspend occurred (since we will need to use that in the retguard
+ * copy code in hibernate_resume_machdep.)
*/
- hibernate_resume_machdep();
+ hibernate_resume_machdep(global_piglet_va + (110 * PAGE_SIZE));
}
/*