diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2014-07-08 15:13:47 +0200 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-10-17 14:18:18 +0200 |
commit | fe6c1b8611aa3a79a937a5e3b85a16576b6ad159 (patch) | |
tree | 48a4677d99954f7abd084be740fbd9457ca190c7 /arch/arc/mm/tlbex.S | |
parent | Documentation/features/vm: pte_special now supported by ARC (diff) | |
download | linux-fe6c1b8611aa3a79a937a5e3b85a16576b6ad159.tar.xz linux-fe6c1b8611aa3a79a937a5e3b85a16576b6ad159.zip |
ARCv2: mm: THP support
MMUv4 in HS38x cores supports Super Pages which are basis for Linux THP
support.
Normal and Super pages can co-exist (ofcourse not overlap) in TLB with a
new bit "SZ" in TLB page desciptor to distinguish between them.
Super Page size is configurable in hardware (4K to 16M), but fixed once
RTL builds.
The exact THP size a Linx configuration will support is a function of:
- MMU page size (typical 8K, RTL fixed)
- software page walker address split between PGD:PTE:PFN (typical
11:8:13, but can be changed with 1 line)
So for above default, THP size supported is 8K * 256 = 2M
Default Page Walker is 2 levels, PGD:PTE:PFN, which in THP regime
reduces to 1 level (as PTE is folded into PGD and canonically referred
to as PMD).
Thus thp PMD accessors are implemented in terms of PTE (just like sparc)
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/mm/tlbex.S')
-rw-r--r-- | arch/arc/mm/tlbex.S | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index b8b014c6904d..552594897655 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S @@ -205,10 +205,18 @@ ex_saved_reg1: #endif lsr r0, r2, PGDIR_SHIFT ; Bits for indexing into PGD - ld.as r1, [r1, r0] ; PGD entry corresp to faulting addr - and.f r1, r1, PAGE_MASK ; Ignoring protection and other flags - ; contains Ptr to Page Table - bz.d do_slow_path_pf ; if no Page Table, do page fault + ld.as r3, [r1, r0] ; PGD entry corresp to faulting addr + tst r3, r3 + bz do_slow_path_pf ; if no Page Table, do page fault + +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + and.f 0, r3, _PAGE_HW_SZ ; Is this Huge PMD (thp) + add2.nz r1, r1, r0 + bnz.d 2f ; YES: PGD == PMD has THP PTE: stop pgd walk + mov.nz r0, r3 + +#endif + and r1, r3, PAGE_MASK ; Get the PTE entry: The idea is ; (1) x = addr >> PAGE_SHIFT -> masks page-off bits from @fault-addr @@ -219,6 +227,9 @@ ex_saved_reg1: lsr r0, r2, (PAGE_SHIFT - 2) and r0, r0, ( (PTRS_PER_PTE - 1) << 2) ld.aw r0, [r1, r0] ; get PTE and PTE ptr for fault addr + +2: + #ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT and.f 0, r0, _PAGE_PRESENT bz 1f |