aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2016-07-26 16:00:22 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-07-25 06:55:33 +0200
commit28c807e5132ecc9f1607461eabfa1fc67b21e163 (patch)
tree43efe509f54607e0dcee7d00a7c143607f3848bc /arch/s390/mm
parents390/mm: add no-dat TLB flush optimization (diff)
downloadlinux-dev-28c807e5132ecc9f1607461eabfa1fc67b21e163.tar.xz
linux-dev-28c807e5132ecc9f1607461eabfa1fc67b21e163.zip
s390/mm: add guest ASCE TLB flush optimization
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r--arch/s390/mm/pageattr.c2
-rw-r--r--arch/s390/mm/pgtable.c36
2 files changed, 25 insertions, 13 deletions
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index 5734b01ca765..567fe92e2bb8 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -328,7 +328,7 @@ static void ipte_range(pte_t *pte, unsigned long address, int nr)
return;
}
for (i = 0; i < nr; i++) {
- __ptep_ipte(address, pte, 0, IPTE_GLOBAL);
+ __ptep_ipte(address, pte, 0, 0, IPTE_GLOBAL);
address += PAGE_SIZE;
pte++;
}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 9696bf89f03a..3f1abc7b5fd2 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -35,9 +35,13 @@ static inline void ptep_ipte_local(struct mm_struct *mm, unsigned long addr,
asce = READ_ONCE(mm->context.gmap_asce);
if (asce == 0UL)
opt |= IPTE_NODAT;
- __ptep_ipte(addr, ptep, opt, IPTE_LOCAL);
+ if (asce != -1UL) {
+ asce = asce ? : mm->context.asce;
+ opt |= IPTE_GUEST_ASCE;
+ }
+ __ptep_ipte(addr, ptep, opt, asce, IPTE_LOCAL);
} else {
- __ptep_ipte(addr, ptep, 0, IPTE_LOCAL);
+ __ptep_ipte(addr, ptep, 0, 0, IPTE_LOCAL);
}
}
@@ -51,9 +55,13 @@ static inline void ptep_ipte_global(struct mm_struct *mm, unsigned long addr,
asce = READ_ONCE(mm->context.gmap_asce);
if (asce == 0UL)
opt |= IPTE_NODAT;
- __ptep_ipte(addr, ptep, opt, IPTE_GLOBAL);
+ if (asce != -1UL) {
+ asce = asce ? : mm->context.asce;
+ opt |= IPTE_GUEST_ASCE;
+ }
+ __ptep_ipte(addr, ptep, opt, asce, IPTE_GLOBAL);
} else {
- __ptep_ipte(addr, ptep, 0, IPTE_GLOBAL);
+ __ptep_ipte(addr, ptep, 0, 0, IPTE_GLOBAL);
}
}
@@ -326,18 +334,20 @@ static inline void pmdp_idte_local(struct mm_struct *mm,
unsigned long addr, pmd_t *pmdp)
{
if (MACHINE_HAS_TLB_GUEST)
- __pmdp_idte(addr, pmdp, IDTE_NODAT, IDTE_LOCAL);
+ __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE,
+ mm->context.asce, IDTE_LOCAL);
else
- __pmdp_idte(addr, pmdp, 0, IDTE_LOCAL);
+ __pmdp_idte(addr, pmdp, 0, 0, IDTE_LOCAL);
}
static inline void pmdp_idte_global(struct mm_struct *mm,
unsigned long addr, pmd_t *pmdp)
{
if (MACHINE_HAS_TLB_GUEST)
- __pmdp_idte(addr, pmdp, IDTE_NODAT, IDTE_GLOBAL);
+ __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE,
+ mm->context.asce, IDTE_GLOBAL);
else if (MACHINE_HAS_IDTE)
- __pmdp_idte(addr, pmdp, 0, IDTE_GLOBAL);
+ __pmdp_idte(addr, pmdp, 0, 0, IDTE_GLOBAL);
else
__pmdp_csp(pmdp);
}
@@ -410,18 +420,20 @@ static inline void pudp_idte_local(struct mm_struct *mm,
unsigned long addr, pud_t *pudp)
{
if (MACHINE_HAS_TLB_GUEST)
- __pudp_idte(addr, pudp, IDTE_NODAT, IDTE_LOCAL);
+ __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE,
+ mm->context.asce, IDTE_LOCAL);
else
- __pudp_idte(addr, pudp, 0, IDTE_LOCAL);
+ __pudp_idte(addr, pudp, 0, 0, IDTE_LOCAL);
}
static inline void pudp_idte_global(struct mm_struct *mm,
unsigned long addr, pud_t *pudp)
{
if (MACHINE_HAS_TLB_GUEST)
- __pudp_idte(addr, pudp, IDTE_NODAT, IDTE_GLOBAL);
+ __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE,
+ mm->context.asce, IDTE_GLOBAL);
else if (MACHINE_HAS_IDTE)
- __pudp_idte(addr, pudp, 0, IDTE_GLOBAL);
+ __pudp_idte(addr, pudp, 0, 0, IDTE_GLOBAL);
else
/*
* Invalid bit position is the same for pmd and pud, so we can