summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatryk Duda <pdk@semihalf.com>2021-08-23 14:21:08 +0200
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-05-01 21:30:06 +0000
commit046b25029f55365dda58e648a9cc47666213397b (patch)
tree3497f92b613c80ff3cc07f30020e12c7a7b1c222
parentef0566e1e9234461c00987ff6e3236a5ac6a5a42 (diff)
downloadchrome-ec-046b25029f55365dda58e648a9cc47666213397b.tar.gz
cortex-m/panic: Introduce CONFIG_PANIC_STRIP_GPR option
If set, this option will prevent saving General Purpose Registers during panic. When software panic occurs, R4 and R5 will be saved, because they contain additional information about panic. This should be enabled on boards which are processing sensitive data and panic could cause the leak. BUG=b:193408648 BRANCH=none TEST=Trigger panic using 'crash' command. After reboot use 'panicinfo' to check what was saved. When CPU exception occurred registers R0-R12 should be set to 0. In case of software panic, R4 and R5 can contain panic reason and additional information. Signed-off-by: Patryk Duda <pdk@semihalf.com> Change-Id: I06f9c4bb07f936f0822f70a05e19c8d99c68abfb Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3114645 Commit-Queue: Marcin Wojtas <mwojtas@google.com> Reviewed-by: Craig Hesling <hesling@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4469248 Tested-by: Rob Barnes <robbarnes@google.com> Reviewed-by: Boris Mittelberg <bmbm@google.com> Commit-Queue: Rob Barnes <robbarnes@google.com>
-rw-r--r--core/cortex-m/panic.c40
-rw-r--r--include/config.h3
-rw-r--r--include/panic.h38
3 files changed, 75 insertions, 6 deletions
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
index 5722e48910..5866a14ca6 100644
--- a/core/cortex-m/panic.c
+++ b/core/cortex-m/panic.c
@@ -339,8 +339,19 @@ void __keep report_panic(void)
sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE - 8 * sizeof(uint32_t)) {
const uint32_t *sregs = (const uint32_t *)sp;
int i;
- for (i = 0; i < 8; i++)
+
+ /* Skip r0-r3 and r12 registers if necessary */
+ for (i = CORTEX_PANIC_FRAME_REGISTER_R0;
+ i <= CORTEX_PANIC_FRAME_REGISTER_R12; i++)
+ if (IS_ENABLED(CONFIG_PANIC_STRIP_GPR))
+ pdata->cm.frame[i] = 0;
+ else
+ pdata->cm.frame[i] = sregs[i];
+
+ for (i = CORTEX_PANIC_FRAME_REGISTER_LR;
+ i < NUM_CORTEX_PANIC_FRAME_REGISTERS; i++)
pdata->cm.frame[i] = sregs[i];
+
pdata->flags |= PANIC_DATA_FLAG_FRAME_VALID;
}
@@ -400,6 +411,33 @@ void exception_panic(void)
"mrs r1, psp\n"
"mrs r2, ipsr\n"
"mov r3, sp\n"
+#ifdef CONFIG_PANIC_STRIP_GPR
+ /*
+ * Check if we are in exception. This is similar to
+ * in_interrupt_context(). Exception bits are 9 LSB, so
+ * we can perform left shift for 23 bits and check if result
+ * is 0 (lsls instruction is setting appropriate flags).
+ */
+ "lsls r6, r2, #23\n"
+ /*
+ * If this is software panic (shift result == 0) then register
+ * r4 and r5 contain additional info about panic.
+ * Clear r6-r11 always and r4, r5 only if this is exception
+ * panic. To clear r4 and r5, 'movne' conditional instruction
+ * is used. It works only when flags contain information that
+ * result was != 0. Itt is pseudo instruction which is used
+ * to make sure we are using correct conditional instructions.
+ */
+ "itt ne\n"
+ "movne r4, #0\n"
+ "movne r5, #0\n"
+ "mov r6, #0\n"
+ "mov r7, #0\n"
+ "mov r8, #0\n"
+ "mov r9, #0\n"
+ "mov r10, #0\n"
+ "mov r11, #0\n"
+#endif
"stmia r0, {r1-r11, lr}\n"
"mov sp, %[pstack]\n"
"bl report_panic\n" : :
diff --git a/include/config.h b/include/config.h
index 753a97e6d5..80abb601c5 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1158,6 +1158,9 @@
*/
#undef CONFIG_CHIP_PANIC_BACKUP
+/* Don't save General Purpose Registers during panic */
+#undef CONFIG_PANIC_STRIP_GPR
+
/*
* When defined, it enables system safe mode. System safe mode allows the AP to
* capture the EC state after a panic.
diff --git a/include/panic.h b/include/panic.h
index 0d3a83a783..b366567468 100644
--- a/include/panic.h
+++ b/include/panic.h
@@ -17,13 +17,41 @@
extern "C" {
#endif
+enum cortex_panic_frame_registers {
+ CORTEX_PANIC_FRAME_REGISTER_R0 = 0,
+ CORTEX_PANIC_FRAME_REGISTER_R1,
+ CORTEX_PANIC_FRAME_REGISTER_R2,
+ CORTEX_PANIC_FRAME_REGISTER_R3,
+ CORTEX_PANIC_FRAME_REGISTER_R12,
+ CORTEX_PANIC_FRAME_REGISTER_LR,
+ CORTEX_PANIC_FRAME_REGISTER_PC,
+ CORTEX_PANIC_FRAME_REGISTER_PSR,
+ NUM_CORTEX_PANIC_FRAME_REGISTERS
+};
+
+enum cortex_panic_registers {
+ CORTEX_PANIC_REGISTER_PSP = 0,
+ CORTEX_PANIC_REGISTER_IPSR,
+ CORTEX_PANIC_REGISTER_MSP,
+ CORTEX_PANIC_REGISTER_R4,
+ CORTEX_PANIC_REGISTER_R5,
+ CORTEX_PANIC_REGISTER_R6,
+ CORTEX_PANIC_REGISTER_R7,
+ CORTEX_PANIC_REGISTER_R8,
+ CORTEX_PANIC_REGISTER_R9,
+ CORTEX_PANIC_REGISTER_R10,
+ CORTEX_PANIC_REGISTER_R11,
+ CORTEX_PANIC_REGISTER_LR,
+ NUM_CORTEX_PANIC_REGISTERS
+};
+
/* ARM Cortex-Mx registers saved on panic */
struct cortex_panic_data {
- uint32_t regs[12]; /* psp, ipsr, msp, r4-r11, lr(=exc_return).
- * In version 1, that was uint32_t regs[11] =
- * psp, ipsr, lr, r4-r11
- */
- uint32_t frame[8]; /* r0-r3, r12, lr, pc, xPSR */
+ /* See cortex_panic_registers enum for information about registers */
+ uint32_t regs[NUM_CORTEX_PANIC_REGISTERS];
+
+ /* See cortex_panic_frame_registers enum for more information */
+ uint32_t frame[NUM_CORTEX_PANIC_FRAME_REGISTERS];
uint32_t mmfs;
uint32_t bfar;