Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 175807
b: refs/heads/master
c: d28513b
h: refs/heads/master
i:
  175805: 387c9b9
  175803: 0a77c38
  175799: 5ead775
  175791: a0b48be
  175775: 52d78d7
  175743: 225c6a1
v: v3
  • Loading branch information
David Gibson authored and Benjamin Herrenschmidt committed Dec 8, 2009
1 parent 43072f1 commit 9a483ba
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 50 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: 5a7b4193e564d1611ecf1cd859aed60d5612d78f
refs/heads/master: d28513bc7f675d28b479db666d572e078ecf182d
35 changes: 35 additions & 0 deletions trunk/arch/powerpc/include/asm/mmu-hash64.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,38 @@ extern void slb_set_size(u16 size);

#ifndef __ASSEMBLY__

#ifdef CONFIG_PPC_SUBPAGE_PROT
/*
* For the sub-page protection option, we extend the PGD with one of
* these. Basically we have a 3-level tree, with the top level being
* the protptrs array. To optimize speed and memory consumption when
* only addresses < 4GB are being protected, pointers to the first
* four pages of sub-page protection words are stored in the low_prot
* array.
* Each page of sub-page protection words protects 1GB (4 bytes
* protects 64k). For the 3-level tree, each page of pointers then
* protects 8TB.
*/
struct subpage_prot_table {
unsigned long maxaddr; /* only addresses < this are protected */
unsigned int **protptrs[2];
unsigned int *low_prot[4];
};

#define SBP_L1_BITS (PAGE_SHIFT - 2)
#define SBP_L2_BITS (PAGE_SHIFT - 3)
#define SBP_L1_COUNT (1 << SBP_L1_BITS)
#define SBP_L2_COUNT (1 << SBP_L2_BITS)
#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)

extern void subpage_prot_free(struct mm_struct *mm);
extern void subpage_prot_init_new_context(struct mm_struct *mm);
#else
static inline void subpage_prot_free(struct mm_struct *mm) {}
static inline void subpage_prot_init_new_context(struct mm_struct *mm) { }
#endif /* CONFIG_PPC_SUBPAGE_PROT */

typedef unsigned long mm_context_id_t;

typedef struct {
Expand All @@ -386,6 +418,9 @@ typedef struct {
u16 sllp; /* SLB page size encoding */
#endif
unsigned long vdso_base;
#ifdef CONFIG_PPC_SUBPAGE_PROT
struct subpage_prot_table spt;
#endif /* CONFIG_PPC_SUBPAGE_PROT */
} mm_context_t;


Expand Down
5 changes: 0 additions & 5 deletions trunk/arch/powerpc/include/asm/pgalloc-64.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@
*/
#define MAX_PGTABLE_INDEX_SIZE 0xf

#ifndef CONFIG_PPC_SUBPAGE_PROT
static inline void subpage_prot_free(pgd_t *pgd) {}
#endif

extern struct kmem_cache *pgtable_cache[];
#define PGT_CACHE(shift) (pgtable_cache[(shift)-1])

Expand All @@ -42,7 +38,6 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)

static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
subpage_prot_free(pgd);
kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
}

Expand Down
37 changes: 0 additions & 37 deletions trunk/arch/powerpc/include/asm/pte-hash64-64k.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,41 +76,4 @@
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))


#ifdef CONFIG_PPC_SUBPAGE_PROT
/*
* For the sub-page protection option, we extend the PGD with one of
* these. Basically we have a 3-level tree, with the top level being
* the protptrs array. To optimize speed and memory consumption when
* only addresses < 4GB are being protected, pointers to the first
* four pages of sub-page protection words are stored in the low_prot
* array.
* Each page of sub-page protection words protects 1GB (4 bytes
* protects 64k). For the 3-level tree, each page of pointers then
* protects 8TB.
*/
struct subpage_prot_table {
unsigned long maxaddr; /* only addresses < this are protected */
unsigned int **protptrs[2];
unsigned int *low_prot[4];
};

