xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>,
	sstabellini@kernel.org, wei.liu2@citrix.com,
	George.Dunlap@eu.citrix.com, andrew.cooper3@citrix.com,
	ian.jackson@eu.citrix.com, tim@xen.org, jbeulich@suse.com
Subject: [PATCH 1/2] xen/x86: return partial memory map in case of not enough space
Date: Mon,  5 Dec 2016 17:34:08 +0100	[thread overview]
Message-ID: <20161205163409.16714-2-jgross@suse.com> (raw)
In-Reply-To: <20161205163409.16714-1-jgross@suse.com>

For XENMEM_machine_memory_map the hypervisor returns EINVAL if the
caller's buffer can't hold all entries.

This is a problem as the caller has normally a static buffer defined
and when he is doing the call no dynamic memory allocation is
possible as nothing is yet known about the system's memory layout.

Instead of just fail deliver as many memory map entries as possible
and return with E2BIG indicating the result was incomplete. Then the
caller will be capable to use at least some memory reported to exist
to allocate a larger buffer for the complete memory map.

As E2BIG wasn't returned before a caller not prepared for this case
will still see just a failure as before, while someone prepared for
this error code running on an old hypervisor won't run into problems
other than without this change.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 xen/arch/x86/mm.c           | 22 ++++++++++++----------
 xen/include/public/memory.h |  2 ++
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 14552a1..f8e679d 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4737,7 +4737,7 @@ static int _handle_iomem_range(unsigned long s, unsigned long e,
         XEN_GUEST_HANDLE(e820entry_t) buffer;
 
         if ( ctxt->n + 1 >= ctxt->map.nr_entries )
-            return -EINVAL;
+            return -E2BIG;
         ent.addr = (uint64_t)ctxt->s << PAGE_SHIFT;
         ent.size = (uint64_t)(s - ctxt->s) << PAGE_SHIFT;
         ent.type = E820_RESERVED;
@@ -4985,8 +4985,6 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 
         if ( copy_from_guest(&ctxt.map, arg, 1) )
             return -EFAULT;
-        if ( ctxt.map.nr_entries < e820.nr_map + 1 )
-            return -EINVAL;
 
         buffer_param = guest_handle_cast(ctxt.map.buffer, e820entry_t);
         buffer = guest_handle_from_param(buffer_param, e820entry_t);
@@ -5005,31 +5003,35 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
                 if ( !rc )
                     rc = handle_iomem_range(s, s, &ctxt);
                 if ( rc )
-                    return rc;
+                    break;
+            }
+            if ( ctxt.map.nr_entries <= ctxt.n + 1 )
+            {
+                rc = -E2BIG;
+                break;
             }
-            if ( ctxt.map.nr_entries <= ctxt.n + (e820.nr_map - i) )
-                return -EINVAL;
             if ( __copy_to_guest_offset(buffer, ctxt.n, e820.map + i, 1) )
                 return -EFAULT;
             ctxt.s = PFN_UP(e820.map[i].addr + e820.map[i].size);
         }
 
-        if ( ctxt.s )
+        if ( !rc && ctxt.s )
         {
             rc = rangeset_report_ranges(current->domain->iomem_caps, ctxt.s,
                                         ~0UL, handle_iomem_range, &ctxt);
             if ( !rc && ctxt.s )
                 rc = handle_iomem_range(~0UL, ~0UL, &ctxt);
-            if ( rc )
-                return rc;
         }
 
+        if ( rc && rc != -E2BIG )
+            return rc;
+
         ctxt.map.nr_entries = ctxt.n;
 
         if ( __copy_to_guest(arg, &ctxt.map, 1) )
             return -EFAULT;
 
-        return 0;
+        return rc;
     }
 
     case XENMEM_machphys_mapping:
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 5bf840f..20df769 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -339,6 +339,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
 /*
  * Returns the real physical memory map. Passes the same structure as
  * XENMEM_memory_map.
+ * In case of a buffer not capable to hold all entries of the physical
+ * memory map -E2BIG is returned and the buffer is filled completely.
  * arg == addr of xen_memory_map_t.
  */
 #define XENMEM_machine_memory_map   10
-- 
2.10.2


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

  reply	other threads:[~2016-12-05 16:34 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-05 16:34 [PATCH 0/2] xen: modify dom0 interface for obtaining memory map Juergen Gross
2016-12-05 16:34 ` Juergen Gross [this message]
2016-12-05 17:17   ` [PATCH 1/2] xen/x86: return partial memory map in case of not enough space Jan Beulich
     [not found]   ` <5845AF3E020000780012541F@suse.com>
2016-12-06  7:43     ` Juergen Gross
2016-12-06  8:15       ` Jan Beulich
     [not found]       ` <584681CA020000780012577A@suse.com>
2016-12-06  8:33         ` Juergen Gross
2016-12-06  8:51           ` Jan Beulich
     [not found]           ` <58468A1202000078001257BE@suse.com>
2016-12-06  9:44             ` Juergen Gross
2016-12-06  9:51               ` Jan Beulich
2016-12-05 16:34 ` [PATCH 2/2] xen/x86: add a way to obtain the needed number of memory map entries Juergen Gross
2016-12-05 16:39 ` [PATCH 0/2] xen: modify dom0 interface for obtaining memory map Andrew Cooper
2016-12-05 16:43   ` Juergen Gross
2016-12-05 17:06     ` Andrew Cooper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161205163409.16714-2-jgross@suse.com \
    --to=jgross@suse.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=sstabellini@kernel.org \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).