Jan Beulich
2013-Feb-27 10:52 UTC
[PATCH] x86: make certain memory sub-ops return valid values
When a domain''s shared info field "max_pfn" is zero, domain_get_maximum_gpfn() so far returned ULONG_MAX, which do_memory_op() in turn converted to -1 (i.e. -EPERM). Make the former always return a sensible number (i.e. zero if the field was zero) and have the latter no longer truncate return values. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -433,7 +433,7 @@ unsigned long domain_get_maximum_gpfn(st if ( is_hvm_domain(d) ) return p2m_get_hostp2m(d)->max_mapped_pfn; /* NB. PV guests specify nr_pfns rather than max_pfn so we adjust here. */ - return arch_get_max_pfn(d) - 1; + return (arch_get_max_pfn(d) ?: 1) - 1; } void share_xen_page_with_guest( --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -15,7 +15,8 @@ CHECK_TYPE(domid); int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) { - int rc, split, op = cmd & MEMOP_CMD_MASK; + int split, op = cmd & MEMOP_CMD_MASK; + long rc; unsigned int start_extent = cmd >> MEMOP_EXTENT_SHIFT; do @@ -204,7 +205,7 @@ int compat_memory_op(unsigned int cmd, X rc = do_memory_op(cmd, nat.hnd); if ( rc < 0 ) - return rc; + break; cmd = 0; if ( hypercall_xlat_continuation(&cmd, 0x02, nat.hnd, compat) ) @@ -326,5 +327,11 @@ int compat_memory_op(unsigned int cmd, X __HYPERVISOR_memory_op, "ih", cmd, compat); } while ( split > 0 ); + if ( unlikely(rc > INT_MAX) ) + return INT_MAX; + + if ( unlikely(rc < INT_MIN) ) + return INT_MIN; + return rc; } --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -545,14 +545,13 @@ static long memory_exchange(XEN_GUEST_HA long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) { struct domain *d; - int rc, op; + long rc; unsigned int address_bits; unsigned long start_extent; struct xen_memory_reservation reservation; struct memop_args args; domid_t domid; - - op = cmd & MEMOP_CMD_MASK; + int op = cmd & MEMOP_CMD_MASK; switch ( op ) { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Tim Deegan
2013-Feb-28 10:13 UTC
Re: [PATCH] x86: make certain memory sub-ops return valid values
At 10:52 +0000 on 27 Feb (1361962378), Jan Beulich wrote:> When a domain''s shared info field "max_pfn" is zero, > domain_get_maximum_gpfn() so far returned ULONG_MAX, which > do_memory_op() in turn converted to -1 (i.e. -EPERM). Make the former > always return a sensible number (i.e. zero if the field was zero) and > have the latter no longer truncate return values. > > Signed-off-by: Jan Beulich <jbeulich@suse.com>Acked-by: Tim Deegan <tim@xen.org> (To the extent that this is an interface to x86/mm/ things).> --- a/xen/arch/x86/mm.c > +++ b/xen/arch/x86/mm.c > @@ -433,7 +433,7 @@ unsigned long domain_get_maximum_gpfn(st > if ( is_hvm_domain(d) ) > return p2m_get_hostp2m(d)->max_mapped_pfn; > /* NB. PV guests specify nr_pfns rather than max_pfn so we adjust here. */ > - return arch_get_max_pfn(d) - 1; > + return (arch_get_max_pfn(d) ?: 1) - 1; > } > > void share_xen_page_with_guest( > --- a/xen/common/compat/memory.c > +++ b/xen/common/compat/memory.c > @@ -15,7 +15,8 @@ CHECK_TYPE(domid); > > int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) > { > - int rc, split, op = cmd & MEMOP_CMD_MASK; > + int split, op = cmd & MEMOP_CMD_MASK; > + long rc; > unsigned int start_extent = cmd >> MEMOP_EXTENT_SHIFT; > > do > @@ -204,7 +205,7 @@ int compat_memory_op(unsigned int cmd, X > > rc = do_memory_op(cmd, nat.hnd); > if ( rc < 0 ) > - return rc; > + break; > > cmd = 0; > if ( hypercall_xlat_continuation(&cmd, 0x02, nat.hnd, compat) ) > @@ -326,5 +327,11 @@ int compat_memory_op(unsigned int cmd, X > __HYPERVISOR_memory_op, "ih", cmd, compat); > } while ( split > 0 ); > > + if ( unlikely(rc > INT_MAX) ) > + return INT_MAX; > + > + if ( unlikely(rc < INT_MIN) ) > + return INT_MIN; > + > return rc; > } > --- a/xen/common/memory.c > +++ b/xen/common/memory.c > @@ -545,14 +545,13 @@ static long memory_exchange(XEN_GUEST_HA > long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) > { > struct domain *d; > - int rc, op; > + long rc; > unsigned int address_bits; > unsigned long start_extent; > struct xen_memory_reservation reservation; > struct memop_args args; > domid_t domid; > - > - op = cmd & MEMOP_CMD_MASK; > + int op = cmd & MEMOP_CMD_MASK; > > switch ( op ) > { > > >> x86: make certain memory sub-ops return valid values > > When a domain''s shared info field "max_pfn" is zero, > domain_get_maximum_gpfn() so far returned ULONG_MAX, which > do_memory_op() in turn converted to -1 (i.e. -EPERM). Make the former > always return a sensible number (i.e. zero if the field was zero) and > have the latter no longer truncate return values. > > Signed-off-by: Jan Beulich <jbeulich@suse.com> > > --- a/xen/arch/x86/mm.c > +++ b/xen/arch/x86/mm.c > @@ -433,7 +433,7 @@ unsigned long domain_get_maximum_gpfn(st > if ( is_hvm_domain(d) ) > return p2m_get_hostp2m(d)->max_mapped_pfn; > /* NB. PV guests specify nr_pfns rather than max_pfn so we adjust here. */ > - return arch_get_max_pfn(d) - 1; > + return (arch_get_max_pfn(d) ?: 1) - 1; > } > > void share_xen_page_with_guest( > --- a/xen/common/compat/memory.c > +++ b/xen/common/compat/memory.c > @@ -15,7 +15,8 @@ CHECK_TYPE(domid); > > int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) > { > - int rc, split, op = cmd & MEMOP_CMD_MASK; > + int split, op = cmd & MEMOP_CMD_MASK; > + long rc; > unsigned int start_extent = cmd >> MEMOP_EXTENT_SHIFT; > > do > @@ -204,7 +205,7 @@ int compat_memory_op(unsigned int cmd, X > > rc = do_memory_op(cmd, nat.hnd); > if ( rc < 0 ) > - return rc; > + break; > > cmd = 0; > if ( hypercall_xlat_continuation(&cmd, 0x02, nat.hnd, compat) ) > @@ -326,5 +327,11 @@ int compat_memory_op(unsigned int cmd, X > __HYPERVISOR_memory_op, "ih", cmd, compat); > } while ( split > 0 ); > > + if ( unlikely(rc > INT_MAX) ) > + return INT_MAX; > + > + if ( unlikely(rc < INT_MIN) ) > + return INT_MIN; > + > return rc; > } > --- a/xen/common/memory.c > +++ b/xen/common/memory.c > @@ -545,14 +545,13 @@ static long memory_exchange(XEN_GUEST_HA > long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) > { > struct domain *d; > - int rc, op; > + long rc; > unsigned int address_bits; > unsigned long start_extent; > struct xen_memory_reservation reservation; > struct memop_args args; > domid_t domid; > - > - op = cmd & MEMOP_CMD_MASK; > + int op = cmd & MEMOP_CMD_MASK; > > switch ( op ) > {> _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel