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

[Xen-changelog] [xen-unstable] libxc: add MMIO hole size parameter to xc_hvm_build()



# HG changeset patch
# User David Vrabel <david.vrabel@xxxxxxxxxx>
# Date 1330615088 0
# Node ID d21b8aabe2954798034eabc563f0bdecfaaa17fe
# Parent  7e1fd8012ca3e5b091b2597aca3377af51feacb3
libxc: add MMIO hole size parameter to xc_hvm_build()

Add a parameter for the MMIO hole size when building a HVM domain.

This is useful for specifying a larger than normal MMIO hole to ensure
that no PCIe device's MMIO region overlaps with RAM in a guest's
physical address space.  This is needed on certain systems with PCIe
switches with a broken ACS capability.  On these systems, if a device
downstream of the switch attempts a DMA to a guest physical address
that overlaps with the MMIO region of another downstream device, then
the switch routes the transfer directly to the device and the read or
write never hits RAM.

Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx>
Acked-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
Committed-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---


diff -r 7e1fd8012ca3 -r d21b8aabe295 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Thu Mar 01 15:16:22 2012 +0000
+++ b/tools/libxc/xc_hvm_build.c        Thu Mar 01 15:18:08 2012 +0000
@@ -46,7 +46,8 @@
 #define NR_SPECIAL_PAGES     5
 #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
 
-static void build_hvm_info(void *hvm_info_page, uint64_t mem_size)
+static void build_hvm_info(void *hvm_info_page, uint64_t mem_size,
+                           uint64_t mmio_start, uint64_t mmio_size)
 {
     struct hvm_info_table *hvm_info = (struct hvm_info_table *)
         (((unsigned char *)hvm_info_page) + HVM_INFO_OFFSET);
@@ -54,10 +55,10 @@
     uint8_t sum;
     int i;
 
-    if ( lowmem_end > HVM_BELOW_4G_RAM_END )
+    if ( lowmem_end > mmio_start )
     {
-        highmem_end = lowmem_end + (1ull<<32) - HVM_BELOW_4G_RAM_END;
-        lowmem_end = HVM_BELOW_4G_RAM_END;
+        highmem_end = (1ull<<32) + (lowmem_end - mmio_start);
+        lowmem_end = mmio_start;
     }
 
     memset(hvm_info_page, 0, PAGE_SIZE);
@@ -126,10 +127,10 @@
  * 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)
+static int check_mmio_hole(uint64_t start, uint64_t memsize,
+                           uint64_t mmio_start, uint64_t mmio_size)
 {
-    if ( start + memsize <= HVM_BELOW_4G_MMIO_START ||
-         start >= HVM_BELOW_4G_MMIO_START + HVM_BELOW_4G_MMIO_LENGTH )
+    if ( start + memsize <= mmio_start || start >= mmio_start + mmio_size )
         return 0;
     else
         return 1;
@@ -142,6 +143,8 @@
     xen_pfn_t *page_array = NULL;
     unsigned long i, nr_pages = args->mem_size >> PAGE_SHIFT;
     unsigned long target_pages = args->mem_target >> PAGE_SHIFT;
+    uint64_t mmio_start = (1ull << 32) - args->mmio_size;
+    uint64_t mmio_size = args->mmio_size;
     unsigned long entry_eip, cur_pages, cur_pfn;
     void *hvm_info_page;
     uint32_t *ident_pt;
@@ -188,8 +191,8 @@
 
     for ( i = 0; i < nr_pages; i++ )
         page_array[i] = i;
-    for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < nr_pages; i++ )
-        page_array[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
+    for ( i = mmio_start >> PAGE_SHIFT; i < nr_pages; i++ )
+        page_array[i] += mmio_size >> PAGE_SHIFT;
 
     /*
      * Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000.
@@ -230,7 +233,8 @@
         if ( ((count | cur_pfn) & (SUPERPAGE_1GB_NR_PFNS - 1)) == 0 &&
              /* Check if there exists MMIO hole in the 1GB memory range */
              !check_mmio_hole(cur_pfn << PAGE_SHIFT,
-                              SUPERPAGE_1GB_NR_PFNS << PAGE_SHIFT) )
+                              SUPERPAGE_1GB_NR_PFNS << PAGE_SHIFT,
+                              mmio_start, mmio_size) )
         {
             long done;
             unsigned long nr_extents = count >> SUPERPAGE_1GB_SHIFT;
@@ -327,7 +331,7 @@
               xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
               HVM_INFO_PFN)) == NULL )
         goto error_out;
-    build_hvm_info(hvm_info_page, v_end);
+    build_hvm_info(hvm_info_page, v_end, mmio_start, mmio_size);
     munmap(hvm_info_page, PAGE_SIZE);
 
     /* Allocate and clear special pages. */
@@ -408,6 +412,9 @@
     if ( args.mem_target == 0 )
         args.mem_target = args.mem_size;
 
+    if ( args.mmio_size == 0 )
+        args.mmio_size = HVM_BELOW_4G_MMIO_LENGTH;
+
     /* An HVM guest must be initialised with at least 2MB memory. */
     if ( args.mem_size < (2ull << 20) || args.mem_target < (2ull << 20) )
         return -1;
diff -r 7e1fd8012ca3 -r d21b8aabe295 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Thu Mar 01 15:16:22 2012 +0000
+++ b/tools/libxc/xenguest.h    Thu Mar 01 15:18:08 2012 +0000
@@ -174,6 +174,7 @@
 struct xc_hvm_build_args {
     uint64_t mem_size;           /* Memory size in bytes. */
     uint64_t mem_target;         /* Memory target in bytes. */
+    uint64_t mmio_size;          /* Size of the MMIO hole in bytes. */
     const char *image_file_name; /* File name of the image to load. */
 };
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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