linux/arch/powerpc/mm
Balbir Singh f923efbcfd powerpc/hash64: Be more careful when generating tlbiel
In ISA v2.05, the tlbiel instruction takes two arguments, RB and L:

tlbiel RB,L

+---------+---------+----+---------+---------+---------+----+
|    31   |    /    | L  |    /    |    RB   |   274   | /  |
| 31 - 26 | 25 - 22 | 21 | 20 - 16 | 15 - 11 |  10 - 1 | 0  |
+---------+---------+----+---------+---------+---------+----+

In ISA v2.06 tlbiel takes only one argument, RB:

tlbiel RB

+---------+---------+---------+---------+---------+----+
|    31   |    /    |    /    |    RB   |   274   | /  |
| 31 - 26 | 25 - 21 | 20 - 16 | 15 - 11 |  10 - 1 | 0  |
+---------+---------+---------+---------+---------+----+

And in ISA v3.00 tlbiel takes five arguments:

tlbiel RB,RS,RIC,PRS,R

+---------+---------+----+---------+----+----+---------+---------+----+
|    31   |    RS   | /  |   RIC   |PRS | R  |    RB   |   274   | /  |
| 31 - 26 | 25 - 21 | 20 | 19 - 18 | 17 | 16 | 15 - 11 |  10 - 1 | 0  |
+---------+---------+----+---------+----+----+---------+---------+----+

However the assembler also accepts "tlbiel RB", and generates
"tlbiel RB,r0,0,0,0".

As you can see above the L field from the v2.05 encoding overlaps with the
reserved field of the v2.06 encoding, and the low bit of the RS field of the
v3.00 encoding.

Currently in __tlbiel() we generate two tlbiel instructions manually using hex
constants. In the first case, for MMU_PAGE_4K, we generate "tlbiel RB,0", which
is safe in all cases, because the L bit is zero.

However in the default case we generate "tlbiel RB,1", therefore setting bit 21
to 1.

This is not an actual bug on v2.06 processors, because the CPU ignores the value
of the reserved field. However software is supposed to encode the reserved
fields as zero to enable forward compatibility.

On v3.00 processors setting bit 21 to 1 and no other bits of RS, means we are
using r1 for the value of RS.

Although it's not obvious, the code sets the IS field (bits 10-11) to 0 (by
omission), and L=1, in the va value, which is passed as RB. We also pass R=0 in
the instruction.

The combination of IS=0, L=1 and R=0 means the value of RS is not used, so even
on ISA v3.00 there is no actual bug.

We should still fix it, as setting a reserved bit on v2.06 is naughty, and we
are only avoiding a bug on v3.00 by accident rather than design. Use
ASM_FTR_IFSET() to generate the single argument form on ISA v2.06 and later, and
the two argument form on pre v2.06.

Although there may be very old toolchains which don't understand tlbiel, we have
other code in the tree which has been using tlbiel for over five years, and no
one has reported any build failures, so just let the assembler generate the
instructions.

