diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index 8a4dd64c99..76c3affe11 100644 --- a/xen/arch/arm/arm64/head.S +++ b/xen/arch/arm/arm64/head.S @@ -607,7 +607,8 @@ create_page_tables: * need an additional 1:1 mapping, the virtual mapping will * suffice. */ - cmp x19, #XEN_VIRT_START + ldr x0, =XEN_VIRT_START + cmp x19, x0 bne 1f ret 1: diff --git a/xen/arch/arm/include/asm/config.h b/xen/arch/arm/include/asm/config.h index 5df0e4c495..c969e6da58 100644 --- a/xen/arch/arm/include/asm/config.h +++ b/xen/arch/arm/include/asm/config.h @@ -72,16 +72,13 @@ #include /* - * Common ARM32 and ARM64 layout: + * ARM32 layout: * 0 - 2M Unmapped * 2M - 4M Xen text, data, bss * 4M - 6M Fixmap: special-purpose 4K mapping slots * 6M - 10M Early boot mapping of FDT * 10M - 12M Livepatch vmap (if compiled in) * - * ARM32 layout: - * 0 - 12M - * * 32M - 128M Frametable: 32 bytes per page for 12GB of RAM * 256M - 1G VMAP: ioremap and early_ioremap use this virtual address * space @@ -90,14 +87,23 @@ * 2G - 4G Domheap: on-demand-mapped * * ARM64 layout: - * 0x0000000000000000 - 0x0000007fffffffff (512GB, L0 slot [0]) - * 0 - 12M + * 0x0000000000000000 - 0x000001ffffffffff (2TB, L0 slots [0..3]) + * + * Reserved to identity map Xen + * + * 0x0000020000000000 - 0x0000027fffffffff (512GB, L0 slot [4]) + * (Relative offsets) + * 0 - 2M Unmapped + * 2M - 4M Xen text, data, bss + * 4M - 6M Fixmap: special-purpose 4K mapping slots + * 6M - 10M Early boot mapping of FDT + * 10M - 12M Livepatch vmap (if compiled in) * * 1G - 2G VMAP: ioremap and early_ioremap * * 32G - 64G Frametable: 56 bytes per page for 2TB of RAM * - * 0x0000008000000000 - 0x00007fffffffffff (127.5TB, L0 slots [1..255]) + * 0x0000028000000000 - 0x00007fffffffffff (125TB, L0 slots [5..255]) * Unused * * 0x0000800000000000 - 0x000084ffffffffff (5TB, L0 slots [256..265]) @@ -107,7 +113,17 @@ * Unused */ +#ifdef CONFIG_ARM_32 #define XEN_VIRT_START _AT(vaddr_t, MB(2)) +#else + +#define SLOT0_ENTRY_BITS 39 +#define SLOT0(slot) (_AT(vaddr_t,slot) << SLOT0_ENTRY_BITS) +#define SLOT0_ENTRY_SIZE SLOT0(1) + +#define XEN_VIRT_START (SLOT0(4) + _AT(vaddr_t, MB(2))) +#endif + #define XEN_VIRT_SIZE _AT(vaddr_t, MB(2)) #define FIXMAP_VIRT_START (XEN_VIRT_START + XEN_VIRT_SIZE) @@ -163,14 +179,12 @@ #else /* ARM_64 */ -#define SLOT0_ENTRY_BITS 39 -#define SLOT0(slot) (_AT(vaddr_t,slot) << SLOT0_ENTRY_BITS) -#define SLOT0_ENTRY_SIZE SLOT0(1) +#define IDENTITY_MAPPING_AREA_NR_L0 4 -#define VMAP_VIRT_START GB(1) +#define VMAP_VIRT_START (SLOT0(4) + GB(1)) #define VMAP_VIRT_SIZE GB(1) -#define FRAMETABLE_VIRT_START GB(32) +#define FRAMETABLE_VIRT_START (SLOT0(4) + GB(32)) #define FRAMETABLE_SIZE GB(32) #define FRAMETABLE_NR (FRAMETABLE_SIZE / sizeof(*frame_table)) diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index b99806af99..1d09d61dd9 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -153,7 +153,19 @@ static void __init __maybe_unused build_assertions(void) #endif /* Page table structure constraints */ #ifdef CONFIG_ARM_64 - BUILD_BUG_ON(zeroeth_table_offset(XEN_VIRT_START)); + /* + * The first few slots of the L0 table is reserved for the identity + * mapping. Check that none of the other regions are overlapping + * with it. + */ +#define CHECK_OVERLAP_WITH_IDMAP(virt) \ + BUILD_BUG_ON(zeroeth_table_offset(virt) < IDENTITY_MAPPING_AREA_NR_L0) + + CHECK_OVERLAP_WITH_IDMAP(XEN_VIRT_START); + CHECK_OVERLAP_WITH_IDMAP(VMAP_VIRT_START); + CHECK_OVERLAP_WITH_IDMAP(FRAMETABLE_VIRT_START); + CHECK_OVERLAP_WITH_IDMAP(DIRECTMAP_VIRT_START); +#undef CHECK_OVERLAP_WITH_IDMAP #endif BUILD_BUG_ON(first_table_offset(XEN_VIRT_START)); #ifdef CONFIG_ARCH_MAP_DOMAIN_PAGE @@ -496,10 +508,11 @@ void __init setup_pagetables(unsigned long boot_phys_offset) phys_offset = boot_phys_offset; #ifdef CONFIG_ARM_64 - p = (void *) xen_pgtable; - p[0] = pte_of_xenaddr((uintptr_t)xen_first); - p[0].pt.table = 1; - p[0].pt.xn = 0; + pte = pte_of_xenaddr((uintptr_t)xen_first); + pte.pt.table = 1; + pte.pt.xn = 0; + xen_pgtable[zeroeth_table_offset(XEN_VIRT_START)] = pte; + p = (void *) xen_first; #else p = (void *) cpu0_pgtable;