diff mbox

[Xen-devel,FOR-4.5] xen: arm64: Handle memory banks which are not 1GB aligned

Message ID 1412952194-3595-1-git-send-email-ian.campbell@citrix.com
State New
Headers show

Commit Message

Ian Campbell Oct. 10, 2014, 2:43 p.m. UTC
The code in the arm64 version of setup_xenheap_mappings was making
some very confused attempts to handle this but was bogus.

As well as adjusting the mapping to start on a 1GB boundary we also
need to account for the offset between the start of the mapping and
the actual start of the heap when converting between page pointers,
virtual addresses and machine addresses.

I preferred to do this by explicitly accounting for the offset rather
than adding an offset to the frametable because that approach could
potentially waste a large amount of frametable (up to just less than
1GB worth) but also because of issues with converting mfns from
outside the regions considered for pdx initialisation (which are not
1GB aligned) back and forth.

We already have an idea of the distinction between the start of the
direct map and the start of the xenheap in the difference between
DIRECTMAP_VIRT_START and XENHEAP_VIRT_START. Until now these were the
same thing, but now we change XENHEAP_VIRT_START to point to the
actual start of heap not the mapping. Surprisingly there was only one
place which was using the conceptually wrong value.

Also change xenheap_virt_end to a vaddr_t for consistency.

We've been lucky so far that most hardware happens to locate memory
on a 1GB boundary (we did have reports of a system with memory at a
half gig boundary which exhibited failures which I didn't manage to
follow up on successfully). The EFI support has exposed this
shortcoming by the way it handles reserved memory, which has a
similar effect to having memory non-1GB aligned.

arm32 does things differently here due to using a small Xen heap and
a demand mapped domain heap, so isn't affected.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Suravee Suthikulanit <suravee.suthikulpanit@amd.com>
Cc: Roy Franz <roy.franz@linaro.org>
Cc: Vijay Kilari <vijay.kilari@gmail.com>
---
FOR-4.5: This is a bug fix.
---
 xen/arch/arm/mm.c            |   36 +++++++++++++++++++++++++-----------
 xen/include/asm-arm/config.h |    2 +-
 xen/include/asm-arm/mm.h     |    7 +++++--
 3 files changed, 31 insertions(+), 14 deletions(-)

Comments

Roy Franz Oct. 10, 2014, 7:12 p.m. UTC | #1
On Fri, Oct 10, 2014 at 7:43 AM, Ian Campbell <ian.campbell@citrix.com> wrote:
> The code in the arm64 version of setup_xenheap_mappings was making
> some very confused attempts to handle this but was bogus.
>
> As well as adjusting the mapping to start on a 1GB boundary we also
> need to account for the offset between the start of the mapping and
> the actual start of the heap when converting between page pointers,
> virtual addresses and machine addresses.
>
> I preferred to do this by explicitly accounting for the offset rather
> than adding an offset to the frametable because that approach could
> potentially waste a large amount of frametable (up to just less than
> 1GB worth) but also because of issues with converting mfns from
> outside the regions considered for pdx initialisation (which are not
> 1GB aligned) back and forth.
>
> We already have an idea of the distinction between the start of the
> direct map and the start of the xenheap in the difference between
> DIRECTMAP_VIRT_START and XENHEAP_VIRT_START. Until now these were the
> same thing, but now we change XENHEAP_VIRT_START to point to the
> actual start of heap not the mapping. Surprisingly there was only one
> place which was using the conceptually wrong value.
>
> Also change xenheap_virt_end to a vaddr_t for consistency.
>
> We've been lucky so far that most hardware happens to locate memory
> on a 1GB boundary (we did have reports of a system with memory at a
> half gig boundary which exhibited failures which I didn't manage to
> follow up on successfully). The EFI support has exposed this
> shortcoming by the way it handles reserved memory, which has a
> similar effect to having memory non-1GB aligned.
>
> arm32 does things differently here due to using a small Xen heap and
> a demand mapped domain heap, so isn't affected.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> Cc: Suravee Suthikulanit <suravee.suthikulpanit@amd.com>
> Cc: Roy Franz <roy.franz@linaro.org>
> Cc: Vijay Kilari <vijay.kilari@gmail.com>

Works for me on the FVP model.  This platform didn't trigger the bug,
so it continues
to work as before.

Roy


