[coreboot] caching in SMI handler

Marc Jones marcj303 at gmail.com
Fri Jun 17 23:58:47 CEST 2011

Hi Sven,

On Fri, Jun 17, 2011 at 6:51 AM, Sven Schnelle <svens at stackframe.org> wrote:
> Hi List,
> i've encountered an interesting problem on my Thinkpad T60:
> whenever i've docked/undocked the thinkpad from the docking station,
> i had to do that twice to get the action actually to happen.
> First i thought that would be some error in the ACPI code. Here's a
> short explanation how docking/undocking works:
> 1) ACPI EC Event 0x37 Handler is executed (EC sends event 0x37 on dock)
> 2) _Q37 does a Trap(SMI_DOCK_CONNECT). Trap is declared as follows:
>   a) Store(Arg0, SMIF) // SMIF is in the GNVS Memory Range
>   b) Store(0, 0x808)   // Generates I/O Trap to SMM
>   c) // SMM is executed
>   d) Return (SMIF)    // Return Result in SMIF
> I've verified that a) is really executed with ACPI debugging in the
> Linux Kernel. It writes the correct value to GNVS Memory. After that,
> i've logged the SMIF value in SMM, which contains some random (or
> former) value of SMIF.
> So i've added the GNVS area to /proc/mtrr which made things work.
> I've also tried a wbinvd() in SMM code, with the same result.
> After reading the src/cpu/x86/smm/smmhandler.S code, i've recognized
> that it starts with:
>        movw    $(smm_gdtptr16 - smm_handler_start +
>        SMM_HANDLER_OFFSET), %bx
>        data32  lgdt %cs:(%bx)
>        movl    %cr0, %eax
>        andl    $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
>        orl     $0x60000001, %eax /* CD, NW, PE = 1 */
>        movl    %eax, %cr0
>        /* Enable protected mode */
>        data32  ljmp    $0x08, $1f
> ...which disables caching in SMM code, but doesn't flush the cache.
> So the problem is:
> - the linux axpi write to the SMIF GNVS Area will be written to Cache,
>  because GNVS is WB
> - the SMM code runs with cache disabled, and fetches SMIF directly from
>  Memory, which is some other value

I don't understand this statement. Even if the cache is disabled, it
should still hit in the cache and get the correct value.  Yet, I
believe that you do see an old values and the MTRR change is telling.
Hmm as long as the memory isn't in SMRAM, since that is the cache
poisoning hack.

> Possible Solutions:
> - enable cache in SMM (yeah, cache poisoning...)
> - flush caches in SMM (really expensive)
> - mark GNVS as UC in Memory Map (will only work if OS
>  really marks that Area as UC. Checked various vendor BIOSes, none
>  of them are marking NVS as UC. So this seems rather uncommon.)
> - flush only the cache line which contains GNVS. Would fix this
>  particular problem, but users/developers could see other Bugs like
>  this. And not everyone likes to debug such problems. So i won't like
>  this solution.
> Opinions?

A wbinvd is probably ok. Everything has stopped for the SMM anyway. It
is a little sad that the resume has to get everything from memory
again. That is probably the bigger performance hit.

The Software Developerʼs Manual book 3a should have the proper
sequence in it somewhere...



More information about the coreboot mailing list