int domain_set_node_affinity(struct domain *d, const nodemask_t *affinity)
{
- /* Being affine with no nodes is just wrong */
- if ( nodes_empty(*affinity) )
+ /* Being disjoint with the system is just wrong. */
+ if ( !nodes_intersects(*affinity, node_online_map) )
return -EINVAL;
spin_lock(&d->node_affinity_lock);
const struct domain *d)
{
nodeid_t first, node = MEMF_get_node(memflags), req_node = node;
- nodemask_t nodemask = d ? d->node_affinity : node_online_map;
+ nodemask_t nodemask = node_online_map;
unsigned int j, zone, nodemask_retry = 0;
struct page_info *pg;
bool use_unscrubbed = (memflags & MEMF_no_scrub);
+ /*
+ * d->node_affinity is our preferred allocation set if provided, but it
+ * may have bits set outside of node_online_map. Clamp it.
+ */
+ if ( d )
+ {
+ /*
+ * It is the callers responsibility to ensure that d->node_affinity
+ * isn't complete junk.
+ */
+ if ( nodes_intersects(nodemask, d->node_affinity) )
+ nodes_and(nodemask, nodemask, d->node_affinity);
+ else
+ ASSERT_UNREACHABLE();
+ }
+
if ( node == NUMA_NO_NODE )
{
if ( d != NULL )