Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 175716
b: refs/heads/master
c: 0895ecd
h: refs/heads/master
v: v3
  • Loading branch information
David Gibson authored and Benjamin Herrenschmidt committed Oct 30, 2009
1 parent 6ffc2fa commit c3ee2b5
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 62 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 883a3e523672ebba2ec3969837ba02af4f70fae2
refs/heads/master: 0895ecda79428df48501e48dd0a868e0c8e1aae2
25 changes: 19 additions & 6 deletions trunk/arch/powerpc/include/asm/hugetlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,15 @@
pte_t *huge_pte_offset_and_shift(struct mm_struct *mm,
unsigned long addr, unsigned *shift);

void flush_dcache_icache_hugepage(struct page *page);

int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
unsigned long len);

void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
unsigned long end, unsigned long floor,
unsigned long ceiling);

void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);

pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);

/*
* The version of vma_mmu_pagesize() in arch/powerpc/mm/hugetlbpage.c needs
* to override the version in mm/hugetlb.c
Expand All @@ -44,9 +40,26 @@ static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
{
}


static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
set_pte_at(mm, addr, ptep, pte);
}

static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1);
return __pte(old);
}

static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
pte_t pte;
pte = huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
flush_tlb_page(vma, addr);
}

static inline int huge_pte_none(pte_t pte)
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/include/asm/mmu-hash64.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ extern int __hash_page_64K(unsigned long ea, unsigned long access,
unsigned long vsid, pte_t *ptep, unsigned long trap,
unsigned int local, int ssize);
struct mm_struct;
unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap);
extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap);
int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
pte_t *ptep, unsigned long trap, int local, int ssize,
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/mm/hash_utils_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
/* page is dirty */
if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
if (trap == 0x400) {
__flush_dcache_icache(page_address(page));
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
} else
pp |= HPTE_R_N;
Expand Down
30 changes: 1 addition & 29 deletions trunk/arch/powerpc/mm/hugetlbpage-hash64.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,6 @@
#include <asm/cacheflush.h>
#include <asm/machdep.h>

/*
* Called by asm hashtable.S for doing lazy icache flush
*/
static unsigned int hash_huge_page_do_lazy_icache(unsigned long rflags,
pte_t pte, int trap, unsigned long sz)
{
struct page *page;
int i;

if (!pfn_valid(pte_pfn(pte)))
return rflags;

page = pte_page(pte);

/* page is dirty */
if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
if (trap == 0x400) {
for (i = 0; i < (sz / PAGE_SIZE); i++)
__flush_dcache_icache(page_address(page+i));
set_bit(PG_arch_1, &page->flags);
} else {
rflags |= HPTE_R_N;
}
}
return rflags;
}

int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
pte_t *ptep, unsigned long trap, int local, int ssize,
unsigned int shift, unsigned int mmu_psize)
Expand Down Expand Up @@ -89,8 +62,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
/* No CPU has hugepages but lacks no execute, so we
* don't need to worry about that case */
rflags = hash_huge_page_do_lazy_icache(rflags, __pte(old_pte),
trap, sz);
rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);

/* Check if pte already has an hpte (case 2) */
if (unlikely(old_pte & _PAGE_HASHPTE)) {
Expand Down
31 changes: 10 additions & 21 deletions trunk/arch/powerpc/mm/hugetlbpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,27 +344,6 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
} while (pgd++, addr = next, addr != end);
}

void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
if (pte_present(*ptep)) {
/* We open-code pte_clear because we need to pass the right
* argument to hpte_need_flush (huge / !huge). Might not be
* necessary anymore if we make hpte_need_flush() get the
* page size from the slices
*/
pte_update(mm, addr, ptep, ~0UL, 1);
}
*ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
}

pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1);
return __pte(old);
}

struct page *
follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
{
Expand Down Expand Up @@ -580,3 +559,13 @@ static int __init hugetlbpage_init(void)
}

module_init(hugetlbpage_init);

void flush_dcache_icache_hugepage(struct page *page)
{
int i;

BUG_ON(!PageCompound(page));

for (i = 0; i < (1UL << compound_order(page)); i++)
__flush_dcache_icache(page_address(page+i));
}
17 changes: 13 additions & 4 deletions trunk/arch/powerpc/mm/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <linux/pagemap.h>
#include <linux/suspend.h>
#include <linux/lmb.h>
#include <linux/hugetlb.h>

#include <asm/pgalloc.h>
#include <asm/prom.h>
Expand Down Expand Up @@ -417,18 +418,26 @@ EXPORT_SYMBOL(flush_dcache_page);

void flush_dcache_icache_page(struct page *page)
{
#ifdef CONFIG_HUGETLB_PAGE
if (PageCompound(page)) {
flush_dcache_icache_hugepage(page);
return;
}
#endif
#ifdef CONFIG_BOOKE
void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
__flush_dcache_icache(start);
kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
{
void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
__flush_dcache_icache(start);
kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
}
#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
/* On 8xx there is no need to kmap since highmem is not supported */
__flush_dcache_icache(page_address(page));
#else
__flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
#endif

}

void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
{
clear_page(page);
Expand Down

0 comments on commit c3ee2b5

Please sign in to comment.