Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 99243
b: refs/heads/master
c: a9a934f
h: refs/heads/master
i:
  99241: 249fa17
  99239: 7e9d9b5
v: v3
  • Loading branch information
Haavard Skinnemoen committed Jul 2, 2008
1 parent 27a4ad3 commit 58e0d04
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 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: cfd23e93a0289cf6711fd3877c5226658d87240a
refs/heads/master: a9a934f278613885816aa9f177968c1dac557240
42 changes: 32 additions & 10 deletions trunk/arch/avr32/kernel/entry-avr32b.S
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ tlb_miss_common:
mfsr r0, SYSREG_TLBEAR
mfsr r1, SYSREG_PTBR

/* Is it the vmalloc space? */
bld r0, 31
brcs handle_vmalloc_miss

/*
* First level lookup: The PGD contains virtual pointers to
* the second-level page tables, but they may be NULL if not
Expand Down Expand Up @@ -143,15 +139,13 @@ pgtbl_lookup:
tlbmiss_restore
rete

handle_vmalloc_miss:
/* Simply do the lookup in init's page table */
mov r1, lo(swapper_pg_dir)
orh r1, hi(swapper_pg_dir)
rjmp pgtbl_lookup

/* The slow path of the TLB miss handler */
.align 2
page_table_not_present:
/* Do we need to synchronize with swapper_pg_dir? */
bld r0, 31
brcs sync_with_swapper_pg_dir

page_not_present:
tlbmiss_restore
sub sp, 4
Expand All @@ -162,6 +156,34 @@ page_not_present:
rcall do_page_fault
rjmp ret_from_exception

.align 2
sync_with_swapper_pg_dir:
/*
* If swapper_pg_dir contains a non-NULL second-level page
* table pointer, copy it into the current PGD. If not, we
* must handle it as a full-blown page fault.
*
* Jumping back to pgtbl_lookup causes an unnecessary lookup,
* but it is guaranteed to be a cache hit, it won't happen
* very often, and we absolutely do not want to sacrifice any
* performance in the fast path in order to improve this.
*/
mov r1, lo(swapper_pg_dir)
orh r1, hi(swapper_pg_dir)
ld.w r3, r1[r2 << 2]
cp.w r3, 0
breq page_not_present
mfsr r1, SYSREG_PTBR
st.w r1[r2 << 2], r3
rjmp pgtbl_lookup

/*
* We currently have two bytes left at this point until we
* crash into the system call handler...
*
* Don't worry, the assembler will let us know.
*/


/* --- System Call --- */

Expand Down
14 changes: 10 additions & 4 deletions trunk/include/asm-avr32/pgalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#define __ASM_AVR32_PGALLOC_H

#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>

static inline void pmd_populate_kernel(struct mm_struct *mm,
pmd_t *pmd, pte_t *pte)
Expand All @@ -30,12 +28,20 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
*/
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL);
pgd_t *pgd;

pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
if (likely(pgd))
memcpy(pgd + USER_PTRS_PER_PGD,
swapper_pg_dir + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));

return pgd;
}

static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
kfree(pgd);
free_page((unsigned long)pgd);
}

static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
Expand Down

0 comments on commit 58e0d04

Please sign in to comment.