ia64/linux-2.6.18-xen.hg

changeset 12:5ce6cd5ee596

Imported patch pmd-shared.patch from xen-unstable.hg 15200:bd3d6b4c52ec
author Ian Campbell <ian.campbell@xensource.com>
date Mon Jun 04 10:05:24 2007 +0100 (2007-06-04)
parents e1c18245a2f5
children f1b1f024f0ed
files arch/i386/mm/pageattr.c arch/i386/mm/pgtable.c include/asm-i386/pgtable-2level-defs.h include/asm-i386/pgtable-3level-defs.h
line diff
     1.1 --- a/arch/i386/mm/pageattr.c	Mon Jun 04 10:05:24 2007 +0100
     1.2 +++ b/arch/i386/mm/pageattr.c	Mon Jun 04 10:05:24 2007 +0100
     1.3 @@ -84,7 +84,7 @@ static void set_pmd_pte(pte_t *kpte, uns
     1.4  	unsigned long flags;
     1.5  
     1.6  	set_pte_atomic(kpte, pte); 	/* change init_mm */
     1.7 -	if (PTRS_PER_PMD > 1)
     1.8 +	if (HAVE_SHARED_KERNEL_PMD)
     1.9  		return;
    1.10  
    1.11  	spin_lock_irqsave(&pgd_lock, flags);
     2.1 --- a/arch/i386/mm/pgtable.c	Mon Jun 04 10:05:24 2007 +0100
     2.2 +++ b/arch/i386/mm/pgtable.c	Mon Jun 04 10:05:24 2007 +0100
     2.3 @@ -214,9 +214,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
     2.4  		spin_lock_irqsave(&pgd_lock, flags);
     2.5  	}
     2.6  
     2.7 -	clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
     2.8 -			swapper_pg_dir + USER_PTRS_PER_PGD,
     2.9 -			KERNEL_PGD_PTRS);
    2.10 +	if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
    2.11 +		clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
    2.12 +				swapper_pg_dir + USER_PTRS_PER_PGD,
    2.13 +				KERNEL_PGD_PTRS);
    2.14  	if (PTRS_PER_PMD > 1)
    2.15  		return;
    2.16  
    2.17 @@ -248,6 +249,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
    2.18  			goto out_oom;
    2.19  		set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
    2.20  	}
    2.21 +
    2.22 +	if (!HAVE_SHARED_KERNEL_PMD) {
    2.23 +		unsigned long flags;
    2.24 +
    2.25 +		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
    2.26 +			pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
    2.27 +			if (!pmd)
    2.28 +				goto out_oom;
    2.29 +			set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
    2.30 +		}
    2.31 +
    2.32 +		spin_lock_irqsave(&pgd_lock, flags);
    2.33 +		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
    2.34 +			unsigned long v = (unsigned long)i << PGDIR_SHIFT;
    2.35 +			pgd_t *kpgd = pgd_offset_k(v);
    2.36 +			pud_t *kpud = pud_offset(kpgd, v);
    2.37 +			pmd_t *kpmd = pmd_offset(kpud, v);
    2.38 +			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
    2.39 +			memcpy(pmd, kpmd, PAGE_SIZE);
    2.40 +		}
    2.41 +		pgd_list_add(pgd);
    2.42 +		spin_unlock_irqrestore(&pgd_lock, flags);
    2.43 +	}
    2.44 +
    2.45  	return pgd;
    2.46  
    2.47  out_oom:
    2.48 @@ -262,9 +287,23 @@ void pgd_free(pgd_t *pgd)
    2.49  	int i;
    2.50  
    2.51  	/* in the PAE case user pgd entries are overwritten before usage */
    2.52 -	if (PTRS_PER_PMD > 1)
    2.53 -		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
    2.54 -			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
    2.55 +	if (PTRS_PER_PMD > 1) {
    2.56 +		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
    2.57 +			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
    2.58 +			kmem_cache_free(pmd_cache, pmd);
    2.59 +		}
    2.60 +		if (!HAVE_SHARED_KERNEL_PMD) {
    2.61 +			unsigned long flags;
    2.62 +			spin_lock_irqsave(&pgd_lock, flags);
    2.63 +			pgd_list_del(pgd);
    2.64 +			spin_unlock_irqrestore(&pgd_lock, flags);
    2.65 +			for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
    2.66 +				pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
    2.67 +				memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
    2.68 +				kmem_cache_free(pmd_cache, pmd);
    2.69 +			}
    2.70 +		}
    2.71 +	}
    2.72  	/* in the non-PAE case, free_pgtables() clears user pgd entries */
    2.73  	kmem_cache_free(pgd_cache, pgd);
    2.74  }
     3.1 --- a/include/asm-i386/pgtable-2level-defs.h	Mon Jun 04 10:05:24 2007 +0100
     3.2 +++ b/include/asm-i386/pgtable-2level-defs.h	Mon Jun 04 10:05:24 2007 +0100
     3.3 @@ -1,6 +1,8 @@
     3.4  #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
     3.5  #define _I386_PGTABLE_2LEVEL_DEFS_H
     3.6  
     3.7 +#define HAVE_SHARED_KERNEL_PMD 0
     3.8 +
     3.9  /*
    3.10   * traditional i386 two-level paging structure:
    3.11   */
     4.1 --- a/include/asm-i386/pgtable-3level-defs.h	Mon Jun 04 10:05:24 2007 +0100
     4.2 +++ b/include/asm-i386/pgtable-3level-defs.h	Mon Jun 04 10:05:24 2007 +0100
     4.3 @@ -1,6 +1,8 @@
     4.4  #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
     4.5  #define _I386_PGTABLE_3LEVEL_DEFS_H
     4.6  
     4.7 +#define HAVE_SHARED_KERNEL_PMD 1
     4.8 +
     4.9  /*
    4.10   * PGDIR_SHIFT determines what a top-level page table entry can map
    4.11   */