Skip to content

Commit

Permalink
mm: pgtable: add shortcuts for accessing kernel PMD and PTE
Browse files Browse the repository at this point in the history
The powerpc 32-bit implementation of pgtable has nice shortcuts for
accessing kernel PMD and PTE for a given virtual address.  Make these
helpers available for all architectures.

[[email protected]: microblaze: fix page table traversal in setup_rt_frame()]
  Link: http://lkml.kernel.org/r/[email protected]
[[email protected]: s/pmd_ptr_k/pmd_off_k/ in various powerpc places]

Signed-off-by: Mike Rapoport <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Cain <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Chris Zankel <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Greentime Hu <[email protected]>
Cc: Greg Ungerer <[email protected]>
Cc: Guan Xuetao <[email protected]>
Cc: Guo Ren <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Helge Deller <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Ley Foon Tan <[email protected]>
Cc: Mark Salter <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Matt Turner <[email protected]>
Cc: Max Filippov <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Nick Hu <[email protected]>
Cc: Paul Walmsley <[email protected]>
Cc: Richard Weinberger <[email protected]>
Cc: Rich Felker <[email protected]>
Cc: Russell King <[email protected]>
Cc: Stafford Horne <[email protected]>
Cc: Thomas Bogendoerfer <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Vincent Chen <[email protected]>
Cc: Vineet Gupta <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Yoshinori Sato <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
rppt authored and torvalds committed Jun 9, 2020
1 parent 88107d3 commit e05c7b1
Show file tree
Hide file tree
Showing 44 changed files with 82 additions and 297 deletions.
10 changes: 1 addition & 9 deletions arch/arc/mm/highmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,9 @@ EXPORT_SYMBOL(kunmap_atomic_high);

static noinline pte_t * __init alloc_kmap_pgtable(unsigned long kvaddr)
{
pgd_t *pgd_k;
p4d_t *p4d_k;
pud_t *pud_k;
pmd_t *pmd_k;
pmd_t *pmd_k = pmd_off_k(kvaddr);
pte_t *pte_k;

pgd_k = pgd_offset_k(kvaddr);
p4d_k = p4d_offset(pgd_k, kvaddr);
pud_k = pud_offset(p4d_k, kvaddr);
pmd_k = pmd_offset(pud_k, kvaddr);

pte_k = (pte_t *)memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
if (!pte_k)
panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-sa1100/assabet.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ static void __init map_sa1100_gpio_regs( void )
int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO);
pmd_t *pmd;

pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset_k(virt), virt), virt), virt);
pmd = pmd_off_k(virt);
*pmd = __pmd(phys | prot);
flush_pmd_entry(pmd);
}
Expand Down
4 changes: 2 additions & 2 deletions arch/arm/mm/highmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
static inline void set_fixmap_pte(int idx, pte_t pte)
{
unsigned long vaddr = __fix_to_virt(idx);
pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
pte_t *ptep = virt_to_kpte(vaddr);

set_pte_ext(ptep, pte, 0);
local_flush_tlb_kernel_page(vaddr);
}

static inline pte_t get_fixmap_pte(unsigned long vaddr)
{
pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
pte_t *ptep = virt_to_kpte(vaddr);

return *ptep;
}
Expand Down
31 changes: 4 additions & 27 deletions arch/arm/mm/ioremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,8 @@ void __check_vmalloc_seq(struct mm_struct *mm)
static void unmap_area_sections(unsigned long virt, unsigned long size)
{
unsigned long addr = virt, end = virt + (size & ~(SZ_1M - 1));
pgd_t *pgd;
p4d_t *p4d;
pud_t *pud;
pmd_t *pmdp;

flush_cache_vunmap(addr, end);
pgd = pgd_offset_k(addr);
p4d = p4d_offset(pgd, addr);
pud = pud_offset(p4d, addr);
pmdp = pmd_offset(pud, addr);
pmd_t *pmdp = pmd_off_k(addr);

do {
pmd_t pmd = *pmdp;

Expand Down Expand Up @@ -191,21 +183,14 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
size_t size, const struct mem_type *type)
{
unsigned long addr = virt, end = virt + size;
pgd_t *pgd;
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
pmd_t *pmd = pmd_off_k(addr);

/*
* Remove and free any PTE-based mapping, and
* sync the current kernel mapping.
*/
unmap_area_sections(virt, size);

pgd = pgd_offset_k(addr);
p4d = p4d_offset(pgd, addr);
pud = pud_offset(p4d, addr);
pmd = pmd_offset(pud, addr);
do {
pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
pfn += SZ_1M >> PAGE_SHIFT;
Expand All @@ -225,21 +210,13 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
size_t size, const struct mem_type *type)
{
unsigned long addr = virt, end = virt + size;
pgd_t *pgd;
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
pmd_t *pmd = pmd_off_k(addr);

/*
* Remove and free any PTE-based mapping, and
* sync the current kernel mapping.
*/
unmap_area_sections(virt, size);

pgd = pgd_offset_k(virt);
p4d = p4d_offset(pgd, addr);
pud = pud_offset(p4d, addr);
pmd = pmd_offset(pud, addr);
do {
unsigned long super_pmd_val, i;

Expand Down
5 changes: 0 additions & 5 deletions arch/arm/mm/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ static inline pte_t get_top_pte(unsigned long va)
return *ptep;
}

static inline pmd_t *pmd_off_k(unsigned long virt)
{
return pmd_offset(pud_offset(p4d_offset(pgd_offset_k(virt), virt), virt), virt);
}

struct mem_type {
pteval_t prot_pte;
pteval_t prot_pte_s2;
Expand Down
7 changes: 1 addition & 6 deletions arch/arm/mm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,7 @@ static pte_t *pte_offset_late_fixmap(pmd_t *dir, unsigned long addr)

static inline pmd_t * __init fixmap_pmd(unsigned long addr)
{
pgd_t *pgd = pgd_offset_k(addr);
p4d_t *p4d = p4d_offset(pgd, addr);
pud_t *pud = pud_offset(p4d, addr);
pmd_t *pmd = pmd_offset(pud, addr);

return pmd;
return pmd_off_k(addr);
}

void __init early_fixmap_init(void)
Expand Down
4 changes: 0 additions & 4 deletions arch/hexagon/include/asm/fixmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,4 @@

#include <asm-generic/fixmap.h>

#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(p4d_offset(pgd_offset_k(vaddr), \
(vaddr)), (vaddr)), (vaddr)), (vaddr))

