[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.11] xen/arm64: Correctly compute the virtual address in maddr_to_virt()



commit 317de0a12f36a4a6424c9fb302c6d81cefd6a840
Author:     Julien Grall <julien.grall@xxxxxxx>
AuthorDate: Thu Jul 18 12:57:14 2019 +0100
Commit:     Stefano Stabellini <sstabellini@xxxxxxxxxx>
CommitDate: Tue Oct 29 11:39:20 2019 -0700

    xen/arm64: Correctly compute the virtual address in maddr_to_virt()
    
    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>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    (cherry picked from commit 612d476e74a314be514ee6a9744eea8db09d32e5)
---
 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 fdf2c0a7d7..d3d4127e98 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -151,6 +151,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;
@@ -822,6 +823,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;
     }
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 89fe10ff15..4ad387064d 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(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
+    ASSERT((pfn_to_pdx(ma >> PAGE_SHIFT) - 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)));
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.