[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v4 3/4] x86/mm: handle foreign mappings in p2m_entry_modify


  • To: "Tian, Kevin" <kevin.tian@xxxxxxxxx>, Roger Pau Monne <roger.pau@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: George Dunlap <george.dunlap@xxxxxxxxxx>
  • Date: Tue, 19 Feb 2019 13:53:20 +0000
  • Autocrypt: addr=george.dunlap@xxxxxxxxxx; prefer-encrypt=mutual; keydata= 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
  • Cc: Wei Liu <wei.liu2@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Tim Deegan <tim@xxxxxxx>, "Nakajima, Jun" <jun.nakajima@xxxxxxxxx>
  • Delivery-date: Tue, 19 Feb 2019 13:54:45 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Openpgp: preference=signencrypt

On 2/19/19 6:14 AM, Tian, Kevin wrote:
>> From: Roger Pau Monne [mailto:roger.pau@xxxxxxxxxx]
>> Sent: Tuesday, February 19, 2019 1:27 AM
>>
>> So that the specific handling can be removed from
>> atomic_write_ept_entry and be shared with npt and shadow code.
>>
>> This commit also removes the check that prevent non-ept PVH dom0 from
>> mapping foreign pages.
> 
> ah, so please ignore my comment to [1/4]. p2m_entry_modify
> is used more than type change now. :-)
> 
>>
>> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
>> ---
>> Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
>> Cc: Jan Beulich <jbeulich@xxxxxxxx>
>> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
>> Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
>> Cc: Jun Nakajima <jun.nakajima@xxxxxxxxx>
>> Cc: Kevin Tian <kevin.tian@xxxxxxxxx>
>> Cc: Tim Deegan <tim@xxxxxxx>
>> ---
>> Changes since v3:
>>  - Replace the mfn_valid BUG_ONs with an assert & return.
>>
>> Changes since v2:
>>  - Return an error code from p2m_entry_modify and propagate it to the
>>    callers.
>>
>> Changes since v1:
>>  - Simply code since mfn_to_page cannot return NULL.
>>  - Check if the mfn is valid before getting/dropping the page reference.
>>  - Use BUG_ON instead of ASSERTs, since getting the reference counting
>>    wrong is more dangerous than a DoS.
>> ---
>>  xen/arch/x86/mm/hap/hap.c       | 12 +++++--
>>  xen/arch/x86/mm/p2m-ept.c       | 56 +++------------------------------
>>  xen/arch/x86/mm/p2m-pt.c        |  7 -----
>>  xen/arch/x86/mm/shadow/common.c |  3 +-
>>  xen/include/asm-x86/p2m.h       | 34 +++++++++++++++++---
>>  5 files changed, 47 insertions(+), 65 deletions(-)
>>
>> diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
>> index 5b507376bc..2daf8424f6 100644
>> --- a/xen/arch/x86/mm/hap/hap.c
>> +++ b/xen/arch/x86/mm/hap/hap.c
>> @@ -714,6 +714,7 @@ hap_write_p2m_entry(struct domain *d, unsigned
>> long gfn, l1_pgentry_t *p,
>>  {
>>      uint32_t old_flags;
>>      bool_t flush_nestedp2m = 0;
>> +    int rc;
>>
>>      /* We know always use the host p2m here, regardless if the vcpu
>>       * is in host or guest mode. The vcpu can be in guest mode by
>> @@ -734,8 +735,15 @@ hap_write_p2m_entry(struct domain *d, unsigned
>> long gfn, l1_pgentry_t *p,
>>              && perms_strictly_increased(old_flags, l1e_get_flags(new)) );
>>      }
>>
>> -    p2m_entry_modify(p2m_get_hostp2m(d),
>> p2m_flags_to_type(l1e_get_flags(new)),
>> -                     p2m_flags_to_type(old_flags), level);
>> +    rc = p2m_entry_modify(p2m_get_hostp2m(d),
>> +                          p2m_flags_to_type(l1e_get_flags(new)),
>> +                          p2m_flags_to_type(old_flags), l1e_get_mfn(new),
>> +                          l1e_get_mfn(*p), level);
> 
> why not passing old/new pte to reduce #parameters and thus stable
> against future changes?
> 
>> +    if ( rc )
>> +    {
>> +        paging_unlock(d);
>> +        return rc;
>> +    }
>>
>>      safe_write_pte(p, new);
>>      if ( old_flags & _PAGE_PRESENT )
>> diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
>> index 0ece6608cb..83bd602fc4 100644
>> --- a/xen/arch/x86/mm/p2m-ept.c
>> +++ b/xen/arch/x86/mm/p2m-ept.c
>> @@ -45,65 +45,19 @@ static inline bool_t is_epte_valid(ept_entry_t *e)
>>      return ((e->epte & ~(1ul << 63)) != 0 && e->sa_p2mt != p2m_invalid);
>>  }
>>
>> -/* returns : 0 for success, -errno otherwise */
>>  static int atomic_write_ept_entry(struct p2m_domain *p2m,
>>                                    ept_entry_t *entryptr, ept_entry_t new,
>>                                    int level)
>>  {
>> -    int rc;
>> -    unsigned long oldmfn = mfn_x(INVALID_MFN);
>> -    bool_t check_foreign = (new.mfn != entryptr->mfn ||
>> -                            new.sa_p2mt != entryptr->sa_p2mt);
>> -
>> -    if ( level )
>> -    {
>> -        ASSERT(!is_epte_superpage(&new)
>> || !p2m_is_foreign(new.sa_p2mt));
>> -        write_atomic(&entryptr->epte, new.epte);
>> -        return 0;
>> -    }
>> -
>> -    if ( unlikely(p2m_is_foreign(new.sa_p2mt)) )
>> -    {
>> -        rc = -EINVAL;
>> -        if ( !is_epte_present(&new) )
>> -                goto out;
>> -
>> -        if ( check_foreign )
>> -        {
>> -            struct domain *fdom;
>> -
>> -            if ( !mfn_valid(_mfn(new.mfn)) )
>> -                goto out;
>> -
>> -            rc = -ESRCH;
>> -            fdom = page_get_owner(mfn_to_page(_mfn(new.mfn)));
>> -            if ( fdom == NULL )
>> -                goto out;
>> +    int rc = p2m_entry_modify(p2m, new.sa_p2mt, entryptr->sa_p2mt,
>> +                              _mfn(new.mfn), _mfn(entryptr->mfn), level);
>>
>> -            /* get refcount on the page */
>> -            rc = -EBUSY;
>> -            if ( !get_page(mfn_to_page(_mfn(new.mfn)), fdom) )
>> -                goto out;
>> -        }
>> -    }
>> -
>> -    if ( unlikely(p2m_is_foreign(entryptr->sa_p2mt)) && check_foreign )
>> -        oldmfn = entryptr->mfn;
>> -
>> -    p2m_entry_modify(p2m, new.sa_p2mt, entryptr->sa_p2mt, level);
>> +    if ( rc )
>> +        return rc;
>>
>>      write_atomic(&entryptr->epte, new.epte);
>>
>> -    if ( unlikely(oldmfn != mfn_x(INVALID_MFN)) )
>> -        put_page(mfn_to_page(_mfn(oldmfn)));
>> -
>> -    rc = 0;
>> -
>> - out:
>> -    if ( rc )
>> -        gdprintk(XENLOG_ERR, "epte o:%"PRIx64" n:%"PRIx64" rc:%d\n",
>> -                 entryptr->epte, new.epte, rc);
>> -    return rc;
>> +    return 0;
>>  }
>>
>>  static void ept_p2m_type_to_flags(struct p2m_domain *p2m, ept_entry_t
>> *entry,
>> diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
>> index 3a8dc04efc..57afa37c71 100644
>> --- a/xen/arch/x86/mm/p2m-pt.c
>> +++ b/xen/arch/x86/mm/p2m-pt.c
>> @@ -564,13 +564,6 @@ p2m_pt_set_entry(struct p2m_domain *p2m,
>> gfn_t gfn_, mfn_t mfn,
>>          __trace_var(TRC_MEM_SET_P2M_ENTRY, 0, sizeof(t), &t);
>>      }
>>
>> -    if ( unlikely(p2m_is_foreign(p2mt)) )
>> -    {
>> -        /* hvm fixme: foreign types are only supported on ept at present */
>> -        gdprintk(XENLOG_WARNING, "Unimplemented foreign p2m type.\n");
>> -        return -EINVAL;
>> -    }
>> -
>>      /* Carry out any eventually pending earlier changes first. */
>>      rc = do_recalc(p2m, gfn);
>>      if ( rc < 0 )
>> diff --git a/xen/arch/x86/mm/shadow/common.c
>> b/xen/arch/x86/mm/shadow/common.c
>> index fe48c4a02b..ad670de515 100644
>> --- a/xen/arch/x86/mm/shadow/common.c
>> +++ b/xen/arch/x86/mm/shadow/common.c
>> @@ -3189,7 +3189,8 @@ shadow_write_p2m_entry(struct domain *d,
>> unsigned long gfn,
>>           sh_unshadow_for_p2m_change(d, gfn, p, new, level);
>>
>>      p2m_entry_modify(p2m_get_hostp2m(d),
>> p2m_flags_to_type(l1e_get_flags(new)),
>> -                     p2m_flags_to_type(l1e_get_flags(*p)), level);
>> +                     p2m_flags_to_type(l1e_get_flags(*p)), l1e_get_mfn(new),
>> +                     l1e_get_mfn(*p), level);
>>
>>      /* Update the entry with new content */
>>      safe_write_pte(p, new);
>> diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
>> index f4ec2becbd..2801a8ccca 100644
>> --- a/xen/include/asm-x86/p2m.h
>> +++ b/xen/include/asm-x86/p2m.h
>> @@ -932,11 +932,14 @@ int p2m_set_ioreq_server(struct domain *d,
>> unsigned int flags,
>>  struct hvm_ioreq_server *p2m_get_ioreq_server(struct domain *d,
>>                                                unsigned int *flags);
>>
>> -static inline void p2m_entry_modify(struct p2m_domain *p2m,
>> p2m_type_t nt,
>> -                                    p2m_type_t ot, unsigned int level)
>> +static inline int p2m_entry_modify(struct p2m_domain *p2m, p2m_type_t
>> nt,
>> +                                   p2m_type_t ot, mfn_t nfn, mfn_t ofn,
>> +                                   unsigned int level)
>>  {
>> -    if ( level != 1 || nt == ot )
>> -        return;
>> +    BUG_ON(level > 1 && (nt == p2m_ioreq_server || nt ==
>> p2m_map_foreign));
>> +
>> +    if ( level != 1 || (nt == ot && mfn_eq(nfn, ofn)) )
>> +        return 0;
> 
> could also return here in case of nt==ot==p2m_ioreq_server,
> otherwise p2m->ioreq.entry_count might be unnecessarily
> inc/dec if mfn changes while type stays as p2m_ioreq_server...

That's an interesting idea.  But it would have you do an extra check for
all operations, rather than doing an extra increment / decrement in a
very unusual corner case.  Probably faster just to let the uncommon case
be a tiny bit slower.

 -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®.