* pages when it is dying.
*/
if ( unlikely(e->is_dying) ||
- unlikely(domain_tot_pages(e) >= e->max_pages) )
+ unlikely(domain_tot_pages(e) >= e->max_pages) ||
+ unlikely(!(e->tot_pages + 1)) )
{
spin_unlock(&e->page_alloc_lock);
e->domain_id);
else
gdprintk(XENLOG_INFO,
- "Transferee d%d has no headroom (tot %u, max %u)\n",
- e->domain_id, domain_tot_pages(e), e->max_pages);
+ "Transferee %pd has no headroom (tot %u, max %u, ex %u)\n",
+ e, domain_tot_pages(e), e->max_pages, e->extra_pages);
gop.status = GNTST_general_error;
goto unlock_and_copyback;
}
else if ( !(memflags & MEMF_no_refcount) )
{
- unsigned int tot_pages = domain_tot_pages(d) + nr;
+ unsigned int tot_pages = domain_tot_pages(d);
if ( unlikely(tot_pages > d->max_pages) )
{
- gprintk(XENLOG_INFO, "Over-allocation for domain %u: "
- "%u > %u\n", d->domain_id, tot_pages, d->max_pages);
+ gprintk(XENLOG_INFO, "Inconsistent allocation for %pd: %u > %u\n",
+ d, tot_pages, d->max_pages);
+ rc = -EPERM;
+ goto out;
+ }
+
+ if ( unlikely(nr > d->max_pages - tot_pages) )
+ {
+ gprintk(XENLOG_INFO, "Over-allocation for %pd: %Lu > %u\n",
+ d, tot_pages + 0ull + nr, d->max_pages);
rc = -E2BIG;
goto out;
}
}
- if ( !(memflags & MEMF_no_refcount) &&
- unlikely(domain_adjust_tot_pages(d, nr) == nr) )
- get_knownalive_domain(d);
+ if ( !(memflags & MEMF_no_refcount) )
+ {
+ if ( unlikely(d->tot_pages + nr < nr) )
+ {
+ gprintk(XENLOG_INFO,
+ "Excess allocation for %pd: %Lu (%u extra)\n",
+ d, d->tot_pages + 0ull + nr, d->extra_pages);
+ if ( pg[0].count_info & PGC_extra )
+ d->extra_pages -= nr;
+ rc = -E2BIG;
+ goto out;
+ }
+
+ if ( unlikely(domain_adjust_tot_pages(d, nr) == nr) )
+ get_knownalive_domain(d);
+ }
for ( i = 0; i < nr; i++ )
{