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

[Xen-devel] [PATCH RFC v1 52/74] xen: mark xenstore/console pages as RAM and add them to dom_io



From: Roger Pau Monne <roger.pau@xxxxxxxxxx>

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 xen/arch/x86/e820.c               |  4 +++
 xen/arch/x86/guest/xen.c          | 76 +++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm.c                 |  3 ++
 xen/common/page_alloc.c           | 15 ++++++++
 xen/drivers/char/xen_pv_console.c |  4 +++
 xen/include/asm-x86/guest/xen.h   | 21 +++++++++++
 6 files changed, 123 insertions(+)

diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c
index b422a684ee..590ea985ef 100644
--- a/xen/arch/x86/e820.c
+++ b/xen/arch/x86/e820.c
@@ -9,6 +9,7 @@
 #include <asm/processor.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
+#include <asm/guest.h>
 
 /*
  * opt_mem: Limit maximum address of physical RAM.
@@ -699,6 +700,9 @@ unsigned long __init init_e820(const char *str, struct 
e820map *raw)
 
     machine_specific_memory_setup(raw);
 
+    if ( xen_guest )
+        hypervisor_fixup_e820(&e820);
+
     printk("%s RAM map:\n", str);
     print_e820_memory_map(e820.map, e820.nr_map);
 
diff --git a/xen/arch/x86/guest/xen.c b/xen/arch/x86/guest/xen.c
index 3fa164aba8..b7743e646d 100644
--- a/xen/arch/x86/guest/xen.c
+++ b/xen/arch/x86/guest/xen.c
@@ -29,6 +29,7 @@
 #include <asm/processor.h>
 
 #include <public/arch-x86/cpuid.h>
+#include <public/hvm/params.h>
 
 bool xen_guest;
 
@@ -259,6 +260,81 @@ int hypervisor_free_unused_page(mfn_t mfn)
     return rangeset_remove_range(mem, mfn_x(mfn), mfn_x(mfn));
 }
 
+static void __init mark_pfn_as_ram(struct e820map *e820, uint64_t pfn)
+{
+    if ( !e820_add_range(e820, pfn << PAGE_SHIFT,
+                         (pfn << PAGE_SHIFT) + PAGE_SIZE, E820_RAM) )
+        if ( !e820_change_range_type(e820, pfn << PAGE_SHIFT,
+                                     (pfn << PAGE_SHIFT) + PAGE_SIZE,
+                                     E820_RESERVED, E820_RAM) )
+            panic("Unable to add/change memory type of pfn %#lx to RAM", pfn);
+}
+
+void __init hypervisor_fixup_e820(struct e820map *e820)
+{
+    uint64_t pfn = 0;
+    long rc;
+
+    if ( !xen_guest )
+        return;
+
+#define MARK_PARAM_RAM(p) ({                    \
+    rc = xen_hypercall_hvm_get_param(p, &pfn);  \
+    if ( rc )                                   \
+        panic("Unable to get " #p);             \
+    mark_pfn_as_ram(e820, pfn);                 \
+})
+    MARK_PARAM_RAM(HVM_PARAM_STORE_PFN);
+    if ( !pv_console )
+        MARK_PARAM_RAM(HVM_PARAM_CONSOLE_PFN);
+#undef MARK_PARAM_RAM
+}
+
+void __init hypervisor_init_memory(void)
+{
+    uint64_t pfn = 0;
+    long rc;
+
+    if ( !xen_guest )
+        return;
+
+#define SHARE_PARAM(p) ({                                                   \
+    rc = xen_hypercall_hvm_get_param(p, &pfn);                              \
+    if ( rc )                                                               \
+        panic("Unable to get " #p);                                         \
+    share_xen_page_with_guest(mfn_to_page(pfn), dom_io, XENSHARE_writable); \
+})
+    SHARE_PARAM(HVM_PARAM_STORE_PFN);
+    if ( !pv_console )
+        SHARE_PARAM(HVM_PARAM_CONSOLE_PFN);
+#undef SHARE_PARAM
+}
+
+const unsigned long *__init hypervisor_reserved_pages(unsigned int *size)
+{
+    static unsigned long __initdata reserved_pages[2];
+    uint64_t pfn = 0;
+    long rc;
+
+    if ( !xen_guest )
+        return NULL;
+
+    *size = 0;
+
+#define RESERVE_PARAM(p) ({                             \
+    rc = xen_hypercall_hvm_get_param(p, &pfn);          \
+    if ( rc )                                           \
+        panic("Unable to get " #p);                     \
+    reserved_pages[(*size)++] = pfn << PAGE_SHIFT;      \
+})
+    RESERVE_PARAM(HVM_PARAM_STORE_PFN);
+    if ( !pv_console )
+        RESERVE_PARAM(HVM_PARAM_CONSOLE_PFN);
+#undef RESERVE_PARAM
+
+    return reserved_pages;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 355e6747bb..4332d3bb39 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -298,6 +298,9 @@ void __init arch_init_memory(void)
         share_xen_page_with_guest(mfn_to_page(_mfn(i)),
                                   dom_io, XENSHARE_writable);
 
+    if ( xen_guest )
+        hypervisor_init_memory();
+
     /* Any areas not specified as RAM by the e820 map are considered I/O. */
     for ( i = 0, pfn = 0; pfn < max_page; i++ )
     {
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index c0c2d82906..4de8988bea 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -143,6 +143,7 @@
 #include <asm/numa.h>
 #include <asm/flushtlb.h>
 #ifdef CONFIG_X86
+#include <asm/guest.h>
 #include <asm/p2m.h>
 #include <asm/setup.h> /* for highmem_start only */
 #else
@@ -303,6 +304,20 @@ void __init init_boot_pages(paddr_t ps, paddr_t pe)
             badpage++;
         }
     }
