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

[Xen-devel] [v7][RFC][PATCH 03/13] tools/libxc: check if modules space is overlapping with reserved device memory



In case of reserved device memory overlapping with ram, it also probably
overlap with modules space so we need to check these reserved device
memory as well.

Signed-off-by: Tiejun Chen <tiejun.chen@xxxxxxxxx>
---
 tools/libxc/xc_hvm_build_x86.c | 111 +++++++++++++++++++++++++++++++++++------
 1 file changed, 96 insertions(+), 15 deletions(-)

diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
index c81a25b..cb590ee 100644
--- a/tools/libxc/xc_hvm_build_x86.c
+++ b/tools/libxc/xc_hvm_build_x86.c
@@ -54,9 +54,99 @@
 
 #define VGA_HOLE_SIZE (0x20)
 
+/* Record reserved device memory. */
+static struct xen_mem_reserved_device_memory *xmrdm = NULL;
+
+/*
+ * Check whether there exists mmio hole in the specified memory range.
+ * Returns 1 if exists, else returns 0.
+ */
+static int check_mmio_hole(uint64_t start, uint64_t memsize,
+                           uint64_t mmio_start, uint64_t mmio_size)
+{
+    if ( start + memsize <= mmio_start || start >= mmio_start + mmio_size )
+        return 0;
+    else
+        return 1;
+}
+
+/* Getting all reserved device memory map info. */
+static int xc_get_reserved_device_memory_map(xc_interface *xch)
+{
+    static uint32_t nr_entries = 0;
+    int rc = 0;
+
+    if ( !xmrdm )
+    {
+        /* Assume we have one entry if not enough we'll expand.*/
+        nr_entries = 1;
+        if ( (xmrdm = malloc(nr_entries *
+                             sizeof(xen_mem_reserved_device_memory_t))) == 
NULL )
+        {
+            PERROR("Could not allocate memory for map.");
+            return -1;
+        }
+
+        rc = xc_reserved_device_memory_map(xch, xmrdm, &nr_entries);
+        if ( rc < 0 )
+        {
+            switch ( errno )
+            {
+            case ENOENT: /* reserved device memory doesn't exist. */
+                rc = 0;
+                break;
+            case ENOBUFS: /* Need more space */
+                free(xmrdm);
+                /* Now we need more space to map all reserved device memory 
maps. */
+                if ( (xmrdm = malloc(nr_entries *
+                                     
sizeof(xen_mem_reserved_device_memory_t))) == NULL )
+                {
+                    PERROR("Could not allocate memory.");
+                    return -1;
+                }
+                rc = xc_reserved_device_memory_map(xch, xmrdm, &nr_entries);
+                if ( rc )
+                {
+                    PERROR("Could not get reserved device memory maps.");
+                    free(xmrdm);
+                    return rc;
+                }
+                break;
+            default: /* Failed to get reserved device memory maps. */
+                PERROR("Could not get reserved device memory maps.");
+                return rc;
+            }
+        }
+    }
+
+    return nr_entries;
+}
+
+static int xc_check_modules_space(xc_interface *xch, uint64_t *mstart_out,
+                                  uint64_t *mend_out)
+{
+    unsigned int i = 0;
+    uint64_t rdm_start = 0, rdm_end = 0;
+    int nr_entries = xc_get_reserved_device_memory_map(xch);
+
+    for ( i = 0; i < nr_entries; i++ )
+    {
+        rdm_start = xmrdm[i].start_pfn << XC_PAGE_SHIFT;
+        rdm_end = rdm_start + (xmrdm[i].nr_pages << XC_PAGE_SHIFT);
+
+        /* Just use check_mmio_hole() to check modules ranges. */
+        if ( check_mmio_hole(rdm_start, xmrdm[i].nr_pages << XC_PAGE_SHIFT,
+                             *mstart_out, *mend_out) )
+            return -1;
+    }
+
+    return 0;
+}
+
 static int modules_init(struct xc_hvm_build_args *args,
                         uint64_t vend, struct elf_binary *elf,
-                        uint64_t *mstart_out, uint64_t *mend_out)
+                        uint64_t *mstart_out, uint64_t *mend_out,
+                        xc_interface *xch)
 {
 #define MODULE_ALIGN 1UL << 7
 #define MB_ALIGN     1UL << 20
@@ -80,6 +170,10 @@ static int modules_init(struct xc_hvm_build_args *args,
     if ( *mend_out > vend )    
         return -1;
 
+    /* Is it overlapping with reserved device memory? */
+    if ( xc_check_modules_space(xch, mstart_out, mend_out) )
+        return -1;
+
     if ( args->acpi_module.length != 0 )
         args->acpi_module.guest_addr_out = *mstart_out;
     if ( args->smbios_module.length != 0 )
@@ -226,19 +320,6 @@ static int loadmodules(xc_interface *xch,
     return rc;
 }
 
-/*
- * Check whether there exists mmio hole in the specified memory range.
- * Returns 1 if exists, else returns 0.
- */
-static int check_mmio_hole(uint64_t start, uint64_t memsize,
-                           uint64_t mmio_start, uint64_t mmio_size)
-{
-    if ( start + memsize <= mmio_start || start >= mmio_start + mmio_size )
-        return 0;
-    else
-        return 1;
-}
-
 static int setup_guest(xc_interface *xch,
                        uint32_t dom, struct xc_hvm_build_args *args,
                        char *image, unsigned long image_size)
@@ -282,7 +363,7 @@ static int setup_guest(xc_interface *xch,
         goto error_out;
     }
 
-    if ( modules_init(args, v_end, &elf, &m_start, &m_end) != 0 )
+    if ( modules_init(args, v_end, &elf, &m_start, &m_end, xch) != 0 )
     {
         ERROR("Insufficient space to load modules.");
         goto error_out;
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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