diff mbox series

[v2,6/7] xen/riscv: implement prereq for DTB relocation

Message ID 2d2d6ca32aa7db490d47154530f01216651ba335.1733937787.git.oleksii.kurochko@gmail.com (mailing list archive)
State Superseded
Headers show
Series Unflattening and relocation of host device tree | expand

Commit Message

Oleksii Kurochko Dec. 11, 2024, 5:27 p.m. UTC
DTB relocatin in Xen heap requires the following functions which are
introduced in current patch:
- xvmalloc_array()
- copy_from_paddr()

For internal use of xvmalloc, the functions flush_page_to_ram() and
virt_to_page() are introduced. virt_to_page() is also required for
free_xenheap_pages().

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V2:
 - Drop variable directmap_virt_end.
 - Update ASSERT in virt_to_page() to use DIRECTMAP_VIRT_END instead of
   variable directmap_virt_end.
 - Declare local varibale v as const inside flush_page_to_ram().
 - Declare copy_from_paddr() in riscv/setup.h as in the future it will be
   used for copying kernel in guest memory.
 - Code style updates for copy_from_paddr().
 - Make l and s variable in copy_from_paddr() as the virables' initializers.
 - Drop call of clean_dcache_va_range(dst, l) in copy_from_paddr() as the
   necessiry of it is Arm-specific:
     After memcpy'ing the kernel in guest memory Arm need to flush the dcache
     to make sure that the data actually reaches the memory before we start
     executing guest code with caches disabled.
   RISC-V has caches always enabled thereby there is no such issue for RISC-V.
 - Make local variable src in copy_from_paddr() as const.
 - Update the commit message and subject: drop information of relocate_fdt()
   introduction and rename it to "prereq for DTB relocation".
 - Add BUG_ON() inside flush_page_to_ram() to check the return value of
   clean_and_invalidate_dcache_va_range().
 - Move relocate_fdt() introduction to the next patch to make this patch
   compilable.
---
 xen/arch/riscv/include/asm/mm.h    |  8 ++++++--
 xen/arch/riscv/include/asm/page.h  | 11 +++++++++--
 xen/arch/riscv/include/asm/setup.h |  4 ++++
 xen/arch/riscv/setup.c             | 26 ++++++++++++++++++++++++++
 4 files changed, 45 insertions(+), 4 deletions(-)

Comments

Jan Beulich Dec. 16, 2024, 2:30 p.m. UTC | #1
On 11.12.2024 18:27, Oleksii Kurochko wrote:
> @@ -175,10 +176,16 @@ static inline void invalidate_icache(void)
>  #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
>  #define copy_page(dp, sp) memcpy(dp, sp, PAGE_SIZE)
>  
> -/* TODO: Flush the dcache for an entire page. */
>  static inline void flush_page_to_ram(unsigned long mfn, bool sync_icache)
>  {
> -    BUG_ON("unimplemented");
> +    const void *v = map_domain_page(_mfn(mfn));
> +
> +    BUG_ON(clean_and_invalidate_dcache_va_range(v, PAGE_SIZE));

Please avoid expressions with side effects in BUG_ON(). This wants to be

    if ( clean_and_invalidate_dcache_va_range(v, PAGE_SIZE) )
        BUG();

Then
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan
diff mbox series

Patch

diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h
index 699ed23f0d..292aa48fc1 100644
--- a/xen/arch/riscv/include/asm/mm.h
+++ b/xen/arch/riscv/include/asm/mm.h
@@ -8,6 +8,7 @@ 
 #include <xen/const.h>
 #include <xen/mm-frame.h>
 #include <xen/pdx.h>
+#include <xen/pfn.h>
 #include <xen/types.h>
 
 #include <asm/page-bits.h>
@@ -148,8 +149,11 @@  static inline void *page_to_virt(const struct page_info *pg)
 /* Convert between Xen-heap virtual addresses and page-info structures. */
 static inline struct page_info *virt_to_page(const void *v)
 {
-    BUG_ON("unimplemented");
-    return NULL;
+    unsigned long va = (unsigned long)v;
+
+    ASSERT((va >= DIRECTMAP_VIRT_START) && (va <= DIRECTMAP_VIRT_END));
+
+    return frametable_virt_start + PFN_DOWN(va - directmap_virt_start);
 }
 
 /*
diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h
index 54c6fe6515..fbb35a6673 100644
--- a/xen/arch/riscv/include/asm/page.h
+++ b/xen/arch/riscv/include/asm/page.h
@@ -7,6 +7,7 @@ 
 
 #include <xen/bug.h>
 #include <xen/const.h>
+#include <xen/domain_page.h>
 #include <xen/errno.h>
 #include <xen/types.h>
 
@@ -175,10 +176,16 @@  static inline void invalidate_icache(void)
 #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
 #define copy_page(dp, sp) memcpy(dp, sp, PAGE_SIZE)
 
-/* TODO: Flush the dcache for an entire page. */
 static inline void flush_page_to_ram(unsigned long mfn, bool sync_icache)
 {
-    BUG_ON("unimplemented");
+    const void *v = map_domain_page(_mfn(mfn));
+
+    BUG_ON(clean_and_invalidate_dcache_va_range(v, PAGE_SIZE));
+
+    unmap_domain_page(v);
+
+    if ( sync_icache )
+        invalidate_icache();
 }
 
 /* Write a pagetable entry. */
diff --git a/xen/arch/riscv/include/asm/setup.h b/xen/arch/riscv/include/asm/setup.h
index 844a2f0ef1..c9d69cdf51 100644
--- a/xen/arch/riscv/include/asm/setup.h
+++ b/xen/arch/riscv/include/asm/setup.h
@@ -3,10 +3,14 @@ 
 #ifndef ASM__RISCV__SETUP_H
 #define ASM__RISCV__SETUP_H
 
+#include <xen/types.h>
+
 #define max_init_domid (0)
 
 void setup_mm(void);
 
+void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
+
 #endif /* ASM__RISCV__SETUP_H */
 
 /*
diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
index 9680332fee..bea3f27c4d 100644
--- a/xen/arch/riscv/setup.c
+++ b/xen/arch/riscv/setup.c
@@ -12,6 +12,7 @@ 
 #include <public/version.h>
 
 #include <asm/early_printk.h>
+#include <asm/fixmap.h>
 #include <asm/sbi.h>
 #include <asm/setup.h>
 #include <asm/smp.h>
@@ -26,6 +27,31 @@  void arch_get_xen_caps(xen_capabilities_info_t *info)
 unsigned char __initdata cpu0_boot_stack[STACK_SIZE]
     __aligned(STACK_SIZE);
 
+/**
+ * copy_from_paddr - copy data from a physical address
+ * @dst: destination virtual address
+ * @paddr: source physical address
+ * @len: length to copy
+ */
+void __init copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
+{
+    const void *src = (void *)FIXMAP_ADDR(FIX_MISC);
+
+    while ( len )
+    {
+        unsigned long s = paddr & (PAGE_SIZE - 1);
+        unsigned long l = min(PAGE_SIZE - s, len);
+
+        set_fixmap(FIX_MISC, maddr_to_mfn(paddr), PAGE_HYPERVISOR_RW);
+        memcpy(dst, src + s, l);
+        clear_fixmap(FIX_MISC);
+
+        paddr += l;
+        dst += l;
+        len -= l;
+    }
+}
+
 void __init noreturn start_xen(unsigned long bootcpu_id,
                                paddr_t dtb_addr)
 {