Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Jun 2018 11:12:06 +0200
From:      Patryk Duda <pdk@semihalf.com>
To:        Andrew Turner <andrew@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r334329 - head/sys/arm64/arm64
Message-ID:  <CAGOBvLpgu5DSgPMQfVhGmb3QA2VavLV2jXv1467Xd3NY6DzzMg@mail.gmail.com>
In-Reply-To: <89A0025A-1048-4A12-AF3C-BC3BD2B99B86@freebsd.org>
References:  <201805291352.w4TDqPur045848@repo.freebsd.org> <CAGOBvLrutyRKLHVqzQg4PJnVgLdxD4aQ0JYMGFOrPtnqmXQ4PA@mail.gmail.com> <89A0025A-1048-4A12-AF3C-BC3BD2B99B86@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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@freebsd.org>:
> I=E2=80=99ve not seen this on the ThunderX2 I have access to with the lat=
est firmware. You=E2=80=99ll need to find out why the kernel is trying to a=
ccess the memory, and where it is in the EFI memory map.
>
> Andrew
>
>> On 21 Jun 2018, at 13:41, Patryk Duda <pdk@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@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 d=
ata
>>>  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
>>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>>> --- head/sys/arm64/arm64/pmap.c Tue May 29 13:43:16 2018        (r33432=
8)
>>> +++ head/sys/arm64/arm64/pmap.c Tue May 29 13:52:25 2018        (r33432=
9)
>>> @@ -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 =3D min_pa & ~L1_OFFSET;
>>>        dmap_phys_max =3D 0;
>>>        dmap_max_addr =3D 0;
>>> +       l2 =3D NULL;
>>> +       prev_l1_slot =3D -1;
>>>
>>> +#define        DMAP_TABLES     ((DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS) =
>> L0_SHIFT)
>>> +       memset(pagetable_dmap, 0, PAGE_SIZE * DMAP_TABLES);
>>> +
>>>        for (i =3D 0; i < (physmap_idx * 2); i +=3D 2) {
>>> -               pa =3D physmap[i] & ~L1_OFFSET;
>>> +               pa =3D physmap[i] & ~L2_OFFSET;
>>>                va =3D 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) !=3D 0) {
>>> +                       l1_slot =3D ((va - DMAP_MIN_ADDRESS) >> L1_SHIF=
T);
>>> +                       if (l1_slot !=3D prev_l1_slot) {
>>> +                               prev_l1_slot =3D l1_slot;
>>> +                               l2 =3D (pt_entry_t *)freemempos;
>>> +                               l2_pa =3D pmap_early_vtophys(kern_l1,
>>> +                                   (vm_offset_t)l2);
>>> +                               freemempos +=3D PAGE_SIZE;
>>> +
>>> +                               pmap_load_store(&pagetable_dmap[l1_slot=
],
>>> +                                   (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE=
);
>>> +
>>> +                               memset(l2, 0, PAGE_SIZE);
>>> +                       }
>>> +                       KASSERT(l2 !=3D NULL,
>>> +                           ("pmap_bootstrap_dmap: NULL l2 map"));
>>> +                       for (; va < DMAP_MAX_ADDRESS && pa < physmap[i =
+ 1];
>>> +                           pa +=3D L2_SIZE, va +=3D L2_SIZE) {
>>> +                               /*
>>> +                                * We are on a boundary, stop to
>>> +                                * create a level 1 block
>>> +                                */
>>> +                               if ((pa & L1_OFFSET) =3D=3D 0)
>>> +                                       break;
>>> +
>>> +                               l2_slot =3D pmap_l2_index(va);
>>> +                               KASSERT(l2_slot !=3D 0, ("..."));
>>> +                               pmap_load_store(&l2[l2_slot],
>>> +                                   (pa & ~L2_OFFSET) | ATTR_DEFAULT | =
ATTR_XN |
>>> +                                   ATTR_IDX(CACHED_MEMORY) | L2_BLOCK)=
;
>>> +                       }
>>> +                       KASSERT(va =3D=3D (pa - dmap_phys_base + DMAP_M=
IN_ADDRESS),
>>> +                           ("..."));
>>> +               }
>>> +
>>> +               for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1] &&
>>> +                   (physmap[i + 1] - pa) >=3D L1_SIZE;
>>>                    pa +=3D L1_SIZE, va +=3D L1_SIZE) {
>>>                        l1_slot =3D ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT=
);
>>> -                       /* We already have an entry */
>>> -                       if (pagetable_dmap[l1_slot] !=3D 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 =3D ((va - DMAP_MIN_ADDRESS) >> L1_SHIF=
T);
>>> +                       if (l1_slot !=3D prev_l1_slot) {
>>> +                               prev_l1_slot =3D l1_slot;
>>> +                               l2 =3D (pt_entry_t *)freemempos;
>>> +                               l2_pa =3D pmap_early_vtophys(kern_l1,
>>> +                                   (vm_offset_t)l2);
>>> +                               freemempos +=3D PAGE_SIZE;
>>> +
>>> +                               pmap_load_store(&pagetable_dmap[l1_slot=
],
>>> +                                   (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE=
);
>>> +
>>> +                               memset(l2, 0, PAGE_SIZE);
>>> +                       }
>>> +                       KASSERT(l2 !=3D NULL,
>>> +                           ("pmap_bootstrap_dmap: NULL l2 map"));
>>> +                       for (; va < DMAP_MAX_ADDRESS && pa < physmap[i =
+ 1];
>>> +                           pa +=3D L2_SIZE, va +=3D L2_SIZE) {
>>> +                               l2_slot =3D 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 =3D pa;
>>>                        dmap_max_addr =3D 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 =3D physmap[i + 1];
>>>        }
>>>
>>> +       freemempos =3D KERNBASE + kernlen;
>>> +       freemempos =3D roundup2(freemempos, PAGE_SIZE);
>>> +
>>>        /* Create a direct map region early so we can use it for pa -> v=
a */
>>> -       pmap_bootstrap_dmap(l1pt, min_pa, max_pa);
>>> +       freemempos =3D pmap_bootstrap_dmap(l1pt, min_pa, freemempos);
>>>
>>>        va =3D KERNBASE;
>>>        start_pa =3D pa =3D KERNBASE - kern_delta;
>>> @@ -762,8 +834,6 @@ pmap_bootstrap(vm_offset_t l0pt, vm_offset_t l1pt, =
vm_
>>>
>>>        va =3D roundup2(va, L1_SIZE);
>>>
>>> -       freemempos =3D KERNBASE + kernlen;
>>> -       freemempos =3D roundup2(freemempos, PAGE_SIZE);
>>>        /* Create the l2 tables up to VM_MAX_KERNEL_ADDRESS */
>>>        freemempos =3D pmap_bootstrap_l2(l1pt, va, freemempos);
>>>        /* And the l3 tables for the early devmap */
>>> _______________________________________________
>>> svn-src-all@freebsd.org mailing list
>>> https://lists.freebsd.org/mailman/listinfo/svn-src-all
>>> To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
>>
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGOBvLpgu5DSgPMQfVhGmb3QA2VavLV2jXv1467Xd3NY6DzzMg>