|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xen/arm64: Correctly compute the virtual address in maddr_to_virt()
On Thu, 18 Jul 2019, Julien Grall wrote:
> The helper maddr_to_virt() is used to translate a machine address to a
> virtual address. To save some valuable address space, some part of the
> machine address may be compressed.
>
> In theory the PDX code is free to compress any bits so there are no
> guarantee the machine index computed will be always greater than
> xenheap_mfn_start. This would result to return a virtual address that is
> not part of the direct map and trigger a crash at least on debug-build later
> on because of the check in virt_to_page().
>
> A recently reverted patch (see 1191156361 "xen/arm: fix mask calculation
> in pdx_init_mask") allows the PDX to compress more bits and triggered a
> crash on AMD Seattle Platform.
>
> Avoid the crash by keeping track of the base PDX for the xenheap and use
> it for computing the virtual address.
>
> Note that virt_to_maddr() does not need to have similar modification as
> it is using the hardware to translate the virtual address to a machine
> address.
>
> Take the opportunity to fix the ASSERT() as the direct map base address
> correspond to the start of the RAM (this is not always 0).
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
Thank you very much for debugging and fixing this problem! It is
surprising that it has been working at all :-)
> ---
>
> With that, the patch 1191156361 "xen/arm: fix mask calculation in
> pdx_init_mask" could be re-instated.
> ---
> xen/arch/arm/mm.c | 2 ++
> xen/include/asm-arm/mm.h | 6 ++++--
> 2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index 44258ad89c..e1cdeaaf2f 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -165,6 +165,7 @@ mfn_t xenheap_mfn_end __read_mostly;
> vaddr_t xenheap_virt_end __read_mostly;
> #ifdef CONFIG_ARM_64
> vaddr_t xenheap_virt_start __read_mostly;
> +unsigned long xenheap_base_pdx __read_mostly;
> #endif
>
> unsigned long frametable_base_pdx __read_mostly;
> @@ -796,6 +797,7 @@ void __init setup_xenheap_mappings(unsigned long base_mfn,
> if ( mfn_eq(xenheap_mfn_start, INVALID_MFN) )
> {
> xenheap_mfn_start = _mfn(base_mfn);
> + xenheap_base_pdx = mfn_to_pdx(_mfn(base_mfn));
> xenheap_virt_start = DIRECTMAP_VIRT_START +
> (base_mfn - mfn) * PAGE_SIZE;
> }
I can see that this would work, but wouldn't it be a better fit to set
xenheap_base_pdx in xen/arch/arm/setup.c:setup_mm, where we already set:
xenheap_virt_end = XENHEAP_VIRT_START + ram_end - ram_start;
xenheap_mfn_start = maddr_to_mfn(ram_start);
xenheap_mfn_end = maddr_to_mfn(ram_end);
Or it too late by then?
> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> index 3dbc8a6469..d6b5544015 100644
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -135,6 +135,7 @@ extern mfn_t xenheap_mfn_start, xenheap_mfn_end;
> extern vaddr_t xenheap_virt_end;
> #ifdef CONFIG_ARM_64
> extern vaddr_t xenheap_virt_start;
> +extern unsigned long xenheap_base_pdx;
> #endif
>
> #ifdef CONFIG_ARM_32
> @@ -253,9 +254,10 @@ static inline void *maddr_to_virt(paddr_t ma)
> #else
> static inline void *maddr_to_virt(paddr_t ma)
> {
> - ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
> + ASSERT((mfn_to_pdx(maddr_to_mfn(ma)) - xenheap_base_pdx) <
> + (DIRECTMAP_SIZE >> PAGE_SHIFT));
> return (void *)(XENHEAP_VIRT_START -
> - mfn_to_maddr(xenheap_mfn_start) +
> + (xenheap_base_pdx << PAGE_SHIFT) +
> ((ma & ma_va_bottom_mask) |
> ((ma & ma_top_mask) >> pfn_pdx_hole_shift)));
> }
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |