Fix the undersupported option KERNLOAD, part 2: fix crashes in locore
when KERNLOAD is smaller than NBPDR (not the default) and PG_G is enabled (the default if the CPU supports it). This case has relatively minor problems with coherency of the permanent double mapping, but the fix in r167869 to improve coherency creates page tables with 3 different errors so never worked. The permanent double mapping is fundamentally broken and will be removed soon. It fundamentally breaks trapping for null pointers and requires complications to avoid cache coherency bugs. It is currently used for only a single instruction in ACPI resume, Many fixes VM86 and/or ACPI and/or the double map were attempted near r1200000. r167869 attempted to fix cache coherency bugs in an unusual case, but the bugs were unreachable because older errors in page tables caused a crash first. This commit just makes r167869 work as intended. Part 1 of these fixes fixed the other errors, but also stopped mapping the PDE for KERNBASE as a large page, so double mapping of this PDE only causes the same problems as when KERNLOAD is the default. Except for the problem of trapping null pointers, r167869 could be used to fix these problems, but it is inactive in usual cases. The only known other problem is that incoherent permissions for page 0 cause spurious traps in VM86 BIOS calls. Reviewed by: kib
This commit is contained in:
parent
64874a795e
commit
4a5eb9ac99
@ -790,8 +790,9 @@ no_kernend:
|
||||
* mapping is destroyed in pmap_bootstrap(). Ordinarily, the same page table
|
||||
* pages are shared by the identity mapping and the kernel's native mapping.
|
||||
* However, the permanent identity mapping cannot contain PG_G mappings.
|
||||
* Thus, if the kernel is loaded within the permanent identity mapping, that
|
||||
* page table page must be duplicated and not shared.
|
||||
* Thus, if the (physical) kernel overlaps the permanent identity mapping
|
||||
* (and PG_G is enabled), the
|
||||
* page table for the first PDE must be duplicated and not shared.
|
||||
*
|
||||
* N.B. Due to errata concerning large pages and physical address zero,
|
||||
* a PG_PS mapping is not used.
|
||||
@ -804,10 +805,15 @@ no_kernend:
|
||||
testl $PG_G, R(pgeflag)
|
||||
jz 1f
|
||||
ALLOCPAGES(1)
|
||||
movl %esi, %eax
|
||||
movl $1, %ecx
|
||||
fillkptphys($PG_RW) /* map the new page table in std map */
|
||||
movl %esi, %edi
|
||||
movl R(IdlePTD), %eax
|
||||
movl (%eax), %esi
|
||||
movl (%eax), %esi /* top bits are 0 for PAE */
|
||||
andl $~PAGE_MASK, %esi
|
||||
movl %edi, (%eax)
|
||||
orl $PG_V | PG_RW, (%eax) /* finish writing new PTD[0] */
|
||||
movl $PAGE_SIZE, %ecx
|
||||
cld
|
||||
rep
|
||||
|
Loading…
Reference in New Issue
Block a user