Date: Sat, 25 Aug 2018 19:21:28 +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: <3CE9AF7F-CD5B-4FE3-9BDA-7F25C7A7C0B9@grem.de> In-Reply-To: <20180824203903.GJ2340@kib.kiev.ua> References: <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> <32F22868-92ED-4223-84B5-77E72C7DCF50@grem.de> <20180824203903.GJ2340@kib.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
>> On 24. Aug 2018, at 22:39, Konstantin Belousov <kostikbel@gmail.com> wrot=
e:
>>=20
>> On Fri, Aug 24, 2018 at 10:32:06PM +0200, Michael Gmelin wrote:
>>=20
>>=20
>>> On 24. Aug 2018, at 21:59, Konstantin Belousov <kostikbel@gmail.com> wro=
te:
>>> Please apply the following debugging patch on top of the previous 'fix'.=
>>> You need debug.late_console=3D0.
>>=20
>> Unfortunately debug.late_console=3D0 doesn???t work on this machine (no m=
ore output on the console), I tried that earlier in this thread - hence the s=
lightly complicated debugging code I had to add to see the contents of physm=
ap.
>>=20
>> I could run this code after boot (feeding it an identical physmap) to get=
debug output, would this make sense?
> Yes, with exactly the same physmap[].
>=20
> Really, I do not need exactly the output from my patch, but just make it
> clear why is_kernel_paddr() did not triggered selection from different
> location.
I have to apologize, something went wrong
when I applied your previous fix, so it was never really used when I tested.=
Now, with the patch applied correctly, the machine actually boots.
Before calling init_ops.mp_bootaddress in
getmemsize (machdep.c), physmap looks like this:
physmap_idx: 8
i mem atop
0 0x0 0x0
1 0x30000 0x30
2 0x40000 0x40
3 0x9e400 0x9e
4 0x100000 0x100
5 0xf00000 0xf00
6 0x1000000 0x1000
7 0x7bf7a000 0x7bf7a
8 0x100000000 0x100000
9 0x100600000 0x100600
10 0x0 0x0
With your patch, it looks like this now
(after calling getmemsize)
0 0x0 0x0
1 0x30000 0x30
2 0x40000 0x40
3 0x9e400 0x9e
4 0x100000 0x100
5 0xf00000 0xf00
6 0x1000000 0x1000
7 0x7bf77000 0x7bf77
8 0x100000000 0x100000
9 0x100600000 0x100600
10 0x0 0x0
PAGETABLES is 0x7bf77000
So I guess this means that the gap is now at the last three pages of [0x1000=
, 0x7bf7a[.
If this is what was intended, I guess it's good, as the machine boots okay n=
ow.
Sorry again for the extra roundtrip, the patched file was simply in the wron=
g path.
Yours,
Michael
p.s. Please see below the patched version of
mp_machdep.c I used for testing (should match yours):
...
#define AP_BOOTPT_SZ (PAGE_SIZE * 3)
extern struct pcpu __pcpu[];
/* Temporary variables for init_secondary() */
char *doublefault_stack;
char *mce_stack;
char *nmi_stack;
char *dbg_stack;
/*
* Local data and functions.
*/
static int start_ap(int apic_id);
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;
alloc_ap_trampoline(physmap, physmap_idx);
/*
* 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) {
/*
* 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.
*/
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;
}
} 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 at %#=
x",
mptramp_pagetables);
}
}
...
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3CE9AF7F-CD5B-4FE3-9BDA-7F25C7A7C0B9>
