On 06/24/15 00:12, Jordan Justen wrote: > On 2015-06-23 12:53:49, Laszlo Ersek wrote: >> At the moment we work with a UC default MTRR type, and set three memory >> ranges to WB: >> - [0, 640 KB), >> - [1 MB, LowerMemorySize), >> - [4 GB, 4 GB + UpperMemorySize). >> >> Unfortunately, coverage for the third range can fail with a high >> likelihood. If the alignment of the base (ie. 4 GB) and the alignment of >> the size (UpperMemorySize) differ, then MtrrLib creates a series of >> variable MTRR entries, with power-of-two sized MTRR masks. And, it's >> really easy to run out of variable MTRR entries, dependent on the >> alignment difference. >> >> This is a problem because a Linux guest will loudly reject any high memory >> that is not covered my MTRR. >> >> So, let's follow the inverse pattern (loosely inspired by SeaBIOS): >> - flip the MTRR default type to WB, >> - set [0, 640 KB) to WB -- fixed MTRRs have precedence over the default >> type and variable MTRRs, so we can't avoid this, >> - set [640 KB, 1 MB) to UC -- implemented with fixed MTRRs, >> - set [LowerMemorySize, 4 GB) to UC -- should succeed with variable MTRRs >> more likely than the other scheme (due to less chaotic alignment >> differences). >> >> Effects of this patch can be observed by setting DEBUG_CACHE (0x00200000) >> in PcdDebugPrintErrorLevel. >> >> Cc: Maoming <maoming.maom...@huawei.com> >> Cc: Huangpeng (Peter) <peter.huangp...@huawei.com> >> Cc: Wei Liu <wei.l...@citrix.com> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Laszlo Ersek <ler...@redhat.com> >> Tested-by: Maoming <maoming.maom...@huawei.com> >> Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com> >> --- >> >> Notes: >> v2: >> - update comments [Jordan] >> - calculate the size of the low 384 KB uncacheable hole as Jordan >> suggested >> >> OvmfPkg/PlatformPei/MemDetect.c | 46 ++++++++++++++++++-- >> 1 file changed, 42 insertions(+), 4 deletions(-) >> >> diff --git a/OvmfPkg/PlatformPei/MemDetect.c >> b/OvmfPkg/PlatformPei/MemDetect.c >> index b74308f..4778a55 100644 >> --- a/OvmfPkg/PlatformPei/MemDetect.c >> +++ b/OvmfPkg/PlatformPei/MemDetect.c >> @@ -252,6 +252,8 @@ QemuInitializeRam ( >> { >> UINT64 LowerMemorySize; >> UINT64 UpperMemorySize; >> + MTRR_SETTINGS MtrrSettings; >> + EFI_STATUS Status; >> >> DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__)); >> >> @@ -272,12 +274,48 @@ QemuInitializeRam ( >> } >> } >> >> - MtrrSetMemoryAttribute (BASE_1MB, LowerMemorySize - BASE_1MB, >> CacheWriteBack); >> + // >> + // We'd like to keep the following ranges uncached: >> + // - [640 KB, 1 MB) >> + // - [LowerMemorySize, 4 GB) >> + // >> + // Everything else should be WB. Unfortunately, programming the inverse >> (ie. >> + // keeping the default UC, and configuring the complement set of the >> above as >> + // WB) is not reliable in general, because the end of the upper RAM can >> have >> + // practically any alignment, and we may not have enough variable MTRRs to >> + // cover it exactly. >> + // >> + if (IsMtrrSupported ()) { >> + MtrrGetAllMtrrs (&MtrrSettings); >> >> - MtrrSetMemoryAttribute (0, BASE_512KB + BASE_128KB, CacheWriteBack); >> + // >> + // MTRRs disabled, fixed MTRRs disabled, default type is uncached >> + // >> + ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0); >> + ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0); >> + ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0); >> >> - if (UpperMemorySize != 0) { >> - MtrrSetMemoryAttribute (BASE_4GB, UpperMemorySize, CacheWriteBack); >> + // >> + // flip default type to writeback >> + // >> + SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06); >> + ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables); >> + MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6; >> + MtrrSetAllMtrrs (&MtrrSettings); >> + >> + // >> + // Set memory from 640KB to 1MB to uncacheable >> + // > > Thanks Laszlo. All the patches look good to me now. > > If I have a nit pick remaining, it would be the comments I suggested > here. :) > > I think maybe 'memory' => 'memory range' seems better. What do you > think?
OK. >> + Status = MtrrSetMemoryAttribute (BASE_512KB + BASE_128KB, >> + BASE_1MB - (BASE_512KB + BASE_128KB), CacheUncacheable); >> + ASSERT_EFI_ERROR (Status); >> + >> + // >> + // Set MMIO just below 4GB to uncacheable >> + // > > You expressed some doubts about this, and I agree. To throw out > another option, maybe: > > // > // Set memory range from the "top of lower RAM" (RAM below 4GB) to > // 4GB as uncacheable > // Works for me. > Or, maybe: > > // > // Set memory range for memory mapped IO below 4GB as uncacheable > // > > Or, perhaps you have a better suggestion? > > Anyway, I don't think it is critical, so with or without changes, > series Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com> Thanks! I'll update these comments when I commit the patches to SVN. But first I'd like to give Wei Liu and Maoming one or two days to re-test; I wouldn't like to lose their Tested-by tags for patch #1. Cheers! Laszlo >> + Status = MtrrSetMemoryAttribute (LowerMemorySize, >> + SIZE_4GB - LowerMemorySize, CacheUncacheable); >> + ASSERT_EFI_ERROR (Status); >> } >> } >> >> -- >> 1.8.3.1 >> >> >> ------------------------------------------------------------------------------ >> Monitor 25 network devices or servers for free with OpManager! >> OpManager is web-based network management software that monitors >> network devices and physical & virtual servers, alerts via email & sms >> for fault. Monitor 25 devices for free with no restriction. Download now >> http://ad.doubleclick.net/ddm/clk/292181274;119417398;o >> _______________________________________________ >> edk2-devel mailing list >> edk2-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/edk2-devel ------------------------------------------------------------------------------ Monitor 25 network devices or servers for free with OpManager! OpManager is web-based network management software that monitors network devices and physical & virtual servers, alerts via email & sms for fault. Monitor 25 devices for free with no restriction. Download now http://ad.doubleclick.net/ddm/clk/292181274;119417398;o _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel