]> xenbits.xensource.com Git - people/royger/freebsd.git/commitdiff
Provide non-final but valid PCB pointer for thread0 for duration of
authorkib <kib@FreeBSD.org>
Wed, 14 Dec 2016 11:40:31 +0000 (11:40 +0000)
committerkib <kib@FreeBSD.org>
Wed, 14 Dec 2016 11:40:31 +0000 (11:40 +0000)
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

sys/amd64/amd64/machdep.c

index b2283339405fc34646ce51183ad9e06dfd84bfe5..682307f5fe42c8f97d9290ba85d62ad6a032ed5b 100644 (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);