diff mbox series

[06/10] mini-os: add memory map service functions

Message ID 20211206072337.9517-7-jgross@suse.com (mailing list archive)
State Superseded
Headers show
Series mini-os: add missing PVH features | expand

Commit Message

Juergen Gross Dec. 6, 2021, 7:23 a.m. UTC
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(+)

Comments

Samuel Thibault Dec. 12, 2021, 12:37 a.m. UTC | #1
Juergen Gross, le lun. 06 déc. 2021 08:23:33 +0100, a ecrit:
> +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++ );

Shouldn't that be addr > e820_map[i].addr + e820_map[i].size?

> +    BUG_ON(i == e820_entries || e820_map[i].type != E820_RESERVED);

We should also BUG_ON e820_map[i].addr > addr (i.e. we didn't find an
entry that contained our address).

> +    if ( addr == e820_map[i].addr )
> +    {
> +        e820_map[i].addr += size;

I'd say BUG_ON here if e820_map[i].size < 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;

? Shouldn't that rather be just

> +        e820_map[i].size -= size;

? (since what we remove is at the end of the area, the start of the area
doesn't change)

> +        return;
> +    }
diff mbox series

Patch

diff --git a/e820.c b/e820.c
index 50029bb..2888932 100644
--- a/e820.c
+++ b/e820.c
@@ -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)
diff --git a/include/e820.h b/include/e820.h
index 49daefa..694ce3b 100644
--- a/include/e820.h
+++ b/include/e820.h
@@ -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*/