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] [IA64] memmap: introduce memmap_info_t

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] memmap: introduce memmap_info_t
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 16 Jun 2007 05:31:11 -0700
Delivery-date: Sat, 16 Jun 2007 05:29:39 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 Alex Williamson <alex.williamson@xxxxxx>
# Date 1179763831 21600
# Node ID c2768258711da6dadd021a5aad883fff949e255d
# Parent  caafa45d24b3cbf05ab97ab33235e5b91ac44323
[IA64] memmap: introduce memmap_info_t

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
 tools/libxc/xc_dom_ia64.c      |   64 +++++++++++
 xen/arch/ia64/xen/dom_fw.c     |  223 ++++++++++++++++++++++++++++++++++++++---
 xen/include/public/arch-ia64.h |    7 +
 3 files changed, 279 insertions(+), 15 deletions(-)

diff -r caafa45d24b3 -r c2768258711d tools/libxc/xc_dom_ia64.c
--- a/tools/libxc/xc_dom_ia64.c Mon May 21 10:09:33 2007 -0600
+++ b/tools/libxc/xc_dom_ia64.c Mon May 21 10:10:31 2007 -0600
@@ -77,6 +77,8 @@ static int shared_info_ia64(struct xc_do
     for (i = 0; i < MAX_VIRT_CPUS; i++)
         shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
     shared_info->arch.start_info_pfn = dom->start_info_pfn;
+    shared_info->arch.memmap_info_num_pages = 1;
+    shared_info->arch.memmap_info_pfn = dom->start_info_pfn - 1;
     return 0;
 }
 
@@ -129,6 +131,8 @@ static void __init register_arch_hooks(v
     xc_dom_register_arch_hooks(&xc_dom_arch_ia64be);
 }
 
+#include "xc_efi.h"
+
 int arch_setup_meminit(struct xc_dom_image *dom)
 {
     xen_pfn_t pfn;
@@ -146,12 +150,69 @@ int arch_setup_meminit(struct xc_dom_ima
     return rc;
 }
 
+static int ia64_setup_memmap(struct xc_dom_image *dom)
+{
+    unsigned int page_size = XC_DOM_PAGE_SIZE(dom);
+    unsigned long memmap_info_pfn;
+    xen_ia64_memmap_info_t* memmap_info;
+    unsigned int num_mds;
+    efi_memory_desc_t *md;
+
+    char* start_info;
+    struct xen_ia64_boot_param* bp;
+
+    /* setup memmap page */
+    memmap_info_pfn = dom->start_info_pfn - 1;
+    xc_dom_printf("%s: memmap: mfn 0x%" PRIpfn "\n",
+                 __FUNCTION__, memmap_info_pfn);
+    memmap_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
+                                       page_size,
+                                       PROT_READ | PROT_WRITE,
+                                       memmap_info_pfn);
+    if (NULL == memmap_info)
+        return -1;
+    /* [0, total_pages) */
+    memmap_info->efi_memdesc_size = sizeof(md[0]);
+    memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
+    num_mds = 0;
+    md = (efi_memory_desc_t*)&memmap_info->memdesc;
+    md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
+    md[num_mds].pad = 0;
+    md[num_mds].phys_addr = 0;
+    md[num_mds].virt_addr = 0;
+    md[num_mds].num_pages = dom->total_pages << (PAGE_SHIFT - EFI_PAGE_SHIFT);
+    md[num_mds].attribute = EFI_MEMORY_WB;
+    num_mds++;
+    memmap_info->efi_memmap_size = num_mds * sizeof(md[0]);
+    munmap(memmap_info, page_size);
+
+    /* kludge: we need to pass memmap_info page's pfn somehow.
+     * we use xen_ia64_boot_param::efi_memmap for this purpose */
+    start_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
+                                     page_size,
+                                     PROT_READ | PROT_WRITE,
+                                     dom->start_info_pfn);
+    if (NULL == start_info)
+        return -1;
+    bp = (struct xen_ia64_boot_param*)(start_info + sizeof(start_info_t));
+    memset(bp, 0, sizeof(*bp));
+    bp->efi_memmap = memmap_info_pfn;
+    /* 4 = memmap info page, start info page, xenstore page and console page */
+    bp->efi_memmap_size = 4 * PAGE_SIZE;
+    munmap(start_info, page_size);
+    return 0;
+}
+
 int arch_setup_bootearly(struct xc_dom_image *dom)
 {
     DECLARE_DOMCTL;
     int rc;
 
     xc_dom_printf("%s: setup firmware\n", __FUNCTION__);
+
+    rc = ia64_setup_memmap(dom);
+    if (rc)
+        return rc;
 
     memset(&domctl, 0, sizeof(domctl));
     domctl.cmd = XEN_DOMCTL_arch_setup;
@@ -160,8 +221,7 @@ int arch_setup_bootearly(struct xc_dom_i
 
     domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT)
         + sizeof(start_info_t);
-    /* 3 = start info page, xenstore page and console page */
-    domctl.u.arch_setup.maxmem = (dom->total_pages - 3) << PAGE_SHIFT;
+    domctl.u.arch_setup.maxmem = dom->total_pages << PAGE_SHIFT;
     rc = do_domctl(dom->guest_xc, &domctl);
     return rc;
 }
diff -r caafa45d24b3 -r c2768258711d xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c        Mon May 21 10:09:33 2007 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c        Mon May 21 10:10:31 2007 -0600
@@ -508,6 +508,63 @@ struct fw_tables {
 #define FW_FIELD_MPA(field) \
    FW_TABLES_BASE_PADDR + offsetof(struct fw_tables, field)
 
+static void
+setup_dom0_memmap_info(struct domain *d, struct fw_tables *tables,
+                      int *num_mds)
+{
+       int i;
+       efi_memory_desc_t *md;
+       efi_memory_desc_t *last_mem_md = NULL;
+       xen_ia64_memmap_info_t* memmap_info;
+       unsigned long paddr_start;
+       unsigned long paddr_end;
+
+       for (i = *num_mds - 1; i >= 0; i--) {
+               md = &tables->efi_memmap[i];
+               if (md->attribute == EFI_MEMORY_WB &&
+                   md->type == EFI_CONVENTIONAL_MEMORY &&
+                   md->num_pages >
+                   2 * (1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT))) {
+                       last_mem_md = md;
+                       break;
+               }
+       }
+
+       if (last_mem_md == NULL) {
+               printk("%s: warning: "
+                      "no dom0 contiguous memory to hold memory map\n",
+                      __func__);
+               return;
+       }
+       paddr_end = last_mem_md->phys_addr +
+               (last_mem_md->num_pages << EFI_PAGE_SHIFT);
+       paddr_start = (paddr_end - PAGE_SIZE) & PAGE_MASK;
+       last_mem_md->num_pages -=
+               (paddr_end - paddr_start) / (1UL << EFI_PAGE_SHIFT);
+
+       md = &tables->efi_memmap[*num_mds];
+       (*num_mds)++;
+       md->type = EFI_RUNTIME_SERVICES_DATA;
+       md->phys_addr = paddr_start;
+       md->virt_addr = 0;
+       md->num_pages = 1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT);
+       md->attribute = EFI_MEMORY_WB;
+
+       memmap_info = domain_mpa_to_imva(d, md->phys_addr);
+       BUG_ON(*num_mds > NUM_MEM_DESCS);
+
+       memmap_info->efi_memdesc_size = sizeof(md[0]);
+       memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
+       memmap_info->efi_memmap_size = *num_mds * sizeof(md[0]);
+       memcpy(&memmap_info->memdesc, &tables->efi_memmap[0],
+              memmap_info->efi_memmap_size);
+       d->shared_info->arch.memmap_info_num_pages = 1;
+       d->shared_info->arch.memmap_info_pfn = md->phys_addr >> PAGE_SHIFT;
+
+       sort(tables->efi_memmap, *num_mds, sizeof(efi_memory_desc_t),
+            efi_mdt_cmp, NULL);
+}
+
 /* Complete the dom0 memmap.  */
 static int
 complete_dom0_memmap(struct domain *d,
@@ -672,9 +729,152 @@ complete_dom0_memmap(struct domain *d,
                                                PAGE_SIZE, flags);
                }
        }
