aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware/hvmloader
diff options
context:
space:
mode:
authorJean Guyader <jean.guyader@eu.citrix.com>2011-11-18 13:42:46 +0000
committerJean Guyader <jean.guyader@eu.citrix.com>2011-11-18 13:42:46 +0000
commite51e2e0e581b91a61835413c3bfa5b46426825f7 (patch)
tree2ff803e5260f0ff933b48de402a22358ee940d88 /tools/firmware/hvmloader
parenta04811a315e059101fa3b3303e75b97eac7c5c95 (diff)
downloadxen-e51e2e0e581b91a61835413c3bfa5b46426825f7.tar.gz
xen-e51e2e0e581b91a61835413c3bfa5b46426825f7.tar.bz2
xen-e51e2e0e581b91a61835413c3bfa5b46426825f7.zip
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@eu.citrix.com> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'tools/firmware/hvmloader')
-rw-r--r--tools/firmware/hvmloader/pci.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/tools/firmware/hvmloader/pci.c b/tools/firmware/hvmloader/pci.c
index 29ec01160b..62aeff2fac 100644
--- a/tools/firmware/hvmloader/pci.c
+++ b/tools/firmware/hvmloader/pci.c
@@ -50,6 +50,7 @@ void pci_setup(void)
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 @@ void pci_setup(void)
((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;