2

I tried multiple ways to break on the write to smbase. First I tried

board.mb.cpu0.core[0][0].break-msr 0x9E

But when I run, it just runs forever without breaking.

Then I tried to break in SMM, and then just trace its access, but this showed no hits.

simics> break-hap X86_Leave_SMM
simics> break-hap X86_Enter_SMM
simics> r
[board.mb.sb.lpc.bank.cs_conf unimpl] Write to unimplemented field cs_conf.oic.aen (0x31ff) (value written = 0x01, contents = 0x00), will not warn again.
[board.mb.cpu0.core[1][0] trace-hap] X86_Enter_SMM 0
[board.mb.cpu0.core[1][0] trace-hap] X86_Enter_SMM 1
break-hap
break-hap
simics> board.mb.cpu0.core[0][0].trace-msr -all
simics> r
[board.mb.cpu0.core[1][0] trace-hap] X86_Leave_SMM 0
[board.mb.cpu0.core[1][0] trace-hap] X86_Leave_SMM 1
Setting new inspection object: board.mb.cpu0.core[1][0]
break-hap
break-hap

Then I thought maybe the SMM exit break was obscuring the write, so I tried setting a break on SMM entry, and then breaking on all MSR writes and letting it continue. But it showed no breaks until the next entry to SMM.

simics> break-hap X86_Enter_SMM
simics> r
[board.mb.sb.lpc.bank.cs_conf unimpl] Write to unimplemented field cs_conf.oic.aen (0x31ff) (value written = 0x01, contents = 0x00), will not warn again.
[board.mb.cpu0.core[1][0] trace-hap] X86_Enter_SMM 0
[board.mb.cpu0.core[1][0] trace-hap] X86_Enter_SMM 1
break-hap
break-hap
simics> board.mb.cpu0.core[0][0].break-msr -all
simics> r
[board.mb.cpu0.core[2][0] trace-hap] X86_Enter_SMM 0
[board.mb.cpu0.core[2][0] trace-hap] X86_Enter_SMM 1
break-hap
break-hap

So in the below you can see concretely that msr_ia32_smbase is definitely getting written after the first exit of SMM. But none of the trace or break capabilities seem to show that, even when run from within SMM. So is this just not supported functionality?

simics> board.mb.cpu0.core[0][0].trace-msr 0x9E
simics> board.mb.cpu0.core[0][0].trace-msr -list
[board.mb.cpu0.core[0][0]] Tracing enabled for these control registers:
  msr_ia32_smbase
simics> board.mb.cpu0.core[0][0].break-msr 0x9E
simics> board.mb.cpu0.core[0][0].break-msr -list
[board.mb.cpu0.core[0][0]] Breaking enabled for these control registers:
  msr_ia32_smbase
simics> break-hap X86_Enter_SMM
simics> break-hap X86_Leave_SMM
simics> print -x %msr_ia32_smbase
0x30000
simics> r
[board.mb.sb.lpc.bank.cs_conf unimpl] Write to unimplemented field cs_conf.oic.aen (0x31ff) (value written = 0x01, contents = 0x00), will not warn again.
[board.mb.cpu0.core[1][0] trace-hap] X86_Enter_SMM 0
[board.mb.cpu0.core[1][0] trace-hap] X86_Enter_SMM 1
break-hap
break-hap
simics> print -x %msr_ia32_smbase
0x30000
simics> r
[board.mb.cpu0.core[1][0] trace-hap] X86_Leave_SMM 0
[board.mb.cpu0.core[1][0] trace-hap] X86_Leave_SMM 1
Setting new inspection object: board.mb.cpu0.core[1][0]
break-hap
break-hap
simics> print -x %msr_ia32_smbase
0xdffcf000

p.s. I think the help for break-msr has a copy-paste error, as it says "The register parameter specifies which segment register should be traced." The trace-msr correctly says model specific register.

Jimmy Wu
  • 149
  • 7

1 Answers1

2

IA32_SMBASE MSR is a read-only MSR, you can check Intel Software Development Manual to find this information.

trace-msr only traces write accesses to the register done by WRMSR instruction, i.e. neither internal flows nor attribute/interfaces accesses will be traced by this command.

Likely, in your case SMBASE is updated as part of RSM flow, you can check "SMBASE relocation" section in SDM for more details. Thus you don't get any messages from trace-msr command.

Another thing that I can notice from the small pieces of logs in you question: you enabled trace-msr and break-msr only on core[0][0] while you observing smbase changes on core[1][0]. Look at this message: "Setting new inspection object: board.mb.cpu0.core[1][0]".

And thanks for the note about the copy-paste error. I will fix it.

  • I saw that it's a RO reg, but since I know that it gets updated via RSM and that SMBASE relocation process, I assumed that only referred to things made possible via the wrmsr assembly instruction. And since Simics doesn't obey the rules of real hardware in some cases (like the fact that the manual also says "IA32_SMBASE is an MSR that can be read only in SMM" but yet I can read it outside SMM in Simics), I thought maybe the commands were meant to break and trace on all MSRs. If they're not, that's fine, it's just something worth considering updating to be more powerful. – Jimmy Wu Sep 10 '21 at 12:03
  • Also you're right about the active core changing, but I forced the system down to a single core, and that didn't make a difference. – Jimmy Wu Sep 10 '21 at 12:10
  • Being able to inspect the contents of all MSRs at all times is an obvious feature of a simulator. There is no reason not to have the MSR values available at all times, unless of course the values are defined to depend on some current state that is not available. – jakobengblom2 Sep 27 '21 at 13:49