Skip to content

Commit 94521b2

Browse files
committed
Merge branch 'parisc-4.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc update from Helge Deller: "This patchset adds Huge Page and HUGETLBFS support for parisc" Honestly, the hugepage support should have gone through in the merge window, and is not really an rc-time fix. But it only touches arch/parisc, and I cannot find it in myself to care. If one of the three parisc users notices a breakage, I will point at Helge and make rude farting noises. * 'parisc-4.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: Map kernel text and data on huge pages parisc: Add Huge Page and HUGETLBFS support parisc: Use long branch to do_syscall_trace_exit parisc: Increase initial kernel mapping to 32MB on 64bit kernel parisc: Initialize the fault vector earlier in the boot process. parisc: Add defines for Huge page support parisc: Drop unused MADV_xxxK_PAGES flags from asm/mman.h parisc: Drop definition of start_thread_som for HP-UX SOM binaries parisc: Fix wrong comment regarding first pmd entry flags
2 parents 727cde6 + 41b85a1 commit 94521b2

File tree

17 files changed

+382
-116
lines changed

17 files changed

+382
-116
lines changed

arch/parisc/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ config PGTABLE_LEVELS
108108
default 3 if 64BIT && PARISC_PAGE_SIZE_4KB
109109
default 2
110110

111+
config SYS_SUPPORTS_HUGETLBFS
112+
def_bool y if PA20
113+
111114
source "init/Kconfig"
112115

113116
source "kernel/Kconfig.freezer"

arch/parisc/include/asm/hugetlb.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#ifndef _ASM_PARISC64_HUGETLB_H
2+
#define _ASM_PARISC64_HUGETLB_H
3+
4+
#include <asm/page.h>
5+
#include <asm-generic/hugetlb.h>
6+
7+
8+
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
9+
pte_t *ptep, pte_t pte);
10+
11+
pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
12+
pte_t *ptep);
13+
14+
static inline int is_hugepage_only_range(struct mm_struct *mm,
15+
unsigned long addr,
16+
unsigned long len) {
17+
return 0;
18+
}
19+
20+
/*
21+
* If the arch doesn't supply something else, assume that hugepage
22+
* size aligned regions are ok without further preparation.
23+
*/
24+
static inline int prepare_hugepage_range(struct file *file,
25+
unsigned long addr, unsigned long len)
26+
{
27+
if (len & ~HPAGE_MASK)
28+
return -EINVAL;
29+
if (addr & ~HPAGE_MASK)
30+
return -EINVAL;
31+
return 0;
32+
}
33+
34+
static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
35+
unsigned long addr, unsigned long end,
36+
unsigned long floor,
37+
unsigned long ceiling)
38+
{
39+
free_pgd_range(tlb, addr, end, floor, ceiling);
40+
}
41+
42+
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
43+
unsigned long addr, pte_t *ptep)
44+
{
45+
}
46+
47+
static inline int huge_pte_none(pte_t pte)
48+
{
49+
return pte_none(pte);
50+
}
51+
52+
static inline pte_t huge_pte_wrprotect(pte_t pte)
53+
{
54+
return pte_wrprotect(pte);
55+
}
56+
57+
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
58+
unsigned long addr, pte_t *ptep)
59+
{
60+
pte_t old_pte = *ptep;
61+
set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
62+
}
63+
64+
static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
65+
unsigned long addr, pte_t *ptep,
66+
pte_t pte, int dirty)
67+
{
68+
int changed = !pte_same(*ptep, pte);
69+
if (changed) {
70+
set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
71+
flush_tlb_page(vma, addr);
72+
}
73+
return changed;
74+
}
75+
76+
static inline pte_t huge_ptep_get(pte_t *ptep)
77+
{
78+
return *ptep;
79+
}
80+
81+
static inline void arch_clear_hugepage_flags(struct page *page)
82+
{
83+
}
84+
85+
#endif /* _ASM_PARISC64_HUGETLB_H */

arch/parisc/include/asm/page.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,22 @@ extern int npmem_ranges;
145145
#endif /* CONFIG_DISCONTIGMEM */
146146

147147
#ifdef CONFIG_HUGETLB_PAGE
148-
#define HPAGE_SHIFT 22 /* 4MB (is this fixed?) */
148+
#define HPAGE_SHIFT PMD_SHIFT /* fixed for transparent huge pages */
149149
#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
150150
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
151151
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
152+
153+
#if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
154+
# define REAL_HPAGE_SHIFT 20 /* 20 = 1MB */
155+
# define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_1M
156+
#elif !defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
157+
# define REAL_HPAGE_SHIFT 22 /* 22 = 4MB */
158+
# define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4M
159+
#else
160+
# define REAL_HPAGE_SHIFT 24 /* 24 = 16MB */
161+
# define _HUGE_PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_16M
152162
#endif
163+
#endif /* CONFIG_HUGETLB_PAGE */
153164

154165
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
155166

arch/parisc/include/asm/pgalloc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
3535
PxD_FLAG_VALID |
3636
PxD_FLAG_ATTACHED)
3737
+ (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT));
38-
/* The first pmd entry also is marked with _PAGE_GATEWAY as
38+
/* The first pmd entry also is marked with PxD_FLAG_ATTACHED as
3939
* a signal that this pmd may not be freed */
4040
__pgd_val_set(*pgd, PxD_FLAG_ATTACHED);
4141
#endif

arch/parisc/include/asm/pgtable.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
8383
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
8484

8585
/* This is the size of the initially mapped kernel memory */
86-
#define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */
86+
#ifdef CONFIG_64BIT
87+
#define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */
88+
#else
89+
#define KERNEL_INITIAL_ORDER 24 /* 1<<24 = 16MB */
90+
#endif
8791
#define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER)
8892

8993
#if CONFIG_PGTABLE_LEVELS == 3
@@ -167,7 +171,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
167171
#define _PAGE_NO_CACHE_BIT 24 /* (0x080) Uncached Page (U bit) */
168172
#define _PAGE_ACCESSED_BIT 23 /* (0x100) Software: Page Accessed */
169173
#define _PAGE_PRESENT_BIT 22 /* (0x200) Software: translation valid */
170-
/* bit 21 was formerly the FLUSH bit but is now unused */
174+
#define _PAGE_HPAGE_BIT 21 /* (0x400) Software: Huge Page */
171175
#define _PAGE_USER_BIT 20 /* (0x800) Software: User accessible page */
172176

173177
/* N.B. The bits are defined in terms of a 32 bit word above, so the */
@@ -194,6 +198,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
194198
#define _PAGE_NO_CACHE (1 << xlate_pabit(_PAGE_NO_CACHE_BIT))
195199
#define _PAGE_ACCESSED (1 << xlate_pabit(_PAGE_ACCESSED_BIT))
196200
#define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT))
201+
#define _PAGE_HUGE (1 << xlate_pabit(_PAGE_HPAGE_BIT))
197202
#define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT))
198203

199204
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
@@ -217,7 +222,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
217222
#define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT))
218223
#define PxD_FLAG_MASK (0xf)
219224
#define PxD_FLAG_SHIFT (4)
220-
#define PxD_VALUE_SHIFT (8) /* (PAGE_SHIFT-PxD_FLAG_SHIFT) */
225+
#define PxD_VALUE_SHIFT (PFN_PTE_SHIFT-PxD_FLAG_SHIFT)
221226

222227
#ifndef __ASSEMBLY__
223228

@@ -362,6 +367,18 @@ static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; ret
362367
static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; }
363368
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
364369

370+
/*
371+
* Huge pte definitions.
372+
*/
373+
#ifdef CONFIG_HUGETLB_PAGE
374+
#define pte_huge(pte) (pte_val(pte) & _PAGE_HUGE)
375+
#define pte_mkhuge(pte) (__pte(pte_val(pte) | _PAGE_HUGE))
376+
#else
377+
#define pte_huge(pte) (0)
378+
#define pte_mkhuge(pte) (pte)
379+
#endif
380+
381+
365382
/*
366383
* Conversion functions: convert a page and protection to a page entry,
367384
* and a page entry and page directory to the page they refer to.
@@ -410,8 +427,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
410427
/* Find an entry in the second-level page table.. */
411428

412429
#if CONFIG_PGTABLE_LEVELS == 3
430+
#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
413431
#define pmd_offset(dir,address) \
414-
((pmd_t *) pgd_page_vaddr(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1)))
432+
((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(address))
415433
#else
416434
#define pmd_offset(dir,addr) ((pmd_t *) dir)
417435
#endif

arch/parisc/include/asm/processor.h

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -192,33 +192,6 @@ void show_trace(struct task_struct *task, unsigned long *stack);
192192
*/
193193
typedef unsigned int elf_caddr_t;
194194

195-
#define start_thread_som(regs, new_pc, new_sp) do { \
196-
unsigned long *sp = (unsigned long *)new_sp; \
197-
__u32 spaceid = (__u32)current->mm->context; \
198-
unsigned long pc = (unsigned long)new_pc; \
199-
/* offset pc for priv. level */ \
200-
pc |= 3; \
201-
\
202-
regs->iasq[0] = spaceid; \
203-
regs->iasq[1] = spaceid; \
204-
regs->iaoq[0] = pc; \
205-
regs->iaoq[1] = pc + 4; \
206-
regs->sr[2] = LINUX_GATEWAY_SPACE; \
207-
regs->sr[3] = 0xffff; \
208-
regs->sr[4] = spaceid; \
209-
regs->sr[5] = spaceid; \
210-
regs->sr[6] = spaceid; \
211-
regs->sr[7] = spaceid; \
212-
regs->gr[ 0] = USER_PSW; \
213-
regs->gr[30] = ((new_sp)+63)&~63; \
214-
regs->gr[31] = pc; \
215-
\
216-
get_user(regs->gr[26],&sp[0]); \
217-
get_user(regs->gr[25],&sp[-1]); \
218-
get_user(regs->gr[24],&sp[-2]); \
219-
get_user(regs->gr[23],&sp[-3]); \
220-
} while(0)
221-
222195
/* The ELF abi wants things done a "wee bit" differently than
223196
* som does. Supporting this behavior here avoids
224197
* having our own version of create_elf_tables.

arch/parisc/include/uapi/asm/mman.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,6 @@
4949
#define MADV_DONTFORK 10 /* don't inherit across fork */
5050
#define MADV_DOFORK 11 /* do inherit across fork */
5151

52-
/* The range 12-64 is reserved for page size specification. */
53-
#define MADV_4K_PAGES 12 /* Use 4K pages */
54-
#define MADV_16K_PAGES 14 /* Use 16K pages */
55-
#define MADV_64K_PAGES 16 /* Use 64K pages */
56-
#define MADV_256K_PAGES 18 /* Use 256K pages */
57-
#define MADV_1M_PAGES 20 /* Use 1 Megabyte pages */
58-
#define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */
59-
#define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */
60-
#define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */
61-
6252
#define MADV_MERGEABLE 65 /* KSM may merge identical pages */
6353
#define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */
6454

arch/parisc/kernel/asm-offsets.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,14 @@ int main(void)
289289
DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE);
290290
DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT);
291291
DEFINE(ASM_PT_INITIAL, PT_INITIAL);
292+
BLANK();
293+
/* HUGEPAGE_SIZE is only used in vmlinux.lds.S to align kernel text
294+
* and kernel data on physical huge pages */
295+
#ifdef CONFIG_HUGETLB_PAGE
296+
DEFINE(HUGEPAGE_SIZE, 1UL << REAL_HPAGE_SHIFT);
297+
#else
298+
DEFINE(HUGEPAGE_SIZE, PAGE_SIZE);
299+
#endif
292300
BLANK();
293301
DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
294302
DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));

0 commit comments

Comments
 (0)