xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] xen: fix setup of PVH Dom0 memory map
@ 2014-05-23 15:27 Roger Pau Monne
  2014-05-26  9:39 ` Jan Beulich
  0 siblings, 1 reply; 4+ messages in thread
From: Roger Pau Monne @ 2014-05-23 15:27 UTC (permalink / raw)
  To: xen-devel; +Cc: Tim Deegan, Jan Beulich, Roger Pau Monne

This patch adds the holes removed by MMIO regions to the end of the
memory map for PVH Dom0, so the guest OS doesn't have to manually
populate this memory.

Also, provide a suitable e820 memory map for PVH Dom0, that matches
the underlying p2m map. This means that PVH guests should always use
XENMEM_memory_map in order to obtain the e820, even when running as
Dom0.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Tim Deegan <tim@xen.org>
Cc: Mukesh Rathor <mukesh.rathor@oracle.com>
---
Changes since v2:
 - Added some break points to call process_pending_softirqs.
 - Print rc on error message.
 - Use PFN_UP instead of an open-coded ceil.
 - Add one space in front of labels.

Changes since v1:
 - Fix comparison of start_pfn and nr_pages to use < instead of <=.
 - Use memory pages from d->page_list in order to fill the holes in
   the memory map.
 - Use assigments instead of memcpy to create the Dom0 e820 map.
 - Make sure we are calculating the right size of the e820 entries by
   always rounding up the size.
---
 xen/arch/x86/domain_build.c |  115 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index 38ed9f6..ba42fc9 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -315,9 +315,13 @@ static __init void pvh_add_mem_mapping(struct domain *d, unsigned long gfn,
     int rc;
 
     for ( i = 0; i < nr_mfns; i++ )
+    {
         if ( (rc = set_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i))) )
             panic("pvh_add_mem_mapping: gfn:%lx mfn:%lx i:%ld rc:%d\n",
                   gfn, mfn, i, rc);
+        if ( !(i & 0xfffff) )
+                process_pending_softirqs();
+    }
 }
 
 /*
@@ -327,11 +331,14 @@ static __init void pvh_add_mem_mapping(struct domain *d, unsigned long gfn,
  * pvh fixme: The following doesn't map MMIO ranges when they sit above the
  *            highest E820 covered address.
  */
-static __init void pvh_map_all_iomem(struct domain *d)
+static __init void pvh_map_all_iomem(struct domain *d, unsigned long nr_pages)
 {
     unsigned long start_pfn, end_pfn, end = 0, start = 0;
     const struct e820entry *entry;
-    unsigned int i, nump;
+    unsigned long nump, nmap, navail, mfn, nr_holes = 0;
+    unsigned int i;
+    struct page_info *page;
+    int rc;
 
     for ( i = 0, entry = e820.map; i < e820.nr_map; i++, entry++ )
     {
@@ -353,6 +360,9 @@ static __init void pvh_map_all_iomem(struct domain *d)
                 nump = end_pfn - start_pfn;
                 /* Add pages to the mapping */
                 pvh_add_mem_mapping(d, start_pfn, start_pfn, nump);
+                if ( start_pfn < nr_pages )
+                    nr_holes += (end_pfn < nr_pages) ?
+                                    nump : (nr_pages - start_pfn);
             }
             start = end;
         }
@@ -369,6 +379,104 @@ static __init void pvh_map_all_iomem(struct domain *d)
         nump = end_pfn - start_pfn;
         pvh_add_mem_mapping(d, start_pfn, start_pfn, nump);
     }
+
+    /*
+     * Add the memory removed by the holes at the end of the
+     * memory map.
+     */
+    page = page_list_first(&d->page_list);
+    for ( i = 0, entry = e820.map; i < e820.nr_map && nr_holes > 0;
+          i++, entry++ )
+    {
+        if ( entry->type != E820_RAM )
+            continue;
+
+        end_pfn = PFN_UP(entry->addr + entry->size);
+        if ( end_pfn <= nr_pages )
+            continue;
+
+        navail = end_pfn - nr_pages;
+        nmap = min(navail, nr_holes);
+        nr_holes -= nmap;
+        start_pfn = max_t(unsigned long, nr_pages, PFN_DOWN(entry->addr));
+        /*
+         * Populate this memory region using the pages
+         * previously removed by the MMIO holes.
+         */
+        do
+        {
+            mfn = page_to_mfn(page);
+            if ( get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY )
+                continue;
+
+            rc = guest_physmap_add_page(d, start_pfn, mfn, 0);
+            if ( rc != 0 )
+                panic("Unable to add gpfn %#lx mfn %#lx to Dom0 physmap: %d",
+                      start_pfn, mfn, rc);
+            start_pfn++;
+            nmap--;
+            if ( !(nmap & 0xfffff) )
+                process_pending_softirqs();
+        } while ( ((page = page_list_next(page, &d->page_list)) != NULL)
+                  && nmap );
+        ASSERT(nmap == 0);
+        if ( page == NULL )
+            break;
+    }
+
+    ASSERT(nr_holes == 0);
+}
+
+static __init void pvh_setup_e820(struct domain *d, unsigned long nr_pages)
+{
+    struct e820entry *entry, *entry_guest;
+    unsigned int i;
+    unsigned long pages, cur_pages = 0;
+
+    /*
+     * Craft the e820 memory map for Dom0 based on the hardware e820 map.
+     */
+    d->arch.e820 = xzalloc_array(struct e820entry, e820.nr_map);
+    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++ )
+    {
+        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
+             */
+            continue;
+        }
+
+        *entry_guest = *entry;
+        pages = PFN_UP(entry_guest->size);
+        if ( (cur_pages + pages) > nr_pages )
+        {
+            /* Truncate region */
+            entry_guest->size = (nr_pages - cur_pages) << PAGE_SHIFT;
+            cur_pages = nr_pages;
+        }
+        else
+        {
+            cur_pages += pages;
+        }
+ next:
+        d->arch.nr_e820++;
+        entry_guest++;
+    }
+    ASSERT(cur_pages == nr_pages);
+    ASSERT(d->arch.nr_e820 <= e820.nr_map);
 }
 
 static __init void dom0_update_physmap(struct domain *d, unsigned long pfn,
@@ -1391,7 +1499,8 @@ int __init construct_dom0(
         pfn = shared_info_paddr >> PAGE_SHIFT;
         dom0_update_physmap(d, pfn, mfn, 0);
 
-        pvh_map_all_iomem(d);
+        pvh_map_all_iomem(d, nr_pages);
+        pvh_setup_e820(d, nr_pages);
     }
 
     if ( d->domain_id == hardware_domid )
-- 
1.7.7.5 (Apple Git-26)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] xen: fix setup of PVH Dom0 memory map
  2014-05-23 15:27 [PATCH v3] xen: fix setup of PVH Dom0 memory map Roger Pau Monne
@ 2014-05-26  9:39 ` Jan Beulich
  2014-05-27 11:40   ` David Vrabel
  2014-05-28  1:02   ` Mukesh Rathor
  0 siblings, 2 replies; 4+ messages in thread
