[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.