@@ -1659,6 +1659,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
break;
case XENMEM_claim_pages:
+ {
+ nodeid_t node;
+
if ( unlikely(start_extent) )
return -EINVAL;
@@ -1671,9 +1674,23 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
if ( reservation.extent_order != 0 )
return -EINVAL;
- if ( reservation.mem_flags != 0 )
+ /* Only allow NUMA-related memory flags to claim on exact nodes */
+ if ( (reservation.mem_flags &
+ !XENMEMF_exact_node(XENMEMF_node_mask - 1)) != 0 )
return -EINVAL;
+ node = XENMEMF_get_node(reservation.mem_flags);
+ if ( node != NUMA_NO_NODE )
+ {
+ /* Disallow advisory nodes. If present, must be exact */
+ if ( !(reservation.mem_flags & XENMEMF_exact_node_request) )
+ return -EINVAL;
+
+ /* Disallow nodes that would overflow the in-hypervisor arrays */
+ if ( node >= MAX_NUMNODES )
+ return -EINVAL;
+ }
+
d = rcu_lock_domain_by_id(reservation.domid);
if ( d == NULL )
return -EINVAL;
@@ -1681,13 +1698,13 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
rc = xsm_claim_pages(XSM_PRIV, d);
if ( !rc )
- rc = domain_set_outstanding_pages(d, NUMA_NO_NODE,
- reservation.nr_extents);
+ rc = domain_set_outstanding_pages(d, node, reservation.nr_extents);
rcu_unlock_domain(d);
break;
+ }
case XENMEM_get_vnumainfo:
{
struct xen_vnuma_topology_info topology;
Extract a NUMA node from mem_flags. This _must_ be an exact node, and has the semantics of making a claim on a specific node. Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com> --- xen/common/memory.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-)