From: Jan Beulich @ 2014-05-26  9:39 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: xen-devel, Tim Deegan

>>> On 23.05.14 at 17:27, <roger.pau@citrix.com> wrote:
> This patch adds the holes removed by MMIO regions to the end of the
> memory map for PVH Dom0, so the guest OS doesn't have to manually
> populate this memory.
> 
> Also, provide a suitable e820 memory map for PVH Dom0, that matches
> the underlying p2m map. This means that PVH guests should always use
> XENMEM_memory_map in order to obtain the e820, even when running as
> Dom0.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>

But before considering for committing I'd want Mukesh's
agreement with at least the general approach.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] xen: fix setup of PVH Dom0 memory map
  2014-05-26  9:39 ` Jan Beulich
@ 2014-05-27 11:40   ` David Vrabel
  2014-05-28  1:02   ` Mukesh Rathor
  1 sibling, 0 replies; 4+ messages in thread
From: David Vrabel @ 2014-05-27 11:40 UTC (permalink / raw)
  To: Jan Beulich, Roger Pau Monne; +Cc: xen-devel, Tim Deegan

On 26/05/14 10:39, Jan Beulich wrote:
>>>> On 23.05.14 at 17:27, <roger.pau@citrix.com> wrote:
>> This patch adds the holes removed by MMIO regions to the end of the
>> memory map for PVH Dom0, so the guest OS doesn't have to manually
>> populate this memory.
>>
>> Also, provide a suitable e820 memory map for PVH Dom0, that matches
>> the underlying p2m map. This means that PVH guests should always use
>> XENMEM_memory_map in order to obtain the e820, even when running as
>> Dom0.
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> 
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> 
> But before considering for committing I'd want Mukesh's
> agreement with at least the general approach.

FWIW, with my Linux maintainer hat on. I agree with this approach.

David

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] xen: fix setup of PVH Dom0 memory map
  2014-05-26  9:39 ` Jan Beulich
  2014-05-27 11:40   ` David Vrabel
@ 2014-05-28  1:02   ` Mukesh Rathor
  1 sibling, 0 replies; 4+ messages in thread
From: Mukesh Rathor @ 2014-05-28  1:02 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, Tim Deegan, Roger Pau Monne

On Mon, 26 May 2014 10:39:37 +0100
"Jan Beulich" <JBeulich@suse.com> wrote:

> >>> On 23.05.14 at 17:27, <roger.pau@citrix.com> wrote:
> > This patch adds the holes removed by MMIO regions to the end of the
> > memory map for PVH Dom0, so the guest OS doesn't have to manually
> > populate this memory.
> > 
> > Also, provide a suitable e820 memory map for PVH Dom0, that matches
> > the underlying p2m map. This means that PVH guests should always use
> > XENMEM_memory_map in order to obtain the e820, even when running as
> > Dom0.
> > 
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> 
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> 
> But before considering for committing I'd want Mukesh's
> agreement with at least the general approach.
> 
> Jan

Ok, I'm in agreement with this approach. Will need to change code on
linux side, but shouldn't be too bad.

thanks
mukesh

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-05-28  1:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-23 15:27 [PATCH v3] xen: fix setup of PVH Dom0 memory map Roger Pau Monne
2014-05-26  9:39 ` Jan Beulich
2014-05-27 11:40   ` David Vrabel
2014-05-28  1:02   ` Mukesh Rathor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).