[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 for-4.9] x86/mm: Fix incorrect unmapping of 2MB and 1GB pages
On Wed, May 10, 2017 at 12:13 PM, Igor Druzhinin <igor.druzhinin@xxxxxxxxxx> 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.druzhinin@xxxxxxxxxx> > --- > Changes in v2: > * changed mistakenly used mfn_valid() to mfn_eq() > * aggregated gfn-mfn mask into one Acked-by: George Dunlap <george.dunlap@xxxxxxxxxx> This will need a release-ack from Julien as well. -George > > CC: Jun Nakajima <jun.nakajima@xxxxxxxxx> > CC: Kevin Tian <kevin.tian@xxxxxxxxx> > CC: George Dunlap <george.dunlap@xxxxxxxxxxxxx> > CC: Jan Beulich <jbeulich@xxxxxxxx> > CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > > 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@xxxxxxxxxxxxx > https://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |