On Wed, May 10, 2017 at 12:13 PM, Igor Druzhinin
<igor.druzhi...@citrix.com> wrote:
> The same set of functions is used to set as well as to clean
> P2M entries, except that for clean operations INVALID_MFN (~0UL)
> is passed as a parameter. Unfortunately, when calculating an
> appropriate target order for a particular mapping INVALID_MFN
> is not taken into account which leads to 4K page target order
> being set each time even for 2MB and 1GB mappings. This eventually
> breaks down an EPT structure irreversibly into 4K mappings which
> prevents consecutive high order mappings to this area.
>
> Signed-off-by: Igor Druzhinin <igor.druzhi...@citrix.com>
> ---
> Changes in v2:
> * changed mistakenly used mfn_valid() to mfn_eq()
> * aggregated gfn-mfn mask into one

Acked-by: George Dunlap <george.dun...@citrix.com>

This will need a release-ack from Julien as well.

 -George


>
> CC: Jun Nakajima <jun.nakaj...@intel.com>
> CC: Kevin Tian <kevin.t...@intel.com>
> CC: George Dunlap <george.dun...@eu.citrix.com>
> CC: Jan Beulich <jbeul...@suse.com>
> CC: Andrew Cooper <andrew.coop...@citrix.com>
>
> Bugfix intended for 4.9 release.
> ---
>  xen/arch/x86/mm/p2m-ept.c |  3 ++-
>  xen/arch/x86/mm/p2m.c     | 11 +++++++----
>  2 files changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
> index f37a1f2..f98121d 100644
> --- a/xen/arch/x86/mm/p2m-ept.c
> +++ b/xen/arch/x86/mm/p2m-ept.c
> @@ -681,6 +681,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, 
> mfn_t mfn,
>      ept_entry_t *table, *ept_entry = NULL;
>      unsigned long gfn_remainder = gfn;
>      unsigned int i, target = order / EPT_TABLE_ORDER;
> +    unsigned long fn_mask = !mfn_eq(mfn, INVALID_MFN) ? (gfn | mfn_x(mfn)) : 
> gfn;
>      int ret, rc = 0;
>      bool_t entry_written = 0;
>      bool_t direct_mmio = (p2mt == p2m_mmio_direct);
> @@ -701,7 +702,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, 
> mfn_t mfn,
>       * 2. gfn not exceeding guest physical address width.
>       * 3. passing a valid order.
>       */
> -    if ( ((gfn | mfn_x(mfn)) & ((1UL << order) - 1)) ||
> +    if ( (fn_mask & ((1UL << order) - 1)) ||
>           ((u64)gfn >> ((ept->wl + 1) * EPT_TABLE_ORDER)) ||
>           (order % EPT_TABLE_ORDER) )
>          return -EINVAL;
> diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
> index ae70a92..e902f1a 100644
> --- a/xen/arch/x86/mm/p2m.c
> +++ b/xen/arch/x86/mm/p2m.c
> @@ -543,12 +543,15 @@ int p2m_set_entry(struct p2m_domain *p2m, unsigned long 
> gfn, mfn_t mfn,
>      while ( todo )
>      {
>          if ( hap_enabled(d) )
> -            order = (!((gfn | mfn_x(mfn) | todo) &
> -                       ((1ul << PAGE_ORDER_1G) - 1)) &&
> +        {
> +            unsigned long fn_mask = !mfn_eq(mfn, INVALID_MFN) ?
> +                                     (gfn | mfn_x(mfn) | todo) : (gfn | 
> todo);
> +
> +            order = (!(fn_mask & ((1ul << PAGE_ORDER_1G) - 1)) &&
>                       hap_has_1gb) ? PAGE_ORDER_1G :
> -                    (!((gfn | mfn_x(mfn) | todo) &
> -                       ((1ul << PAGE_ORDER_2M) - 1)) &&
> +                    (!(fn_mask & ((1ul << PAGE_ORDER_2M) - 1)) &&
>                       hap_has_2mb) ? PAGE_ORDER_2M : PAGE_ORDER_4K;
> +        }
>          else
>              order = 0;
>
> --
> 2.7.4
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

Reply via email to