Signed-off-by: Balbir Singh <bsingharora@gmail.com>
[mpe: Rewrite change log, use IFSET instead of IFCLR]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2016-11-14 11:11:51 +11:00
..
8xx_mmu.c powerpc/8xx: add CONFIG_PIN_TLB_IMMR 2016-07-09 02:02:48 -05:00
40x_mmu.c powerpc/mm: Don't use pmd_val, pud_val and pgd_val as lvalue 2015-12-14 15:19:07 +11:00
44x_mmu.c powerpc: Delete __cpuinit usage from all users 2013-07-01 11:10:36 +10:00
copro_fault.c powerpc/mm: Prevent unlikely crash in copro_calculate_slb() 2016-10-19 20:32:49 +11:00
dma-noncoherent.c powerpc: Simplify test in __dma_sync() 2016-03-11 17:20:12 -06:00
fault.c powerpc: Add support for relative exception tables 2016-11-14 11:11:51 +11:00
fsl_booke_mmu.c powerpc/mm: Convert pte_user() to static inline 2016-05-01 18:32:24 +10:00
hash64_4k.c powerpc/mm: Move hash table ops to a separate structure 2016-07-21 18:59:09 +10:00
hash64_64k.c powerpc/mm: Move hash table ops to a separate structure 2016-07-21 18:59:09 +10:00
hash_low_32.S ppc: move exports to definitions 2016-08-07 23:50:09 -04:00
hash_native_64.c powerpc/hash64: Be more careful when generating tlbiel 2016-11-14 11:11:51 +11:00
hash_utils_64.c powerpc updates for 4.9 #2 2016-10-14 11:07:42 -07:00
highmem.c sched/preempt, mm/kmap: Explicitly disable/enable preemption in kmap_atomic_* 2015-05-19 08:39:14 +02:00
hugepage-hash64.c powerpc/mm: Move hash table ops to a separate structure 2016-07-21 18:59:09 +10:00
hugetlbpage-book3e.c powerpc/fsl-book3e: Avoid lbarx on e5500 2016-03-03 23:43:05 -06:00
hugetlbpage-hash64.c powerpc/mm: Move hash table ops to a separate structure 2016-07-21 18:59:09 +10:00
hugetlbpage-radix.c powerpc/mm/hugetlb: Add flush_hugetlb_tlb_range 2016-08-01 11:15:13 +10:00
hugetlbpage.c powerpc: Fix usage of _PAGE_RO in hugepage 2016-09-23 07:54:22 +10:00
icswx_pid.c
icswx.c
icswx.h
init_32.c powerpc/32: Add missing \n and switch to pr_warn() 2016-09-13 17:37:11 +10:00
init_64.c powerpc/mm: Convert early cpu/mmu feature check to use the new helpers 2016-08-01 11:15:01 +10:00
Makefile powerpc/Makefile: Drop CONFIG_WORD_SIZE for BITS 2016-09-13 17:37:06 +10:00
mem.c powerpc: Fix build with CONFIG_MEMORY_HOTPLUG on some configs 2016-07-07 16:33:27 +10:00
mmap.c powerpc/mm/radix: Pick the address layout for radix config 2016-05-11 21:53:47 +10:00
mmu_context_book3s64.c powerpc/mm/radix: Update PID switch sequence 2016-07-17 16:42:53 +10:00
mmu_context_hash32.c powerpc: Remove power3 from comments 2014-07-28 14:10:26 +10:00
mmu_context_iommu.c KVM: PPC: Book3S HV: Migrate pinned pages out of CMA 2016-09-29 15:14:44 +10:00
mmu_context_nohash.c powerpc/mmu nohash: Convert to hotplug state machine 2016-09-06 18:30:27 +02:00
mmu_decl.h powerpc/8xx: Map IMMR area with 512k page at a fixed address 2016-07-09 02:02:48 -05:00
numa.c powerpc: Fix numa topology console print 2016-10-19 20:35:41 +11:00
pgtable_32.c treewide: replace obsolete _refok by __ref 2016-08-02 17:31:41 -04:00
pgtable_64.c tree wide: get rid of __GFP_REPEAT for order-0 allocations part I 2016-06-24 17:23:52 -07:00
pgtable-book3e.c powerpc/mm: Make page table size a variable 2016-05-01 18:32:48 +10:00
pgtable-book3s64.c powerpc/64/kexec: Fix MMU cleanup on radix 2016-09-23 07:54:17 +10:00
pgtable-hash64.c powerpc/mm/thp: Abstraction for THP functions 2016-05-11 21:53:57 +10:00
pgtable-radix.c powerpc/64/kexec: Fix MMU cleanup on radix 2016-09-23 07:54:17 +10:00
pgtable.c powerpc/mm/radix: Use different pte update sequence for different POWER9 revs 2016-09-13 17:37:10 +10:00
ppc_mmu_32.c powerpc32: refactor x_mapped_by_bats() and x_mapped_by_tlbcam() together 2016-03-11 17:18:02 -06:00
slb_low.S powerpc updates for 4.9 2016-10-07 20:19:31 -07:00
slb.c powerpc/mm: Remove long disabled SLB code 2016-04-11 20:30:40 +10:00
slice.c powerpc/mm/radix: Add checks in slice code to catch radix usage 2016-05-11 21:53:46 +10:00
subpage-prot.c thp: rename split_huge_page_pmd() to split_huge_pmd() 2016-01-15 17:56:32 -08:00
tlb_hash32.c powerpc/mm: remove flush_tlb_page_nohash 2016-08-01 11:15:13 +10:00
tlb_hash64.c powerpc/mm: Hash abstraction for tlbflush routines 2016-05-01 18:33:08 +10:00
tlb_low_64e.S powerpc: Fix misspellings in comments. 2016-03-01 19:27:20 +11:00
tlb_nohash_low.S powerpc: Fix misspellings in comments. 2016-03-01 19:27:20 +11:00
tlb_nohash.c powerpc/mm: Drop multiple definition of mm_is_core_local 2016-08-01 11:15:10 +10:00
tlb-radix.c powerpc/mm/radix: Use tlbiel only if we ever ran on the current cpu 2016-10-27 21:55:13 +11:00
vphn.c powerpc/vphn: parsing code rewrite 2015-03-18 10:48:59 +11:00
vphn.h powerpc/vphn: parsing code rewrite 2015-03-18 10:48:59 +11:00