Message ID | 1405699976-9260-3-git-send-email-ian.campbell@citrix.com |
---|---|
State | New |
Headers | show |
Hi Ian, On 18/07/14 17:12, Ian Campbell wrote: > Level 0 does not support superpage mappings, meaning that systems on where Xen > is loaded above 512GB (I'm not aware of any such systems) the 1:1 mapping on > the boot page tables is invalid. > > In order to avoid this issue we need an additional first level page table > mapped by the appropriate L0 slot and containing a 1:1 superpage mapping. > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Julien Grall <julien.grall@linaro.org> Regards, > --- > v2: Fixed stray hard tab > --- > xen/arch/arm/arm64/head.S | 21 ++++++++++++++++++--- > xen/arch/arm/mm.c | 3 +++ > 2 files changed, 21 insertions(+), 3 deletions(-) > > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S > index 5d7b2b5..6ba9d94 100644 > --- a/xen/arch/arm/arm64/head.S > +++ b/xen/arch/arm/arm64/head.S > @@ -267,13 +267,28 @@ skip_bss: > orr x2, x1, x3 /* + rights for linear PT */ > str x2, [x4, #0] /* Map it in slot 0 */ > > - /* ... map of paddr(start) in boot_pgtable */ > + /* ... map of paddr(start) in boot_pgtable+boot_first_id */ > lsr x1, x19, #ZEROETH_SHIFT/* Offset of base paddr in boot_pgtable */ > cbz x1, 1f /* It's in slot 0, map in boot_first > * or boot_second later on */ > > - lsl x2, x1, #ZEROETH_SHIFT /* Base address for 512GB mapping */ > - mov x3, #PT_MEM /* x2 := Section mapping */ > + /* Level zero does not support superpage mappings, so we have > + * to use an extra first level page in which we create a 1GB mapping. > + */ > + ldr x2, =boot_first_id > + add x2, x2, x20 /* x2 := paddr (boot_first_id) */ > + > + mov x3, #PT_PT /* x2 := table map of boot_first_id */ > + orr x2, x2, x3 /* + rights for linear PT */ > + lsl x1, x1, #3 /* x1 := Slot offset */ > + str x2, [x4, x1] > + > + ldr x4, =boot_first_id /* Next level into boot_first_id */ > + add x4, x4, x20 /* x4 := paddr(boot_first_id) */ > + > + lsr x1, x19, #FIRST_SHIFT /* x1 := Offset of base paddr in boot_first_id */ > + lsl x2, x1, #FIRST_SHIFT /* x2 := Base address for 1GB mapping */ > + mov x3, #PT_MEM /* x2 := Section map */ > orr x2, x2, x3 > and x1, x1, #0x1ff /* x1 := Slot offset */ > lsl x1, x1, #3 > diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c > index fdc7c98..0a243b0 100644 > --- a/xen/arch/arm/mm.c > +++ b/xen/arch/arm/mm.c > @@ -68,6 +68,7 @@ struct domain *dom_xen, *dom_io, *dom_cow; > lpae_t boot_pgtable[LPAE_ENTRIES] __attribute__((__aligned__(4096))); > #ifdef CONFIG_ARM_64 > lpae_t boot_first[LPAE_ENTRIES] __attribute__((__aligned__(4096))); > +lpae_t boot_first_id[LPAE_ENTRIES] __attribute__((__aligned__(4096))); > #endif > lpae_t boot_second[LPAE_ENTRIES] __attribute__((__aligned__(4096))); > lpae_t boot_third[LPAE_ENTRIES] __attribute__((__aligned__(4096))); > @@ -491,6 +492,8 @@ void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr) > #ifdef CONFIG_ARM_64 > memset(boot_first, 0x0, PAGE_SIZE); > clean_and_invalidate_xen_dcache(boot_first); > + memset(boot_first_id, 0x0, PAGE_SIZE); > + clean_and_invalidate_xen_dcache(boot_first_id); > #endif > memset(boot_second, 0x0, PAGE_SIZE); > clean_and_invalidate_xen_dcache(boot_second); >
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index 5d7b2b5..6ba9d94 100644 --- a/xen/arch/arm/arm64/head.S +++ b/xen/arch/arm/arm64/head.S @@ -267,13 +267,28 @@ skip_bss: orr x2, x1, x3 /* + rights for linear PT */ str x2, [x4, #0] /* Map it in slot 0 */ - /* ... map of paddr(start) in boot_pgtable */ + /* ... map of paddr(start) in boot_pgtable+boot_first_id */ lsr x1, x19, #ZEROETH_SHIFT/* Offset of base paddr in boot_pgtable */ cbz x1, 1f /* It's in slot 0, map in boot_first * or boot_second later on */ - lsl x2, x1, #ZEROETH_SHIFT /* Base address for 512GB mapping */ - mov x3, #PT_MEM /* x2 := Section mapping */ + /* Level zero does not support superpage mappings, so we have + * to use an extra first level page in which we create a 1GB mapping. + */ + ldr x2, =boot_first_id + add x2, x2, x20 /* x2 := paddr (boot_first_id) */ + + mov x3, #PT_PT /* x2 := table map of boot_first_id */ + orr x2, x2, x3 /* + rights for linear PT */ + lsl x1, x1, #3 /* x1 := Slot offset */ + str x2, [x4, x1] + + ldr x4, =boot_first_id /* Next level into boot_first_id */ + add x4, x4, x20 /* x4 := paddr(boot_first_id) */ + + lsr x1, x19, #FIRST_SHIFT /* x1 := Offset of base paddr in boot_first_id */ + lsl x2, x1, #FIRST_SHIFT /* x2 := Base address for 1GB mapping */ + mov x3, #PT_MEM /* x2 := Section map */ orr x2, x2, x3 and x1, x1, #0x1ff /* x1 := Slot offset */ lsl x1, x1, #3 diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index fdc7c98..0a243b0 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -68,6 +68,7 @@ struct domain *dom_xen, *dom_io, *dom_cow; lpae_t boot_pgtable[LPAE_ENTRIES] __attribute__((__aligned__(4096))); #ifdef CONFIG_ARM_64 lpae_t boot_first[LPAE_ENTRIES] __attribute__((__aligned__(4096))); +lpae_t boot_first_id[LPAE_ENTRIES] __attribute__((__aligned__(4096))); #endif lpae_t boot_second[LPAE_ENTRIES] __attribute__((__aligned__(4096))); lpae_t boot_third[LPAE_ENTRIES] __attribute__((__aligned__(4096))); @@ -491,6 +492,8 @@ void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr) #ifdef CONFIG_ARM_64 memset(boot_first, 0x0, PAGE_SIZE); clean_and_invalidate_xen_dcache(boot_first); + memset(boot_first_id, 0x0, PAGE_SIZE); + clean_and_invalidate_xen_dcache(boot_first_id); #endif memset(boot_second, 0x0, PAGE_SIZE); clean_and_invalidate_xen_dcache(boot_second);
Level 0 does not support superpage mappings, meaning that systems on where Xen is loaded above 512GB (I'm not aware of any such systems) the 1:1 mapping on the boot page tables is invalid. In order to avoid this issue we need an additional first level page table mapped by the appropriate L0 slot and containing a 1:1 superpage mapping. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> --- v2: Fixed stray hard tab --- xen/arch/arm/arm64/head.S | 21 ++++++++++++++++++--- xen/arch/arm/mm.c | 3 +++ 2 files changed, 21 insertions(+), 3 deletions(-)