[Skiboot] [PATCH] external/mambo: mce injection step over uninteresting states
Nicholas Piggin
npiggin at gmail.com
Thu Jul 18 11:54:27 AEST 2019
The MCE injection/step test skips over MSR[RI]=0, as it's an
"uninteresting" state (leads to die/crash). MSR[ME]=0 is similarly
uninteresting. MSR[PR]=1 is not interesting to do fine grained
injection because all MSR[PR]=1 states are much the same, from
machine check point of view, so skip this too.
MSR[EE]=1 is often not very interesting, because the kernel is well
tested for interrupt re-entrancy by asynchronous interrupts in these
states. However it is possible for the machine check handler to have
bugs in MSR[EE]=1, so make it optional to disable this state.
This makes injection testing easier and faster.
This patch also adds a bit more output to exc_mce, including printing
the initial 0x200 instruction details which makes things much less
confusing when stepping through a machine check.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
external/mambo/mambo_utils.tcl | 67 +++++++++++++++++++++++-----------
1 file changed, 46 insertions(+), 21 deletions(-)
diff --git a/external/mambo/mambo_utils.tcl b/external/mambo/mambo_utils.tcl
index 1defe95ad..0518fe81c 100644
--- a/external/mambo/mambo_utils.tcl
+++ b/external/mambo/mambo_utils.tcl
@@ -562,6 +562,9 @@ proc exc_sreset { } {
upvar #0 target_c c
upvar #0 target_p p
+ set pc [mysim cpu $p:$c:$t display spr pc]
+ puts "\[$p:$c:$t\]: $pc injecting SRESET"
+
# In case of recoverable MCE, idle wakeup always sets RI, others get
# RI from current environment. For unrecoverable, RI would always be
# clear by hardware.
@@ -601,6 +604,8 @@ proc exc_sreset { } {
if { [expr [mysim cpu $p:$c:$t display spr pc] == 0x104 ] } {
sreset_trigger
}
+
+ ipc $t $c $p
}
proc mce_trigger { args } {
@@ -642,7 +647,8 @@ proc exc_mce { { d_side 0 } { cause 0x5 } { recoverable 1 } } {
upvar #0 target_c c
upvar #0 target_p p
-# puts "INJECTING MCE"
+ set pc [mysim cpu $p:$c:$t display spr pc]
+ puts "\[$p:$c:$t\]: $pc injecting MCE"
# In case of recoverable MCE, idle wakeup always sets RI, others get
# RI from current environment. For unrecoverable, RI would always be
@@ -698,6 +704,8 @@ proc exc_mce { { d_side 0 } { cause 0x5 } { recoverable 1 } } {
if { [expr [mysim cpu $p:$c:$t display spr pc] == 0x204 ] } {
mce_trigger
}
+
+ ipc $t $c $p
}
set R1 0
@@ -713,7 +721,7 @@ proc stop_stack_match { args } {
set r1 [mysim cpu $p:$c:$t display gpr 1]
if { $R1 == $r1 } {
simstop
- ipca
+ ipc $t $c $p
}
}
@@ -754,8 +762,16 @@ proc inject_mce_step { {nr 1} } {
}
}
-# inject if RI is set and step over one instruction, and repeat.
-proc inject_mce_step_ri { {nr 1} } {
+# inject if ME and RI is set and PR is clear, step over the MCE to the next
+# instruction, and repeat.
+# Optionally skip the MCE if EE is set, as it's less interesting and allows
+# faster test coverage (however some interesting cases can be missed here,
+# e.g., user copies that modify AMR).
+#
+# This also contains some logic to avoid always killing reservations and
+# halting progress, but it does not always work so sometimes you get caught
+# in a reservation loop and have to step out of it manually.
+proc inject_mce_step_skip { {nr 1} {skip_ee 0} } {
upvar #0 target_t t
upvar #0 target_c c
upvar #0 target_p p
@@ -765,29 +781,38 @@ proc inject_mce_step_ri { {nr 1} } {
set reserve_counter 0
for { set i 0 } { $i < $nr } { incr i 1 } {
- if { [expr [mysim cpu $p:$c:$t display spr msr] & 0x2] } {
- # inject_mce
- if { [mysim cpu $p:$c:$t display reservation] in { "none" } } {
+ # Skip the injection if MSR[RI]=0 or MSR[ME]=0 or MSR[PR]=1
+ if { [ expr {!([p msr] & 0x2) || !([p msr] & 0x1000) || ([p msr] & 0x4000) } ] } {
+ mysim step 1
+ continue
+ }
+
+ if { $skip_ee && ([p msr] & 0x8000)} {
+ mysim step 1
+ continue
+ }
+
+ # inject_mce
+ if { [mysim cpu $p:$c:$t display reservation] in { "none" } } {
+ inject_mce
+ mysim cpu $p:$c:$t set reservation none
+ if { $reserve_inject_skip } {
+ set reserve_inject 1
+ set reserve_inject_skip 0
+ }
+ } else {
+ if { $reserve_inject } {
inject_mce
mysim cpu $p:$c:$t set reservation none
- if { $reserve_inject_skip } {
- set reserve_inject 1
- set reserve_inject_skip 0
- }
+ set reserve_inject 0
} else {
- if { $reserve_inject } {
- inject_mce
+ set reserve_inject_skip 1
+ set reserve_counter [ expr $reserve_counter + 1 ]
+ if { $reserve_counter > 30 } {
mysim cpu $p:$c:$t set reservation none
- set reserve_inject 0
- } else {
- set reserve_inject_skip 1
- set reserve_counter [ expr $reserve_counter + 1 ]
- if { $reserve_counter > 30 } {
- mysim cpu $p:$c:$t set reservation none
- }
}
}
}
- s
+ mysim step 1
}
}
--
2.20.1
More information about the Skiboot
mailing list