Commit 64a6cde7 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Stefan Bader

s390/mm: no local TLB flush for clearing-by-ASCE IDTE

BugLink: http://bugs.launchpad.net/bugs/1708399

The local-clearing control of the IDTE instruction does not have any effect
for the clearing-by-ASCE operation. Only the invalidation-and-clearing
operation respects the local-clearing bit.

Remove __tlb_flush_idte_local and simplify the batched TLB flushing code.
Reviewed-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
(backported from commit d5dcafee)
[Kept MACHINE_HAS_TLB_LC checks as 64f31d58 is not applied.]
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
Acked-by: default avatarColin King <colin.king@canonical.com>
Acked-by: default avatarBrad Figg <brad.figg@canonical.com>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
parent 81a8f561
...@@ -25,17 +25,6 @@ static inline void __tlb_flush_idte(unsigned long asce) ...@@ -25,17 +25,6 @@ static inline void __tlb_flush_idte(unsigned long asce)
: : "a" (2048), "a" (asce) : "cc"); : : "a" (2048), "a" (asce) : "cc");
} }
/*
* Flush TLB entries for a specific ASCE on the local CPU
*/
static inline void __tlb_flush_idte_local(unsigned long asce)
{
/* Local TLB flush for the mm */
asm volatile(
" .insn rrf,0xb98e0000,0,%0,%1,1"
: : "a" (2048), "a" (asce) : "cc");
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void smp_ptlb_all(void); void smp_ptlb_all(void);
...@@ -86,24 +75,15 @@ static inline void __tlb_flush_full(struct mm_struct *mm) ...@@ -86,24 +75,15 @@ static inline void __tlb_flush_full(struct mm_struct *mm)
*/ */
static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce)
{ {
int active, count;
preempt_disable(); preempt_disable();
active = (mm == current->active_mm) ? 1 : 0; atomic_add(0x10000, &mm->context.attach_count);
count = atomic_add_return(0x10000, &mm->context.attach_count); if (MACHINE_HAS_IDTE)
if (MACHINE_HAS_TLB_LC && (count & 0xffff) <= active && __tlb_flush_idte(asce);
cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { else
__tlb_flush_idte_local(asce); __tlb_flush_global();
} else { /* Reset TLB flush mask */
if (MACHINE_HAS_IDTE) if (MACHINE_HAS_TLB_LC)
__tlb_flush_idte(asce); cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
else
__tlb_flush_global();
/* Reset TLB flush mask */
if (MACHINE_HAS_TLB_LC)
cpumask_copy(mm_cpumask(mm),
&mm->context.cpu_attach_mask);
}
atomic_sub(0x10000, &mm->context.attach_count); atomic_sub(0x10000, &mm->context.attach_count);
preempt_enable(); preempt_enable();
} }
...@@ -124,18 +104,12 @@ static inline void __tlb_flush_kernel(void) ...@@ -124,18 +104,12 @@ static inline void __tlb_flush_kernel(void)
*/ */
static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce) static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce)
{ {
if (MACHINE_HAS_TLB_LC) __tlb_flush_local();
__tlb_flush_idte_local(asce);
else
__tlb_flush_local();
} }
static inline void __tlb_flush_kernel(void) static inline void __tlb_flush_kernel(void)
{ {
if (MACHINE_HAS_TLB_LC) __tlb_flush_local();
__tlb_flush_idte_local(init_mm.context.asce);
else
__tlb_flush_local();
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment