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

[Xen-devel] [PATCH RFC v1 44/74] xen/pvshim: keep track of unused pages



Simple infrastructure to keep track of allocate and free unused pages,
so that we can use them to map special pages like shared info and
grant table.

As rangeset depends on malloc being ready we introduce
hypervisor_setup for things that can be initialised late in the
process.

Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxx>
Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 xen/arch/x86/guest/xen.c        | 48 +++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/setup.c            |  3 +++
 xen/include/asm-x86/guest/xen.h | 22 +++++++++++++++++++
 3 files changed, 73 insertions(+)

diff --git a/xen/arch/x86/guest/xen.c b/xen/arch/x86/guest/xen.c
index 0319a5f9e8..f66c10fbe5 100644
--- a/xen/arch/x86/guest/xen.c
+++ b/xen/arch/x86/guest/xen.c
@@ -21,6 +21,7 @@
 #include <xen/init.h>
 #include <xen/types.h>
 #include <xen/pv_console.h>
+#include <xen/rangeset.h>
 
 #include <asm/apic.h>
 #include <asm/guest.h>
@@ -34,6 +35,7 @@ bool xen_guest;
 static uint32_t xen_cpuid_base;
 static uint8_t evtchn_upcall_vector;
 extern char hypercall_page[];
+static struct rangeset *mem;
 
 static void __init find_xen_leaves(void)
 {
@@ -161,9 +163,38 @@ static void __init init_evtchn(void)
     ap_setup_event_channels(true);
 }
 
+static void __init init_memmap(void)
+{
+    unsigned int i;
+
+    mem = rangeset_new(NULL, "host memory map", 0);
+    if ( !mem )
+        panic("failed to allocate host memory rangeset");
+
+    /* Mark up to the last memory page (or 4GB) as RAM. */
+    if ( rangeset_add_range(mem, 0, max_t(unsigned long, max_page,
+                                          (GB(4) - 1) >> PAGE_SHIFT)) )
+        panic("unable to add RAM to memory rangeset");
+
+    for ( i = 0; i < e820.nr_map; i++ )
+    {
+        struct e820entry *e = &e820.map[i];
+
+        if ( rangeset_add_range(mem, e->addr >> PAGE_SHIFT,
+                                (e->addr + e->size) >> PAGE_SHIFT) )
+            panic("unable to add range %#lx - %#lx to memory rangeset",
+                  e->addr, e->addr + e->size);
+    }
+}
+
 void __init hypervisor_early_setup(struct e820map *e820)
 {
     map_shared_info(e820);
+}
+
+void __init hypervisor_setup(void)
+{
+    init_memmap();
 
     init_evtchn();
 }
@@ -173,6 +204,23 @@ void hypervisor_ap_setup(void)
     ap_setup_event_channels(false);
 }
 
+int hypervisor_alloc_unused_page(mfn_t *mfn)
+{
+    unsigned long m;
+    int rc;
+
+    rc = rangeset_reserve_hole(mem, 1, &m);
+    if ( !rc )
+        *mfn = _mfn(m);
+
+    return rc;
+}
+
+int hypervisor_free_unused_page(mfn_t mfn)
+{
+    return rangeset_remove_range(mem, mfn_x(mfn), mfn_x(mfn));
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 99f5d61eb8..1b3576bc7d 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1481,6 +1481,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         max_cpus = nr_cpu_ids;
     }
 
+    if ( xen_guest )
+        hypervisor_setup();
+
     /* Low mappings were only needed for some BIOS table parsing. */
     zap_low_mappings();
 
diff --git a/xen/include/asm-x86/guest/xen.h b/xen/include/asm-x86/guest/xen.h
index 56cabb1934..ba826d75db 100644
--- a/xen/include/asm-x86/guest/xen.h
+++ b/xen/include/asm-x86/guest/xen.h
@@ -32,7 +32,10 @@ extern bool xen_guest;
 
 void probe_hypervisor(void);
 void hypervisor_early_setup(struct e820map *e820);
+void hypervisor_setup(void);
 void hypervisor_ap_setup(void);
+int hypervisor_alloc_unused_page(mfn_t *mfn);
+int hypervisor_free_unused_page(mfn_t mfn);
 
 #else
 
@@ -43,11 +46,30 @@ static inline void hypervisor_early_setup(struct e820map 
*e820)
 {
     ASSERT_UNREACHABLE();
 };
+
+static inline void hypervisor_setup(void)
+{
+    ASSERT_UNREACHABLE();
+}
+
 static inline void hypervisor_ap_setup(void)
 {
     ASSERT_UNREACHABLE();
 };
 
+static inline int hypervisor_alloc_unused_page(mfn_t *mfn)
+{
+
+    ASSERT_UNREACHABLE();
+    return 0;
+}
+
+static inline int hypervisor_free_unused_page(mfn_t mfn)
+{
+    ASSERT_UNREACHABLE();
+    return 0;
+}
+
 #endif /* CONFIG_XEN_GUEST */
 #endif /* __X86_GUEST_XEN_H__ */
 
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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