Provide non-final but valid PCB pointer for thread0 for duration of

hammer_time().  This makes assembler exception handlers not fault
itself when setting PCB flags, and allow normal kernel trap handler to
get control.  The pointer is reset after FPU parameters are obtained.

Set thread0.td_critnest to 1 for duration of hammer_time() as well.
In particular, page faults at that early stage panic immediately
instead of trying to call not yet operational VM to resolve it.

As result, faults during second half of the hammer_time() execution
have a chance to be reported instead of silent machine reboot or hang.

Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2016-12-14 11:40:31 +00:00
parent ca276276f1
commit 396a688bd9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=310050

View File

@ -1672,6 +1672,16 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
wrmsr(MSR_STAR, msr);
wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D);
/*
* Temporary forge some valid pointer to PCB, for exception
* handlers. It is reinitialized properly below after FPU is
* set up. Also set up td_critnest to short-cut the page
* fault handler.
*/
cpu_max_ext_state_size = sizeof(struct savefpu);
thread0.td_pcb = get_pcb_td(&thread0);
thread0.td_critnest = 1;
/*
* The console and kdb should be initialized even earlier than here,
* but some console drivers don't work until after getmemsize().
@ -1762,6 +1772,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
#ifdef FDT
x86_init_fdt();
#endif
thread0.td_critnest = 0;
/* Location of kernel stack for locore */
return ((u_int64_t)thread0.td_pcb);