> ---
> FOR-4.5: This is a bug fix.
> ---
>  xen/arch/arm/mm.c            |   36 +++++++++++++++++++++++++-----------
>  xen/include/asm-arm/config.h |    2 +-
>  xen/include/asm-arm/mm.h     |    7 +++++--
>  3 files changed, 31 insertions(+), 14 deletions(-)
>
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index c5b48ef..97e5bc39 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -138,7 +138,10 @@ static paddr_t phys_offset;
>  /* Limits of the Xen heap */
>  unsigned long xenheap_mfn_start __read_mostly = ~0UL;
>  unsigned long xenheap_mfn_end __read_mostly;
> -unsigned long xenheap_virt_end __read_mostly;
> +vaddr_t xenheap_virt_end __read_mostly;
> +#ifdef CONFIG_ARM_64
> +vaddr_t xenheap_virt_start __read_mostly;
> +#endif
>
>  unsigned long frametable_base_pdx __read_mostly;
>  unsigned long frametable_virt_end __read_mostly;
> @@ -155,7 +158,11 @@ static inline void check_memory_layout_alignment_constraints(void) {
>      BUILD_BUG_ON(FIXMAP_ADDR(0) & ~SECOND_MASK);
>      BUILD_BUG_ON(BOOT_RELOC_VIRT_START & ~SECOND_MASK);
>      /* 1GB aligned regions */
> +#ifdef CONFIG_ARM_32
>      BUILD_BUG_ON(XENHEAP_VIRT_START & ~FIRST_MASK);
> +#else
> +    BUILD_BUG_ON(DIRECTMAP_VIRT_START & ~FIRST_MASK);
> +#endif
>      /* Page table structure constraints */
>  #ifdef CONFIG_ARM_64
>      BUILD_BUG_ON(zeroeth_table_offset(XEN_VIRT_START));
> @@ -665,12 +672,19 @@ void __init setup_xenheap_mappings(unsigned long base_mfn,
>                                     unsigned long nr_mfns)
>  {
>      lpae_t *first, pte;
> -    unsigned long offset, end_mfn;
> +    unsigned long mfn, end_mfn;
>      vaddr_t vaddr;
>
> -    /* First call sets the xenheap physical offset. */
> +    /* Align to previous 1GB boundary */
> +    mfn = base_mfn & ~((FIRST_SIZE>>PAGE_SHIFT)-1);
> +
> +    /* First call sets the xenheap physical and virtual offset. */
>      if ( xenheap_mfn_start == ~0UL )
> +    {
>          xenheap_mfn_start = base_mfn;
> +        xenheap_virt_start = DIRECTMAP_VIRT_START +
> +            (base_mfn - mfn) * PAGE_SIZE;
> +    }
>
>      if ( base_mfn < xenheap_mfn_start )
>          panic("cannot add xenheap mapping at %lx below heap start %lx",
> @@ -678,13 +692,13 @@ void __init setup_xenheap_mappings(unsigned long base_mfn,
>
>      end_mfn = base_mfn + nr_mfns;
>
> -    /* Align to previous 1GB boundary */
> -    base_mfn &= ~((FIRST_SIZE>>PAGE_SHIFT)-1);
> -
> -    offset = pfn_to_pdx(base_mfn - xenheap_mfn_start);
> -    vaddr = DIRECTMAP_VIRT_START + offset*PAGE_SIZE;
> +    /*
> +     * Virtual address aligned to previous 1GB to match physical
> +     * address alignment done above.
> +     */
> +    vaddr = (vaddr_t)mfn_to_virt(base_mfn) & FIRST_MASK;
>
> -    while ( base_mfn < end_mfn )
> +    while ( mfn < end_mfn )
>      {
>          int slot = zeroeth_table_offset(vaddr);
>          lpae_t *p = &xen_pgtable[slot];
> @@ -716,11 +730,11 @@ void __init setup_xenheap_mappings(unsigned long base_mfn,
>              first = mfn_to_virt(first_mfn);
>          }
>
> -        pte = mfn_to_xen_entry(base_mfn, WRITEALLOC);
> +        pte = mfn_to_xen_entry(mfn, WRITEALLOC);
>          /* TODO: Set pte.pt.contig when appropriate. */
>          write_pte(&first[first_table_offset(vaddr)], pte);
>
> -        base_mfn += FIRST_SIZE>>PAGE_SHIFT;
> +        mfn += FIRST_SIZE>>PAGE_SHIFT;
>          vaddr += FIRST_SIZE;
>      }
>
> diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
> index 59b2887..264e2c1 100644
> --- a/xen/include/asm-arm/config.h
> +++ b/xen/include/asm-arm/config.h
> @@ -162,7 +162,7 @@
>  #define DIRECTMAP_SIZE         (SLOT0_ENTRY_SIZE * (265-256))
>  #define DIRECTMAP_VIRT_END     (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE - 1)
>
> -#define XENHEAP_VIRT_START     DIRECTMAP_VIRT_START
> +#define XENHEAP_VIRT_START     xenheap_virt_start
>
>  #define HYPERVISOR_VIRT_END    DIRECTMAP_VIRT_END
>
> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> index 1e4711c..d25e485 100644
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -110,7 +110,10 @@ struct page_info
>  #define PGC_count_mask    ((1UL<<PGC_count_width)-1)
>
>  extern unsigned long xenheap_mfn_start, xenheap_mfn_end;
> -extern unsigned long xenheap_virt_end;
> +extern vaddr_t xenheap_virt_end;
> +#ifdef CONFIG_ARM_64
> +extern vaddr_t xenheap_virt_start;
> +#endif
>
>  #ifdef CONFIG_ARM_32
>  #define is_xen_heap_page(page) is_xen_heap_mfn(page_to_mfn(page))
> @@ -227,7 +230,7 @@ static inline void *maddr_to_virt(paddr_t ma)
>  static inline void *maddr_to_virt(paddr_t ma)
>  {
>      ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
> -    return (void *)(DIRECTMAP_VIRT_START -
> +    return (void *)(XENHEAP_VIRT_START -
>                      pfn_to_paddr(xenheap_mfn_start) +
>                      ((ma & ma_va_bottom_mask) |
>                       ((ma & ma_top_mask) >> pfn_pdx_hole_shift)));
> --
> 1.7.10.4
>
Suthikulpanit, Suravee Oct. 11, 2014, 12:28 a.m. UTC | #2
Ian,

This one seems to workaround the issue with pagetable setup in Xen we 
saw earlier here:

http://lists.xen.org/archives/html/xen-devel/2014-10/msg01013.html

However, it's now breaking in Dom0 when trying to parse device tree. 
I'll look at this over the weekend. Here is the boot log.

Shell> FS0:xen -cfg=xen-seattle.cfg
Xen 4.5-unstable (c/s Fri Oct 10 15:43:14 2014 +0100 git:38bbdef-dirty) 
EFI loader
Image: 0x00000083fbc25000-0x00000083fc525890
- UART enabled -
- CPU 00000000 booting -
- Current EL 00000008 -
- Xen starting at EL2 -
- Zero BSS -
- Setting up control registers -
- Setup boot first -
- Setup boot second -
- Setup boot third -
- Turning on paging -
- Ready -
(XEN) Checking for initrd in /chosen
(XEN) RAM: 0000008001000000 - 0000008007ffdfff
(XEN) RAM: 0000008007ffe000 - 0000008007ffffff
(XEN) RAM: 0000008008000000 - 000000801fffdfff
(XEN) RAM: 000000801fffe000 - 000000801fffffff
(XEN) RAM: 0000008020000000 - 0000008027ffffff
(XEN) RAM: 0000008028100000 - 000000802fffffff
(XEN) RAM: 0000008030001000 - 00000083f0ffffff
(XEN) RAM: 00000083f1000000 - 00000083f101ffff
(XEN) RAM: 00000083f1020000 - 00000083fbc22fff
(XEN) RAM: 00000083fc529000 - 00000083fc529fff
(XEN) RAM: 00000083fc715000 - 00000083fec1cfff
(XEN) RAM: 00000083fec1d000 - 00000083fee7bfff
(XEN) RAM: 00000083fee7c000 - 00000083ff21cfff
(XEN) RAM: 00000083ff21d000 - 00000083ff253fff
(XEN) RAM: 00000083ffe70000 - 00000083ffffffff
(XEN)
(XEN) MODULE[0]: 00000083fc526000 - 00000083fc529000 Device Tree
(XEN) MODULE[1]: 00000083fbc25000 - 00000083fc525890 Kernel 
console=hvc0 console=ttyAMA0,115200 earlycon=pl011,0xe1010000 
root=/dev/sda2 rootwait
(XEN) MODULE[2]: 0000008020000000 - 00000080209e6950 Kernel
(XEN)
(XEN) Command line: FS0:xen no-bootscrub console=dtuart conswitch=x 
dtuart=serial0 noreboot sync_console dom0_mem=256M dom0_max_vcpus=1
(XEN) Placing Xen at 0x0000008027e00000-0x0000008028000000
(XEN) Update BOOTMOD_XEN from 00000083fc52b000-00000083fc635d81 => 
0000008027e00000-0000008027f0ad81
(XEN) Domain heap initialised
(XEN) Looking for UART console serial0
  Xen 4.5-unstable
(XEN) Xen version 4.5-unstable (ssuthiku@amd.com) (aarch64-linux-gnu-gcc 
(crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) 4.8.3 
20140106 (prerelease)) debug=y Fri Oct 10 19:02:44 CDT 2014
(XEN) Latest ChangeSet: Fri Oct 10 15:43:14 2014 +0100 git:38bbdef-dirty
(XEN) Console output is synchronous.
(XEN) Processor: 410fd070: "ARM Limited", variant: 0x0, part 0xd07, rev 0x0
(XEN) 64-bit Execution:
(XEN)   Processor Features: 0000000000002222 0000000000000000
(XEN)     Exception Levels: EL3:64+32 EL2:64+32 EL1:64+32 EL0:64+32
(XEN)     Extensions: FloatingPoint AdvancedSIMD
(XEN)   Debug Features: 0000000010305106 0000000000000000
(XEN)   Auxiliary Features: 0000000000000000 0000000000000000
(XEN)   Memory Model Features: 0000000000001124 0000000000000000
(XEN)   ISA Features:  0000000000011120 0000000000000000
(XEN) 32-bit Execution:
(XEN)   Processor Features: 00000131:00011011
(XEN)     Instruction Sets: AArch32 Thumb Thumb-2 Jazelle
(XEN)     Extensions: GenericTimer Security
(XEN)   Debug Features: 03010066
(XEN)   Auxiliary Features: 00000000
(XEN)   Memory Model Features: 10101105 40000000 01260000 02102211
(XEN)  ISA Features: 02101110 13112111 21232042 01112131 00011142 00011121
(XEN) Platform: SEATTLE
(XEN) Generic Timer IRQ: phys=30 hyp=26 virt=27
(XEN) Using generic timer at 187500 KHz
(XEN) GICv2 initialization:
(XEN)         gic_dist_addr=00000000e1110000
(XEN)         gic_cpu_addr=00000000e112f000
(XEN)         gic_hyp_addr=00000000e1140000
(XEN)         gic_vcpu_addr=00000000e1160000
(XEN)         gic_maintenance_irq=24
(XEN) GICv2: 448 lines, 8 cpus, secure (IID 0200143b).
(XEN) Using scheduler: SMP Credit Scheduler (credit)
(XEN) I/O virtualisation disabled
(XEN) Allocated console ring of 64 KiB.
(XEN) Bringing up CPU1
- CPU 00000201 booting -
- Current EL 00000008 -
- Xen starting at EL2 -
- Setting up control registers -
- Setup boot first -
- Setup boot second -
- Setup boot third -
- Turning on paging -
- Ready -
(XEN) CPU 1 booted.
(XEN) Bringing up CPU2
- CPU 00000200 booting -
- Current EL 00000008 -
- Xen starting at EL2 -
- Setting up control registers -
- Setup boot first -
- Setup boot second -
- Setup boot third -
- Turning on paging -
- Ready -
(XEN) CPU 2 booted.
(XEN) Bringing up CPU3
- CPU 00000101 booting -
- Current EL 00000008 -
- Xen starting at EL2 -
- Setting up control registers -
- Setup boot first -
- Setup boot second -
- Setup boot third -
- Turning on paging -
- Ready -
(XEN) CPU 3 booted.
(XEN) Bringing up CPU4
- CPU 00000100 booting -
- Current EL 00000008 -
- Xen starting at EL2 -
- Setting up control registers -
- Setup boot first -
- Setup boot second -
- Setup boot third -
- Turning on paging -
- Ready -
(XEN) CPU 4 booted.
(XEN) Bringing up CPU5
- CPU 00000001 booting -
- Current EL 00000008 -
- Xen starting at EL2 -
- Setting up control registers -
- Setup boot first -
- Setup boot second -
- Setup boot third -
- Turning on paging -
- Ready -
(XEN) Brought up 6 CPUs
(XEN) CPU 5 booted.
(XEN) P2M: 44-bit IPA with 44-bit PA
(XEN) P2M: 4 levels with order-0 root, VTCR 0x80043594
(XEN) *** LOADING DOMAIN 0 ***
(XEN) Loading kernel from boot module @ 00000083fbc25000
(XEN) Allocating 1:1 mappings totalling 256MB for dom0:
(XEN) BANK[0] 0x00008010000000-0x00008020000000 (256MB)
(XEN) Loading zImage from 00000083fbc25000 to 
0000008010080000-0000008010980890
(XEN) Loading dom0 DTB to 0x0000008018000000-0x000000801800190d
(XEN) Std. Loglevel: All
(XEN) Guest Loglevel: All
(XEN) **********************************************
(XEN) ******* WARNING: CONSOLE OUTPUT IS SYNCHRONOUS
(XEN) ******* This option is intended to aid debugging of Xen by ensuring
(XEN) ******* that all output is synchronously delivered on the serial line.
(XEN) ******* However it can introduce SIGNIFICANT latencies and affect
(XEN) ******* timekeeping. It is NOT recommended for production use!
(XEN) **********************************************
(XEN) 3... 2... 1...
(XEN) *** Serial input -> DOM0 (type 'CTRL-x' three times to switch 
input to Xen)
(XEN) Freed 288kB init memory.
(XEN) DOM0: Linux version 3.17.0-rc7-styx-xen+ 
(ssuthiku@ssuthiku-fedora-lt) (gcc version 4.8.3 20140106 (prerelease) 
(crosstool-NG linaro
(XEN) DOM0: -1.13.1-4.8-2014.01 - Linaro GCC 2013.11) ) #25 SMP Tue Sep 
30 03:07:19 CDT 2014
(XEN) DOM0: CPU: AArch64 Processor [410fd070] revision 0
(XEN) DOM0: Detected PIPT I-cache on CPU0
(XEN) DOM0: Early serial console at I/O port 0x0 (options '')
(XEN) DOM0: bootconsole [uart0] enabled
(XEN) DOM0: efi: Getting EFI parameters from FDT:
(XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at 
0xffff7ffffbc7ff18
(XEN) DOM0: Internal error: : 96000000 [#1] SMP
(XEN) DOM0: Modules linked in:
(XEN) DOM0: CPU: 0 PID: 0 Comm: swapper Not tainted 3.17.0-rc7-styx-xen+ #25
(XEN) DOM0: task: ffff8000009188e0 ti: ffff80000090c000 task.ti: 
ffff80000090c000
(XEN) DOM0: PC is at uefi_init+0xac/0x1a4
(XEN) DOM0: LR is at uefi_init+0xa0/0x1a4
(XEN) DOM0: pc : [<ffff8000008c0dc0>] lr : [<ffff8000008c0db4>] pstate: 
600000c5
(XEN) DOM0: sp : ffff80000090fdf0
(XEN) DOM0: x29: ffff80000090fdf0 x28: 0000808010000000
(XEN) DOM0: x27: ffff8000000805a8 x26: 0000008010a02000
(XEN) DOM0: x25: 00000080109ff000 x24: 0000008010000000
(XEN) DOM0: x23: ffff80000095e338 x22: ffff80000095e000
(XEN) DOM0: x21: ffff80000095e000 x20: ffff80000090fe38
(XEN) DOM0: x19: ffff80000095e000 x18: 0000000000001124
(XEN) DOM0: x17: 0000000000000000 x16: 0000000000002222
(XEN) DOM0: x15: ffffffffffffffff x14: 0fffffffffffffff
(XEN) DOM0: x13: ffffff0000000000 x12: 0000000000000000
(XEN) DOM0: x11: fffffffffffffffd x10: 0000000000000003
(XEN) DOM0: x9 : 0000000000000008 x8 : 0000000000000003
(XEN) DOM0: x7 : 0000000000000001 x6 : 0000000000180000
(XEN) DOM0: x5 : 0000008010983000 x4 : ffff800000983000
(XEN) DOM0: x3 : 0000000000000020 x2 : ffff7ffffbc7ff18
(XEN) DOM0: x1 : ffff80000095e338 x0 : 0000000020494249
(XEN) DOM0:
(XEN) DOM0: Process swapper (pid: 0, stack limit = 0xffff80000090c058)
(XEN) DOM0: Stack: (0xffff80000090fdf0 to 0xffff800000910000)
(XEN) DOM0: fde0:                                     0090fea0 ffff8000 
008c155c ffff8000
(XEN) DOM0: fe00: 008f9000 ffff8000 008f91c0 ffff8000 009845a0 ffff8000 
00984000 ffff8000
(XEN) DOM0: fe20: 00984598 ffff8000 008d1408 ffff8000 008f9000 ffff8000 
6e6b6e75 006e776f
(XEN) DOM0: fe40: 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 00000000
(XEN) DOM0: fe60: 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 00000000
(XEN) DOM0: fe80: 00000000 00000000 00000000 00000000 00000000 00000000 
00000000 ffff8000
(XEN) DOM0: fea0: 0090ff10 ffff8000 008bf718 ffff8000 00984000 ffff8000 
00984000 ffff8000
(XEN) DOM0: fec0: 00080000 ffff8000 0090ffe8 ffff8000 1091a000 00000080 
10000000 00000080
(XEN) DOM0: fee0: 109ff000 00000080 10a02000 00000080 ff3bef18 00000083 
fbc23018 00000083
(XEN) DOM0: ff00: 000004e0 00000030 00000001 ffff8000 0090ffa0 ffff8000 
008bd67c ffff8000
(XEN) DOM0: ff20: 00984000 ffff8000 008f7e30 ffff8000 00000000 00000000 
00984000 ffff8000
(XEN) DOM0: ff40: 1091a000 00000080 10000000 00000080 109ff000 00000080 
10a02000 00000080
(XEN) DOM0: ff60: 000805a8 ffff8000 006a90c8 ffff8000 00000001 00000000 
18000000 00000080
(XEN) DOM0: ff80: 00984100 ffff8000 00115ce0 ffff8000 009845e8 ffff8000 
009fed78 ffff8000
(XEN) DOM0: ffa0: 00000000 00000000 10080340 00000080 00000000 00000000 
00000e11 00000000
(XEN) DOM0: ffc0: 18000000 00000080 410fd070 00000000 1091a000 00000080 
00000000 00000000
(XEN) DOM0: ffe0: 00000000 00000000 008f8658 ffff8000 00000000 00000000 
00000000 00000000
(XEN) DOM0: Call trace:
(XEN) DOM0: [<ffff8000008c0dc0>] uefi_init+0xac/0x1a4
(XEN) DOM0: [<ffff8000008c1558>] efi_init+0x98/0x1d8
(XEN) DOM0: [<ffff8000008bf714>] setup_arch+0x224/0x528
(XEN) DOM0: [<ffff8000008bd678>] start_kernel+0x8c/0x39c
(XEN) DOM0: Code: 97ed8f84 f9412e62 d2884920 f2a40920 (f9400041)
(XEN) DOM0: ---[ end trace cb88537fdc8fa200 ]---
(XEN) DOM0: Kernel panic - not syncing: Attempted to kill the idle task!
(XEN) DOM0: ---[ end Kernel panic - not syncing: Attempted to kill the 
idle task!

Thanks,
Suravee
Vijay Kilari Oct. 13, 2014, 12:35 p.m. UTC | #3
Hi Roy,

   I too observe the same issue. I have enabled uefi_debug

(XEN) DOM0: bootconsole [uart0] enabled
(XEN) DOM0: Memory limited to 512MB
(XEN) DOM0: efi: Getting parameters from FDT:
(XEN) DOM0: efi:   System Table: 0x000000007fb79f18
(XEN) DOM0: efi:   MemMap Address: 0x000000007a88c018
(XEN) DOM0: efi:   MemMap Size: 0x000004e0
(XEN) DOM0: efi:   MemMap Desc. Size: 0x00000030
(XEN) DOM0: efi:   MemMap Desc. Version: 0x00000001
(XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
0xffffffbffbc7ff18
(XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
(XEN) DOM0: Modules linked in:
(XEN) DOM0: CPU: 0 PID: 0 Comm: swapper Not tainted 3.16.0-rc4+ #3
(XEN) DOM0: task: ffffffc0007048a0 ti: ffffffc0006f8000 task.ti:
ffffffc0006f8000
(XEN) DOM0: PC is at uefi_init+0x94/0x1a0
(XEN) DOM0: LR is at uefi_init+0x84/0x1a0

I have not digged into the issue. Xen has not mapped this table to Dom0?

Regards
Vijay

On Sat, Oct 11, 2014 at 5:58 AM, Suravee Suthikulanit
<suravee.suthikulpanit@amd.com> wrote:
> Ian,
>
> This one seems to workaround the issue with pagetable setup in Xen we saw
> earlier here:
>
> http://lists.xen.org/archives/html/xen-devel/2014-10/msg01013.html
>
> However, it's now breaking in Dom0 when trying to parse device tree. I'll
> look at this over the weekend. Here is the boot log.
>
> Shell> FS0:xen -cfg=xen-seattle.cfg
> Xen 4.5-unstable (c/s Fri Oct 10 15:43:14 2014 +0100 git:38bbdef-dirty) EFI
> loader
> Image: 0x00000083fbc25000-0x00000083fc525890
> - UART enabled -
> - CPU 00000000 booting -
> - Current EL 00000008 -
> - Xen starting at EL2 -
> - Zero BSS -
> - Setting up control registers -
> - Setup boot first -
> - Setup boot second -
> - Setup boot third -
> - Turning on paging -
> - Ready -
> (XEN) Checking for initrd in /chosen
> (XEN) RAM: 0000008001000000 - 0000008007ffdfff
> (XEN) RAM: 0000008007ffe000 - 0000008007ffffff
> (XEN) RAM: 0000008008000000 - 000000801fffdfff
> (XEN) RAM: 000000801fffe000 - 000000801fffffff
> (XEN) RAM: 0000008020000000 - 0000008027ffffff
> (XEN) RAM: 0000008028100000 - 000000802fffffff
> (XEN) RAM: 0000008030001000 - 00000083f0ffffff
> (XEN) RAM: 00000083f1000000 - 00000083f101ffff
> (XEN) RAM: 00000083f1020000 - 00000083fbc22fff
> (XEN) RAM: 00000083fc529000 - 00000083fc529fff
> (XEN) RAM: 00000083fc715000 - 00000083fec1cfff
> (XEN) RAM: 00000083fec1d000 - 00000083fee7bfff
> (XEN) RAM: 00000083fee7c000 - 00000083ff21cfff
> (XEN) RAM: 00000083ff21d000 - 00000083ff253fff
> (XEN) RAM: 00000083ffe70000 - 00000083ffffffff
> (XEN)
> (XEN) MODULE[0]: 00000083fc526000 - 00000083fc529000 Device Tree
> (XEN) MODULE[1]: 00000083fbc25000 - 00000083fc525890 Kernel console=hvc0
> console=ttyAMA0,115200 earlycon=pl011,0xe1010000 root=/dev/sda2 rootwait
> (XEN) MODULE[2]: 0000008020000000 - 00000080209e6950 Kernel
> (XEN)
> (XEN) Command line: FS0:xen no-bootscrub console=dtuart conswitch=x
> dtuart=serial0 noreboot sync_console dom0_mem=256M dom0_max_vcpus=1
> (XEN) Placing Xen at 0x0000008027e00000-0x0000008028000000
> (XEN) Update BOOTMOD_XEN from 00000083fc52b000-00000083fc635d81 =>
> 0000008027e00000-0000008027f0ad81
> (XEN) Domain heap initialised
> (XEN) Looking for UART console serial0
>  Xen 4.5-unstable
> (XEN) Xen version 4.5-unstable (ssuthiku@amd.com) (aarch64-linux-gnu-gcc
> (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) 4.8.3 20140106
> (prerelease)) debug=y Fri Oct 10 19:02:44 CDT 2014
> (XEN) Latest ChangeSet: Fri Oct 10 15:43:14 2014 +0100 git:38bbdef-dirty
> (XEN) Console output is synchronous.
> (XEN) Processor: 410fd070: "ARM Limited", variant: 0x0, part 0xd07, rev 0x0
> (XEN) 64-bit Execution:
> (XEN)   Processor Features: 0000000000002222 0000000000000000
> (XEN)     Exception Levels: EL3:64+32 EL2:64+32 EL1:64+32 EL0:64+32
> (XEN)     Extensions: FloatingPoint AdvancedSIMD
> (XEN)   Debug Features: 0000000010305106 0000000000000000
> (XEN)   Auxiliary Features: 0000000000000000 0000000000000000
> (XEN)   Memory Model Features: 0000000000001124 0000000000000000
> (XEN)   ISA Features:  0000000000011120 0000000000000000
> (XEN) 32-bit Execution:
> (XEN)   Processor Features: 00000131:00011011
> (XEN)     Instruction Sets: AArch32 Thumb Thumb-2 Jazelle
> (XEN)     Extensions: GenericTimer Security
> (XEN)   Debug Features: 03010066
> (XEN)   Auxiliary Features: 00000000
> (XEN)   Memory Model Features: 10101105 40000000 01260000 02102211
> (XEN)  ISA Features: 02101110 13112111 21232042 01112131 00011142 00011121
> (XEN) Platform: SEATTLE
> (XEN) Generic Timer IRQ: phys=30 hyp=26 virt=27
> (XEN) Using generic timer at 187500 KHz
> (XEN) GICv2 initialization:
> (XEN)         gic_dist_addr=00000000e1110000
> (XEN)         gic_cpu_addr=00000000e112f000
> (XEN)         gic_hyp_addr=00000000e1140000
> (XEN)         gic_vcpu_addr=00000000e1160000
> (XEN)         gic_maintenance_irq=24
> (XEN) GICv2: 448 lines, 8 cpus, secure (IID 0200143b).
> (XEN) Using scheduler: SMP Credit Scheduler (credit)
> (XEN) I/O virtualisation disabled
> (XEN) Allocated console ring of 64 KiB.
> (XEN) Bringing up CPU1
> - CPU 00000201 booting -
> - Current EL 00000008 -
> - Xen starting at EL2 -
> - Setting up control registers -
> - Setup boot first -
> - Setup boot second -
> - Setup boot third -
> - Turning on paging -
> - Ready -
> (XEN) CPU 1 booted.
> (XEN) Bringing up CPU2
> - CPU 00000200 booting -
> - Current EL 00000008 -
> - Xen starting at EL2 -
> - Setting up control registers -
> - Setup boot first -
> - Setup boot second -
> - Setup boot third -
> - Turning on paging -
> - Ready -
> (XEN) CPU 2 booted.
> (XEN) Bringing up CPU3
> - CPU 00000101 booting -
> - Current EL 00000008 -
> - Xen starting at EL2 -
> - Setting up control registers -
> - Setup boot first -
> - Setup boot second -
> - Setup boot third -
> - Turning on paging -
> - Ready -
> (XEN) CPU 3 booted.
> (XEN) Bringing up CPU4
> - CPU 00000100 booting -
> - Current EL 00000008 -
> - Xen starting at EL2 -
> - Setting up control registers -
> - Setup boot first -
> - Setup boot second -
> - Setup boot third -
> - Turning on paging -
> - Ready -
> (XEN) CPU 4 booted.
> (XEN) Bringing up CPU5
> - CPU 00000001 booting -
> - Current EL 00000008 -
> - Xen starting at EL2 -
> - Setting up control registers -
> - Setup boot first -
> - Setup boot second -
> - Setup boot third -
> - Turning on paging -
> - Ready -
> (XEN) Brought up 6 CPUs
> (XEN) CPU 5 booted.
> (XEN) P2M: 44-bit IPA with 44-bit PA
> (XEN) P2M: 4 levels with order-0 root, VTCR 0x80043594
> (XEN) *** LOADING DOMAIN 0 ***
> (XEN) Loading kernel from boot module @ 00000083fbc25000
> (XEN) Allocating 1:1 mappings totalling 256MB for dom0:
> (XEN) BANK[0] 0x00008010000000-0x00008020000000 (256MB)
> (XEN) Loading zImage from 00000083fbc25000 to
> 0000008010080000-0000008010980890
> (XEN) Loading dom0 DTB to 0x0000008018000000-0x000000801800190d
> (XEN) Std. Loglevel: All
> (XEN) Guest Loglevel: All
> (XEN) **********************************************
> (XEN) ******* WARNING: CONSOLE OUTPUT IS SYNCHRONOUS
> (XEN) ******* This option is intended to aid debugging of Xen by ensuring
> (XEN) ******* that all output is synchronously delivered on the serial line.
> (XEN) ******* However it can introduce SIGNIFICANT latencies and affect
> (XEN) ******* timekeeping. It is NOT recommended for production use!
> (XEN) **********************************************
> (XEN) 3... 2... 1...
> (XEN) *** Serial input -> DOM0 (type 'CTRL-x' three times to switch input to
> Xen)
> (XEN) Freed 288kB init memory.
> (XEN) DOM0: Linux version 3.17.0-rc7-styx-xen+ (ssuthiku@ssuthiku-fedora-lt)
> (gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro
> (XEN) DOM0: -1.13.1-4.8-2014.01 - Linaro GCC 2013.11) ) #25 SMP Tue Sep 30
> 03:07:19 CDT 2014
> (XEN) DOM0: CPU: AArch64 Processor [410fd070] revision 0
> (XEN) DOM0: Detected PIPT I-cache on CPU0
> (XEN) DOM0: Early serial console at I/O port 0x0 (options '')
> (XEN) DOM0: bootconsole [uart0] enabled
> (XEN) DOM0: efi: Getting EFI parameters from FDT:
> (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
> 0xffff7ffffbc7ff18
> (XEN) DOM0: Internal error: : 96000000 [#1] SMP
> (XEN) DOM0: Modules linked in:
> (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper Not tainted 3.17.0-rc7-styx-xen+ #25
> (XEN) DOM0: task: ffff8000009188e0 ti: ffff80000090c000 task.ti:
> ffff80000090c000
> (XEN) DOM0: PC is at uefi_init+0xac/0x1a4
> (XEN) DOM0: LR is at uefi_init+0xa0/0x1a4
> (XEN) DOM0: pc : [<ffff8000008c0dc0>] lr : [<ffff8000008c0db4>] pstate:
> 600000c5
> (XEN) DOM0: sp : ffff80000090fdf0
> (XEN) DOM0: x29: ffff80000090fdf0 x28: 0000808010000000
> (XEN) DOM0: x27: ffff8000000805a8 x26: 0000008010a02000
> (XEN) DOM0: x25: 00000080109ff000 x24: 0000008010000000
> (XEN) DOM0: x23: ffff80000095e338 x22: ffff80000095e000
> (XEN) DOM0: x21: ffff80000095e000 x20: ffff80000090fe38
> (XEN) DOM0: x19: ffff80000095e000 x18: 0000000000001124
> (XEN) DOM0: x17: 0000000000000000 x16: 0000000000002222
> (XEN) DOM0: x15: ffffffffffffffff x14: 0fffffffffffffff
> (XEN) DOM0: x13: ffffff0000000000 x12: 0000000000000000
> (XEN) DOM0: x11: fffffffffffffffd x10: 0000000000000003
> (XEN) DOM0: x9 : 0000000000000008 x8 : 0000000000000003
> (XEN) DOM0: x7 : 0000000000000001 x6 : 0000000000180000
> (XEN) DOM0: x5 : 0000008010983000 x4 : ffff800000983000
> (XEN) DOM0: x3 : 0000000000000020 x2 : ffff7ffffbc7ff18
> (XEN) DOM0: x1 : ffff80000095e338 x0 : 0000000020494249
> (XEN) DOM0:
> (XEN) DOM0: Process swapper (pid: 0, stack limit = 0xffff80000090c058)
> (XEN) DOM0: Stack: (0xffff80000090fdf0 to 0xffff800000910000)
> (XEN) DOM0: fde0:                                     0090fea0 ffff8000
> 008c155c ffff8000
> (XEN) DOM0: fe00: 008f9000 ffff8000 008f91c0 ffff8000 009845a0 ffff8000
> 00984000 ffff8000
> (XEN) DOM0: fe20: 00984598 ffff8000 008d1408 ffff8000 008f9000 ffff8000
> 6e6b6e75 006e776f
> (XEN) DOM0: fe40: 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000
> (XEN) DOM0: fe60: 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000
> (XEN) DOM0: fe80: 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 ffff8000
> (XEN) DOM0: fea0: 0090ff10 ffff8000 008bf718 ffff8000 00984000 ffff8000
> 00984000 ffff8000
> (XEN) DOM0: fec0: 00080000 ffff8000 0090ffe8 ffff8000 1091a000 00000080
> 10000000 00000080
> (XEN) DOM0: fee0: 109ff000 00000080 10a02000 00000080 ff3bef18 00000083
> fbc23018 00000083
> (XEN) DOM0: ff00: 000004e0 00000030 00000001 ffff8000 0090ffa0 ffff8000
> 008bd67c ffff8000
> (XEN) DOM0: ff20: 00984000 ffff8000 008f7e30 ffff8000 00000000 00000000
> 00984000 ffff8000
> (XEN) DOM0: ff40: 1091a000 00000080 10000000 00000080 109ff000 00000080
> 10a02000 00000080
> (XEN) DOM0: ff60: 000805a8 ffff8000 006a90c8 ffff8000 00000001 00000000
> 18000000 00000080
> (XEN) DOM0: ff80: 00984100 ffff8000 00115ce0 ffff8000 009845e8 ffff8000
> 009fed78 ffff8000
> (XEN) DOM0: ffa0: 00000000 00000000 10080340 00000080 00000000 00000000
> 00000e11 00000000
> (XEN) DOM0: ffc0: 18000000 00000080 410fd070 00000000 1091a000 00000080
> 00000000 00000000
> (XEN) DOM0: ffe0: 00000000 00000000 008f8658 ffff8000 00000000 00000000
> 00000000 00000000
> (XEN) DOM0: Call trace:
> (XEN) DOM0: [<ffff8000008c0dc0>] uefi_init+0xac/0x1a4
> (XEN) DOM0: [<ffff8000008c1558>] efi_init+0x98/0x1d8
> (XEN) DOM0: [<ffff8000008bf714>] setup_arch+0x224/0x528
> (XEN) DOM0: [<ffff8000008bd678>] start_kernel+0x8c/0x39c
> (XEN) DOM0: Code: 97ed8f84 f9412e62 d2884920 f2a40920 (f9400041)
> (XEN) DOM0: ---[ end trace cb88537fdc8fa200 ]---
> (XEN) DOM0: Kernel panic - not syncing: Attempted to kill the idle task!
> (XEN) DOM0: ---[ end Kernel panic - not syncing: Attempted to kill the idle
> task!
>
> Thanks,
> Suravee
>
Julien Grall Oct. 13, 2014, 12:45 p.m. UTC | #4
On 10/13/2014 01:35 PM, Vijay Kilari wrote:
> Hi Roy,

Hi all,

>    I too observe the same issue. I have enabled uefi_debug
> 
> (XEN) DOM0: bootconsole [uart0] enabled
> (XEN) DOM0: Memory limited to 512MB
> (XEN) DOM0: efi: Getting parameters from FDT:
> (XEN) DOM0: efi:   System Table: 0x000000007fb79f18
> (XEN) DOM0: efi:   MemMap Address: 0x000000007a88c018
> (XEN) DOM0: efi:   MemMap Size: 0x000004e0
> (XEN) DOM0: efi:   MemMap Desc. Size: 0x00000030
> (XEN) DOM0: efi:   MemMap Desc. Version: 0x00000001
> (XEN) DOM0: Unhandled fault: ttbr address size fault (0x96000000) at
> 0xffffffbffbc7ff18
> (XEN) DOM0: Internal error: : 96000000 [#1] PREEMPT SMP
> (XEN) DOM0: Modules linked in:
> (XEN) DOM0: CPU: 0 PID: 0 Comm: swapper Not tainted 3.16.0-rc4+ #3
> (XEN) DOM0: task: ffffffc0007048a0 ti: ffffffc0006f8000 task.ti:
> ffffffc0006f8000
> (XEN) DOM0: PC is at uefi_init+0x94/0x1a0
> (XEN) DOM0: LR is at uefi_init+0x84/0x1a0
> 
> I have not digged into the issue. Xen has not mapped this table to Dom0?

DOM0 should only boot with Device Tree and not using EFI. I suspect that
Xen is copying the EFI properties/nodes in the DOM0 DT.

We have to remove at least the following parameters from the device tree:

- linux,uefi-system-table
- linux,uefi-mmap-start
- linux,uefi-mmap-size
- linux,uefi-mmap-desc-size
- linux,uefi-mmap-desc-ver

Regards,
Julien Grall Oct. 13, 2014, 1:09 p.m. UTC | #5
Hi Ian,

On 10/10/2014 03:43 PM, Ian Campbell wrote:
> The code in the arm64 version of setup_xenheap_mappings was making
> some very confused attempts to handle this but was bogus.
> 
> As well as adjusting the mapping to start on a 1GB boundary we also
> need to account for the offset between the start of the mapping and
> the actual start of the heap when converting between page pointers,
> virtual addresses and machine addresses.
> 
> I preferred to do this by explicitly accounting for the offset rather
> than adding an offset to the frametable because that approach could
> potentially waste a large amount of frametable (up to just less than
> 1GB worth) but also because of issues with converting mfns from
> outside the regions considered for pdx initialisation (which are not
> 1GB aligned) back and forth.
> 
> We already have an idea of the distinction between the start of the
> direct map and the start of the xenheap in the difference between
> DIRECTMAP_VIRT_START and XENHEAP_VIRT_START. Until now these were the
> same thing, but now we change XENHEAP_VIRT_START to point to the
> actual start of heap not the mapping. Surprisingly there was only one
> place which was using the conceptually wrong value.
> 
> Also change xenheap_virt_end to a vaddr_t for consistency.
> 
> We've been lucky so far that most hardware happens to locate memory
> on a 1GB boundary (we did have reports of a system with memory at a
> half gig boundary which exhibited failures which I didn't manage to
> follow up on successfully). The EFI support has exposed this
> shortcoming by the way it handles reserved memory, which has a
> similar effect to having memory non-1GB aligned.
> 
> arm32 does things differently here due to using a small Xen heap and
> a demand mapped domain heap, so isn't affected.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> Cc: Suravee Suthikulanit <suravee.suthikulpanit@amd.com>
> Cc: Roy Franz <roy.franz@linaro.org>
> Cc: Vijay Kilari <vijay.kilari@gmail.com>
> ---
> FOR-4.5: This is a bug fix.

Looks good to me:

Reviewed-by: Julien Grall <julien.grall@linaro.org>

Regards,
Suthikulpanit, Suravee Oct. 13, 2014, 3:57 p.m. UTC | #6
On 10/10/2014 9:43 AM, Ian Campbell wrote:
> The code in the arm64 version of setup_xenheap_mappings was making
> some very confused attempts to handle this but was bogus.
>
> As well as adjusting the mapping to start on a 1GB boundary we also
> need to account for the offset between the start of the mapping and
> the actual start of the heap when converting between page pointers,
> virtual addresses and machine addresses.
>
> I preferred to do this by explicitly accounting for the offset rather
> than adding an offset to the frametable because that approach could
> potentially waste a large amount of frametable (up to just less than
> 1GB worth) but also because of issues with converting mfns from
> outside the regions considered for pdx initialisation (which are not
> 1GB aligned) back and forth.
>
> We already have an idea of the distinction between the start of the
> direct map and the start of the xenheap in the difference between
> DIRECTMAP_VIRT_START and XENHEAP_VIRT_START. Until now these were the
> same thing, but now we change XENHEAP_VIRT_START to point to the
> actual start of heap not the mapping. Surprisingly there was only one
> place which was using the conceptually wrong value.
>
> Also change xenheap_virt_end to a vaddr_t for consistency.
>
> We've been lucky so far that most hardware happens to locate memory
> on a 1GB boundary (we did have reports of a system with memory at a
> half gig boundary which exhibited failures which I didn't manage to
> follow up on successfully). The EFI support has exposed this
> shortcoming by the way it handles reserved memory, which has a
> similar effect to having memory non-1GB aligned.
>
> arm32 does things differently here due to using a small Xen heap and
> a demand mapped domain heap, so isn't affected.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> Cc: Suravee Suthikulanit <suravee.suthikulpanit@amd.com>
> Cc: Roy Franz <roy.franz@linaro.org>
> Cc: Vijay Kilari <vijay.kilari@gmail.com>
> ---
> FOR-4.5: This is a bug fix.
> ---
>   xen/arch/arm/mm.c            |   36 +++++++++++++++++++++++++-----------
>   xen/include/asm-arm/config.h |    2 +-
>   xen/include/asm-arm/mm.h     |    7 +++++--
>   3 files changed, 31 insertions(+), 14 deletions(-)
>
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index c5b48ef..97e5bc39 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -138,7 +138,10 @@ static paddr_t phys_offset;
>   /* Limits of the Xen heap */
>   unsigned long xenheap_mfn_start __read_mostly = ~0UL;
>   unsigned long xenheap_mfn_end __read_mostly;
> -unsigned long xenheap_virt_end __read_mostly;
> +vaddr_t xenheap_virt_end __read_mostly;
> +#ifdef CONFIG_ARM_64
> +vaddr_t xenheap_virt_start __read_mostly;
> +#endif
>
>   unsigned long frametable_base_pdx __read_mostly;
>   unsigned long frametable_virt_end __read_mostly;
> @@ -155,7 +158,11 @@ static inline void check_memory_layout_alignment_constraints(void) {
>       BUILD_BUG_ON(FIXMAP_ADDR(0) & ~SECOND_MASK);
>       BUILD_BUG_ON(BOOT_RELOC_VIRT_START & ~SECOND_MASK);
>       /* 1GB aligned regions */
> +#ifdef CONFIG_ARM_32
>       BUILD_BUG_ON(XENHEAP_VIRT_START & ~FIRST_MASK);
> +#else
> +    BUILD_BUG_ON(DIRECTMAP_VIRT_START & ~FIRST_MASK);
> +#endif
>       /* Page table structure constraints */
>   #ifdef CONFIG_ARM_64
>       BUILD_BUG_ON(zeroeth_table_offset(XEN_VIRT_START));
> @@ -665,12 +672,19 @@ void __init setup_xenheap_mappings(unsigned long base_mfn,
>                                      unsigned long nr_mfns)
>   {
>       lpae_t *first, pte;
> -    unsigned long offset, end_mfn;
> +    unsigned long mfn, end_mfn;
>       vaddr_t vaddr;
>
> -    /* First call sets the xenheap physical offset. */
> +    /* Align to previous 1GB boundary */
> +    mfn = base_mfn & ~((FIRST_SIZE>>PAGE_SHIFT)-1);
> +
> +    /* First call sets the xenheap physical and virtual offset. */
>       if ( xenheap_mfn_start == ~0UL )
> +    {
>           xenheap_mfn_start = base_mfn;
> +        xenheap_virt_start = DIRECTMAP_VIRT_START +
> +            (base_mfn - mfn) * PAGE_SIZE;
> +    }
>
>       if ( base_mfn < xenheap_mfn_start )
>           panic("cannot add xenheap mapping at %lx below heap start %lx",
> @@ -678,13 +692,13 @@ void __init setup_xenheap_mappings(unsigned long base_mfn,
>
>       end_mfn = base_mfn + nr_mfns;
>
> -    /* Align to previous 1GB boundary */
> -    base_mfn &= ~((FIRST_SIZE>>PAGE_SHIFT)-1);
> -
> -    offset = pfn_to_pdx(base_mfn - xenheap_mfn_start);
> -    vaddr = DIRECTMAP_VIRT_START + offset*PAGE_SIZE;
> +    /*
> +     * Virtual address aligned to previous 1GB to match physical
> +     * address alignment done above.
> +     */
> +    vaddr = (vaddr_t)mfn_to_virt(base_mfn) & FIRST_MASK;
>
> -    while ( base_mfn < end_mfn )
> +    while ( mfn < end_mfn )
>       {
>           int slot = zeroeth_table_offset(vaddr);
>           lpae_t *p = &xen_pgtable[slot];
> @@ -716,11 +730,11 @@ void __init setup_xenheap_mappings(unsigned long base_mfn,
>               first = mfn_to_virt(first_mfn);
>           }
>
> -        pte = mfn_to_xen_entry(base_mfn, WRITEALLOC);
> +        pte = mfn_to_xen_entry(mfn, WRITEALLOC);
>           /* TODO: Set pte.pt.contig when appropriate. */
>           write_pte(&first[first_table_offset(vaddr)], pte);
>
> -        base_mfn += FIRST_SIZE>>PAGE_SHIFT;
> +        mfn += FIRST_SIZE>>PAGE_SHIFT;
>           vaddr += FIRST_SIZE;
>       }
>
> diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
> index 59b2887..264e2c1 100644
> --- a/xen/include/asm-arm/config.h
> +++ b/xen/include/asm-arm/config.h
> @@ -162,7 +162,7 @@
>   #define DIRECTMAP_SIZE         (SLOT0_ENTRY_SIZE * (265-256))
>   #define DIRECTMAP_VIRT_END     (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE - 1)
>
> -#define XENHEAP_VIRT_START     DIRECTMAP_VIRT_START
> +#define XENHEAP_VIRT_START     xenheap_virt_start
>
>   #define HYPERVISOR_VIRT_END    DIRECTMAP_VIRT_END
>
> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> index 1e4711c..d25e485 100644
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -110,7 +110,10 @@ struct page_info
>   #define PGC_count_mask    ((1UL<<PGC_count_width)-1)
>
>   extern unsigned long xenheap_mfn_start, xenheap_mfn_end;
> -extern unsigned long xenheap_virt_end;
> +extern vaddr_t xenheap_virt_end;
> +#ifdef CONFIG_ARM_64
> +extern vaddr_t xenheap_virt_start;
> +#endif
>
>   #ifdef CONFIG_ARM_32
>   #define is_xen_heap_page(page) is_xen_heap_mfn(page_to_mfn(page))
> @@ -227,7 +230,7 @@ static inline void *maddr_to_virt(paddr_t ma)
>   static inline void *maddr_to_virt(paddr_t ma)
>   {
>       ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
> -    return (void *)(DIRECTMAP_VIRT_START -
> +    return (void *)(XENHEAP_VIRT_START -
>                       pfn_to_paddr(xenheap_mfn_start) +
>                       ((ma & ma_va_bottom_mask) |
>                        ((ma & ma_top_mask) >> pfn_pdx_hole_shift)));
>

<Tested-by> Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Ian Campbell Oct. 14, 2014, 10:59 a.m. UTC | #7
On Fri, 2014-10-10 at 12:12 -0700, Roy Franz wrote:
> Works for me on the FVP model.  This platform didn't trigger the bug,
> so it continues
> to work as before.

Thanks, I took this as a Tested-by and applied with the other
ack/reviewed-by from the thread.
Ian
diff mbox

Patch

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index c5b48ef..97e5bc39 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -138,7 +138,10 @@  static paddr_t phys_offset;
 /* Limits of the Xen heap */
 unsigned long xenheap_mfn_start __read_mostly = ~0UL;
 unsigned long xenheap_mfn_end __read_mostly;
-unsigned long xenheap_virt_end __read_mostly;
+vaddr_t xenheap_virt_end __read_mostly;
+#ifdef CONFIG_ARM_64
+vaddr_t xenheap_virt_start __read_mostly;
+#endif
 
 unsigned long frametable_base_pdx __read_mostly;
 unsigned long frametable_virt_end __read_mostly;
@@ -155,7 +158,11 @@  static inline void check_memory_layout_alignment_constraints(void) {
     BUILD_BUG_ON(FIXMAP_ADDR(0) & ~SECOND_MASK);
     BUILD_BUG_ON(BOOT_RELOC_VIRT_START & ~SECOND_MASK);
     /* 1GB aligned regions */
+#ifdef CONFIG_ARM_32
     BUILD_BUG_ON(XENHEAP_VIRT_START & ~FIRST_MASK);
+#else
+    BUILD_BUG_ON(DIRECTMAP_VIRT_START & ~FIRST_MASK);
+#endif
     /* Page table structure constraints */
 #ifdef CONFIG_ARM_64
     BUILD_BUG_ON(zeroeth_table_offset(XEN_VIRT_START));
@@ -665,12 +672,19 @@  void __init setup_xenheap_mappings(unsigned long base_mfn,
                                    unsigned long nr_mfns)
 {
     lpae_t *first, pte;
-    unsigned long offset, end_mfn;
+    unsigned long mfn, end_mfn;
     vaddr_t vaddr;
 
-    /* First call sets the xenheap physical offset. */
+    /* Align to previous 1GB boundary */
+    mfn = base_mfn & ~((FIRST_SIZE>>PAGE_SHIFT)-1);
+
+    /* First call sets the xenheap physical and virtual offset. */
     if ( xenheap_mfn_start == ~0UL )
+    {
         xenheap_mfn_start = base_mfn;
+        xenheap_virt_start = DIRECTMAP_VIRT_START +
+            (base_mfn - mfn) * PAGE_SIZE;
+    }
 
     if ( base_mfn < xenheap_mfn_start )
         panic("cannot add xenheap mapping at %lx below heap start %lx",
@@ -678,13 +692,13 @@  void __init setup_xenheap_mappings(unsigned long base_mfn,
 
     end_mfn = base_mfn + nr_mfns;
 
-    /* Align to previous 1GB boundary */
-    base_mfn &= ~((FIRST_SIZE>>PAGE_SHIFT)-1);
-
-    offset = pfn_to_pdx(base_mfn - xenheap_mfn_start);
-    vaddr = DIRECTMAP_VIRT_START + offset*PAGE_SIZE;
+    /*
+     * Virtual address aligned to previous 1GB to match physical
+     * address alignment done above.
+     */
+    vaddr = (vaddr_t)mfn_to_virt(base_mfn) & FIRST_MASK;
 
-    while ( base_mfn < end_mfn )
+    while ( mfn < end_mfn )
     {
         int slot = zeroeth_table_offset(vaddr);
         lpae_t *p = &xen_pgtable[slot];
@@ -716,11 +730,11 @@  void __init setup_xenheap_mappings(unsigned long base_mfn,
             first = mfn_to_virt(first_mfn);
         }
 
-        pte = mfn_to_xen_entry(base_mfn, WRITEALLOC);
+        pte = mfn_to_xen_entry(mfn, WRITEALLOC);
         /* TODO: Set pte.pt.contig when appropriate. */
         write_pte(&first[first_table_offset(vaddr)], pte);
 
-        base_mfn += FIRST_SIZE>>PAGE_SHIFT;
+        mfn += FIRST_SIZE>>PAGE_SHIFT;
         vaddr += FIRST_SIZE;
     }
 
diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
index 59b2887..264e2c1 100644
--- a/xen/include/asm-arm/config.h
+++ b/xen/include/asm-arm/config.h
@@ -162,7 +162,7 @@ 
 #define DIRECTMAP_SIZE         (SLOT0_ENTRY_SIZE * (265-256))
 #define DIRECTMAP_VIRT_END     (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE - 1)
 
-#define XENHEAP_VIRT_START     DIRECTMAP_VIRT_START
+#define XENHEAP_VIRT_START     xenheap_virt_start
 
 #define HYPERVISOR_VIRT_END    DIRECTMAP_VIRT_END
 
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 1e4711c..d25e485 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -110,7 +110,10 @@  struct page_info
 #define PGC_count_mask    ((1UL<<PGC_count_width)-1)
 
 extern unsigned long xenheap_mfn_start, xenheap_mfn_end;
-extern unsigned long xenheap_virt_end;
+extern vaddr_t xenheap_virt_end;
+#ifdef CONFIG_ARM_64
+extern vaddr_t xenheap_virt_start;
+#endif
 
 #ifdef CONFIG_ARM_32
 #define is_xen_heap_page(page) is_xen_heap_mfn(page_to_mfn(page))
@@ -227,7 +230,7 @@  static inline void *maddr_to_virt(paddr_t ma)
 static inline void *maddr_to_virt(paddr_t ma)
 {
     ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
-    return (void *)(DIRECTMAP_VIRT_START -
+    return (void *)(XENHEAP_VIRT_START -
                     pfn_to_paddr(xenheap_mfn_start) +
                     ((ma & ma_va_bottom_mask) |
                      ((ma & ma_top_mask) >> pfn_pdx_hole_shift)));