#undef PGD_TABLE_SIZE
#define PGD_TABLE_SIZE ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \
sizeof(struct subpage_prot_table))

#define SBP_L1_BITS (PAGE_SHIFT - 2)
#define SBP_L2_BITS (PAGE_SHIFT - 3)
#define SBP_L1_COUNT (1 << SBP_L1_BITS)
#define SBP_L2_COUNT (1 << SBP_L2_BITS)
#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)

extern void subpage_prot_free(pgd_t *pgd);

static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
{
return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD);
}
#endif /* CONFIG_PPC_SUBPAGE_PROT */
#endif /* __ASSEMBLY__ */
6 changes: 3 additions & 3 deletions trunk/arch/powerpc/mm/hash_utils_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -835,9 +835,9 @@ void demote_segment_4k(struct mm_struct *mm, unsigned long addr)
* Result is 0: full permissions, _PAGE_RW: read-only,
* _PAGE_USER or _PAGE_USER|_PAGE_RW: no access.
*/
static int subpage_protection(pgd_t *pgdir, unsigned long ea)
static int subpage_protection(struct mm_struct *mm, unsigned long ea)
{
struct subpage_prot_table *spt = pgd_subpage_prot(pgdir);
struct subpage_prot_table *spt = &mm->context.spt;
u32 spp = 0;
u32 **sbpm, *sbpp;

Expand Down Expand Up @@ -865,7 +865,7 @@ static int subpage_protection(pgd_t *pgdir, unsigned long ea)
}

#else /* CONFIG_PPC_SUBPAGE_PROT */
static inline int subpage_protection(pgd_t *pgdir, unsigned long ea)
static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
{
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/mm/mmu_context_hash64.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
*/
if (slice_mm_new_context(mm))
slice_set_user_psize(mm, mmu_virtual_psize);
subpage_prot_init_new_context(mm);
mm->context.id = index;

return 0;
Expand All @@ -92,5 +93,6 @@ EXPORT_SYMBOL_GPL(__destroy_context);
void destroy_context(struct mm_struct *mm)
{
__destroy_context(mm->context.id);
subpage_prot_free(mm);
mm->context.id = NO_CONTEXT;
}
15 changes: 11 additions & 4 deletions trunk/arch/powerpc/mm/subpage-prot.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
* Also makes sure that the subpage_prot_table structure is
* reinitialized for the next user.
*/
void subpage_prot_free(pgd_t *pgd)
void subpage_prot_free(struct mm_struct *mm)
{
struct subpage_prot_table *spt = pgd_subpage_prot(pgd);
struct subpage_prot_table *spt = &mm->context.spt;
unsigned long i, j, addr;
u32 **p;

Expand All @@ -51,6 +51,13 @@ void subpage_prot_free(pgd_t *pgd)
spt->maxaddr = 0;
}

void subpage_prot_init_new_context(struct mm_struct *mm)
{
struct subpage_prot_table *spt = &mm->context.spt;

memset(spt, 0, sizeof(*spt));
}

static void hpte_flush_range(struct mm_struct *mm, unsigned long addr,
int npages)
{
Expand Down Expand Up @@ -87,7 +94,7 @@ static void hpte_flush_range(struct mm_struct *mm, unsigned long addr,
static void subpage_prot_clear(unsigned long addr, unsigned long len)
{
struct mm_struct *mm = current->mm;
struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
struct subpage_prot_table *spt = &mm->context.spt;
u32 **spm, *spp;
int i, nw;
unsigned long next, limit;
Expand Down Expand Up @@ -136,7 +143,7 @@ static void subpage_prot_clear(unsigned long addr, unsigned long len)
long sys_subpage_prot(unsigned long addr, unsigned long len, u32 __user *map)
{
struct mm_struct *mm = current->mm;
struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
struct subpage_prot_table *spt = &mm->context.spt;
u32 **spm, *spp;
int i, nw;
unsigned long next, limit;
Expand Down

0 comments on commit 9a483ba

Please sign in to comment.