Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Aug 2018 22:32:06 +0200
From:      Michael Gmelin <freebsd@grem.de>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        John Baldwin <jhb@FreeBSD.org>, "freebsd-current@freebsd.org" <freebsd-current@freebsd.org>, Matthias Apitz <guru@unixarea.de>
Subject:   Re: Fatal trap 12: page fault on Acer Chromebook 720 (peppy)
Message-ID:  <32F22868-92ED-4223-84B5-77E72C7DCF50@grem.de>
In-Reply-To: <20180824195947.GG2340@kib.kiev.ua>
References:  <8726bc32-6023-bfe1-7600-5b2c706236f8@FreeBSD.org> <20180819165951.274d61b0@bsd64.grem.de> <20180819161642.GP2340@kib.kiev.ua> <20180820004512.5171fa75@bsd64.grem.de> <20180820150904.GS2340@kib.kiev.ua> <57B6DC4C-16EE-4B7B-B691-CB79D8C40289@grem.de> <20180822154603.GW2340@kib.kiev.ua> <C8BC1622-4F47-4E56-A428-46DAC5CE71B4@grem.de> <20180822211528.GB2340@kib.kiev.ua> <1C7DACDC-36F2-4E65-8C75-7B7215BB6546@grem.de> <20180824195947.GG2340@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help


> On 24. Aug 2018, at 21:59, Konstantin Belousov <kostikbel@gmail.com> wrote=
:
>=20
>> On Thu, Aug 23, 2018 at 12:10:34AM +0200, Michael Gmelin wrote:
>>=20
>>=20
>>>> On 22. Aug 2018, at 23:15, Konstantin Belousov <kostikbel@gmail.com> wr=
ote:
>>>>=20
>>>> On Wed, Aug 22, 2018 at 10:03:54PM +0200, Michael Gmelin wrote:
>>>>=20
>>>>=20
>>>>>> On 22. Aug 2018, at 17:46, Konstantin Belousov <kostikbel@gmail.com> w=
rote:
>>>>>>=20
>>>>>> On Tue, Aug 21, 2018 at 12:14:35AM +0200, Michael Gmelin wrote:
>>>>>>=20
>>>>>>=20
>>>>>>>> On 20. Aug 2018, at 17:09, Konstantin Belousov <kostikbel@gmail.com=
> wrote:
>>>>>>>>=20
>>>>>>>> On Mon, Aug 20, 2018 at 12:45:12AM +0200, Michael Gmelin wrote:
>>>>>>>>=20
>>>>>>>> See here for a screenshot (also including the output of "show pte
>>>>>>>> 0xfffff80001000000"):
>>>>>>>>=20
>>>>>>>> https://gist.github.com/grembo/78d0f2a100dd4f16775b85a118769658#fil=
e-ddb1-png
>>>>>>> It is too early for ddb routines to register.
>>>>>>> Ok can you try the following debugging patch, to verify my guess ?
>>>>>>>=20
>>>>>>> diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
>>>>>>> index 18777d23f09..cd05fdb763f 100644
>>>>>>> --- a/sys/amd64/amd64/pmap.c
>>>>>>> +++ b/sys/amd64/amd64/pmap.c
>>>>>>> @@ -1052,8 +1052,7 @@ create_pagetables(vm_paddr_t *firstaddr)
>>>>>>>     pd_p =3D (pd_entry_t *)DMPDkernphys;
>>>>>>>     for (i =3D 0; i < (NPDEPG * nkdmpde); i++)
>>>>>>>         pd_p[i] =3D (i << PDRSHIFT) | X86_PG_V | PG_PS | pg_g |
>>>>>>> -                X86_PG_M | X86_PG_A | pg_nx |
>>>>>>> -                bootaddr_rwx(i << PDRSHIFT);
>>>>>>> +                X86_PG_M | X86_PG_A | pg_nx | X86_PG_RW;
>>>>>>>     for (i =3D 0; i < nkdmpde; i++)
>>>>>>>         pdp_p[i] =3D (DMPDkernphys + ptoa(i)) | X86_PG_RW |
>>>>>>>             X86_PG_V;
>>>>>>=20
>>>>>> With this change it boots okay (mptramp_pagetables is 0x1000000, as e=
xpected).
>>>>>=20
>>>>> Can you apply the following on top of the previous debugging patch and=
 show
>>>>> me the line printed ?
>>>>>=20
>>>>> diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
>>>>> index 3d70532b7fd..613fa9f2165 100644
>>>>> --- a/sys/amd64/amd64/pmap.c
>>>>> +++ b/sys/amd64/amd64/pmap.c
>>>>> @@ -2662,6 +2662,7 @@ pmap_pinit0(pmap_t pmap)
>>>>>      pmap->pm_pcids[i].pm_gen =3D 1;
>>>>>  }
>>>>>  pmap_activate_boot(pmap);
>>>>> +printf("bootaddr addr %#lx rwx %#lx btext %#lx _end %#lx brwsection %=
#lx etext %#lx KERNBASE %#lx\n", 0x1000000UL, bootaddr_rwx(0x1000000UL), (ui=
ntptr_t)btext, (uintptr_t)_end, (uintptr_t)brwsection, (uintptr_t)etext, (ui=
ntptr_t)KERNBASE);
>>>>> }
>>>>>=20
>>>>> void
>>>>=20
>>>> bootaddr addr 0x1000000 rwx 0 btext 0xffffffff80342000 _end 0xffffffff8=
23cf840 brwsection #ffffffff81a00000 etext 0xffffffff812041e4 KERNBASE 0xfff=
fffff80000000
>>>>=20
>>>=20
>>> Try this, please.  Revert all debugging pmap.c patches that I provided
>>> before.
>>>=20
>>> diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c=

