/*
* Craft the e820 memory map for Dom0 based on the hardware e820 map.
+ * Add an extra entry in case we have to split a RAM entry into a RAM and a
+ * UNUSABLE one in order to truncate it.
*/
- d->arch.e820 = xzalloc_array(struct e820entry, e820.nr_map);
+ d->arch.e820 = xzalloc_array(struct e820entry, e820.nr_map + 1);
if ( !d->arch.e820 )
panic("Unable to allocate memory for Dom0 e820 map");
entry_guest = d->arch.e820;
/* Clamp e820 memory map to match the memory assigned to Dom0 */
for ( i = 0, entry = e820.map; i < e820.nr_map; i++, entry++ )
{
+ *entry_guest = *entry;
+
if ( entry->type != E820_RAM )
- {
- *entry_guest = *entry;
goto next;
- }
if ( nr_pages == cur_pages )
{
/*
- * We already have all the assigned memory,
- * skip this entry
+ * We already have all the requested memory, turn this RAM region
+ * into a UNUSABLE region in order to prevent Dom0 from placing
+ * BARs in this area.
*/
- continue;
+ entry_guest->type = E820_UNUSABLE;
+ goto next;
}
/*
{
/* Truncate region */
entry_guest->size = (nr_pages - cur_pages) << PAGE_SHIFT;
+ /* Add the remaining of the RAM region as UNUSABLE. */
+ entry_guest++;
+ d->arch.nr_e820++;
+ entry_guest->type = E820_UNUSABLE;
+ entry_guest->addr = start + ((nr_pages - cur_pages) << PAGE_SHIFT);
+ entry_guest->size = end - entry_guest->addr;
cur_pages = nr_pages;
}
else
next:
d->arch.nr_e820++;
entry_guest++;
+ ASSERT(d->arch.nr_e820 <= e820.nr_map + 1);
}
ASSERT(cur_pages == nr_pages);
- ASSERT(d->arch.nr_e820 <= e820.nr_map);
}
static int __init pvh_setup_p2m(struct domain *d)