Skip to content

Commit e6416c2

Browse files
Rongronggg9bp3tk0v
authored andcommitted
x86/CPU/AMD: Prevent reset reasons from being retained across reboot
The S5_RESET_STATUS register is parsed on boot and printed to kmsg. However, this could sometimes be misleading and lead to users wasting a lot of time on meaningless debugging for two reasons: * Some bits are never cleared by hardware. It's the software's responsibility to clear them as per the Processor Programming Reference (see [1]). * Some rare hardware-initiated platform resets do not update the register at all. In both cases, a previous reboot could leave its trace in the register, resulting in users seeing unrelated reboot reasons while debugging random reboots afterward. Write the read value back to the register in order to clear all reason bits since they are write-1-to-clear while the others must be preserved. [1]: https://bugzilla.kernel.org/show_bug.cgi?id=206537#attach_303991 [ bp: Massage commit message. ] Fixes: ab81310 ("x86/CPU/AMD: Print the reason for the last reset") Signed-off-by: Rong Zhang <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Mario Limonciello (AMD) <[email protected]> Reviewed-by: Yazen Ghannam <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/all/[email protected]/
1 parent 83b0177 commit e6416c2

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

arch/x86/kernel/cpu/amd.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,11 +1355,23 @@ static __init int print_s5_reset_status_mmio(void)
13551355
return 0;
13561356

13571357
value = ioread32(addr);
1358-
iounmap(addr);
13591358

13601359
/* Value with "all bits set" is an error response and should be ignored. */
1361-
if (value == U32_MAX)
1360+
if (value == U32_MAX) {
1361+
iounmap(addr);
13621362
return 0;
1363+
}
1364+
1365+
/*
1366+
* Clear all reason bits so they won't be retained if the next reset
1367+
* does not update the register. Besides, some bits are never cleared by
1368+
* hardware so it's software's responsibility to clear them.
1369+
*
1370+
* Writing the value back effectively clears all reason bits as they are
1371+
* write-1-to-clear.
1372+
*/
1373+
iowrite32(value, addr);
1374+
iounmap(addr);
13631375

13641376
for (i = 0; i < ARRAY_SIZE(s5_reset_reason_txt); i++) {
13651377
if (!(value & BIT(i)))

0 commit comments

Comments
 (0)