[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 2/2] x86/p2m: force return value checking of p2m_set_entry()
On 12/20/2017 09:35 AM, Jan Beulich wrote: > As XSAs 246 and 247 have shown, not doing so is rather dangerous. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx> > > --- a/xen/arch/x86/mm/p2m.c > +++ b/xen/arch/x86/mm/p2m.c > @@ -1550,9 +1550,11 @@ void p2m_mem_paging_populate(struct doma > 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 ) > + return; On the failure path we call vm_event_claim_slot(), but don't release it. Looks like maybe we need an out_cancel that calls vm_event_cancel_slot()? I was going to say something about |= MEM_PAGING_EVICT_FAIL, but it looks like that only gets used on success. > /* Pause domain if request came from guest and gfn has paging type */ > if ( p2m_is_paging(p2mt) && v->domain == d ) > @@ -1700,10 +1702,12 @@ void p2m_mem_paging_resume(struct domain > */ > 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); > } > @@ -2463,9 +2467,9 @@ static void p2m_reset_altp2m(struct p2m_ > 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; > @@ -2474,9 +2478,10 @@ void p2m_altp2m_propagate_change(struct > 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); > > @@ -2515,17 +2520,25 @@ void p2m_altp2m_propagate_change(struct > 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; > + } Hmm, this isn't great -- add this to the long list of functions that say, "Something went wrong -- maybe nothing was done, maybe it was half done; good luck." Wasn't there a patch floating around that would crash a domain if p2m_set_entry() failed to break down a superpage? I can't seem to find that now. Anyway I think apart from the "leak" mentioned above, the rest of the patch is fine; the situation isn't great but you're not really making it worse. -George _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |