From: Kurt Kennett <Kurt.Kennett@microsoft.com>
To: edk2-devel <edk2-devel@lists.01.org>
Subject: Problem with Arm Mmu code in CpuDxe
Date: Wed, 21 Sep 2016 16:09:06 +0000 [thread overview]
Message-ID: <BL2PR03MB433AE7DE3D7F0D64807EF659CF60@BL2PR03MB433.namprd03.prod.outlook.com> (raw)
I am having a problem on my system (assert), and during investigation I may have found a problem with the Arm CpuDxe Mmu code that may affect all ARM platform users.
CpuDxeInitialize is the entry point, and pretty soon after entry it does:
SyncCacheConfig (&mCpu);
This calls into:
ArmPkg\Drivers\CpuDxe\Arm\Mmu.c
The code asserts that the Mmu is enabled, gets the memory space map, then starts to process the page tables by getting the TTBR0 base address.
// obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)(ArmGetTTBR0BaseAddress ());
// Get the first region
NextSectionAttributes = FirstLevelTable[0] & (TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK | TT_DESCRIPTOR_SECTION_AP_MASK);
// iterate through each 1MB descriptor
NextRegionBase = NextRegionLength = 0;
for (i=0; i < TRANSLATION_TABLE_SECTION_COUNT; i++) {
if ((FirstLevelTable[i] & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
...<snip>
} else if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(FirstLevelTable[i])) {
Status = SyncCacheConfigPage (
i,FirstLevelTable[i],
NumberOfDescriptors, MemorySpaceMap,
&NextRegionBase,&NextRegionLength,&NextSectionAttributes);
ASSERT_EFI_ERROR (Status);
} else {
Note that the "NextSectionAttributes" is computed based on the assumption that the entry is indeed a section, and not a first-level pagetable entry. The cache policy mask and ap mask have no meaning for a pagetable entry.
Assume my TTBR0 points to 0x80000000 and the very first entry in the translation table is 0x4FFEB009. Decoding this entry gives:
Entry is a Page table (low bits 01)
NS is 1 (Not Secure)
Domain is 0
Page table base address is 0x4FFEB000
But the 'NextSectionAttributes' computed above is 0xB000 (again, which is garbage since the entry is a page table not a section).
Above, the system calls SyncCacheConfigPage, with the 'NextSectionAttributes' address, which leads to:
// Convert SectionAttributes into PageAttributes
NextPageAttributes =
TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(*NextSectionAttributes,0) |
TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(*NextSectionAttributes);
>From 0xB000, this creates page attributes which are invalid.
The code then follows:
for (i=0; i < TRANSLATION_TABLE_PAGE_COUNT; i++) {
if ((SecondLevelTable[i] & TT_DESCRIPTOR_PAGE_TYPE_MASK) == TT_DESCRIPTOR_PAGE_TYPE_PAGE) {
// extract attributes (cacheability and permissions)
PageAttributes = SecondLevelTable[i] & (TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK | TT_DESCRIPTOR_PAGE_AP_MASK);
if (NextPageAttributes == 0) {
...<snip>
} else if (PageAttributes != NextPageAttributes) {
// Convert Section Attributes into GCD Attributes
Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
ASSERT_EFI_ERROR (Status);
...<snip>
}
} else if (NextPageAttributes != 0) {
Assume the second level descriptor is something harmless like 0x00000072.
00000072 =
Small Page, NX clear
C = 0, B = 0, TEX = 001, so Outer and Inner Non-cacheable Normal Memory
AP = 011, so Read/Write for both Priviledged and User
Physical page address 00000000
This is at least something different from 'NextPageAttributes' (which is not zero)
This leads to "convert section attributes into gcd attributes" a call to PageToGcdAttributes with the (invalid) NextPageAttributes.
The code does:
switch(PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {
Which results in an unknown cache policy, and the function returns EFU_UNSUPPORTED. This causes an ASSERT.
I was investigating a fix but at the same time wanted to let the mailing list chime in on whether anyone else had run into this problem or had ideas on the proper way to solve it.
K2
next reply other threads:[~2016-09-21 16:09 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-21 16:09 Kurt Kennett [this message]
2016-09-21 17:20 ` Problem with Arm Mmu code in CpuDxe Ard Biesheuvel
2016-09-21 17:31 ` Kurt Kennett
2016-09-21 17:54 ` Kurt Kennett
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BL2PR03MB433AE7DE3D7F0D64807EF659CF60@BL2PR03MB433.namprd03.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox