]> xenbits.xensource.com Git - xen.git/commitdiff
xen/riscv: implement prereq for DTB relocation
authorOleksii Kurochko <oleksii.kurochko@gmail.com>
Thu, 19 Dec 2024 09:23:28 +0000 (10:23 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 19 Dec 2024 09:23:28 +0000 (10:23 +0100)
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>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/riscv/include/asm/mm.h
xen/arch/riscv/include/asm/page.h
xen/arch/riscv/include/asm/setup.h
xen/arch/riscv/setup.c

index 699ed23f0db67587a5cad3d137638b7e742af0d0..292aa48fc1a5cad31605d15bc131463cb4ea83fb 100644 (file)
@@ -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);
 }
 
 /*
index 06f3effcbedb83d5b69794f102b194be5a191dc8..7a6174a109375387278ac062c81f992e400cb6ef 100644 (file)
@@ -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>
 
@@ -176,10 +177,17 @@ 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));
+
+    if ( clean_and_invalidate_dcache_va_range(v, PAGE_SIZE) )
+        BUG();
+
+    unmap_domain_page(v);
+
+    if ( sync_icache )
+        invalidate_icache();
 }
 
 /* Write a pagetable entry. */
index 844a2f0ef1d762b3a9bc90b61a336a23f1693cc9..c9d69cdf51666c0ec31196411b52e9b39439ba5f 100644 (file)
@@ -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 */
 
 /*
index 9680332fee9224183a230b17dc1725d3fe574ded..bea3f27c4dd7cb7b4a6fffd2e8810f657a6087a5 100644 (file)
@@ -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)
 {