|
@@ -63,7 +63,7 @@ static void *alloc_pgt_page(void *context)
|
|
static struct alloc_pgt_data pgt_data;
|
|
static struct alloc_pgt_data pgt_data;
|
|
|
|
|
|
/* The top level page table entry pointer. */
|
|
/* The top level page table entry pointer. */
|
|
-static unsigned long level4p;
|
|
|
|
|
|
+static unsigned long top_level_pgt;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Mapping information structure passed to kernel_ident_mapping_init().
|
|
* Mapping information structure passed to kernel_ident_mapping_init().
|
|
@@ -91,9 +91,15 @@ void initialize_identity_maps(void)
|
|
* If we came here via startup_32(), cr3 will be _pgtable already
|
|
* If we came here via startup_32(), cr3 will be _pgtable already
|
|
* and we must append to the existing area instead of entirely
|
|
* and we must append to the existing area instead of entirely
|
|
* overwriting it.
|
|
* overwriting it.
|
|
|
|
+ *
|
|
|
|
+ * With 5-level paging, we use '_pgtable' to allocate the p4d page table,
|
|
|
|
+ * the top-level page table is allocated separately.
|
|
|
|
+ *
|
|
|
|
+ * p4d_offset(top_level_pgt, 0) would cover both the 4- and 5-level
|
|
|
|
+ * cases. On 4-level paging it's equal to 'top_level_pgt'.
|
|
*/
|
|
*/
|
|
- level4p = read_cr3_pa();
|
|
|
|
- if (level4p == (unsigned long)_pgtable) {
|
|
|
|
|
|
+ top_level_pgt = read_cr3_pa();
|
|
|
|
+ if (p4d_offset((pgd_t *)top_level_pgt, 0) == (p4d_t *)_pgtable) {
|
|
debug_putstr("booted via startup_32()\n");
|
|
debug_putstr("booted via startup_32()\n");
|
|
pgt_data.pgt_buf = _pgtable + BOOT_INIT_PGT_SIZE;
|
|
pgt_data.pgt_buf = _pgtable + BOOT_INIT_PGT_SIZE;
|
|
pgt_data.pgt_buf_size = BOOT_PGT_SIZE - BOOT_INIT_PGT_SIZE;
|
|
pgt_data.pgt_buf_size = BOOT_PGT_SIZE - BOOT_INIT_PGT_SIZE;
|
|
@@ -103,7 +109,7 @@ void initialize_identity_maps(void)
|
|
pgt_data.pgt_buf = _pgtable;
|
|
pgt_data.pgt_buf = _pgtable;
|
|
pgt_data.pgt_buf_size = BOOT_PGT_SIZE;
|
|
pgt_data.pgt_buf_size = BOOT_PGT_SIZE;
|
|
memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size);
|
|
memset(pgt_data.pgt_buf, 0, pgt_data.pgt_buf_size);
|
|
- level4p = (unsigned long)alloc_pgt_page(&pgt_data);
|
|
|
|
|
|
+ top_level_pgt = (unsigned long)alloc_pgt_page(&pgt_data);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -123,7 +129,7 @@ void add_identity_map(unsigned long start, unsigned long size)
|
|
return;
|
|
return;
|
|
|
|
|
|
/* Build the mapping. */
|
|
/* Build the mapping. */
|
|
- kernel_ident_mapping_init(&mapping_info, (pgd_t *)level4p,
|
|
|
|
|
|
+ kernel_ident_mapping_init(&mapping_info, (pgd_t *)top_level_pgt,
|
|
start, end);
|
|
start, end);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -134,5 +140,5 @@ void add_identity_map(unsigned long start, unsigned long size)
|
|
*/
|
|
*/
|
|
void finalize_identity_maps(void)
|
|
void finalize_identity_maps(void)
|
|
{
|
|
{
|
|
- write_cr3(level4p);
|
|
|
|
|
|
+ write_cr3(top_level_pgt);
|
|
}
|
|
}
|