void p2m_mem_paging_populate(struct p2m_domain *p2m, unsigned long gfn) { struct vcpu *v = current; mem_event_request_t req; p2m_type_t p2mt; struct domain *d = p2m->domain; + p2m_lock(p2m); /* Check that there's space on the ring for this request */ if ( mem_event_check_ring(d) ) + { + p2m_unlock(p2m); return; + } memset(&req, 0, sizeof(req)); req.type = MEM_EVENT_TYPE_PAGING; /* Fix p2m mapping */ /* XXX: It seems inefficient to have this here, as it's only needed * in one case (ept guest accessing paging out page) */ gfn_to_mfn(p2m, gfn, &p2mt); if ( p2mt == p2m_ram_paged ) { - p2m_lock(p2m); set_p2m_entry(p2m, gfn, _mfn(PAGING_MFN), 0, p2m_ram_paging_in_start, p2m->default_access); audit_p2m(p2m, 1); - p2m_unlock(p2m); } /* Pause domain */ if ( v->domain->domain_id == d->domain_id ) { vcpu_pause_nosync(v); req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED; } else if ( p2mt != p2m_ram_paging_out && p2mt != p2m_ram_paged ) { /* gfn is already on its way back and vcpu is not paused */ + p2m_unlock(p2m); return; } /* Send request to pager */ req.gfn = gfn; req.p2mt = p2mt; req.vcpu_id = v->vcpu_id; mem_event_put_request(d, &req); + p2m_unlock(p2m); }