|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH] plat/xen/x86: Create and initialize p2m table
From: Radu Nicolau <radunicolau102@xxxxxxxxx>
Build p2m table needed for direct paging on paravirtualized Xen
Code adapted from Mini-OS.
Signed-off-by: Radu Nicolau <radunicolau102@xxxxxxxxx>
---
plat/xen/Config.uk | 8 +++++
plat/xen/include/xen-arm/mm.h | 2 ++
plat/xen/include/xen-x86/mm_pv.h | 11 +++++--
plat/xen/memory.c | 8 +++++
plat/xen/x86/mm.c | 71 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/plat/xen/Config.uk b/plat/xen/Config.uk
index 6f6c214..18896b9 100644
--- a/plat/xen/Config.uk
+++ b/plat/xen/Config.uk
@@ -2,6 +2,7 @@ menuconfig PLAT_XEN
bool "Xen guest image"
default n
depends on (ARCH_X86_32 || ARCH_X86_64 || ARCH_ARM_32)
+ imply XEN_PV_BUILD_P2M
select LIBUKDEBUG
select LIBNOLIBC if !HAVE_LIBC
select LIBUKTIME if !HAVE_LIBC && ARCH_X86_64
@@ -48,6 +49,13 @@ config XEN_DEBUG_EMG_CONSOLE
Send debug messages to the emergency console.
endmenu
+config XEN_PV_BUILD_P2M
+ bool "Create p2m table"
+ default n
+ help
+ Create and initialize physical to machine (p2m) table on a PV
+ xen host
+
config XEN_GNTTAB
bool "Grant table support"
default y
diff --git a/plat/xen/include/xen-arm/mm.h b/plat/xen/include/xen-arm/mm.h
index 0f5c8f5..4de76f4 100644
--- a/plat/xen/include/xen-arm/mm.h
+++ b/plat/xen/include/xen-arm/mm.h
@@ -56,4 +56,6 @@ extern uint32_t _libxenplat_paddr_offset;
#define virtual_to_mfn(_virt) virt_to_mfn(_virt)
+#define arch_mm_init(a)
+
#endif
diff --git a/plat/xen/include/xen-x86/mm_pv.h b/plat/xen/include/xen-x86/mm_pv.h
index f78e62f..dc2a02e 100644
--- a/plat/xen/include/xen-x86/mm_pv.h
+++ b/plat/xen/include/xen-x86/mm_pv.h
@@ -34,6 +34,7 @@
#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
/* for P2M */
+#ifdef CONFIG_XEN_PV_BUILD_P2M
#ifdef __x86_64__
#define P2M_SHIFT 9
#else
@@ -49,13 +50,17 @@
#define L3_P2M_IDX(pfn) (((pfn) >> L2_P2M_SHIFT) & P2M_MASK)
#define INVALID_P2M_ENTRY (~0UL)
-void p2m_chk_pfn(unsigned long pfn);
-
static inline unsigned long p2m_pages(unsigned long pages)
{
return (pages + P2M_ENTRIES - 1) >> L1_P2M_SHIFT;
}
-void arch_init_p2m(unsigned long max_pfn_p);
+void arch_mm_init(struct uk_alloc *a);
+
+#ifdef CONFIG_MIGRATION
+void arch_mm_pre_suspend(void);
+void arch_mm_post_suspend(int canceled);
+#endif /* CONFIG_MIGRATION */
+#endif /* CONFIG_XEN_PV_BUILD_P2M */
#endif /* _MM_PV_H */
diff --git a/plat/xen/memory.c b/plat/xen/memory.c
index 8f170dd..709c04c 100644
--- a/plat/xen/memory.c
+++ b/plat/xen/memory.c
@@ -39,8 +39,10 @@
#include <common/gnttab.h>
#if (defined __X86_32__) || (defined __X86_64__)
#include <xen-x86/setup.h>
+#include <xen-x86/mm_pv.h>
#elif (defined __ARM_32__) || (defined __ARM_64__)
#include <xen-arm/setup.h>
+#include <xen-arm/mm.h>
#endif
#include <uk/assert.h>
@@ -141,8 +143,14 @@ int ukplat_memregion_get(int i, struct
ukplat_memregion_desc *m)
return 0;
}
+void mm_init(void)
+{
+ arch_mm_init(ukplat_memallocator_get());
+}
+
int _ukplat_mem_mappings_init(void)
{
+ mm_init();
#ifdef CONFIG_XEN_GNTTAB
gnttab_init();
#endif
diff --git a/plat/xen/x86/mm.c b/plat/xen/x86/mm.c
index 2f23855..dc9cc75 100644
--- a/plat/xen/x86/mm.c
+++ b/plat/xen/x86/mm.c
@@ -47,6 +47,7 @@
#include <uk/assert.h>
#ifdef CONFIG_PARAVIRT
+#include <xen-x86/mm_pv.h>
unsigned long *phys_to_machine_mapping;
#endif
unsigned long mfn_zero;
@@ -684,6 +685,76 @@ void _init_mem_clear_bootstrap(void)
#endif
}
+#ifdef CONFIG_XEN_PV_BUILD_P2M
+static unsigned long max_pfn;
+static unsigned long *l3_list;
+static unsigned long *l2_list_pages[P2M_ENTRIES];
+
+void _arch_init_p2m(struct uk_alloc *a)
+{
+ unsigned long pfn;
+ unsigned long *l2_list = NULL;
+
+ max_pfn = HYPERVISOR_start_info->nr_pages;
+
+ if (((max_pfn - 1) >> L3_P2M_SHIFT) > 0)
+ UK_CRASH("Error: Too many pfns.\n");
+
+ l3_list = uk_malloc_page(a);
+ for (pfn = 0; pfn < max_pfn; pfn += P2M_ENTRIES) {
+ if (!(pfn % (P2M_ENTRIES * P2M_ENTRIES))) {
+ l2_list = uk_malloc_page(a);
+ l3_list[L3_P2M_IDX(pfn)] = virt_to_mfn(l2_list);
+ l2_list_pages[L3_P2M_IDX(pfn)] = l2_list;
+ }
+
+ l2_list[L2_P2M_IDX(pfn)] =
+ virt_to_mfn(phys_to_machine_mapping + pfn);
+ }
+ HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+ virt_to_mfn(l3_list);
+ HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+}
+
+void _arch_rebuild_p2m(void)
+{
+ unsigned long pfn;
+ unsigned long *l2_list = NULL;
+
+ for (pfn = 0; pfn < max_pfn; pfn += P2M_ENTRIES) {
+ if (!(pfn % (P2M_ENTRIES * P2M_ENTRIES))) {
+ l2_list = l2_list_pages[L3_P2M_IDX(pfn)];
+ l3_list[L3_P2M_IDX(pfn)] = virt_to_mfn(l2_list);
+ }
+
+ l2_list[L2_P2M_IDX(pfn)] =
+ virt_to_mfn(phys_to_machine_mapping + pfn);
+ }
+ HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+ virt_to_mfn(l3_list);
+ HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+}
+
+#ifdef CONFIG_MIGRATION
+void arch_mm_pre_suspend(void)
+{
+
+}
+void arch_mm_post_suspend(int canceled)
+{
+ if (!canceled)
+ arch_rebuild_p2m();
+}
+#endif
+#endif /* CONFIG_XEN_PV_BUILD_P2M */
+
+void arch_mm_init(struct uk_alloc *a)
+{
+#ifdef CONFIG_XEN_PV_BUILD_P2M
+ _arch_init_p2m(a);
+#endif
+}
+
void _init_mem_prepare(unsigned long *start_pfn, unsigned long *max_pfn)
{
#ifdef CONFIG_PARAVIRT
--
2.7.4
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |