[Skiboot] [PATCH 1/3] core/fast-reboot: verify mem regions before fast reboot
Nicholas Piggin
npiggin at gmail.com
Sun Mar 25 11:44:31 AEDT 2018
Run the mem_region sanity checkers before proceeding with fast
reboot.
This is the beginning of proactive sanity checks on opal data
for fast reboot (with complements the reactive disable_fast_reboot
cases). This is encouraged to re-use and share any kind of debug
code and unit test code.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
core/fast-reboot.c | 25 +++++++++++++++++++++++--
core/init.c | 2 --
core/mem_region.c | 15 ++++++++++++---
include/mem_region.h | 4 ++++
4 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/core/fast-reboot.c b/core/fast-reboot.c
index d702044a..9f8c4d9a 100644
--- a/core/fast-reboot.c
+++ b/core/fast-reboot.c
@@ -19,6 +19,7 @@
#include <fsp.h>
#include <psi.h>
#include <opal.h>
+#include <mem_region.h>
#include <xscom.h>
#include <interrupts.h>
#include <cec.h>
@@ -71,6 +72,23 @@ void disable_fast_reboot(const char *reason)
fast_reboot_disabled = reason;
}
+/*
+ * This is called by the reboot CPU after all other CPUs have been
+ * quiesced and stopped, to perform various sanity checks on firmware
+ * data (and potentially hardware), to determine whether the fast
+ * reboot should go ahead.
+ */
+static bool fast_reboot_sanity_check(void)
+{
+ if (!mem_check_all()) {
+ prlog(PR_NOTICE, "REST: Fast reboot failed due to inconsistent "
+ "firmware data\n");
+ return false;
+ }
+
+ return true;
+}
+
void fast_reboot(void)
{
struct cpu_thread *cpu;
@@ -104,8 +122,6 @@ void fast_reboot(void)
return;
}
- /* Should mem_check() all regions before allowing fast reboot? */
-
prlog(PR_NOTICE, "RESET: Initiating fast reboot %d...\n", ++fast_reboot_count);
fast_boot_release = false;
sync();
@@ -118,6 +134,11 @@ void fast_reboot(void)
return;
}
+ if (!fast_reboot_sanity_check()) {
+ opal_quiesce(QUIESCE_RESUME, -1);
+ return;
+ }
+
/*
* There is no point clearing special wakeup or un-quiesce due to
* failure after this point, because we will be going to full IPL.
diff --git a/core/init.c b/core/init.c
index a60b7843..3de89a72 100644
--- a/core/init.c
+++ b/core/init.c
@@ -454,8 +454,6 @@ static void load_initramfs(void)
(uint64_t)INITRAMFS_LOAD_BASE + initramfs_size);
}
-int64_t mem_dump_free(void);
-
void *fdt;
void __noreturn load_and_boot_kernel(bool is_reboot)
diff --git a/core/mem_region.c b/core/mem_region.c
index 4479a23a..aa0c850b 100644
--- a/core/mem_region.c
+++ b/core/mem_region.c
@@ -26,9 +26,6 @@
#include <mem_region.h>
#include <mem_region-malloc.h>
-int64_t mem_dump_free(void);
-void mem_dump_allocs(void);
-
/* Memory poisoning on free (if POISON_MEM_REGION set to 1) */
#ifdef DEBUG
#define POISON_MEM_REGION 1
@@ -622,6 +619,18 @@ bool mem_check(const struct mem_region *region)
return true;
}
+bool mem_check_all(void)
+{
+ struct mem_region *r;
+
+ list_for_each(®ions, r, list) {
+ if (!mem_check(r))
+ return false;
+ }
+
+ return true;
+}
+
static struct mem_region *new_region(const char *name,
uint64_t start, uint64_t len,
struct dt_node *node,
diff --git a/include/mem_region.h b/include/mem_region.h
index 324e98e1..2a9453f5 100644
--- a/include/mem_region.h
+++ b/include/mem_region.h
@@ -63,7 +63,11 @@ bool mem_resize(struct mem_region *region, void *mem, size_t len,
const char *location);
size_t mem_allocated_size(const void *ptr);
bool mem_check(const struct mem_region *region);
+bool mem_check_all(void);
void mem_region_release_unused(void);
+void mem_region_clear_unused(void);
+int64_t mem_dump_free(void);
+void mem_dump_allocs(void);
/* Specifically for working on the heap. */
extern struct mem_region skiboot_heap;
--
2.16.1
More information about the Skiboot
mailing list