@@ -66,6 +66,21 @@ static void e820_remove_entry(int idx)
e820_map[i] = e820_map[i + 1];
}
+static void e820_insert_entry(int idx)
+{
+ int i;
+
+ if ( e820_entries == E820_MAX )
+ {
+ xprintk("E820 memory map overflow\n");
+ do_exit();
+ }
+
+ e820_entries++;
+ for ( i = e820_entries - 1; i > idx; i-- )
+ e820_map[i] = e820_map[i - 1];
+}
+
static void e820_swap_entries(int idx1, int idx2)
{
struct e820entry entry;
@@ -153,6 +168,63 @@ void arch_print_memmap(void)
printk("%012lx-%012lx: %s\n", from, to, type);
}
}
+
+unsigned long e820_get_reserved_pfns(int pages)
+{
+ int i;
+ unsigned long last = 0, needed = (long)pages << PAGE_SHIFT;
+
+ for ( i = 0; i < e820_entries && e820_map[i].addr < last + needed; i++ )
+ last = e820_map[i].addr + e820_map[i].size;
+
+ if ( i == 0 || e820_map[i - 1].type != E820_RESERVED )
+ {
+ e820_insert_entry(i);
+ e820_map[i].addr = last;
+ e820_map[i].size = needed;
+ e820_map[i].type = E820_RESERVED;
+ }
+ else
+ {
+ e820_map[i - 1].size += needed;
+ }
+
+ return last >> PAGE_SHIFT;
+}
+
+void e820_put_reserved_pfns(unsigned long start_pfn, int pages)
+{
+ int i;
+ unsigned long addr = start_pfn << PAGE_SHIFT;
+ unsigned long size = (long)pages << PAGE_SHIFT;
+
+ for ( i = 0; i < e820_entries && addr < e820_map[i].addr; i++ );
+
+ BUG_ON(i == e820_entries || e820_map[i].type != E820_RESERVED);
+
+ if ( addr == e820_map[i].addr )
+ {
+ e820_map[i].addr += size;
+ e820_map[i].size -= size;
+ if ( e820_map[i].size == 0 )
+ e820_remove_entry(i);
+ return;
+ }
+
+ if ( addr + size == e820_map[i].addr + e820_map[i].size )
+ {
+ e820_map[i].addr = addr;
+ e820_map[i].size = size;
+ return;
+ }
+
+ e820_insert_entry(i + 1);
+ e820_map[i + 1].addr = addr + size;
+ e820_map[i + 1].size = e820_map[i].addr + e820_map[i].size -
+ e820_map[i + 1].addr;
+ e820_map[i + 1].type = E820_RESERVED;
+ e820_map[i].size = addr - e820_map[i].addr;
+}
#endif
unsigned long e820_get_maxpfn(unsigned long pages)
@@ -51,5 +51,9 @@ extern unsigned e820_entries;
unsigned long e820_get_maxpfn(unsigned long pages);
unsigned long e820_get_max_pages(unsigned long pfn, unsigned long pages);
+#ifndef CONFIG_E820_TRIVIAL
+unsigned long e820_get_reserved_pfns(int pages);
+void e820_put_reserved_pfns(unsigned long start_pfn, int pages);
+#endif
#endif /*__E820_HEADER*/
Add two functions for adding reserved areas to the memory map and for removing them again. Those will be needed for proper grant table/mapping support in PVH mode. Signed-off-by: Juergen Gross <jgross@suse.com> --- e820.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/e820.h | 4 +++ 2 files changed, 76 insertions(+)