Skip to content

Commit daba790

Browse files
chleroympe
authored andcommitted
powerpc/mm: add pte helpers to query and change pte flags
In order to avoid using generic _PAGE_XXX flags in powerpc core functions, define helpers for all needed flags: - pte_mkuser() and pte_mkprivileged() to set/unset and/or unset/set _PAGE_USER and/or _PAGE_PRIVILEGED - pte_hashpte() to check if _PAGE_HASHPTE is set. - pte_ci() check if cache is inhibited (already existing on book3s/64) - pte_exprotect() to protect against execution - pte_exec() and pte_mkexec() to query and set page execution - pte_mkpte() to set _PAGE_PTE flag. - pte_hw_valid() to check _PAGE_PRESENT since pte_present does something different on book3s/64. On book3s/32 there is no exec protection, so pte_mkexec() and pte_exprotect() are nops and pte_exec() returns always true. Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent aa9cd50 commit daba790

File tree

5 files changed

+114
-0
lines changed

5 files changed

+114
-0
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,29 @@ static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY);
301301
static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); }
302302
static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); }
303303
static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
304+
static inline bool pte_exec(pte_t pte) { return true; }
304305
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
305306

306307
static inline int pte_present(pte_t pte)
307308
{
308309
return pte_val(pte) & _PAGE_PRESENT;
309310
}
310311