>>> index 4ca2e07e578..2ee8f862854 100644
>>> --- a/sys/amd64/amd64/mp_machdep.c
>>> +++ b/sys/amd64/amd64/mp_machdep.c
>>> @@ -87,6 +87,8 @@ __FBSDID("$FreeBSD$");
>>>=20
>>> #define GiB(v)            (v ## ULL << 30)
>>>=20
>>> +#define    AP_BOOTPT_SZ        (PAGE_SIZE * 3)
>>> +
>>> extern    struct pcpu __pcpu[];
>>>=20
>>> /* Temporary variables for init_secondary()  */
>>> @@ -101,45 +103,78 @@ char *dbg_stack;
>>>=20
>>> static int    start_ap(int apic_id);
>>>=20
>>> +static bool
>>> +is_kernel_paddr(vm_paddr_t pa)
>>> +{
>>> +
>>> +    return (pa >=3D trunc_2mpage(btext - KERNBASE) &&
>>> +       pa < round_page(_end - KERNBASE));
>>> +}
>>> +
>>> +static bool
>>> +is_mpboot_good(vm_paddr_t start, vm_paddr_t end)
>>> +{
>>> +
>>> +    return (start + AP_BOOTPT_SZ <=3D GiB(4) &&
>>> +        end >=3D start + AP_BOOTPT_SZ && atop(end) < Maxmem);
>>> +}
>>> +
>>> /*
>>> * Calculate usable address in base memory for AP trampoline code.
>>> */
>>> void
>>> mp_bootaddress(vm_paddr_t *physmap, unsigned int *physmap_idx)
>>> {
>>> +    vm_paddr_t start, end;
>>>   unsigned int i;
>>>   bool allocated;
>>>=20
>>>   alloc_ap_trampoline(physmap, physmap_idx);
>>>=20
>>> +    /*
>>> +     * Find a memory region big enough below the 4GB boundary to
>>> +     * store the initial page tables.  Region must be mapped by
>>> +     * the direct map.
>>> +     *
>>> +     * Note that it needs to be aligned to a page boundary.
>>> +     */
>>>   allocated =3D false;
>>>   for (i =3D *physmap_idx; i <=3D *physmap_idx; i -=3D 2) {
>>>       /*
>>> -         * Find a memory region big enough below the 4GB
>>> -         * boundary to store the initial page tables.  Region
>>> -         * must be mapped by the direct map.
>>> -         *
>>> -         * Note that it needs to be aligned to a page
>>> -         * boundary.
>>> +         * First, try to chomp at the start of the physmap region.
>>> +         * Kernel binary might claim it already.
>>> +         */
>>> +        start =3D round_page(physmap[i]);
>>> +        end =3D trunc_page(physmap[i + 1]);
>>> +        if (is_mpboot_good(start, end) &&
>>> +            !is_kernel_paddr(start) && !is_kernel_paddr(end - 1)) {
>>> +            allocated =3D true;
>>> +            physmap[i] =3D start + AP_BOOTPT_SZ;
>>> +            break;
>>> +        }
>>> +
>>> +        /*
>>> +         * Second, try to chomp at the end.  Again, check
>>> +         * against kernel.
>>>        */
>>> -        if (physmap[i] >=3D GiB(4) || physmap[i + 1] -
>>> -            round_page(physmap[i]) < PAGE_SIZE * 3 ||
>>> -            atop(physmap[i + 1]) > Maxmem)
>>> -            continue;
>>> -
>>> -        allocated =3D true;
>>> -        mptramp_pagetables =3D round_page(physmap[i]);
>>> -        physmap[i] =3D round_page(physmap[i]) + (PAGE_SIZE * 3);
>>> +        end =3D trunc_page(physmap[i + 1]);
>>> +        start =3D end - AP_BOOTPT_SZ;
>>> +        if (start >=3D physmap[i] && is_mpboot_good(start, end) &&
>>> +            !is_kernel_paddr(start) && !is_kernel_paddr(end - 1)) {
>>> +            allocated =3D true;
>>> +            physmap[i + 1] =3D start;
>>> +            break;
>>> +        }
>>> +    }
>>> +    if (allocated) {
>>> +        mptramp_pagetables =3D start;
>>>       if (physmap[i] =3D=3D physmap[i + 1] && *physmap_idx !=3D 0) {
>>>           memmove(&physmap[i], &physmap[i + 2],
>>>               sizeof(*physmap) * (*physmap_idx - i + 2));
>>>           *physmap_idx -=3D 2;
>>>       }
>>> -        break;
>>> -    }
>>> -
>>> -    if (!allocated) {
>>> -        mptramp_pagetables =3D trunc_page(boot_address) - (PAGE_SIZE * 3=
);
>>> +    } else {
>>> +        mptramp_pagetables =3D trunc_page(boot_address) - AP_BOOTPT_SZ;=

>>>       if (bootverbose)
>>>           printf(
>>> "Cannot find enough space for the initial AP page tables, placing them a=
t %#x",
>>=20
>> Reverted back to r337813 and applied the patch. Unfortunately it panics j=
ust like before. Adding back physmap debugging like before shows that it???s=
 still using pages 0x1000-0x1003 (Stopped at native_start_all_aps+0x92: movq=
 %rax,(%rsi))
>>=20
>=20
> Please apply the following debugging patch on top of the previous 'fix'.
> You need debug.late_console=3D0.

Unfortunately debug.late_console=3D0 doesn=E2=80=99t work on this machine (n=
o more output on the console), I tried that earlier in this thread - hence t=
he slightly complicated debugging code I had to add to see the contents of p=
hysmap.

I could run this code after boot (feeding it an identical physmap) to get de=
bug output, would this make sense?

Best,
Michael

>=20
> diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
> index 2ee8f862854..1a14b1800b1 100644
> --- a/sys/amd64/amd64/mp_machdep.c
> +++ b/sys/amd64/amd64/mp_machdep.c
> @@ -130,7 +130,7 @@ mp_bootaddress(vm_paddr_t *physmap, unsigned int *phys=
map_idx)
>    bool allocated;
>=20
>    alloc_ap_trampoline(physmap, physmap_idx);
> -
> +printf("btext %#lx _end %#lx brwsection %#lx etext %#lx KERNBASE %#lx\n",=
 (uintptr_t)btext, (uintptr_t)_end, (uintptr_t)brwsection, (uintptr_t)etext,=
 (uintptr_t)KERNBASE);
>    /*
>     * Find a memory region big enough below the 4GB boundary to
>     * store the initial page tables.  Region must be mapped by
> @@ -146,10 +146,13 @@ mp_bootaddress(vm_paddr_t *physmap, unsigned int *ph=
ysmap_idx)
>         */
>        start =3D round_page(physmap[i]);
>        end =3D trunc_page(physmap[i + 1]);
> +printf("physmap[%d] %#lx physmap[%d] %#lx\n", i, physmap[i], i + 1, physm=
ap[i + 1]);
> +printf("start %#lx end %#lx is_mpboot_good %d is_kernel_paddr(start) %d i=
s_kernel_paddr(end - 1) %d\n", start, end, is_mpboot_good(start, end), is_ke=
rnel_paddr(start), is_kernel_paddr(end - 1));
>        if (is_mpboot_good(start, end) &&
>            !is_kernel_paddr(start) && !is_kernel_paddr(end - 1)) {
>            allocated =3D true;
>            physmap[i] =3D start + AP_BOOTPT_SZ;
> +printf("allocated\n");
>            break;
>        }
>=20
> @@ -159,10 +162,12 @@ mp_bootaddress(vm_paddr_t *physmap, unsigned int *ph=
ysmap_idx)
>         */
>        end =3D trunc_page(physmap[i + 1]);
>        start =3D end - AP_BOOTPT_SZ;
> +printf("start %#lx end %#lx is_mpboot_good %d is_kernel_paddr(start) %d i=
s_kernel_paddr(end - 1) %d\n", start, end, is_mpboot_good(start, end), is_ke=
rnel_paddr(start), is_kernel_paddr(end - 1));
>        if (start >=3D physmap[i] && is_mpboot_good(start, end) &&
>            !is_kernel_paddr(start) && !is_kernel_paddr(end - 1)) {
>            allocated =3D true;
>            physmap[i + 1] =3D start;
> +printf("allocated\n");
>            break;
>        }
>    }




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?32F22868-92ED-4223-84B5-77E72C7DCF50>