+
+    if ( xen_guest )
+    {
+        badpage = hypervisor_reserved_pages(&array_size);
+        if ( badpage )
+        {
+            for ( i = 0; i < array_size; i++ )
+            {
+                bootmem_region_zap(*badpage >> PAGE_SHIFT,
+                                   (*badpage >> PAGE_SHIFT) + 1);
+                badpage++;
+            }
+        }
+    }
 #endif
 
     /* Check new pages against the bad-page list. */
diff --git a/xen/drivers/char/xen_pv_console.c 
b/xen/drivers/char/xen_pv_console.c
index 2df7d982ba..6aa694e395 100644
--- a/xen/drivers/char/xen_pv_console.c
+++ b/xen/drivers/char/xen_pv_console.c
@@ -35,6 +35,8 @@ static evtchn_port_t cons_evtchn;
 static serial_rx_fn cons_rx_handler;
 static DEFINE_SPINLOCK(tx_lock);
 
+bool pv_console;
+
 void __init pv_console_init(void)
 {
     struct evtchn_unmask unmask;
@@ -64,6 +66,8 @@ void __init pv_console_init(void)
 
     printk("Initialised PV console at 0x%p with pfn %#lx and evtchn %#x\n",
             cons_ring, raw_pfn, cons_evtchn);
+    pv_console = true;
+
     return;
 
  error:
diff --git a/xen/include/asm-x86/guest/xen.h b/xen/include/asm-x86/guest/xen.h
index 7a4d734795..898156d42e 100644
--- a/xen/include/asm-x86/guest/xen.h
+++ b/xen/include/asm-x86/guest/xen.h
@@ -29,16 +29,21 @@
 #ifdef CONFIG_XEN_GUEST
 
 extern bool xen_guest;
+extern bool pv_console;
 
 void probe_hypervisor(void);
 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);
+void hypervisor_fixup_e820(struct e820map *e820);
+void hypervisor_init_memory(void);
+const unsigned long *hypervisor_reserved_pages(unsigned int *size);
 
 #else
 
 #define xen_guest 0
+#define pv_console 0
 
 static inline void probe_hypervisor(void) {};
 
@@ -65,6 +70,22 @@ static inline int hypervisor_free_unused_page(mfn_t mfn)
     return 0;
 }
 
+static inline void hypervisor_fixup_e820(struct e820map *e820)
+{
+    ASSERT_UNREACHABLE();
+}
+
+static inline void hypervisor_init_memory(void)
+{
+    ASSERT_UNREACHABLE();
+}
+
+static inline const unsigned long *hypervisor_reserved_pages(unsigned int 
*size)
+{
+    ASSERT_UNREACHABLE();
+    return NULL;
+};
+
 #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®.