On 06/27/2018 03:55 PM, Janosch Frank wrote: > From: Janosch Frank <frankja@xxxxxxxxxxxxxxxxxx> > > When changing guest pmds, we don't need to take care of the > corresponding host pmd. This means, we don't need to flush the host > TLB entries and we don't need to notify on all gmaps. > > Let's introduce a function, that exchanges a pmd and takes care of the > necessary flushing. > > Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxxxxxxx> > --- > arch/s390/mm/gmap.c | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > > diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c > index bae0b4f674b5..f5b48426dde8 100644 > --- a/arch/s390/mm/gmap.c > +++ b/arch/s390/mm/gmap.c > @@ -23,6 +23,9 @@ > > #define GMAP_SHADOW_FAKE_TABLE 1ULL > > +static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *old, pmd_t new, > + unsigned long gaddr); > + > /** > * gmap_alloc - allocate and initialize a guest address space > * @mm: pointer to the parent mm_struct > @@ -2165,6 +2168,29 @@ void ptep_notify(struct mm_struct *mm, unsigned long vmaddr, > } > EXPORT_SYMBOL_GPL(ptep_notify); > > +/** > + * gmap_pmdp_xchg - exchange a gmap pmd with another > + * @gmap: pointer to the guest address space structure > + * @pmdp: pointer to the pmd entry > + * @new: replacement entry > + * @gaddr: the affected guest address > + * > + * This function is assumed to be called with the guest_table_lock > + * held. > + */ > +static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *pmdp, pmd_t new, > + unsigned long gaddr) > +{ > + if (MACHINE_HAS_TLB_GUEST) > + __pmdp_idte(gaddr, (pmd_t *)pmdp, IDTE_GUEST_ASCE, gmap->asce, > + IDTE_GLOBAL); do we need an else here? > + if (MACHINE_HAS_IDTE) > + __pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL); > + else > + __pmdp_csp(pmdp); > + *pmdp = new; > +} > + > static inline void thp_split_mm(struct mm_struct *mm) > { > #ifdef CONFIG_TRANSPARENT_HUGEPAGE >