Message ID | 20180627135510.117945-3-frankja@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 06/27/2018 03:55 PM, Janosch Frank wrote: > From: Janosch Frank <frankja@linux.vnet.ibm.com> > > 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@linux.vnet.ibm.com> > --- > 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 >
On 28.06.2018 11:17, Christian Borntraeger wrote: > > > On 06/27/2018 03:55 PM, Janosch Frank wrote: >> From: Janosch Frank <frankja@linux.vnet.ibm.com> >> >> 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@linux.vnet.ibm.com> >> --- >> 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? Good catch It would be better to have one and avoid the second IDTE. > >> + 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 >> >
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); + 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