Skip to content

Commit d96885e

Browse files
rppttorvalds
authored andcommitted
parisc: use pgtable-nopXd instead of 4level-fixup
parisc has two or three levels of page tables and can use appropriate pgtable-nopXd and folding of the upper layers. Replace usage of include/asm-generic/4level-fixup.h and explicit definitions of __PAGETABLE_PxD_FOLDED in parisc with include/asm-generic/pgtable-nopmd.h for two-level configurations and with include/asm-generic/pgtable-nopud.h for three-lelve configurations and adjust page table manipulation macros and functions accordingly. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Mike Rapoport <[email protected]> Acked-by: Helge Deller <[email protected]> Cc: Anatoly Pugachev <[email protected]> Cc: Anton Ivanov <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: Geert Uytterhoeven <[email protected]> Cc: Greentime Hu <[email protected]> Cc: Greg Ungerer <[email protected]> Cc: "James E.J. Bottomley" <[email protected]> Cc: Jeff Dike <[email protected]> Cc: "Kirill A. Shutemov" <[email protected]> Cc: Mark Salter <[email protected]> Cc: Matt Turner <[email protected]> Cc: Michal Simek <[email protected]> Cc: Peter Rosin <[email protected]> Cc: Richard Weinberger <[email protected]> Cc: Rolf Eike Beer <[email protected]> Cc: Russell King <[email protected]> Cc: Russell King <[email protected]> Cc: Sam Creasey <[email protected]> Cc: Vincent Chen <[email protected]> Cc: Vineet Gupta <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 7c2763c commit d96885e

File tree

7 files changed

+81
-76
lines changed

7 files changed

+81
-76
lines changed

arch/parisc/include/asm/page.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,48 +42,54 @@ typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */
4242

4343
/* NOTE: even on 64 bits, these entries are __u32 because we allocate
4444
* the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
45-
typedef struct { __u32 pmd; } pmd_t;
4645
typedef struct { __u32 pgd; } pgd_t;
4746
typedef struct { unsigned long pgprot; } pgprot_t;
4847

49-
#define pte_val(x) ((x).pte)
50-
/* These do not work lvalues, so make sure we don't use them as such. */
48+
#if CONFIG_PGTABLE_LEVELS == 3
49+
typedef struct { __u32 pmd; } pmd_t;
50+
#define __pmd(x) ((pmd_t) { (x) } )
51+
/* pXd_val() do not work as lvalues, so make sure we don't use them as such. */
5152
#define pmd_val(x) ((x).pmd + 0)
53+
#endif
54+
55+
#define pte_val(x) ((x).pte)
5256
#define pgd_val(x) ((x).pgd + 0)
5357
#define pgprot_val(x) ((x).pgprot)
5458

5559
#define __pte(x) ((pte_t) { (x) } )
56-
#define __pmd(x) ((pmd_t) { (x) } )
5760
#define __pgd(x) ((pgd_t) { (x) } )
5861
#define __pgprot(x) ((pgprot_t) { (x) } )
5962

60-
#define __pmd_val_set(x,n) (x).pmd = (n)
61-
#define __pgd_val_set(x,n) (x).pgd = (n)
62-
6363
#else
6464
/*
6565
* .. while these make it easier on the compiler
6666
*/
6767
typedef unsigned long pte_t;
68+
69+
#if CONFIG_PGTABLE_LEVELS == 3
6870
typedef __u32 pmd_t;
71+
#define pmd_val(x) (x)
72+
#define __pmd(x) (x)
73+
#endif
74+
6975
typedef __u32 pgd_t;
7076
typedef unsigned long pgprot_t;
7177

7278
#define pte_val(x) (x)
73-
#define pmd_val(x) (x)
7479
#define pgd_val(x) (x)
7580
#define pgprot_val(x) (x)
7681

7782
#define __pte(x) (x)
78-
#define __pmd(x) (x)
7983
#define __pgd(x) (x)
8084
#define __pgprot(x) (x)
8185

