Hello everybody,

in the master branch, marss/ptlsim/x86/decode-complex.cpp, lines 2048+,

  case 0xfa: { // cli
    EndOfDecode();

        // this << TransOp(OP_collcc, REG_temp0, REG_zf, REG_cf, REG_of,
        // 3, 0, 0, FLAGS_DEFAULT_ALU);
        TransOp ast(OP_ast, REG_temp1, REG_temp0, REG_zero, REG_zero, 3);
        ast.riptaken = L_ASSIST_CLI;

and lines 2061+,

  case 0xfb: { // sti
    EndOfDecode();

        // this << TransOp(OP_collcc, REG_temp0, REG_zf, REG_cf, REG_of,
        // 3, 0, 0, FLAGS_DEFAULT_ALU);
        TransOp ast(OP_ast, REG_temp1, REG_temp0, REG_zero, REG_zero, 3);
        ast.riptaken = L_ASSIST_STI;

The lightweight assist functions are called with uninitialized values of the ra
parameter. Lines 231+,

W64 l_assist_sti(Context& ctx, W64 ra, W64 rb, W64 rc, W16 raflags,
                W16 rbflags, W16 rcflags, W16& flags) {

        W16 current_flags = (W16)ra;
        current_flags |= IF_MASK;
        flags = current_flags;

and lines 254+,

W64 l_assist_cli(Context& ctx, W64 ra, W64 rb, W64 rc, W16 raflags,
        W16 rbflags, W16 rcflags, W16& flags) {

        W16 current_flags = (W16)ra;
        current_flags &= ~IF_MASK;
        flags = current_flags;

Now, the unintialized ra parameter might have FLAG_INV set. This will make the
assist uop fail and can cause indefinite re-issues of this and preceding
not-yet-committed uops if the uninitialized REG_temp0/1 registers remain
unchanged.

Changing the

        W16 current_flags = (W16)ra;

lines to

        W16 current_flags = (W16)ctx.reg_flags;

worked for me. (However, this might not be quite clean with regard to uop
issue vs commit semantics.)

I came across this error when investigating spurious Linux kernel freezes after
scheduler timer interrupts.


Regards,

gunnar.


_______________________________________________
http://www.marss86.org
Marss86-Devel mailing list
[email protected]
https://www.cs.binghamton.edu/mailman/listinfo/marss86-devel

Reply via email to