#endif
26 changes: 4 additions & 22 deletions arch/m68k/mm/motorola.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,8 @@ static inline void nocache_page(void *vaddr)
unsigned long addr = (unsigned long)vaddr;

if (CPU_IS_040_OR_060) {
pgd_t *dir;
p4d_t *p4dp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;

dir = pgd_offset_k(addr);
p4dp = p4d_offset(dir, addr);
pudp = pud_offset(p4dp, addr);
pmdp = pmd_offset(pudp, addr);
ptep = pte_offset_kernel(pmdp, addr);
pte_t *ptep = virt_to_kpte(addr);

*ptep = pte_mknocache(*ptep);
}
}
Expand All @@ -74,17 +65,8 @@ static inline void cache_page(void *vaddr)
unsigned long addr = (unsigned long)vaddr;

if (CPU_IS_040_OR_060) {
pgd_t *dir;
p4d_t *p4dp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;

dir = pgd_offset_k(addr);
p4dp = p4d_offset(dir, addr);
pudp = pud_offset(p4dp, addr);
pmdp = pmd_offset(pudp, addr);
ptep = pte_offset_kernel(pmdp, addr);
pte_t *ptep = virt_to_kpte(addr);

*ptep = pte_mkcache(*ptep);
}
}
Expand Down
8 changes: 1 addition & 7 deletions arch/microblaze/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,6 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
int err = 0, sig = ksig->sig;
unsigned long address = 0;
#ifdef CONFIG_MMU
pgd_t *pgdp;
p4d_t *p4dp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
#endif
Expand Down Expand Up @@ -197,10 +194,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,

address = ((unsigned long)frame->tramp);
#ifdef CONFIG_MMU
pgdp = pgd_offset(current->mm, address);
p4dp = p4d_offset(pgdp, address);
pudp = pud_offset(p4dp, address);
pmdp = pmd_offset(pudp, address);
pmdp = pmd_off(current->mm, address);

preempt_disable();
ptep = pte_offset_map(pmdp, address);
Expand Down
9 changes: 0 additions & 9 deletions arch/microblaze/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,6 @@ unsigned long lowmem_size;
pte_t *kmap_pte;
EXPORT_SYMBOL(kmap_pte);

static inline pte_t *virt_to_kpte(unsigned long vaddr)
{
pgd_t *pgd = pgd_offset_k(vaddr);
p4d_t *p4d = p4d_offset(pgd, vaddr);
pud_t *pud = pud_offset(p4d, vaddr);

return pte_offset_kernel(pmd_offset(pud, vaddr), vaddr);
}

