mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
arm/mmu: Move init_ttbr to a new section .data.idmap
With the upcoming work to color Xen, the binary will not be anymore physically contiguous. This will be a problem during boot as the assembly code will need to work out where each piece of Xen reside. An easy way to solve the issue is to have all code/data accessed by the secondary CPUs while the MMU is off within a single page. Right now, init_ttbr is used by secondary CPUs to find there page-tables before the MMU is on. Yet it is currently in .data which is unlikely to be within the same page as the rest of the idmap. Create a new section .data.idmap that will be used for variables accessed by the early boot code. The first one is init_ttbr. The idmap is currently part of the text section and therefore will be mapped read-only executable. This means that we need to temporarily remap init_ttbr in order to update it. Introduce a new function set_init_ttbr() for this purpose so the code is not duplicated between arm64 and arm32. Signed-off-by: Julien Grall <jgrall@amazon.com> Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
b24b540de6
commit
5ed59e62c6
2 files changed
+30
-5
No files matched your search
@@ -9,6 +9,10 @@
|
||||
|
||||
#include <asm/setup.h>
|
||||
|
||||
/* Override macros from asm/page.h to make them work with mfn_t */
|
||||
#undef virt_to_mfn
|
||||
#define virt_to_mfn(va) _mfn(__virt_to_mfn(va))
|
||||
|
||||
/*
|
||||
* Static start-of-day pagetables that we use before the allocators
|
||||
* are up. These are used by all CPUs during bringup before switching
|
||||
@@ -44,7 +48,7 @@ DEFINE_BOOT_PAGE_TABLE(boot_second);
|
||||
DEFINE_BOOT_PAGE_TABLES(boot_third, XEN_NR_ENTRIES(2));
|
||||
|
||||
/* Non-boot CPUs use this to find the correct pagetables. */
|
||||
uint64_t init_ttbr;
|
||||
uint64_t __section(".data.idmap") init_ttbr;
|
||||
|
||||
/* Clear a translation table and clean & invalidate the cache */
|
||||
static void clear_table(void *table)
|
||||
@@ -68,6 +72,27 @@ static void clear_boot_pagetables(void)
|
||||
clear_table(boot_third);
|
||||
}
|
||||
|
||||
static void set_init_ttbr(lpae_t *root)
|
||||
{
|
||||
/*
|
||||
* init_ttbr is part of the identity mapping which is read-only. So
|
||||
* we need to re-map the region so it can be updated.
|
||||
*/
|
||||
void *ptr = map_domain_page(virt_to_mfn(&init_ttbr));
|
||||
|
||||
ptr += PAGE_OFFSET(&init_ttbr);
|
||||
|
||||
*(uint64_t *)ptr = virt_to_maddr(root);
|
||||
|
||||
/*
|
||||
* init_ttbr will be accessed with the MMU off, so ensure the update
|
||||
* is visible by cleaning the cache.
|
||||
*/
|
||||
clean_dcache(ptr);
|
||||
|
||||
unmap_domain_page(ptr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_64
|
||||
int prepare_secondary_mm(int cpu)
|
||||
{
|
||||
@@ -77,8 +102,8 @@ int prepare_secondary_mm(int cpu)
|
||||
* Set init_ttbr for this CPU coming up. All CPUs share a single setof
|
||||
* pagetables, but rewrite it each time for consistency with 32 bit.
|
||||
*/
|
||||
init_ttbr = virt_to_maddr(xen_pgtable);
|
||||
clean_dcache(init_ttbr);
|
||||
set_init_ttbr(xen_pgtable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@@ -109,8 +134,7 @@ int prepare_secondary_mm(int cpu)
|
||||
clear_boot_pagetables();
|
||||
|
||||
/* Set init_ttbr for this CPU coming up */
|
||||
init_ttbr = __pa(first);
|
||||
clean_dcache(init_ttbr);
|
||||
set_init_ttbr(first);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ SECTIONS
|
||||
*(.text.header)
|
||||
*(.text.idmap)
|
||||
*(.rodata.idmap)
|
||||
*(.data.idmap)
|
||||
_idmap_end = .;
|
||||
|
||||
*(.text.cold)
|
||||
|
||||