Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 24660
b: refs/heads/master
c: bab70a4
h: refs/heads/master
v: v3
  • Loading branch information
Eugene Surovegin authored and Paul Mackerras committed Mar 29, 2006
1 parent 4da0576 commit dc694cb
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 32 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: bac30d1a78d0f11c613968fc8b351a91ed465386
refs/heads/master: bab70a4af737f623de5b034976a311055308ab86
30 changes: 17 additions & 13 deletions trunk/arch/powerpc/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,25 +267,29 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
#endif
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
pte_t *ptep;
pmd_t *pmdp;

/* Since 4xx/Book-E supports per-page execute permission,
* we lazily flush dcache to icache. */
ptep = NULL;
if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
struct page *page = pte_page(*ptep);

if (! test_bit(PG_arch_1, &page->flags)) {
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
if (get_pteptr(mm, address, &ptep, &pmdp)) {
spinlock_t *ptl = pte_lockptr(mm, pmdp);
spin_lock(ptl);
if (pte_present(*ptep)) {
struct page *page = pte_page(*ptep);

if (!test_bit(PG_arch_1, &page->flags)) {
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
}
pte_update(ptep, 0, _PAGE_HWEXEC);
_tlbie(address);
pte_unmap_unlock(ptep, ptl);
up_read(&mm->mmap_sem);
return 0;
}
pte_update(ptep, 0, _PAGE_HWEXEC);
_tlbie(address);
pte_unmap(ptep);
up_read(&mm->mmap_sem);
return 0;
pte_unmap_unlock(ptep, ptl);
}
if (ptep != NULL)
pte_unmap(ptep);
#endif
/* a write */
} else if (is_write) {
Expand Down
6 changes: 4 additions & 2 deletions trunk/arch/powerpc/mm/pgtable_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
* the PTE pointer is unmodified if PTE is not found.
*/
int
get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
{
pgd_t *pgd;
pmd_t *pmd;
Expand All @@ -387,6 +387,8 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
if (pte) {
retval = 1;
*ptep = pte;
if (pmdp)
*pmdp = pmd;
/* XXX caller needs to do pte_unmap, yuck */
}
}
Expand Down Expand Up @@ -424,7 +426,7 @@ unsigned long iopa(unsigned long addr)
mm = &init_mm;

pa = 0;
if (get_pteptr(mm, addr, &pte)) {
if (get_pteptr(mm, addr, &pte, NULL)) {
pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
pte_unmap(pte);
}
Expand Down
30 changes: 17 additions & 13 deletions trunk/arch/ppc/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
/* an exec - 4xx/Book-E allows for per-page execute permission */
} else if (TRAP(regs) == 0x400) {
pte_t *ptep;
pmd_t *pmdp;

#if 0
/* It would be nice to actually enforce the VM execute
Expand All @@ -215,21 +216,24 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
/* Since 4xx/Book-E supports per-page execute permission,
* we lazily flush dcache to icache. */
ptep = NULL;
if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
struct page *page = pte_page(*ptep);

if (! test_bit(PG_arch_1, &page->flags)) {
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
if (get_pteptr(mm, address, &ptep, &pmdp)) {
spinlock_t *ptl = pte_lockptr(mm, pmdp);
spin_lock(ptl);
if (pte_present(*ptep)) {
struct page *page = pte_page(*ptep);

if (!test_bit(PG_arch_1, &page->flags)) {
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
}
pte_update(ptep, 0, _PAGE_HWEXEC);
_tlbie(address);
pte_unmap_unlock(ptep, ptl);
up_read(&mm->mmap_sem);
return 0;
}
pte_update(ptep, 0, _PAGE_HWEXEC);
_tlbie(address);
pte_unmap(ptep);
up_read(&mm->mmap_sem);
return 0;
pte_unmap_unlock(ptep, ptl);
}
if (ptep != NULL)
pte_unmap(ptep);
#endif
/* a read */
} else {
Expand Down
6 changes: 4 additions & 2 deletions trunk/arch/ppc/mm/pgtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
* the PTE pointer is unmodified if PTE is not found.
*/
int
get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
{
pgd_t *pgd;
pmd_t *pmd;
Expand All @@ -383,6 +383,8 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
if (pte) {
retval = 1;
*ptep = pte;
if (pmdp)
*pmdp = pmd;
/* XXX caller needs to do pte_unmap, yuck */
}
}
Expand Down Expand Up @@ -420,7 +422,7 @@ unsigned long iopa(unsigned long addr)
mm = &init_mm;

pa = 0;
if (get_pteptr(mm, addr, &pte)) {
if (get_pteptr(mm, addr, &pte, NULL)) {
pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
pte_unmap(pte);
}
Expand Down
3 changes: 2 additions & 1 deletion trunk/include/asm-ppc/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,8 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
*/
#define pgtable_cache_init() do { } while (0)

extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
pmd_t **pmdp);

#include <asm-generic/pgtable.h>

Expand Down

0 comments on commit dc694cb

Please sign in to comment.