Revert "powerpc/mm: Fix bug in pagetable cache cleanup with CONFIG_PPC_SUBPAGE_PROT"

This reverts commit c045256d14.

It breaks build when CONFIG_PPC_SUBPAGE_PROT is not set. I will
commit a fixed version separately

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Benjamin Herrenschmidt 2009-12-02 09:28:35 +11:00
parent 86f9e097f3
commit 5a7b4193e5
6 changed files with 49 additions and 51 deletions

View File

@ -373,38 +373,6 @@ 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(pgd_t *pgd) {}
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 {
@ -418,9 +386,6 @@ 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;

View File

@ -28,6 +28,10 @@
*/
#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])
@ -38,6 +42,7 @@ 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);
}

View File

@ -76,4 +76,41 @@
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__ */

View File

@ -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(struct mm_struct *mm, unsigned long ea)
static int subpage_protection(pgd_t *pgdir, unsigned long ea)
{
struct subpage_prot_table *spt = &mm->context.spt;
struct subpage_prot_table *spt = pgd_subpage_prot(pgdir);
u32 spp = 0;
u32 **sbpm, *sbpp;
@ -865,7 +865,7 @@ static int subpage_protection(struct mm_struct *mm, unsigned long ea)
}
#else /* CONFIG_PPC_SUBPAGE_PROT */
static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
static inline int subpage_protection(pgd_t *pgdir, unsigned long ea)
{
return 0;
}

View File

@ -76,7 +76,6 @@ 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;
@ -93,6 +92,5 @@ 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;
}

View File

@ -24,9 +24,9 @@
* Also makes sure that the subpage_prot_table structure is
* reinitialized for the next user.
*/
void subpage_prot_free(struct mm_struct *mm)
void subpage_prot_free(pgd_t *pgd)
{
struct subpage_prot_table *spt = &mm->context.spt;
struct subpage_prot_table *spt = pgd_subpage_prot(pgd);
unsigned long i, j, addr;
u32 **p;
@ -51,13 +51,6 @@ void subpage_prot_free(struct mm_struct *mm)
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)
{
@ -94,7 +87,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 = &mm->context.spt;
struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
u32 **spm, *spp;
int i, nw;
unsigned long next, limit;
@ -143,7 +136,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 = &mm->context.spt;
struct subpage_prot_table *spt = pgd_subpage_prot(mm->pgd);
u32 **spm, *spp;
int i, nw;
unsigned long next, limit;