aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2011-11-21 21:28:34 +0000
committerKeir Fraser <keir@xen.org>2011-11-21 21:28:34 +0000
commit5a9a98a7a680012d7259848f1957ad32cdde4e14 (patch)
tree75959c46f9bd0ba16c89a8728323729a8050e854 /tools/firmware
parent74424351709ecedc057583588fc4a64688e63376 (diff)
downloadxen-5a9a98a7a680012d7259848f1957ad32cdde4e14.tar.gz
xen-5a9a98a7a680012d7259848f1957ad32cdde4e14.tar.bz2
xen-5a9a98a7a680012d7259848f1957ad32cdde4e14.zip
hvmloader: Fix memory relocation loop.
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'tools/firmware')
-rw-r--r--tools/firmware/hvmloader/pci.c26
-rw-r--r--tools/firmware/hvmloader/util.h5
2 files changed, 18 insertions, 13 deletions
diff --git a/tools/firmware/hvmloader/pci.c b/tools/firmware/hvmloader/pci.c
index 62aeff2fac..00490f184e 100644
--- a/tools/firmware/hvmloader/pci.c
+++ b/tools/firmware/hvmloader/pci.c
@@ -50,7 +50,6 @@ 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;
@@ -186,25 +185,26 @@ void pci_setup(void)
((pci_mem_start << 1) != 0) )
pci_mem_start <<= 1;
- /* 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)
+ /* Relocate RAM that overlaps PCI space (in 64k-page chunks). */
+ while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
{
struct xen_add_to_physmap xatp;
- unsigned int size = hvm_info->low_mem_pgend - pci_mem_reloc_pg;
+ unsigned int nr_pages = min_t(
+ unsigned int,
+ hvm_info->low_mem_pgend - (pci_mem_start >> PAGE_SHIFT),
+ (1u << 16) - 1);
+ if ( hvm_info->high_mem_pgend == 0 )
+ hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
+ hvm_info->low_mem_pgend -= nr_pages;
xatp.domid = DOMID_SELF;
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;
-
+ xatp.idx = hvm_info->low_mem_pgend;
+ xatp.gpfn = hvm_info->high_mem_pgend;
+ xatp.size = nr_pages;
if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
BUG();
- pci_mem_reloc_pg += size;
- hvm_info->high_mem_pgend += size;
+ hvm_info->high_mem_pgend += nr_pages;
}
- hvm_info->low_mem_pgend = pci_mem_start >> PAGE_SHIFT;
mem_resource.base = pci_mem_start;
mem_resource.max = pci_mem_end;
diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h
index 464cf98f61..ac2b0d33d9 100644
--- a/tools/firmware/hvmloader/util.h
+++ b/tools/firmware/hvmloader/util.h
@@ -31,6 +31,11 @@ void __bug(char *file, int line) __attribute__((noreturn));
#define BUG_ON(p) do { if (p) BUG(); } while (0)
#define BUILD_BUG_ON(p) ((void)sizeof(char[1 - 2 * !!(p)]))
+#define min_t(type,x,y) \
+ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+#define max_t(type,x,y) \
+ ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
+
static inline int test_bit(unsigned int b, void *p)
{
return !!(((uint8_t *)p)[b>>3] & (1u<<(b&7)));