summaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/pgtable.c
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/pgtable.c
parent118bd31bea2cdb7f1dbf22dd9a58e818b5313156 (diff)
downloadop-kernel-dev-28c807e5132ecc9f1607461eabfa1fc67b21e163.zip
op-kernel-dev-28c807e5132ecc9f1607461eabfa1fc67b21e163.tar.gz
s390/mm: add guest ASCE TLB flush optimization
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm/pgtable.c')
-rw-r--r--arch/s390/mm/pgtable.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 9696bf8..3f1abc7 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
OpenPOWER on IntegriCloud