+       setup_dom0_memmap_info(d, tables, &num_mds);
        return num_mds;
 }
        
+static int
+complete_domu_memmap(struct domain *d,
+                     struct fw_tables *tables,
+                     unsigned long maxmem,
+                     int num_mds,
+                    unsigned long memmap_info_pfn,
+                    unsigned long memmap_size)
+{
+       efi_memory_desc_t *md;
+       int i = num_mds; /* for MAKE_MD */
+       int create_memmap = 0;
+       xen_ia64_memmap_info_t* memmap_info;
+       unsigned long paddr_start;
+       unsigned long paddr_end;
+       void *p;
+       void *memmap_start;
+       void *memmap_end;
+
+       if (memmap_info_pfn == 0 || memmap_size == 0) {
+               /* old domain builder which doesn't setup
+                * memory map. create it for compatibility */
+               memmap_info_pfn = (maxmem >> PAGE_SHIFT) - 1;
+               /* 4 = memmap info page, start info page, xenstore page and
+                  console page */
+               memmap_size = 4 << PAGE_SHIFT;
+               create_memmap = 1;
+       }
+       paddr_start = memmap_info_pfn << PAGE_SHIFT;
+       paddr_end = paddr_start + memmap_size;
+       memmap_info = domain_mpa_to_imva(d, paddr_start);
+       if (memmap_info->efi_memmap_size == 0) {
+               create_memmap = 1;
+       } else if (memmap_info->efi_memdesc_size != sizeof(md[0]) ||
+                  memmap_info->efi_memdesc_version !=
+                  EFI_MEMORY_DESCRIPTOR_VERSION) {
+               printk(XENLOG_WARNING
+                      "%s: Warning: unknown memory map "
+                      "memmap size %"PRIu64" "
+                      "memdesc size %"PRIu64" "
+                      "version %"PRIu32"\n",
+                      __func__,
+                      memmap_info->efi_memmap_size,
+                      memmap_info->efi_memdesc_size,
+                      memmap_info->efi_memdesc_version);
+               create_memmap = 1;
+       } else if (max(memmap_size, memmap_info->efi_memmap_size) >
+                  PAGE_SIZE - sizeof(*memmap_info)) {
+               /*
+                * curently memmap spanning more than single page isn't
+                * supported.
+                */
+               printk(XENLOG_WARNING
+                      "%s: Warning: too large memmap_size %"PRIu64"\n",
+                      __func__, memmap_size);
+               return -ENOSYS;
+       }
+       
+       if (create_memmap) {
+               /* old domain builder which doesn't setup
+                * memory map. create it for compatibility */
+               memmap_info->efi_memdesc_size = sizeof(md[0]);
+               memmap_info->efi_memdesc_version =
+                       EFI_MEMORY_DESCRIPTOR_VERSION;
+               memmap_info->efi_memmap_size = 1 * sizeof(md[0]);
+               md = (efi_memory_desc_t*)&memmap_info->memdesc;
+               md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
+               md[num_mds].pad = 0;
+               md[num_mds].phys_addr = 0;
+               md[num_mds].virt_addr = 0;
+               md[num_mds].num_pages = maxmem >> EFI_PAGE_SHIFT;
+               md[num_mds].attribute = EFI_MEMORY_WB;
+       }
+       /*
+        * XXX kludge.
+        * when XEN_DOMCTL_arch_setup is called, shared_info can't
+        * be accessed by libxc so that memmap_info_pfn isn't initialized.
+        * But dom_fw_set_convmem_end() requires it, so here we initialize it.
+        */
+       d->shared_info->arch.memmap_info_num_pages = 1;
+       d->shared_info->arch.memmap_info_pfn = memmap_info_pfn;
+
+       memmap_start = &memmap_info->memdesc;
+       memmap_end = memmap_start + memmap_info->efi_memmap_size;
+       /* XXX Currently the table must be in a single page. */
+       if ((unsigned long)memmap_end > (unsigned long)memmap_info + PAGE_SIZE)
+               return -EINVAL;
+
+       /* sort it bofore use
+        * XXX: this is created by user space domain builder so that
+        * we should check its integrity */
+       sort(&memmap_info->memdesc,
+            memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size,
+            memmap_info->efi_memdesc_size,
+            efi_mdt_cmp, NULL);
+
+       for (p = memmap_start; p < memmap_end; p += 
memmap_info->efi_memdesc_size) {
+               unsigned long start;
+               unsigned long end;
+               md = p;
+               start = md->phys_addr;
+               end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+
+               if (start < FW_END_PADDR)
+                       start = FW_END_PADDR;
+               if (end <= start)
+                       continue;
+
+               /* exclude [paddr_start, paddr_end) */
+               if (paddr_end <= start || end <= paddr_start) {
+                       MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+                               start, end);
+               } else if (paddr_start <= start && paddr_end < end) {
+                       MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+                               paddr_end, end);
+               } else if (start < paddr_start && end <= paddr_end) {
+                       MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+                               start, paddr_start);
+               } else {
+                       MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+                               start, paddr_start);
+                       MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+                               paddr_end, end);
+               }
+               d->arch.convmem_end = end;
+       }
+
+       /* memmap info page. */
+       MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB,
+               paddr_start, paddr_end);
+       if (d->arch.convmem_end < paddr_end)
+               d->arch.convmem_end = paddr_end;
+
+       /* Create an entry for IO ports.  */
+       MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
+               IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
+
+       num_mds = i;
+       sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
+            efi_mdt_cmp, NULL);
+       return num_mds;
+}
+
 static void
 dom_fw_init(struct domain *d,
             struct ia64_boot_param *bp,
@@ -842,18 +1042,17 @@ dom_fw_init(struct domain *d,
        if (d != dom0 || running_on_sim) {
                /* DomU (or hp-ski).
                   Create a continuous memory area.  */
-               /* Memory.  */
-               MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
-                       FW_END_PADDR, maxmem);
-               d->arch.convmem_end = maxmem;
-               
-               /* Create an entry for IO ports.  */
-               MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
-                       IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
-
-               num_mds = i;
-       }
-       else {
+               /* kludge: bp->efi_memmap is used to pass memmap_info
+                * page's pfn and number of pages to reserve. 
+                * Currently the following pages must be reserved.
+                * memmap info page, start info page, xenstore page
+                * and console page.
+                * see ia64_setup_memmap() @ xc_dom_boot.c
+                */
+               num_mds = complete_domu_memmap(d, tables, maxmem, i,
+                                              bp->efi_memmap,
+                                              bp->efi_memmap_size);
+       } else {
                /* Dom0.
                   We must preserve ACPI data from real machine,
                   as well as IO areas.  */
diff -r caafa45d24b3 -r c2768258711d xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Mon May 21 10:09:33 2007 -0600
+++ b/xen/include/public/arch-ia64.h    Mon May 21 10:10:31 2007 -0600
@@ -339,7 +339,12 @@ struct arch_shared_info {
     /* Interrupt vector for event channel.  */
     int evtchn_vector;
 
-    uint64_t pad[32];
+    /* PFN of memmap_info page */
+    unsigned int memmap_info_num_pages;/* currently only = 1 case is
+                                          supported. */
+    unsigned long memmap_info_pfn;
+
+    uint64_t pad[31];
 };
 typedef struct arch_shared_info arch_shared_info_t;
 

_______________________________________________
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] [IA64] memmap: introduce memmap_info_t, Xen patchbot-unstable <=