Always initialize PCPU kcr3 for vmspace0 pmap.

If an exception or NMI occurs before CPU switched to a pmap different
from vmspace0, PCPU kcr3 is left zero for pti config, which causes
triple-fault in the handler.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
This commit is contained in:
Konstantin Belousov 2018-08-20 19:07:57 +00:00
parent 5747fe4fb9
commit b0568ddbec
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=338112

View File

@ -2661,10 +2661,6 @@ pmap_pinit0(pmap_t pmap)
CPU_FOREACH(i) { CPU_FOREACH(i) {
pmap->pm_pcids[i].pm_pcid = PMAP_PCID_KERN + 1; pmap->pm_pcids[i].pm_pcid = PMAP_PCID_KERN + 1;
pmap->pm_pcids[i].pm_gen = 1; pmap->pm_pcids[i].pm_gen = 1;
if (!pti) {
__pcpu[i].pc_kcr3 = PMAP_NO_CR3;
__pcpu[i].pc_ucr3 = PMAP_NO_CR3;
}
} }
pmap_activate_boot(pmap); pmap_activate_boot(pmap);
} }
@ -7571,6 +7567,7 @@ pmap_activate(struct thread *td)
void void
pmap_activate_boot(pmap_t pmap) pmap_activate_boot(pmap_t pmap)
{ {
uint64_t kcr3;
u_int cpuid; u_int cpuid;
/* /*
@ -7586,6 +7583,11 @@ pmap_activate_boot(pmap_t pmap)
CPU_SET(cpuid, &pmap->pm_active); CPU_SET(cpuid, &pmap->pm_active);
#endif #endif
PCPU_SET(curpmap, pmap); PCPU_SET(curpmap, pmap);
kcr3 = pmap->pm_cr3;
if (pmap_pcid_enabled)
kcr3 |= pmap->pm_pcids[cpuid].pm_pcid | CR3_PCID_SAVE;
PCPU_SET(kcr3, kcr3);
PCPU_SET(ucr3, PMAP_NO_CR3);
} }
void void