if ( p2mt == p2m_ram_paging_out )
req.u.mem_paging.flags |= MEM_PAGING_EVICT_FAIL;
- p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K, p2m_ram_paging_in, a);
+ rc = p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K, p2m_ram_paging_in, a);
}
gfn_unlock(p2m, gfn, 0);
+ if ( rc < 0 )
+ goto out_cancel;
/* Pause domain if request came from guest and gfn has paging type */
if ( p2m_is_paging(p2mt) && v->domain == d )
else if ( p2mt != p2m_ram_paging_out && p2mt != p2m_ram_paged )
{
/* gfn is already on its way back and vcpu is not paused */
+ out_cancel:
vm_event_cancel_slot(d, d->vm_event_paging);
return;
}
*/
if ( mfn_valid(mfn) && (p2mt == p2m_ram_paging_in) )
{
- p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K,
- paging_mode_log_dirty(d) ? p2m_ram_logdirty :
- p2m_ram_rw, a);
- set_gpfn_from_mfn(mfn_x(mfn), gfn_x(gfn));
+ int rc = p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K,
+ paging_mode_log_dirty(d) ? p2m_ram_logdirty :
+ p2m_ram_rw, a);
+
+ if ( !rc )
+ set_gpfn_from_mfn(mfn_x(mfn), gfn_x(gfn));
}
gfn_unlock(p2m, gfn, 0);
}
p2m->max_remapped_gfn = 0;
}
-void p2m_altp2m_propagate_change(struct domain *d, gfn_t gfn,
- mfn_t mfn, unsigned int page_order,
- p2m_type_t p2mt, p2m_access_t p2ma)
+int p2m_altp2m_propagate_change(struct domain *d, gfn_t gfn,
+ mfn_t mfn, unsigned int page_order,
+ p2m_type_t p2mt, p2m_access_t p2ma)
{
struct p2m_domain *p2m;
p2m_access_t a;
unsigned int i;
unsigned int reset_count = 0;
unsigned int last_reset_idx = ~0;
+ int ret = 0;
if ( !altp2m_active(d) )
- return;
+ return 0;
altp2m_list_lock(d);
p2m_unlock(p2m);
}
- goto out;
+ ret = 0;
+ break;
}
}
else if ( !mfn_eq(m, INVALID_MFN) )
- p2m_set_entry(p2m, gfn, mfn, page_order, p2mt, p2ma);
+ {
+ int rc = p2m_set_entry(p2m, gfn, mfn, page_order, p2mt, p2ma);
+
+ /* Best effort: Don't bail on error. */
+ if ( !ret )
+ ret = rc;
+ }
__put_gfn(p2m, gfn_x(gfn));
}
- out:
altp2m_list_unlock(d);
+
+ return ret;
}
/*** Audit ***/
/* Directly set a p2m entry: only for use by p2m code. Does not need
* a call to put_gfn afterwards/ */
-int p2m_set_entry(struct p2m_domain *p2m, gfn_t gfn, mfn_t mfn,
- unsigned int page_order, p2m_type_t p2mt, p2m_access_t p2ma);
+int __must_check p2m_set_entry(struct p2m_domain *p2m, gfn_t gfn, mfn_t mfn,
+ unsigned int page_order, p2m_type_t p2mt,
+ p2m_access_t p2ma);
/* Set up function pointers for PT implementation: only for use by p2m code */
extern void p2m_pt_init(struct p2m_domain *p2m);
gfn_t old_gfn, gfn_t new_gfn);
/* Propagate a host p2m change to all alternate p2m's */
-void p2m_altp2m_propagate_change(struct domain *d, gfn_t gfn,
- mfn_t mfn, unsigned int page_order,
- p2m_type_t p2mt, p2m_access_t p2ma);
+int p2m_altp2m_propagate_change(struct domain *d, gfn_t gfn,
+ mfn_t mfn, unsigned int page_order,
+ p2m_type_t p2mt, p2m_access_t p2ma);
/*
* p2m type to IOMMU flags