[Skiboot] [PATCH] mambo/mambo_utils.tcl: Inject an MCE at a specified address
Nicholas Piggin
npiggin at gmail.com
Wed Apr 11 08:19:23 AEST 2018
On Wed, 11 Apr 2018 07:00:06 +1000
Balbir Singh <bsingharora at gmail.com> wrote:
> On Tue, Apr 10, 2018 at 11:14 PM, Nicholas Piggin <npiggin at gmail.com> wrote:
> > On Tue, 10 Apr 2018 21:25:18 +1000
> > Balbir Singh <bsingharora at gmail.com> wrote:
> >
> >> Currently we don't support injecting an MCE on a specific address.
> >> This is useful for testing functionality like memcpy_mcsafe()
> >> (see https://patchwork.ozlabs.org/cover/893339/)
> >>
> >> This patch refactors exc_mce into setup_mce and exc_mce. setup_mce
> >> is generally useful to setup a MCE context with variables DSISR,
> >> SRR1 and DAR. setup_mce supports setting up dsisr as a new
> >> function argument. It's useful when we want to set up both the
> >> cause and DSIR.
> >
> > Hum, I actually have a patch sitting around that reworks this stuff
> > quite significantly for stop states (which mambo doesn't handle very
> > well). It doesn't look like there's a big conflict, but if I can send
> > it and get you to test and merge on top of it that would be good.
>
> Sure, send it across
I put it on the end of this email.
> >>
> >> The core of the functionality is a routine called
> >> inject_mce_ue_on_addr, which takes an addr argument and injects
> >> an MCE (load/store with UE) when the specified address is accessed
> >> by code. This functionality can easily be enhanced to cover
> >> instruction UE's as well.
> >>
> >> Signed-off-by: Balbir Singh <bsingharora at gmail.com>
> >> ---
> >> external/mambo/mambo_utils.tcl | 29 ++++++++++++++++++++++++-----
> >> 1 file changed, 24 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/external/mambo/mambo_utils.tcl b/external/mambo/mambo_utils.tcl
> >> index 7a27f0f4..a9225e3e 100644
> >> --- a/external/mambo/mambo_utils.tcl
> >> +++ b/external/mambo/mambo_utils.tcl
> >> @@ -442,11 +442,12 @@ proc mce_trigger { args } {
> >> #
> >> # Default with no arguments is a recoverable i-side TLB multi-hit
> >> # Other options:
> >> -# d_side=1 cause=0x80 - recoverable d-side SLB multi-hit
> >> +# d_side=1 dsisr=0x80 - recoverable d-side SLB multi-hit
> >> +# d_side=1 dsisr=0x8000, cause=0x1 - ue error on instruction fetch
> >> # d_side=0 cause=0xd - unrecoverable i-side async store timeout (POWER9 only)
> >> # d_side=0 cause=0x1 - unrecoverable i-side ifetch
> >> #
> >> -proc exc_mce { { d_side 0 } { cause 0x5 } { recoverable 1 } } {
> >> +proc setup_mce { { d_side 0 } {dsisr 0x5} { cause 0x5 } { recoverable 1 }} {
> >> variable SRR1
> >> variable DSISR
> >> variable DAR
> >> @@ -466,11 +467,10 @@ proc exc_mce { { d_side 0 } { cause 0x5 } { recoverable 1 } } {
> >> set msr_ri 0x0
> >> }
> >>
> >> - # recoverable d-side SLB multihit
> >> if { $d_side } {
> >> set is_dside 1
> >> - set SRR1_mc_cause 0x0
> >> - set DSISR $cause
> >> + set SRR1_mc_cause $cause
> >> + set DSISR $dsisr
> >> set DAR 0xdeadbeefdeadbeef
> >> } else {
> >> set is_dside 0
> >
> > This doesn't seem right. ue error on ifetch is i-side which can not
> > set DSISR. I have the ifetch UE in the comment. What was wrong with
> > the original code here?
> >
>
> This is called from a trigger on data access and sets up an MCE with
> d_side set to 1.
> So it's not an ifetch i-side change. Am I missing something?
Oh I was talking about the previous hunk as well.
d-side MCEs don't get SRR1 set, which is why the cause is DSISR when
it's d-side, and SRR1 when it's i-side.
Thanks,
Nick
external/mambo: improve helper for machine checks
Improve workarounds for stop injection, because mambo often will
trigger on 0x104/204 when waking from stop.
This also adds a workaround to skip injecting on reservations to
avoid infinite loops when doing inject_mce_step.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
external/mambo/mambo_utils.tcl | 62 +++++++++++++++++++++++++++++-----
1 file changed, 53 insertions(+), 9 deletions(-)
diff --git a/external/mambo/mambo_utils.tcl b/external/mambo/mambo_utils.tcl
index 7a27f0f4..6cbb222a 100644
--- a/external/mambo/mambo_utils.tcl
+++ b/external/mambo/mambo_utils.tcl
@@ -378,6 +378,7 @@ proc sreset_trigger { args } {
variable SRR1
mysim trigger clear pc 0x100
+ mysim trigger clear pc 0x104
set s [expr [mysim cpu 0 display spr srr1] & ~0x00000000003c0002]
set SRR1 [expr $SRR1 | $s]
mysim cpu 0 set spr srr1 $SRR1
@@ -410,14 +411,23 @@ proc exc_sreset { } {
if { [current_insn] in { "stop" "nap" "sleep" "winkle" } } {
# mambo has a quirk that interrupts from idle wake immediately
+ # and go over current instruction.
mysim trigger set pc 0x100 "sreset_trigger"
- mysim cpu 0 interrupt MachineCheck
- # XXX: only trigger if pc is 0x100
- sreset_trigger
+ mysim trigger set pc 0x104 "sreset_trigger"
+ mysim cpu 0 interrupt SystemReset
} else {
mysim trigger set pc 0x100 "sreset_trigger"
+ mysim trigger set pc 0x104 "sreset_trigger"
mysim cpu 0 interrupt SystemReset
}
+
+ # sleep and sometimes other types of interrupts do not trigger 0x100
+ if { [expr [mysim cpu 0 display spr pc] == 0x100 ] } {
+ sreset_trigger
+ }
+ if { [expr [mysim cpu 0 display spr pc] == 0x104 ] } {
+ sreset_trigger
+ }
}
proc mce_trigger { args } {
@@ -426,12 +436,13 @@ proc mce_trigger { args } {
variable DAR
mysim trigger clear pc 0x200
+ mysim trigger clear pc 0x204
set s [expr [mysim cpu 0 display spr srr1] & ~0x00000000801f0002]
set SRR1 [expr $SRR1 | $s]
mysim cpu 0 set spr srr1 $SRR1
mysim cpu 0 set spr dsisr $DSISR
- mysim cpu 0 set spr dar $DAR
+ mysim cpu 0 set spr dar $DAR ; list
}
#
@@ -451,6 +462,8 @@ proc exc_mce { { d_side 0 } { cause 0x5 } { recoverable 1 } } {
variable DSISR
variable DAR
+# puts "INJECTING MCE"
+
# 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.
@@ -466,7 +479,6 @@ proc exc_mce { { d_side 0 } { cause 0x5 } { recoverable 1 } } {
set msr_ri 0x0
}
- # recoverable d-side SLB multihit
if { $d_side } {
set is_dside 1
set SRR1_mc_cause 0x0
@@ -489,14 +501,23 @@ proc exc_mce { { d_side 0 } { cause 0x5 } { recoverable 1 } } {
if { [current_insn] in { "stop" "nap" "sleep" "winkle" } } {
# mambo has a quirk that interrupts from idle wake immediately
+ # and go over current instruction.
mysim trigger set pc 0x200 "mce_trigger"
+ mysim trigger set pc 0x204 "mce_trigger"
mysim cpu 0 interrupt MachineCheck
- # XXX: only trigger if pc is 0x200
- mce_trigger
} else {
mysim trigger set pc 0x200 "mce_trigger"
+ mysim trigger set pc 0x204 "mce_trigger"
mysim cpu 0 interrupt MachineCheck
}
+
+ # sleep and sometimes other types of interrupts do not trigger 0x200
+ if { [expr [mysim cpu 0 display spr pc] == 0x200 ] } {
+ mce_trigger
+ }
+ if { [expr [mysim cpu 0 display spr pc] == 0x204 ] } {
+ mce_trigger
+ }
}
global R1
@@ -536,11 +557,34 @@ 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} } {
+ set reserve_inject 1
+ set reserve_inject_skip 0
+ set reserve_counter 0
+
for { set i 0 } { $i < $nr } { incr i 1 } {
if { [expr [mysim cpu 0 display spr msr] & 0x2] } {
- inject_mce
+ # inject_mce
+ if { [mysim cpu 0 display reservation] in { "none" } } {
+ inject_mce
+ mysim cpu 0 set reservation none
+ if { $reserve_inject_skip } {
+ set reserve_inject 1
+ set reserve_inject_skip 0
+ }
+ } else {
+ if { $reserve_inject } {
+ inject_mce
+ mysim cpu 0 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 0 set reservation none
+ }
+ }
+ }
}
s
}
}
-
--
2.17.0
More information about the Skiboot
mailing list