82-
#define __pmd_val_set(x,n) (x) = (n)
83-
#define __pgd_val_set(x,n) (x) = (n)
84-
8586
#endif /* STRICT_MM_TYPECHECKS */
8687

88+
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
89+
#if CONFIG_PGTABLE_LEVELS == 3
90+
#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
91+
#endif
92+
8793
typedef struct page *pgtable_t;
8894

8995
typedef struct __physmem_range {

arch/parisc/include/asm/pgalloc.h

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
3434
/* Populate first pmd with allocated memory. We mark it
3535
* with PxD_FLAG_ATTACHED as a signal to the system that this
3636
* pmd entry may not be cleared. */
37-
__pgd_val_set(*actual_pgd, (PxD_FLAG_PRESENT |
38-
PxD_FLAG_VALID |
39-
PxD_FLAG_ATTACHED)
40-
+ (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT));
37+
set_pgd(actual_pgd, __pgd((PxD_FLAG_PRESENT |
38+
PxD_FLAG_VALID |
39+
PxD_FLAG_ATTACHED)
40+
+ (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT)));
4141
/* The first pmd entry also is marked with PxD_FLAG_ATTACHED as
4242
* a signal that this pmd may not be freed */
43-
__pgd_val_set(*pgd, PxD_FLAG_ATTACHED);
43+
set_pgd(pgd, __pgd(PxD_FLAG_ATTACHED));
4444
#endif
4545
}
4646
spin_lock_init(pgd_spinlock(actual_pgd));
@@ -59,10 +59,10 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
5959

6060
/* Three Level Page Table Support for pmd's */
6161

