Skip to content
  • Bernhard Kaindl's avatar
    [PATCH] x86: Save the MTRRs of the BSP before booting an AP · 2b1f6278
    Bernhard Kaindl authored
    Applied fix by Andew Morton:
    http://lkml.org/lkml/2007/4/8/88
    
     - Fix `make headers_check'.
    
    AMD and Intel x86 CPU manuals state that it is the responsibility of
    system software to initialize and maintain MTRR consistency across
    all processors in Multi-Processing Environments.
    
    Quote from page 188 of the AMD64 System Programming manual (Volume 2):
    
    7.6.5 MTRRs in Multi-Processing Environments
    
    "In multi-processing environments, the MTRRs located in all processors must
    characterize memory in the same way. Generally, this means that identical
    values are written to the MTRRs used by the processors." (short omission here)
    "Failure to do so may result in coherency violations or loss of atomicity.
    Processor implementations do not check the MTRR settings in other processors
    to ensure consistency. It is the responsibility of system software to
    initialize and maintain MTRR consistency across all processors."
    
    Current Linux MTRR code already implements the above in the case that the
    BIOS does not properly initialize MTRRs on the secondary processors,
    but the case where the fixed-range MTRRs of the boot processor are changed
    after Linux started to boot, before the initialsation of a secondary
    processor, is not handled yet.
    
    In this case, secondary processors are currently initialized by Linux
    with MTRRs which the boot processor had very early, when mtrr_bp_init()
    did run, but not with the MTRRs which the boot processor uses at the
    time when that secondary processors is actually booted,
    causing differing MTRR contents on the secondary processors.
    
    Such situation happens on Acer Ferrari 1000 and 5000 notebooks where the
    BIOS enables and sets AMD-specific IORR bits in the fixed-range MTRRs
    of the boot processor when it transitions the system into ACPI mode.
    The SMI handler of the BIOS does this in SMM, entered while Linux ACPI
    code runs acpi_enable().
    
    Other occasions where the SMI handler of the BIOS may change bits in
    the MTRRs could occur as well. To initialize newly booted secodary
    processors with the fixed-range MTRRs which the boot processor uses
    at that time, this patch saves the fixed-range MTRRs of the boot
    processor before new secondary processors are started. When the
    secondary processors run their Linux initialisation code, their
    fixed-range MTRRs will be updated with the saved fixed-range MTRRs.
    
    If CONFIG_MTRR is not set, we define mtrr_save_state
    as an empty statement because there is nothing to do.
    
    Possible TODOs:
    
    *) CPU-hotplugging outside of SMP suspend/resume is not yet tested
       with this patch.
    
    *) If, even in this case, an AP never runs i386/do_boot_cpu or x86_64/cpu_up,
       then the calls to mtrr_save_state() could be replaced by calls to
       mtrr_save_fixed_ranges(NULL) and  mtrr_save_state() would not be
       needed.
    
       That would need either verification of the CPU-hotplug code or
       at least a test on a >2 CPU machine.
    
    *) The MTRRs of other running processors are not yet checked at this
       time but it might be interesting to syncronize the MTTRs of all
       processors before booting. That would be an incremental patch,
       but of rather low priority since there is no machine known so
       far which would require this.
    
    AK: moved prototypes on x86-64 around to fix warnings
    
    Signed-off-by: default avatarBernhard Kaindl <bk@suse.de>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarAndi Kleen <ak@suse.de>
    Cc: Andi Kleen <ak@suse.de>
    Cc: Dave Jones <davej@codemonkey.org.uk>
    2b1f6278