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

[Xen-changelog] [xen-unstable] hvmloader: Change memory relocation loop when overlap with PCI hole



# HG changeset patch
# User Jean Guyader <jean.guyader@xxxxxxxxxxxxx>
# Date 1321623766 0
# Node ID 89a4d97731c58db2790f63dd687edc537e7ce2b8
# Parent  707d27fe03e7e3b331d804c4743ae7534a9c3043
hvmloader: Change memory relocation loop when overlap with PCI hole

Change the way we relocate the memory page if they overlap with pci
hole.  Use new map space (XENMAPSPACE_gmfn_range) to move the loop
into xen.

This code usually get triggered when a device is pass through to a
guest and the PCI hole has to be extended to have enough room to map
the device BARs.  The PCI hole will starts lower and it might overlap
with some RAM that has been alocated for the guest. That usually
happen if the guest has more than 4G of RAM.  We have to relocate
those pages in high mem otherwise they won't be accessible.

Signed-off-by: Jean Guyader <jean.guyader@xxxxxxxxxxxxx>
Committed-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 707d27fe03e7 -r 89a4d97731c5 tools/firmware/hvmloader/pci.c
--- a/tools/firmware/hvmloader/pci.c    Fri Nov 18 13:42:08 2011 +0000
+++ b/tools/firmware/hvmloader/pci.c    Fri Nov 18 13:42:46 2011 +0000
@@ -50,6 +50,7 @@
         uint32_t devfn, bar_reg, bar_sz;
     } *bars = (struct bars *)scratch_start;
     unsigned int i, nr_bars = 0;
+    unsigned long pci_mem_reloc_pg;
 
     /* Program PCI-ISA bridge with appropriate link routes. */
     isa_irq = 0;
@@ -185,18 +186,25 @@
             ((pci_mem_start << 1) != 0) )
         pci_mem_start <<= 1;
 
-    while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
+    /* Relocate RAM that overlaps (in 64K chunks) */
+    pci_mem_reloc_pg = (pci_mem_start >> PAGE_SHIFT);
+    while (pci_mem_reloc_pg < hvm_info->low_mem_pgend)
     {
         struct xen_add_to_physmap xatp;
-        if ( hvm_info->high_mem_pgend == 0 )
-            hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
+        unsigned int size = hvm_info->low_mem_pgend - pci_mem_reloc_pg;
         xatp.domid = DOMID_SELF;
-        xatp.space = XENMAPSPACE_gmfn;
-        xatp.idx   = --hvm_info->low_mem_pgend;
-        xatp.gpfn  = hvm_info->high_mem_pgend++;
+        xatp.space = XENMAPSPACE_gmfn_range;
+        xatp.idx = pci_mem_reloc_pg;
+        xatp.gpfn = hvm_info->high_mem_pgend;
+        size = size > ((1 << 16) - 1) ? ((1 << 16) - 1) : size;
+        xatp.size = size;
+
         if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
             BUG();
+        pci_mem_reloc_pg += size;
+        hvm_info->high_mem_pgend += size;
     }
+    hvm_info->low_mem_pgend = pci_mem_start >> PAGE_SHIFT;
 
     mem_resource.base = pci_mem_start;
     mem_resource.max = pci_mem_end;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
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®.