62-
static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
62+
static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
6363
{
64-
__pgd_val_set(*pgd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
65-
(__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT));
64+
set_pud(pud, __pud((PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
65+
(__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
6666
}
6767

6868
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
@@ -88,19 +88,6 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
8888
free_pages((unsigned long)pmd, PMD_ORDER);
8989
}
9090

91-
#else
92-
93-
/* Two Level Page Table Support for pmd's */
94-
95-
/*
96-
* allocating and freeing a pmd is trivial: the 1-entry pmd is
97-
* inside the pgd, so has no extra memory associated with it.
98-
*/
99-
100-
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
101-
#define pmd_free(mm, x) do { } while (0)
102-
#define pgd_populate(mm, pmd, pte) BUG()
103-
10491
#endif
10592

10693
static inline void
@@ -110,14 +97,14 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
11097
/* preserve the gateway marker if this is the beginning of
11198
* the permanent pmd */
11299
if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
113-
__pmd_val_set(*pmd, (PxD_FLAG_PRESENT |
114-
PxD_FLAG_VALID |
115-
PxD_FLAG_ATTACHED)
116-
+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
100+
set_pmd(pmd, __pmd((PxD_FLAG_PRESENT |
101+
PxD_FLAG_VALID |
102+
PxD_FLAG_ATTACHED)
103+
+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
117104
else
118105
#endif
119-
__pmd_val_set(*pmd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID)
120-
+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
106+
set_pmd(pmd, __pmd((PxD_FLAG_PRESENT | PxD_FLAG_VALID)
107+
+ (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
121108
}
122109

123110
#define pmd_populate(mm, pmd, pte_page) \

arch/parisc/include/asm/pgtable.h

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
#define _PARISC_PGTABLE_H
44

55
#include <asm/page.h>
6-
#include <asm-generic/4level-fixup.h>
6+
7+
#if CONFIG_PGTABLE_LEVELS == 3
8+
#include <asm-generic/pgtable-nopud.h>
9+
#elif CONFIG_PGTABLE_LEVELS == 2
10+
#include <asm-generic/pgtable-nopmd.h>
11+
#endif
712

813
#include <asm/fixmap.h>
914

@@ -101,8 +106,10 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
101106

102107
#define pte_ERROR(e) \
103108
printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
109+
#if CONFIG_PGTABLE_LEVELS == 3
104110
#define pmd_ERROR(e) \
105111
printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, (unsigned long)pmd_val(e))
112+
#endif
106113
#define pgd_ERROR(e) \
107114
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
108115

@@ -132,19 +139,18 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
132139
#define PTRS_PER_PTE (1UL << BITS_PER_PTE)
133140

134141
/* Definitions for 2nd level */
142+
#if CONFIG_PGTABLE_LEVELS == 3
135143
#define PMD_SHIFT (PLD_SHIFT + BITS_PER_PTE)
136144
#define PMD_SIZE (1UL << PMD_SHIFT)
137145
#define PMD_MASK (~(PMD_SIZE-1))
138-
#if CONFIG_PGTABLE_LEVELS == 3
139146
#define BITS_PER_PMD (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY)
147+
#define PTRS_PER_PMD (1UL << BITS_PER_PMD)
140148
#else
141-
#define __PAGETABLE_PMD_FOLDED 1
142149
#define BITS_PER_PMD 0
143150
#endif
144-
#define PTRS_PER_PMD (1UL << BITS_PER_PMD)
145151

146152
/* Definitions for 1st level */
147-
#define PGDIR_SHIFT (PMD_SHIFT + BITS_PER_PMD)
153+
#define PGDIR_SHIFT (PLD_SHIFT + BITS_PER_PTE + BITS_PER_PMD)
148154
#if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG
149155
#define BITS_PER_PGD (BITS_PER_LONG - PGDIR_SHIFT)
150156
#else
@@ -317,6 +323,8 @@ extern unsigned long *empty_zero_page;
317323

318324
#define pmd_flag(x) (pmd_val(x) & PxD_FLAG_MASK)
319325
#define pmd_address(x) ((unsigned long)(pmd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
326+
#define pud_flag(x) (pud_val(x) & PxD_FLAG_MASK)
327+
#define pud_address(x) ((unsigned long)(pud_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
320328
#define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK)
321329
#define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
322330

@@ -334,42 +342,32 @@ static inline void pmd_clear(pmd_t *pmd) {
334342
if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
335343
/* This is the entry pointing to the permanent pmd
336344
* attached to the pgd; cannot clear it */
337-
__pmd_val_set(*pmd, PxD_FLAG_ATTACHED);
345+
set_pmd(pmd, __pmd(PxD_FLAG_ATTACHED));
338346
else
339347
#endif
340-
__pmd_val_set(*pmd, 0);
348+
set_pmd(pmd, __pmd(0));
341349
}
342350

343351

344352

345353
#if CONFIG_PGTABLE_LEVELS == 3
346-
#define pgd_page_vaddr(pgd) ((unsigned long) __va(pgd_address(pgd)))
347-
#define pgd_page(pgd) virt_to_page((void *)pgd_page_vaddr(pgd))
354+
#define pud_page_vaddr(pud) ((unsigned long) __va(pud_address(pud)))
355+
#define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud))
348356

349357
/* For 64 bit we have three level tables */
350358

351-
#define pgd_none(x) (!pgd_val(x))
352-
#define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID))
353-
#define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT)
354-
static inline void pgd_clear(pgd_t *pgd) {
359+
#define pud_none(x) (!pud_val(x))
360+
#define pud_bad(x) (!(pud_flag(x) & PxD_FLAG_VALID))
361+
#define pud_present(x) (pud_flag(x) & PxD_FLAG_PRESENT)
362+
static inline void pud_clear(pud_t *pud) {
355363
#if CONFIG_PGTABLE_LEVELS == 3
356-
if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED)
357-
/* This is the permanent pmd attached to the pgd; cannot
364+
if(pud_flag(*pud) & PxD_FLAG_ATTACHED)
365+
/* This is the permanent pmd attached to the pud; cannot
358366
* free it */
359367
return;
360368
#endif
361-
__pgd_val_set(*pgd, 0);
369+
set_pud(pud, __pud(0));
362370
}
363-
#else
364-
/*
365-
* The "pgd_xxx()" functions here are trivial for a folded two-level
366-
* setup: the pgd is never bad, and a pmd always exists (as it's folded
367-
* into the pgd entry)
368-
*/
369-
static inline int pgd_none(pgd_t pgd) { return 0; }
370-
static inline int pgd_bad(pgd_t pgd) { return 0; }
371-
static inline int pgd_present(pgd_t pgd) { return 1; }
372-
static inline void pgd_clear(pgd_t * pgdp) { }
373371
#endif
374372

375373
/*
@@ -452,7 +450,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
452450
#if CONFIG_PGTABLE_LEVELS == 3
453451
#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
454452
#define pmd_offset(dir,address) \
455-
((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(address))
453+
((pmd_t *) pud_page_vaddr(*(dir)) + pmd_index(address))
456454
#else
457455
#define pmd_offset(dir,addr) ((pmd_t *) dir)
458456
#endif

arch/parisc/include/asm/tlb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
#include <asm-generic/tlb.h>
66

7+
#if CONFIG_PGTABLE_LEVELS == 3
78
#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
9+
#endif
810
#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
911

1012
#endif

arch/parisc/kernel/cache.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,11 +534,14 @@ static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr)
534534
pte_t *ptep = NULL;
535535

536536
if (!pgd_none(*pgd)) {
537-
pud_t *pud = pud_offset(pgd, addr);
538-
if (!pud_none(*pud)) {
539-
pmd_t *pmd = pmd_offset(pud, addr);
540-
if (!pmd_none(*pmd))
541-
ptep = pte_offset_map(pmd, addr);
537+
p4d_t *p4d = p4d_offset(pgd, addr);
538+
if (!p4d_none(*p4d)) {
539+
pud_t *pud = pud_offset(p4d, addr);
540+
if (!pud_none(*pud)) {
541+
pmd_t *pmd = pmd_offset(pud, addr);
542+
if (!pmd_none(*pmd))
543+
ptep = pte_offset_map(pmd, addr);
544+
}
542545
}
543546
}
544547
return ptep;

arch/parisc/kernel/pci-dma.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,14 @@ static inline int map_uncached_pages(unsigned long vaddr, unsigned long size,
133133

134134
dir = pgd_offset_k(vaddr);
135135
do {
136+
p4d_t *p4d;
137+
pud_t *pud;
136138
pmd_t *pmd;
137-
138-
pmd = pmd_alloc(NULL, dir, vaddr);
139+
140+
p4d = p4d_offset(dir, vaddr);
141+
pud = pud_offset(p4d, vaddr);
142+
pmd = pmd_alloc(NULL, pud, vaddr);
143+
139144
if (!pmd)
140145
return -ENOMEM;
141146
if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr))

arch/parisc/mm/fixmap.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
1414
{
1515
unsigned long vaddr = __fix_to_virt(idx);
1616
pgd_t *pgd = pgd_offset_k(vaddr);
17-
pmd_t *pmd = pmd_offset(pgd, vaddr);
17+
p4d_t *p4d = p4d_offset(pgd, vaddr);
18+
pud_t *pud = pud_offset(p4d, vaddr);
19+
pmd_t *pmd = pmd_offset(pud, vaddr);
1820
pte_t *pte;
1921

2022
if (pmd_none(*pmd))
21-
pmd = pmd_alloc(NULL, pgd, vaddr);
23+
pmd = pmd_alloc(NULL, pud, vaddr);
2224

2325
pte = pte_offset_kernel(pmd, vaddr);
2426
if (pte_none(*pte))
@@ -32,7 +34,9 @@ void notrace clear_fixmap(enum fixed_addresses idx)
3234
{
3335
unsigned long vaddr = __fix_to_virt(idx);
3436
pgd_t *pgd = pgd_offset_k(vaddr);
35-
pmd_t *pmd = pmd_offset(pgd, vaddr);
37+
p4d_t *p4d = p4d_offset(pgd, vaddr);
38+
pud_t *pud = pud_offset(p4d, vaddr);
39+
pmd_t *pmd = pmd_offset(pud, vaddr);
3640
pte_t *pte = pte_offset_kernel(pmd, vaddr);
3741

3842
if (WARN_ON(pte_none(*pte)))

0 commit comments

Comments
 (0)