WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] hvmloader: Reserve BIOS memory and VGA me

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvmloader: Reserve BIOS memory and VGA memory at top of 4GB memory hole.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 16 Jan 2009 02:50:32 -0800
Delivery-date: Fri, 16 Jan 2009 02:52:13 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1231433961 0
# Node ID 67ffce500feb0c815404b5d25ab8ff9472c8e9e3
# Parent  61dc77689daf1f9d2697c93f10decb57e8f57f7e
hvmloader: Reserve BIOS memory and VGA memory at top of 4GB memory hole.

To make memory management easier in hvmloader, defer building a
generic E820 map until the end of hvmloader bootstrap.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/firmware/hvmloader/32bitbios_support.c |    2 
 tools/firmware/hvmloader/acpi/build.c        |   11 +--
 tools/firmware/hvmloader/config.h            |    4 +
 tools/firmware/hvmloader/hvmloader.c         |   52 +++++---------
 tools/firmware/hvmloader/smbios.c            |   22 +-----
 tools/firmware/hvmloader/util.c              |   99 +++++++++++++--------------
 tools/firmware/hvmloader/util.h              |    5 -
 7 files changed, 89 insertions(+), 106 deletions(-)

diff -r 61dc77689daf -r 67ffce500feb 
tools/firmware/hvmloader/32bitbios_support.c
--- a/tools/firmware/hvmloader/32bitbios_support.c      Thu Jan 08 16:53:15 
2009 +0000
+++ b/tools/firmware/hvmloader/32bitbios_support.c      Thu Jan 08 16:59:21 
2009 +0000
@@ -76,7 +76,7 @@ static void relocate_32bitbios(char *elf
      */
     reloc_size = reloc_off;
     printf("%d bytes of ROMBIOS high-memory extensions:\n", reloc_size);
-    highbiosarea = (char *)(long)e820_malloc(reloc_size, 0);
+    highbiosarea = mem_alloc(reloc_size, 0);
     BUG_ON(highbiosarea == NULL);
     printf("  Relocating to 0x%x-0x%x ... ",
            (uint32_t)&highbiosarea[0],
diff -r 61dc77689daf -r 67ffce500feb tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Thu Jan 08 16:53:15 2009 +0000
+++ b/tools/firmware/hvmloader/acpi/build.c     Thu Jan 08 16:59:21 2009 +0000
@@ -199,6 +199,7 @@ static int construct_secondary_tables(ui
     struct acpi_20_tcpa *tcpa;
     static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};
     uint16_t *tis_hdr;
+    void *lasa;
 
     /* MADT. */
     if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
@@ -246,11 +247,11 @@ static int construct_secondary_tables(ui
         tcpa->header.oem_revision = ACPI_OEM_REVISION;
         tcpa->header.creator_id   = ACPI_CREATOR_ID;
         tcpa->header.creator_revision = ACPI_CREATOR_REVISION;
-        tcpa->lasa = e820_malloc(ACPI_2_0_TCPA_LAML_SIZE, 0);
-        if ( tcpa->lasa )
-        {
+        if ( (lasa = mem_alloc(ACPI_2_0_TCPA_LAML_SIZE, 0)) != NULL )
+        {
+            tcpa->lasa = virt_to_phys(lasa);
             tcpa->laml = ACPI_2_0_TCPA_LAML_SIZE;
-            memset((char *)(unsigned long)tcpa->lasa, 0, tcpa->laml);
+            memset(lasa, 0, tcpa->laml);
             set_checksum(tcpa,
                          offsetof(struct acpi_header, checksum),
                          tcpa->header.length);
@@ -376,7 +377,7 @@ void acpi_build_tables(void)
     memset(buf, 0, high_sz);
 
     /* Allocate data area and set up ACPI tables there. */
-    buf = (uint8_t *)e820_malloc(high_sz, 0);
+    buf = mem_alloc(high_sz, 0);
     __acpi_build_tables(buf, &low_sz, &high_sz);
 
     printf(" - Lo data: %08lx-%08lx\n"
diff -r 61dc77689daf -r 67ffce500feb tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Thu Jan 08 16:53:15 2009 +0000
+++ b/tools/firmware/hvmloader/config.h Thu Jan 08 16:59:21 2009 +0000
@@ -16,6 +16,10 @@
 
 #define PCI_MEMBASE         0xf0000000
 #define PCI_MEMSIZE         0x0c000000
+
+/* We reserve 16MB at the top of the 4GB memory hole. */
+#define RESERVED_MEMBASE    0xff000000
+#define RESERVED_MEMSIZE    0x01000000
 
 #define ROMBIOS_SEG            0xF000
 #define ROMBIOS_BEGIN          0x000F0000
diff -r 61dc77689daf -r 67ffce500feb tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Thu Jan 08 16:53:15 2009 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c      Thu Jan 08 16:59:21 2009 +0000
@@ -488,22 +488,13 @@ static int pci_load_option_roms(uint32_t
 /* Replace possibly erroneous memory-size CMOS fields with correct values. */
 static void cmos_write_memory_size(void)
 {
-    struct e820entry *map = E820;
-    int i, nr = *E820_NR;
-    uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0;
-
-    for ( i = 0; i < nr; i++ )
-        if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) )
-            break;
-
-    if ( i != nr )
-    {
-        alt_mem = ext_mem = map[i].addr + map[i].size;
-        ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
-        if ( ext_mem > 0xffff )
-            ext_mem = 0xffff;
-        alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
-    }
+    uint32_t base_mem = 640, ext_mem, alt_mem;
+
+    alt_mem = ext_mem = hvm_info->low_mem_pgend << PAGE_SHIFT;
+    ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
+    if ( ext_mem > 0xffff )
+        ext_mem = 0xffff;
+    alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
 
     /* All BIOSes: conventional memory (CMOS *always* reports 640kB). */
     cmos_outb(0x15, (uint8_t)(base_mem >> 0));
@@ -548,16 +539,16 @@ static uint16_t init_xen_platform_io_bas
  */
 static void init_vm86_tss(void)
 {
-    uint32_t tss;
+    void *tss;
     struct xen_hvm_param p;
 
-    tss = e820_malloc(128, 128);
-    memset((char *)tss, 0, 128);
+    tss = mem_alloc(128, 128);
+    memset(tss, 0, 128);
     p.domid = DOMID_SELF;
     p.index = HVM_PARAM_VM86_TSS;
-    p.value = tss;
+    p.value = virt_to_phys(tss);
     hypercall_hvm_op(HVMOP_set_param, &p);
-    printf("vm86 TSS at %08x\n", tss);
+    printf("vm86 TSS at %08lx\n", virt_to_phys(tss));
 }
 
 /* Create an E820 table based on memory parameters provided in hvm_info. */
@@ -603,14 +594,11 @@ static void build_e820_table(void)
     e820[nr].type = E820_RAM;
     nr++;
 
-    if ( hvm_info->reserved_mem_pgstart )
-    {
-        /* Explicitly reserve space for special pages. */
-        e820[nr].addr = hvm_info->reserved_mem_pgstart << PAGE_SHIFT;
-        e820[nr].size = (uint32_t)-e820[nr].addr;
-        e820[nr].type = E820_RESERVED;
-        nr++;
-    }
+    /* Explicitly reserve space for special pages. */
+    e820[nr].addr = RESERVED_MEMBASE;
+    e820[nr].size = (uint32_t)-e820[nr].addr;
+    e820[nr].type = E820_RESERVED;
+    nr++;
 
     if ( hvm_info->high_mem_pgend )
     {
@@ -632,8 +620,6 @@ int main(void)
     uint16_t xen_pfiob;
 
     printf("HVM Loader\n");
-
-    build_e820_table();
 
     init_hypercalls();
 
@@ -680,7 +666,7 @@ int main(void)
 
     if ( virtual_vga != VGA_none )
     {
-        vga_ram = e820_malloc(8 << 20, 4096);
+        vga_ram = virt_to_phys(mem_alloc(8 << 20, 4096));
         printf("VGA RAM at %08x\n", vga_ram);
     }
 
@@ -728,6 +714,8 @@ int main(void)
     if ( xen_pfiob && vga_ram )
         outl(xen_pfiob + 4, vga_ram);
 
+    build_e820_table();
+
     printf("Invoking ROMBIOS ...\n");
     return 0;
 }
diff -r 61dc77689daf -r 67ffce500feb tools/firmware/hvmloader/smbios.c
--- a/tools/firmware/hvmloader/smbios.c Thu Jan 08 16:53:15 2009 +0000
+++ b/tools/firmware/hvmloader/smbios.c Thu Jan 08 16:59:21 2009 +0000
@@ -143,28 +143,18 @@ static uint64_t
 static uint64_t
 get_memsize(void)
 {
-    struct e820entry *map = E820;
-    uint8_t num_entries = *E820_NR;
-    uint64_t memsize = 0;
-    int i;
-
-    /*
-     * Walk through e820map, ignoring any entries that aren't marked
-     * as usable or reserved.
-     */
-    for ( i = 0; i < num_entries; i++ )
-    {
-        if ( (map->type == E820_RAM) || (map->type == E820_RESERVED) )
-            memsize += map->size;
-        map++;
-    }
+    uint64_t sz;
+
+    sz = (uint64_t)hvm_info->low_mem_pgend << PAGE_SHIFT;
+    if ( hvm_info->high_mem_pgend )
+        sz += (hvm_info->high_mem_pgend << PAGE_SHIFT) - (1ull << 32);
 
     /*
      * Round up to the nearest MB.  The user specifies domU pseudo-physical 
      * memory in megabytes, so not doing this could easily lead to reporting 
      * one less MB than the user specified.
      */
-    return (memsize + (1 << 20) - 1) >> 20;
+    return (sz + (1ul << 20) - 1) >> 20;
 }
 
 int
diff -r 61dc77689daf -r 67ffce500feb tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c   Thu Jan 08 16:53:15 2009 +0000
+++ b/tools/firmware/hvmloader/util.c   Thu Jan 08 16:59:21 2009 +0000
@@ -303,63 +303,62 @@ uuid_to_string(char *dest, uint8_t *uuid
     *p = '\0';
 }
 
-static void e820_collapse(void)
-{
-    int i = 0;
-    struct e820entry *ent = E820;
-
-    while ( i < (*E820_NR-1) )
-    {
-        if ( (ent[i].type == ent[i+1].type) &&
-             ((ent[i].addr + ent[i].size) == ent[i+1].addr) )
-        {
-            ent[i].size += ent[i+1].size;
-            memcpy(&ent[i+1], &ent[i+2], (*E820_NR-i-2) * sizeof(*ent));
-            (*E820_NR)--;
-        }
-        else
-        {
-            i++;
-        }
-    }
-}
-
-uint32_t e820_malloc(uint32_t size, uint32_t align)
-{
-    uint32_t addr;
-    int i;
-    struct e820entry *ent = E820;
+void *mem_alloc(uint32_t size, uint32_t align)
+{
+    static uint32_t reserve = RESERVED_MEMBASE - 1;
+    static int over_allocated;
+    struct xen_memory_reservation xmr;
+    xen_pfn_t mfn;
+    uint32_t s, e;
 
     /* Align to at least one kilobyte. */
     if ( align < 1024 )
         align = 1024;
 
-    for ( i = *E820_NR - 1; i >= 0; i-- )
-    {
-        addr = (ent[i].addr + ent[i].size - size) & ~(align-1);
-        if ( (ent[i].type != E820_RAM) || /* not ram? */
-             (addr < ent[i].addr) ||      /* too small or starts above 4gb? */
-             ((addr + size) < addr) )     /* ends above 4gb? */
+    s = (reserve + align) & ~(align - 1);
+    e = s + size - 1;
+
+    BUG_ON((e < s) || (e >> PAGE_SHIFT) >= hvm_info->reserved_mem_pgstart);
+
+    while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) )
+    {
+        reserve += PAGE_SIZE;
+
+        /* Try to allocate another page in the reserved area. */
+        xmr.domid = DOMID_SELF;
+        xmr.mem_flags = 0;
+        xmr.extent_order = 0;
+        xmr.nr_extents = 1;
+        set_xen_guest_handle(xmr.extent_start, &mfn);
+        mfn = reserve >> PAGE_SHIFT;
+        if ( !over_allocated &&
+             (hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1) )
             continue;
 
-        if ( addr != ent[i].addr )
-        {
-            memmove(&ent[i+1], &ent[i], (*E820_NR-i) * sizeof(*ent));
-            (*E820_NR)++;
-            ent[i].size = addr - ent[i].addr;
-            ent[i+1].addr = addr;
-            ent[i+1].size -= ent[i].size;
-            i++;
-        }
-
-        ent[i].type = E820_RESERVED;
-
-        e820_collapse();
-
-        return addr;
-    }
-
-    return 0;
+        /* If we fail, steal a page from the ordinary RAM map. */
+        over_allocated = 1;
+        if ( hvm_info->high_mem_pgend )
+        {
+            mfn = --hvm_info->high_mem_pgend;
+            if ( mfn == (1ull << (32 - PAGE_SHIFT)) )
+                hvm_info->high_mem_pgend = 0;
+        }
+        else
+        {
+            mfn = --hvm_info->low_mem_pgend;
+        }
+        if ( hypercall_memory_op(XENMEM_decrease_reservation, &xmr) != 1 )
+            BUG();
+
+        /* Now try the allocation again. Must not fail. */
+        mfn = reserve >> PAGE_SHIFT;
+        if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) != 1 )
+            BUG();
+    }
+
+    reserve = e;
+
+    return (void *)(unsigned long)s;
 }
 
 uint32_t ioapic_read(uint32_t reg)
diff -r 61dc77689daf -r 67ffce500feb tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h   Thu Jan 08 16:53:15 2009 +0000
+++ b/tools/firmware/hvmloader/util.h   Thu Jan 08 16:59:21 2009 +0000
@@ -131,8 +131,9 @@ int printf(const char *fmt, ...) __attri
 int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
 int vprintf(const char *fmt, va_list ap);
 
-/* Reserve a RAM region in the e820 table. */
-uint32_t e820_malloc(uint32_t size, uint32_t align);
+/* Allocate memory in a reserved region below 4GB. */
+void *mem_alloc(uint32_t size, uint32_t align);
+#define virt_to_phys(v) ((unsigned long)(v))
 
 /* Prepare the 32bit BIOS */
 void highbios_setup(void);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] hvmloader: Reserve BIOS memory and VGA memory at top of 4GB memory hole., Xen patchbot-unstable <=