Skip to content

Commit ebd3119

Browse files
oohalmpe
authored andcommitted
powerpc/mm: Add devmap support for ppc64
Add support for the devmap bit on PTEs and PMDs for PPC64 Book3S. This is used to differentiate device backed memory from transparent huge pages since they are handled in more or less the same manner by the core mm code. Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent b584c25 commit ebd3119

File tree

7 files changed

+55
-7
lines changed

7 files changed

+55
-7
lines changed

arch/powerpc/include/asm/book3s/64/pgtable.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#ifndef __ASSEMBLY__
77
#include <linux/mmdebug.h>
8+
#include <linux/bug.h>
89
#endif
910

1011
/*
@@ -79,6 +80,9 @@
7980

8081
#define _PAGE_SOFT_DIRTY _RPAGE_SW3 /* software: software dirty tracking */
8182
#define _PAGE_SPECIAL _RPAGE_SW2 /* software: special page */
83+
#define _PAGE_DEVMAP _RPAGE_SW1 /* software: ZONE_DEVICE page */
84+
#define __HAVE_ARCH_PTE_DEVMAP
85+
8286
/*
8387
* Drivers request for cache inhibited pte mapping using _PAGE_NO_CACHE
8488
* Instead of fixing all of them, add an alternate define which
@@ -599,6 +603,16 @@ static inline pte_t pte_mkhuge(pte_t pte)
599603
return pte;
600604
}
601605

606+
static inline pte_t pte_mkdevmap(pte_t pte)
607+
{
608+
return __pte(pte_val(pte) | _PAGE_SPECIAL|_PAGE_DEVMAP);
609+
}
610+
611+
static inline int pte_devmap(pte_t pte)
612+
{
613+
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_DEVMAP));
614+
}
615+
602616
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
603617
{
604618
/* FIXME!! check whether this need to be a conditional */
@@ -1146,6 +1160,37 @@ static inline bool arch_needs_pgtable_deposit(void)
11461160
return true;
11471161
}
11481162

1163+
1164+
static inline pmd_t pmd_mkdevmap(pmd_t pmd)
1165+
{
1166+
return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP));
1167+
}
1168+
1169+
static inline int pmd_devmap(pmd_t pmd)
1170+
{
1171+
return pte_devmap(pmd_pte(pmd));
1172+
}
1173+
1174+
static inline int pud_devmap(pud_t pud)
1175+
{
1176+
return 0;
1177+
}
1178+
1179+
static inline int pgd_devmap(pgd_t pgd)
1180+
{
1181+
return 0;
1182+
}
11491183
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
1184+
1185+
static inline const int pud_pfn(pud_t pud)
1186+
{
1187+
/*
1188+
* Currently all calls to pud_pfn() are gated around a pud_devmap()
1189+
* check so this should never be used. If it grows another user we
1190+
* want to know about it.
1191+
*/
1192+
BUILD_BUG();
1193+
return 0;
1194+
}
11501195
#endif /* __ASSEMBLY__ */
11511196
#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */

arch/powerpc/include/asm/book3s/64/radix.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static inline int radix__pgd_bad(pgd_t pgd)
252252

253253
static inline int radix__pmd_trans_huge(pmd_t pmd)
254254
{
255-
return !!(pmd_val(pmd) & _PAGE_PTE);
255+
return (pmd_val(pmd) & (_PAGE_PTE | _PAGE_DEVMAP)) == _PAGE_PTE;
256256
}
257257

258258
static inline pmd_t radix__pmd_mkhuge(pmd_t pmd)

arch/powerpc/mm/hugetlbpage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
964964
if (pmd_none(pmd))
965965
return NULL;
966966

967-
if (pmd_trans_huge(pmd)) {
967+
if (pmd_trans_huge(pmd) || pmd_devmap(pmd)) {
968968
if (is_thp)
969969
*is_thp = true;
970970
ret_pte = (pte_t *) pmdp;

arch/powerpc/mm/pgtable-book3s64.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
3232
{
3333
int changed;
3434
#ifdef CONFIG_DEBUG_VM
35-
WARN_ON(!pmd_trans_huge(*pmdp));
35+
WARN_ON(!pmd_trans_huge(*pmdp) && !pmd_devmap(*pmdp));
3636
assert_spin_locked(&vma->vm_mm->page_table_lock);
3737
#endif
3838
changed = !pmd_same(*(pmdp), entry);
@@ -59,7 +59,7 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
5959
#ifdef CONFIG_DEBUG_VM
6060
WARN_ON(pte_present(pmd_pte(*pmdp)) && !pte_protnone(pmd_pte(*pmdp)));
6161
assert_spin_locked(&mm->page_table_lock);
62-
WARN_ON(!pmd_trans_huge(pmd));
62+
WARN_ON(!(pmd_trans_huge(pmd) || pmd_devmap(pmd)));
6363
#endif
6464
trace_hugepage_set_pmd(addr, pmd_val(pmd));
6565
return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd));

arch/powerpc/mm/pgtable-hash64.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ unsigned long hash__pmd_hugepage_update(struct mm_struct *mm, unsigned long addr
184184
unsigned long old;
185185

186186
#ifdef CONFIG_DEBUG_VM
187-
WARN_ON(!pmd_trans_huge(*pmdp));
187+
WARN_ON(!hash__pmd_trans_huge(*pmdp) && !pmd_devmap(*pmdp));
188188
assert_spin_locked(&mm->page_table_lock);
189189
#endif
190190

@@ -216,6 +216,7 @@ pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addres
216216

217217
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
218218
VM_BUG_ON(pmd_trans_huge(*pmdp));
219+
VM_BUG_ON(pmd_devmap(*pmdp));
219220

220221
pmd = *pmdp;
221222
pmd_clear(pmdp);
@@ -296,6 +297,7 @@ void hash__pmdp_huge_split_prepare(struct vm_area_struct *vma,
296297
{
297298
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
298299
VM_BUG_ON(REGION_ID(address) != USER_REGION_ID);
300+
VM_BUG_ON(pmd_devmap(*pmdp));
299301

300302
/*
301303
* We can't mark the pmd none here, because that will cause a race

arch/powerpc/mm/pgtable-radix.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long add
696696
unsigned long old;
697697

698698
#ifdef CONFIG_DEBUG_VM
699-
WARN_ON(!radix__pmd_trans_huge(*pmdp));
699+
WARN_ON(!radix__pmd_trans_huge(*pmdp) && !pmd_devmap(*pmdp));
700700
assert_spin_locked(&mm->page_table_lock);
701701
#endif
702702

@@ -714,6 +714,7 @@ pmd_t radix__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addre
714714

715715
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
716716
VM_BUG_ON(radix__pmd_trans_huge(*pmdp));
717+
VM_BUG_ON(pmd_devmap(*pmdp));
717718
/*
718719
* khugepaged calls this for normal pmd
719720
*/

arch/powerpc/mm/pgtable_64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ struct page *pud_page(pud_t pud)
324324
*/
325325
struct page *pmd_page(pmd_t pmd)
326326
{
327-
if (pmd_trans_huge(pmd) || pmd_huge(pmd))
327+
if (pmd_trans_huge(pmd) || pmd_huge(pmd) || pmd_devmap(pmd))
328328
return pte_page(pmd_pte(pmd));
329329
return virt_to_page(pmd_page_vaddr(pmd));
330330
}

0 commit comments

Comments
 (0)