static void __init highmem_init(void)
{
pr_debug("%x\n", (u32)PKMAP_BASE);
Expand Down
3 changes: 0 additions & 3 deletions arch/mips/include/asm/fixmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ enum fixed_addresses {

#include <asm-generic/fixmap.h>

#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(p4d_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)), (vaddr))

/*
* Called from pgtable_init()
*/
Expand Down
10 changes: 2 additions & 8 deletions arch/mips/mm/c-r3k.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,6 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma,
unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT);
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
p4d_t *p4dp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;

Expand All @@ -252,11 +249,8 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma,
if (cpu_context(smp_processor_id(), mm) == 0)
return;

pgdp = pgd_offset(mm, addr);
p4dp = p4d_offset(pgdp, addr);
pudp = pud_offset(p4dp, addr);
pmdp = pmd_offset(pudp, addr);
ptep = pte_offset(pmdp, addr);
pmdp = pmd_off(mm, addr);
ptep = pte_offset_kernel(pmdp, addr);

/* Invalid => no such page in the cache. */
if (!(pte_val(*ptep) & _PAGE_PRESENT))
Expand Down
10 changes: 2 additions & 8 deletions arch/mips/mm/c-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,9 +652,6 @@ static inline void local_r4k_flush_cache_page(void *args)
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
int map_coherent = 0;
pgd_t *pgdp;
p4d_t *p4dp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
void *vaddr;
Expand All @@ -667,11 +664,8 @@ static inline void local_r4k_flush_cache_page(void *args)
return;

addr &= PAGE_MASK;
pgdp = pgd_offset(mm, addr);
p4dp = p4d_offset(pgdp, addr);
pudp = pud_offset(p4dp, addr);
pmdp = pmd_offset(pudp, addr);
ptep = pte_offset(pmdp, addr);
pmdp = pmd_off(mm, addr);
ptep = pte_offset_kernel(pmdp, addr);

/*
* If the page isn't marked valid, the page cannot possibly be
Expand Down
10 changes: 2 additions & 8 deletions arch/mips/mm/c-tx39.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,6 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
{
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
p4d_t *p4dp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;

Expand All @@ -182,11 +179,8 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
return;

page &= PAGE_MASK;
pgdp = pgd_offset(mm, page);
p4dp = p4d_offset(pgdp, page);
pudp = pud_offset(p4dp, page);
pmdp = pmd_offset(pudp, page);
ptep = pte_offset(pmdp, page);
pmdp = pmd_off(mm, page);
ptep = pte_offset_kernel(pmdp, page);

/*
* If the page isn't marked valid, the page cannot possibly be
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/mm/highmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,5 @@ void __init kmap_init(void)

/* cache the first kmap pte */
kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
kmap_pte = virt_to_kpte(kmap_vstart);
}
2 changes: 0 additions & 2 deletions arch/nds32/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ extern void paging_init(void);
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)

#define pmd_off_k(address) pmd_offset(pud_offset(p4d_offset(pgd_offset_k(address), (address)), (address)), (address))

#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
/*
* Set a level 1 translation table entry, and clean it out of
Expand Down
13 changes: 2 additions & 11 deletions arch/nds32/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ static pmd_t *fixmap_pmd_p;
static void __init fixedrange_init(void)
{
unsigned long vaddr;
pgd_t *pgd;
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
#ifdef CONFIG_HIGHMEM
pte_t *pte;
Expand All @@ -110,10 +107,7 @@ static void __init fixedrange_init(void)
* Fixed mappings:
*/
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
pgd = swapper_pg_dir + pgd_index(vaddr);
p4d = p4d_offset(pgd, vaddr);
pud = pud_offset(p4d, vaddr);
pmd = pmd_offset(pud, vaddr);
pmd = pmd_off_k(vaddr);
fixmap_pmd_p = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
if (!fixmap_pmd_p)
panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
Expand All @@ -126,10 +120,7 @@ static void __init fixedrange_init(void)
*/
vaddr = PKMAP_BASE;

pgd = swapper_pg_dir + pgd_index(vaddr);
p4d = p4d_offset(pgd, vaddr);
pud = pud_offset(p4d, vaddr);
pmd = pmd_offset(pud, vaddr);
pmd = pmd_off_k(vaddr);
pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
if (!pte)
panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
Expand Down
6 changes: 1 addition & 5 deletions arch/nds32/mm/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@ extern struct cache_info L1_cache_info[2];

int va_kernel_present(unsigned long addr)
{
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
pte_t *ptep, pte;

p4d = p4d_offset(pgd_offset_k(addr), addr);
pud = pud_offset(p4d, addr);
pmd = pmd_offset(pud, addr);
pmd = pmd_off_k(addr);
if (!pmd_none(*pmd)) {
ptep = pte_offset_map(pmd, addr);
pte = *ptep;
Expand Down
6 changes: 1 addition & 5 deletions arch/parisc/mm/fixmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,7 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
void notrace clear_fixmap(enum fixed_addresses idx)
{
unsigned long vaddr = __fix_to_virt(idx);
pgd_t *pgd = pgd_offset_k(vaddr);
p4d_t *p4d = p4d_offset(pgd, vaddr);
pud_t *pud = pud_offset(p4d, vaddr);
pmd_t *pmd = pmd_offset(pud, vaddr);
pte_t *pte = pte_offset_kernel(pmd, vaddr);
pte_t *pte = virt_to_kpte(vaddr);

if (WARN_ON(pte_none(*pte)))
return;
Expand Down
Loading

0 comments on commit e05c7b1

Please sign in to comment.