Message ID | 20161206134743.2813-1-jgross@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
>>> On 06.12.16 at 14:47, <JGross@suse.com> wrote: > Today there is no way for a domain to obtain the number of entries of > the machine memory map returned by XENMEM_machine_memory_map hypercall. > > Modify the interface to return just the needed number of map entries > in case the buffer was specified as NULL. > > Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> albeit I'd like to have at least one more REST maintainer's agreement that ... > --- 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. > + * Specifying buffer as NULL will return the number of entries required > + * to store the complete memory map. > * arg == addr of xen_memory_map_t. > */ > #define XENMEM_machine_memory_map 10 ... this slight behavioral change is fine to make. Jan
On Tue, Dec 06, 2016 at 07:19:13AM -0700, Jan Beulich wrote: > >>> On 06.12.16 at 14:47, <JGross@suse.com> wrote: > > Today there is no way for a domain to obtain the number of entries of > > the machine memory map returned by XENMEM_machine_memory_map hypercall. > > > > Modify the interface to return just the needed number of map entries > > in case the buffer was specified as NULL. > > > > Signed-off-by: Juergen Gross <jgross@suse.com> > > Reviewed-by: Jan Beulich <jbeulich@suse.com> > > albeit I'd like to have at least one more REST maintainer's agreement > that ... > > > --- 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. > > + * Specifying buffer as NULL will return the number of entries required > > + * to store the complete memory map. > > * arg == addr of xen_memory_map_t. > > */ > > #define XENMEM_machine_memory_map 10 > > ... this slight behavioral change is fine to make. I think it is fine. It won't break the existing guests. And it is inline with what we are doing when retroffiting other hypercalls. Thanks. > > Jan >
>>> On 06.12.16 at 14:47, <JGross@suse.com> wrote: > Today there is no way for a domain to obtain the number of entries of > the machine memory map returned by XENMEM_machine_memory_map hypercall. > > Modify the interface to return just the needed number of map entries > in case the buffer was specified as NULL. > > Signed-off-by: Juergen Gross <jgross@suse.com> I've committed this, but whether to add it to my list of backports depends on whether you intend to make use of this in Linux. Please let me know. Jan
On 07/12/16 14:05, Jan Beulich wrote: >>>> On 06.12.16 at 14:47, <JGross@suse.com> wrote: >> Today there is no way for a domain to obtain the number of entries of >> the machine memory map returned by XENMEM_machine_memory_map hypercall. >> >> Modify the interface to return just the needed number of map entries >> in case the buffer was specified as NULL. >> >> Signed-off-by: Juergen Gross <jgross@suse.com> > > I've committed this, but whether to add it to my list of backports > depends on whether you intend to make use of this in Linux. > Please let me know. I've no such plans in the moment. Juergen
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 14552a1..3ff0e97 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4736,15 +4736,18 @@ static int _handle_iomem_range(unsigned long s, unsigned long e, XEN_GUEST_HANDLE_PARAM(e820entry_t) buffer_param; XEN_GUEST_HANDLE(e820entry_t) buffer; - if ( ctxt->n + 1 >= ctxt->map.nr_entries ) - return -EINVAL; - ent.addr = (uint64_t)ctxt->s << PAGE_SHIFT; - ent.size = (uint64_t)(s - ctxt->s) << PAGE_SHIFT; - ent.type = E820_RESERVED; - buffer_param = guest_handle_cast(ctxt->map.buffer, e820entry_t); - buffer = guest_handle_from_param(buffer_param, e820entry_t); - if ( __copy_to_guest_offset(buffer, ctxt->n, &ent, 1) ) - return -EFAULT; + if ( !guest_handle_is_null(ctxt->map.buffer) ) + { + if ( ctxt->n + 1 >= ctxt->map.nr_entries ) + return -EINVAL; + ent.addr = (uint64_t)ctxt->s << PAGE_SHIFT; + ent.size = (uint64_t)(s - ctxt->s) << PAGE_SHIFT; + ent.type = E820_RESERVED; + buffer_param = guest_handle_cast(ctxt->map.buffer, e820entry_t); + buffer = guest_handle_from_param(buffer_param, e820entry_t); + if ( __copy_to_guest_offset(buffer, ctxt->n, &ent, 1) ) + return -EFAULT; + } ctxt->n++; } ctxt->s = e + 1; @@ -4978,6 +4981,7 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) XEN_GUEST_HANDLE(e820entry_t) buffer; XEN_GUEST_HANDLE_PARAM(e820entry_t) buffer_param; unsigned int i; + bool store; rc = xsm_machine_memory_map(XSM_PRIV); if ( rc ) @@ -4985,12 +4989,15 @@ 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 ) + + store = !guest_handle_is_null(ctxt.map.buffer); + + if ( store && 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); - if ( !guest_handle_okay(buffer, ctxt.map.nr_entries) ) + if ( store && !guest_handle_okay(buffer, ctxt.map.nr_entries) ) return -EFAULT; for ( i = 0, ctxt.n = 0, ctxt.s = 0; i < e820.nr_map; ++i, ++ctxt.n ) @@ -5007,10 +5014,13 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( rc ) return rc; } - 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; + if ( store ) + { + 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); } diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 5bf840f..e633047 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. + * Specifying buffer as NULL will return the number of entries required + * to store the complete memory map. * arg == addr of xen_memory_map_t. */ #define XENMEM_machine_memory_map 10
Today there is no way for a domain to obtain the number of entries of the machine memory map returned by XENMEM_machine_memory_map hypercall. Modify the interface to return just the needed number of map entries in case the buffer was specified as NULL. Signed-off-by: Juergen Gross <jgross@suse.com> --- xen/arch/x86/mm.c | 40 +++++++++++++++++++++++++--------------- xen/include/public/memory.h | 2 ++ 2 files changed, 27 insertions(+), 15 deletions(-)