svn commit: r334329 - head/sys/arm64/arm64
Patryk Duda
pdk at semihalf.com
Tue Jun 26 09:12:10 UTC 2018
Could you provide some details about firmware? I would like to
reproduce it on our ThunderX2.
2018-06-25 17:28 GMT+02:00 Andrew Turner <andrew at freebsd.org>:
> I’ve not seen this on the ThunderX2 I have access to with the latest firmware. You’ll need to find out why the kernel is trying to access the memory, and where it is in the EFI memory map.
>
> Andrew
>
>> On 21 Jun 2018, at 13:41, Patryk Duda <pdk at semihalf.com> wrote:
>>
>> Hi,
>>
>> I'm trying to boot kernel on ThunderX2 but I've got following error:
>>
>> panic: efi_init: PA out of range, PA: 0xfafd0018
>>
>> This error comes from PHYS_TO_DMAP macro.
>> I can workaround this issue by disabling EFI Runtime Services in
>> kernel config but it seems to be
>> a problem with discontignous DMAP mapping.
>>
>>
>> 2018-05-29 15:52 GMT+02:00 Andrew Turner <andrew at freebsd.org>:
>>> Author: andrew
>>> Date: Tue May 29 13:52:25 2018
>>> New Revision: 334329
>>> URL: https://svnweb.freebsd.org/changeset/base/334329
>>>
>>> Log:
>>> On ThunderX2 we need to be careful to only map the memory the firmware
>>> lists in the EFI memory map. As such we need to reduce the mappings to
>>> restrict them to not be the full 1G block. For now reduce this to a 2M
>>> block, however this may be further restricted to be 4k page aligned as
>>> other SoCs may require.
>>>
>>> This allows ThunderX2 to boot reliably to userspace without performing
>>> any speculative memory accesses to invalid physical memory.
>>>
>>> This is a recommit of r334035 now that we can access the EFI Runtime data
>>> through the DMAP region.
>>>
>>> Tested by: tuexen
>>> Sponsored by: DARPA, AFRL
>>>
>>> Modified:
>>> head/sys/arm64/arm64/pmap.c
>>>
>>> Modified: head/sys/arm64/arm64/pmap.c
>>> ==============================================================================
>>> --- head/sys/arm64/arm64/pmap.c Tue May 29 13:43:16 2018 (r334328)
>>> +++ head/sys/arm64/arm64/pmap.c Tue May 29 13:52:25 2018 (r334329)
>>> @@ -590,33 +590,100 @@ pmap_early_vtophys(vm_offset_t l1pt, vm_offset_t va)
>>> return ((l2[l2_slot] & ~ATTR_MASK) + (va & L2_OFFSET));
>>> }
>>>
>>> -static void
>>> -pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa, vm_paddr_t max_pa)
>>> +static vm_offset_t
>>> +pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa,
>>> + vm_offset_t freemempos)
>>> {
>>> + pt_entry_t *l2;
>>> vm_offset_t va;
>>> - vm_paddr_t pa;
>>> - u_int l1_slot;
>>> + vm_paddr_t l2_pa, pa;
>>> + u_int l1_slot, l2_slot, prev_l1_slot;
>>> int i;
>>>
>>> dmap_phys_base = min_pa & ~L1_OFFSET;
>>> dmap_phys_max = 0;
>>> dmap_max_addr = 0;
>>> + l2 = NULL;
>>> + prev_l1_slot = -1;
>>>
>>> +#define DMAP_TABLES ((DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS) >> L0_SHIFT)
>>> + memset(pagetable_dmap, 0, PAGE_SIZE * DMAP_TABLES);
>>> +
>>> for (i = 0; i < (physmap_idx * 2); i += 2) {
>>> - pa = physmap[i] & ~L1_OFFSET;
>>> + pa = physmap[i] & ~L2_OFFSET;
>>> va = pa - dmap_phys_base + DMAP_MIN_ADDRESS;
>>>
>>> - for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1];
>>> + /* Create L2 mappings at the start of the region */
>>> + if ((pa & L1_OFFSET) != 0) {
>>> + l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT);
>>> + if (l1_slot != prev_l1_slot) {
>>> + prev_l1_slot = l1_slot;
>>> + l2 = (pt_entry_t *)freemempos;
>>> + l2_pa = pmap_early_vtophys(kern_l1,
>>> + (vm_offset_t)l2);
>>> + freemempos += PAGE_SIZE;
>>> +
>>> + pmap_load_store(&pagetable_dmap[l1_slot],
>>> + (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE);
>>> +
>>> + memset(l2, 0, PAGE_SIZE);
>>> + }
>>> + KASSERT(l2 != NULL,
>>> + ("pmap_bootstrap_dmap: NULL l2 map"));
>>> + for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1];
>>> + pa += L2_SIZE, va += L2_SIZE) {
>>> + /*
>>> + * We are on a boundary, stop to
>>> + * create a level 1 block
>>> + */
>>> + if ((pa & L1_OFFSET) == 0)
>>> + break;
>>> +
>>> + l2_slot = pmap_l2_index(va);
>>> + KASSERT(l2_slot != 0, ("..."));
>>> + pmap_load_store(&l2[l2_slot],
>>> + (pa & ~L2_OFFSET) | ATTR_DEFAULT | ATTR_XN |
>>> + ATTR_IDX(CACHED_MEMORY) | L2_BLOCK);
>>> + }
>>> + KASSERT(va == (pa - dmap_phys_base + DMAP_MIN_ADDRESS),
>>> + ("..."));
>>> + }
>>> +
>>> + for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1] &&
>>> + (physmap[i + 1] - pa) >= L1_SIZE;
>>> pa += L1_SIZE, va += L1_SIZE) {
>>> l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT);
>>> - /* We already have an entry */
>>> - if (pagetable_dmap[l1_slot] != 0)
>>> - continue;
>>> pmap_load_store(&pagetable_dmap[l1_slot],
>>> (pa & ~L1_OFFSET) | ATTR_DEFAULT | ATTR_XN |
>>> ATTR_IDX(CACHED_MEMORY) | L1_BLOCK);
>>> }
>>>
>>> + /* Create L2 mappings at the end of the region */
>>> + if (pa < physmap[i + 1]) {
>>> + l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT);
>>> + if (l1_slot != prev_l1_slot) {
>>> + prev_l1_slot = l1_slot;
>>> + l2 = (pt_entry_t *)freemempos;
>>> + l2_pa = pmap_early_vtophys(kern_l1,
>>> + (vm_offset_t)l2);
>>> + freemempos += PAGE_SIZE;
>>> +
>>> + pmap_load_store(&pagetable_dmap[l1_slot],
>>> + (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE);
>>> +
>>> + memset(l2, 0, PAGE_SIZE);
>>> + }
>>> + KASSERT(l2 != NULL,
>>> + ("pmap_bootstrap_dmap: NULL l2 map"));
>>> + for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1];
>>> + pa += L2_SIZE, va += L2_SIZE) {
>>> + l2_slot = pmap_l2_index(va);
>>> + pmap_load_store(&l2[l2_slot],
>>> + (pa & ~L2_OFFSET) | ATTR_DEFAULT | ATTR_XN |
>>> + ATTR_IDX(CACHED_MEMORY) | L2_BLOCK);
>>> + }
>>> + }
>>> +
>>> if (pa > dmap_phys_max) {
>>> dmap_phys_max = pa;
>>> dmap_max_addr = va;
>>> @@ -624,6 +691,8 @@ pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t mi
>>> }
>>>
>>> cpu_tlb_flushID();
>>> +
>>> + return (freemempos);
>>> }
>>>
>>> static vm_offset_t
>>> @@ -729,8 +798,11 @@ pmap_bootstrap(vm_offset_t l0pt, vm_offset_t l1pt, vm_
>>> max_pa = physmap[i + 1];
>>> }
>>>
>>> + freemempos = KERNBASE + kernlen;
>>> + freemempos = roundup2(freemempos, PAGE_SIZE);
>>> +
>>> /* Create a direct map region early so we can use it for pa -> va */
>>> - pmap_bootstrap_dmap(l1pt, min_pa, max_pa);
>>> + freemempos = pmap_bootstrap_dmap(l1pt, min_pa, freemempos);
>>>
>>> va = KERNBASE;
>>> start_pa = pa = KERNBASE - kern_delta;
>>> @@ -762,8 +834,6 @@ pmap_bootstrap(vm_offset_t l0pt, vm_offset_t l1pt, vm_
>>>
>>> va = roundup2(va, L1_SIZE);
>>>
>>> - freemempos = KERNBASE + kernlen;
>>> - freemempos = roundup2(freemempos, PAGE_SIZE);
>>> /* Create the l2 tables up to VM_MAX_KERNEL_ADDRESS */
>>> freemempos = pmap_bootstrap_l2(l1pt, va, freemempos);
>>> /* And the l3 tables for the early devmap */
>>> _______________________________________________
>>> svn-src-all at freebsd.org mailing list
>>> https://lists.freebsd.org/mailman/listinfo/svn-src-all
>>> To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
>>
>
More information about the svn-src-all
mailing list