312+
static inline bool pte_hw_valid(pte_t pte)
313+
{
314+
return pte_val(pte) & _PAGE_PRESENT;
315+
}
316+
317+
static inline bool pte_hashpte(pte_t pte)
318+
{
319+
return !!(pte_val(pte) & _PAGE_HASHPTE);
320+
}
321+
322+
static inline bool pte_ci(pte_t pte)
323+
{
324+
return !!(pte_val(pte) & _PAGE_NO_CACHE);
325+
}
326+
311327
/*
312328
* We only find page table entry in the last level
313329
* Hence no need for other accessors
@@ -354,6 +370,11 @@ static inline pte_t pte_wrprotect(pte_t pte)
354370
return __pte(pte_val(pte) & ~_PAGE_RW);
355371
}
356372

373+
static inline pte_t pte_exprotect(pte_t pte)
374+
{
375+
return pte;
376+
}
377+
357378
static inline pte_t pte_mkclean(pte_t pte)
358379
{
359380
return __pte(pte_val(pte) & ~_PAGE_DIRTY);
@@ -364,6 +385,16 @@ static inline pte_t pte_mkold(pte_t pte)
364385
return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
365386
}
366387

388+
static inline pte_t pte_mkexec(pte_t pte)
389+
{
390+
return pte;
391+
}
392+
393+
static inline pte_t pte_mkpte(pte_t pte)
394+
{
395+
return pte;
396+
}
397+
367398
static inline pte_t pte_mkwrite(pte_t pte)
368399
{
369400
return __pte(pte_val(pte) | _PAGE_RW);
@@ -389,6 +420,16 @@ static inline pte_t pte_mkhuge(pte_t pte)
389420
return pte;
390421
}
391422

423+
static inline pte_t pte_mkprivileged(pte_t pte)
424+
{
425+
return __pte(pte_val(pte) & ~_PAGE_USER);
426+
}
427+
428+
static inline pte_t pte_mkuser(pte_t pte)
429+
{
430+
return __pte(pte_val(pte) | _PAGE_USER);
431+
}
432+
392433
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
393434
{
394435
return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,11 @@ static inline int pte_special(pte_t pte)
519519
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_SPECIAL));
520520
}
521521

522+
static inline bool pte_exec(pte_t pte)
523+
{
524+
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_EXEC));
525+
}
526+
522527
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
523528

524529
#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
@@ -587,6 +592,11 @@ static inline int pte_present(pte_t pte)
587592
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID));
588593
}
589594

595+
static inline bool pte_hw_valid(pte_t pte)
596+
{
597+
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT));
598+
}
599+
590600
#ifdef CONFIG_PPC_MEM_KEYS
591601
extern bool arch_pte_access_permitted(u64 pte, bool write, bool execute);
592602
#else
@@ -646,6 +656,11 @@ static inline pte_t pte_wrprotect(pte_t pte)
646656
return __pte(pte_val(pte) & ~_PAGE_WRITE);
647657
}
648658

659+
static inline pte_t pte_exprotect(pte_t pte)
660+
{
661+
return __pte(pte_val(pte) & ~_PAGE_EXEC);
662+
}
663+
649664
static inline pte_t pte_mkclean(pte_t pte)
650665
{
651666
return __pte(pte_val(pte) & ~_PAGE_DIRTY);
@@ -656,6 +671,16 @@ static inline pte_t pte_mkold(pte_t pte)
656671
return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
657672
}
658673

674+
static inline pte_t pte_mkexec(pte_t pte)
675+
{
676+
return __pte(pte_val(pte) | _PAGE_EXEC);
677+
}
678+
679+
static inline pte_t pte_mkpte(pte_t pte)
680+
{
681+
return __pte(pte_val(pte) | _PAGE_PTE);
682+
}
683+
659684
static inline pte_t pte_mkwrite(pte_t pte)
660685
{
661686
/*
@@ -689,6 +714,16 @@ static inline pte_t pte_mkdevmap(pte_t pte)
689714
return __pte(pte_val(pte) | _PAGE_SPECIAL|_PAGE_DEVMAP);
690715
}
691716

717+
static inline pte_t pte_mkprivileged(pte_t pte)
718+
{
719+
return __pte(pte_val(pte) | _PAGE_PRIVILEGED);
720+
}
721+
722+
static inline pte_t pte_mkuser(pte_t pte)
723+
{
724+
return __pte(pte_val(pte) & ~_PAGE_PRIVILEGED);
725+
}
726+
692727
/*
693728
* This is potentially called with a pmd as the argument, in which case it's not
694729
* safe to check _PAGE_DEVMAP unless we also confirm that _PAGE_PTE is set.

arch/powerpc/include/asm/nohash/32/pgtable.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ static inline pte_t pte_wrprotect(pte_t pte)
164164
return __pte(ptev);
165165
}
166166

167+
static inline pte_t pte_mkexec(pte_t pte)
168+
{
169+
return __pte(pte_val(pte) | _PAGE_EXEC);
170+
}
171+
167172
#define pmd_none(pmd) (!pmd_val(pmd))
168173
#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
169174
#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ static inline pte_t pte_wrprotect(pte_t pte)
114114
return __pte(pte_val(pte) & ~_PAGE_RW);
115115
}
116116

117+
static inline pte_t pte_mkexec(pte_t pte)
118+
{
119+
return __pte(pte_val(pte) | _PAGE_EXEC);
120+
}
121+
117122
#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
118123
#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
119124

arch/powerpc/include/asm/nohash/pgtable.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ static inline int pte_read(pte_t pte) { return 1; }
1919
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
2020
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
2121
static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
22+
static inline bool pte_hashpte(pte_t pte) { return false; }
23+
static inline bool pte_ci(pte_t pte) { return pte_val(pte) & _PAGE_NO_CACHE; }
24+
static inline bool pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC; }
2225
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
2326

2427
#ifdef CONFIG_NUMA_BALANCING
@@ -44,6 +47,11 @@ static inline int pte_present(pte_t pte)
4447
return pte_val(pte) & _PAGE_PRESENT;
4548
}
4649

50+
static inline bool pte_hw_valid(pte_t pte)
51+
{
52+
return pte_val(pte) & _PAGE_PRESENT;
53+
}
54+
4755
/*
4856
* We only find page table entry in the last level
4957
* Hence no need for other accessors
@@ -77,6 +85,11 @@ static inline unsigned long pte_pfn(pte_t pte) {
7785
return pte_val(pte) >> PTE_RPN_SHIFT; }
7886

7987
/* Generic modifiers for PTE bits */
88+
static inline pte_t pte_exprotect(pte_t pte)
89+
{
90+
return __pte(pte_val(pte) & ~_PAGE_EXEC);
91+
}
92+
8093
static inline pte_t pte_mkclean(pte_t pte)
8194
{
8295
return __pte(pte_val(pte) & ~(_PAGE_DIRTY | _PAGE_HWWRITE));
@@ -87,6 +100,11 @@ static inline pte_t pte_mkold(pte_t pte)
87100
return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
88101
}
89102

103+
static inline pte_t pte_mkpte(pte_t pte)
104+
{
105+
return pte;
106+
}
107+
90108
static inline pte_t pte_mkspecial(pte_t pte)
91109
{
92110
return __pte(pte_val(pte) | _PAGE_SPECIAL);
@@ -97,6 +115,16 @@ static inline pte_t pte_mkhuge(pte_t pte)
97115
return __pte(pte_val(pte) | _PAGE_HUGE);
98116
}
99117

118+
static inline pte_t pte_mkprivileged(pte_t pte)
119+
{
120+
return __pte((pte_val(pte) & ~_PAGE_USER) | _PAGE_PRIVILEGED);
121+
}
122+
123+
static inline pte_t pte_mkuser(pte_t pte)
124+
{
125+
return __pte((pte_val(pte) & ~_PAGE_PRIVILEGED) | _PAGE_USER);
126+
}
127+
100128
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
101129
{
102130
return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));

0 commit comments

Comments
 (0)