示例#1
0
static inline pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
{
	pgd_t * pgd;
	pmd_t * pmd;
	pte_t * pte = NULL;

	pgd = pgd_offset(mm, addr);
	if (pgd_none(*pgd))
		goto end;
	if (pgd_bad(*pgd)) {
		pgd_ERROR(*pgd);
		pgd_clear(pgd);
		goto end;
	}

	pmd = pmd_offset(pgd, addr);
	if (pmd_none(*pmd))
		goto end;
	if (pmd_bad(*pmd)) {
		pmd_ERROR(*pmd);
		pmd_clear(pmd);
		goto end;
	}

	pte = pte_offset_map_nested(pmd, addr);
	if (pte_none(*pte)) {
		pte_unmap_nested(pte);
		pte = NULL;
	}
end:
	return pte;
}
示例#2
0
文件: pgd.c 项目: chrmorais/miniemc2
/*
 * need to get a 16k page for level 1
 */
pgd_t *get_pgd_slow(struct mm_struct *mm)
{
	pgd_t *new_pgd, *init_pgd;
	pmd_t *new_pmd, *init_pmd;
	pte_t *new_pte, *init_pte;
	unsigned long flags;

	new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
	if (!new_pgd)
		goto no_pgd;

	memset(new_pgd, 0, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));

	/*
	 * Copy over the kernel and IO PGD entries
	 */
	init_pgd = pgd_offset_k(0);
	pgd_list_lock(flags);
	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
	pgd_list_add(new_pgd);
	pgd_list_unlock(flags);

	clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));

	if (!vectors_high()) {
#ifdef CONFIG_ARM_FCSE
		/* FCSE does not work without high vectors. */
		BUG();
#endif /* CONFIG_ARM_FCSE */

		/*
		 * On ARM, first page must always be allocated since it
		 * contains the machine vectors.
		 */
		new_pmd = pmd_alloc(mm, new_pgd, 0);
		if (!new_pmd)
			goto no_pmd;

		new_pte = pte_alloc_map(mm, new_pmd, 0);
		if (!new_pte)
			goto no_pte;

		init_pmd = pmd_offset(init_pgd, 0);
		init_pte = pte_offset_map_nested(init_pmd, 0);
		set_pte_ext(new_pte, *init_pte, 0);
		pte_unmap_nested(init_pte);
		pte_unmap(new_pte);
	}

	return new_pgd;

no_pte:
	pmd_free(mm, new_pmd);
no_pmd:
	free_pages((unsigned long)new_pgd, 2);
no_pgd:
	return NULL;
}
示例#3
0
/*
 * get_pgd_slow:申请一个pgd项
 * notice:一个pgd占用4个页框,每一个pgt项大小为8字节
 */
pgd_t *get_pgd_slow(struct mm_struct *mm)
{
	pgd_t *new_pgd, *init_pgd;
	pmd_t *new_pmd, *init_pmd;
	pte_t *new_pte, *init_pte;

	/*pgd占用四个页框*/
	new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
	if (!new_pgd)
		goto no_pgd;

	memset(new_pgd, 0, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));

	/*
	 * 复制内核与I/O PGD entries
	 */
	init_pgd = pgd_offset_k(0);
	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));

	clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));

	if (!vectors_high()) {
		/*
		 * On ARM, first page must always be allocated since it
		 * contains the machine vectors.
		 */
		new_pmd = pmd_alloc(mm, new_pgd, 0);
		if (!new_pmd)
			goto no_pmd;

		/*返回pmd的第0项页表项,因为第0项用于映射中断向量*/
		new_pte = pte_alloc_map(mm, new_pmd, 0);
		if (!new_pte)
			goto no_pte;

		/*返回中断向量的页表项,中断向量位于低地址空间时(0地址开始处)*/
		init_pmd = pmd_offset(init_pgd, 0);
		init_pte = pte_offset_map_nested(init_pmd, 0);
		/*给新的页表项映射中断向量的页表项*/
		set_pte_ext(new_pte, *init_pte, 0);
		pte_unmap_nested(init_pte);
		/*取消new_pte的高端内存的页表映射*/
		pte_unmap(new_pte);
	}

	return new_pgd;

no_pte:
	pmd_free(mm, new_pmd);
no_pmd:
	free_pages((unsigned long)new_pgd, 2);
no_pgd:
	return NULL;
}
示例#4
0
/*
 * need to get a 16k page for level 1
 */
pgd_t *get_pgd_slow(struct mm_struct *mm)
{
    pgd_t *new_pgd, *init_pgd;
    pmd_t *new_pmd, *init_pmd;
    pte_t *new_pte, *init_pte;

    new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
    if (!new_pgd)
        goto no_pgd;

    memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));

    /*
     * Copy over the kernel and IO PGD entries
     */
    init_pgd = pgd_offset_k(0);
    memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
           (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));

    clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));

    if (!vectors_high()) {
        /*
         * On ARM, first page must always be allocated since it
         * contains the machine vectors.
         */
        new_pmd = pmd_alloc(mm, new_pgd, 0);
        if (!new_pmd)
            goto no_pmd;

        new_pte = pte_alloc_map(mm, new_pmd, 0);
        if (!new_pte)
            goto no_pte;

        init_pmd = pmd_offset(init_pgd, 0);
        init_pte = pte_offset_map_nested(init_pmd, 0);
        set_pte_ext(new_pte, *init_pte, 0);
        pte_unmap_nested(init_pte);
        pte_unmap(new_pte);
    }

    return new_pgd;

no_pte:
    pmd_free(mm, new_pmd);
no_pmd:
    free_pages((unsigned long)new_pgd, 2);
no_pgd:
    return NULL;
}
示例#5
0
/*
 * need to get a 16k page for level 1
 */
pgd_t *get_pgd_slow(struct mm_struct *mm)
{
	pgd_t *new_pgd, *init_pgd;
	pmd_t *new_pmd, *init_pmd;
	pte_t *new_pte, *init_pte;

	new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
	if (!new_pgd)
		goto no_pgd;

	memset(new_pgd, 0, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));

	/*
	 * Copy over the kernel and IO PGD entries
	 */
	//#define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
	//其实就是要拷贝内核空间的页表项...
	init_pgd = pgd_offset_k(0);
	//拷贝内核空间的pgd表项到新创建的pgd表项
	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
	//把Dcache行的数据写回到主存,并清除cache行的脏标记.
	//参数:主存的物理地址,(确定cache行) 需要写回的长度...
	clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
	
	//异常向量表是在高端地址或是在低端地址...
	if (!vectors_high()) {
		 //如果是在低端地址.那么异常向量表在第一页..
		/*
		 * On ARM, first page must always be allocated since it
		 * contains the machine vectors.
		 */
		//该函数是在new_pgd指定的PGD页表上找到地址0对应的表项,然后分配一个页.
		//接着填充PGD的页表项(PMD).
		//哦,好像略过了PUD了、对于ARM来说PMD也是直接返回pgd.
		new_pmd = pmd_alloc(mm, new_pgd, 0);
		if (!new_pmd)
			goto no_pmd;
		//如果为空则分配一个页面,然后设置PGD的页表项.
		new_pte = pte_alloc_map(mm, new_pmd, 0);
		if (!new_pte)
			goto no_pte;
		//init_pgd就是init进程的页表,这里得到地址0的PGD页表的表项(PMD)
		init_pmd = pmd_offset(init_pgd, 0);
		//根据init_pmd,得到了PMD页表,然后根据0地址得到了PMD的表项(PTE)
		init_pte = pte_offset_map_nested(init_pmd, 0);
		//new_pte指定了要存放PTE的地址,init_pte就是PTE的值。
		set_pte_ext(new_pte, *init_pte, 0);
		pte_unmap_nested(init_pte);
		pte_unmap(new_pte);
	}

	return new_pgd;

no_pte:
	pmd_free(mm, new_pmd);
no_pmd:
	free_pages((unsigned long)new_pgd, 2);
no_pgd:
	return NULL;
}