1

VMALLOC_START~VMALLOC_END でページ フォールトが発生した場合、do_translation_fault がページ テーブル エントリを埋めず、PG、PUD、PMD だけを埋めてしまうのはなぜですか?

arch/arm/mm/fault.c 内の対応するソース コード @do_translation_fault:

414 static int __kprobes
415 do_translation_fault(unsigned long addr, unsigned int fsr,
416                      struct pt_regs *regs)
417 {
418         unsigned int index;
419         pgd_t *pgd, *pgd_k;
420         pud_t *pud, *pud_k;
421         pmd_t *pmd, *pmd_k;
422
423         if (addr < TASK_SIZE)
424                 return do_page_fault(addr, fsr, regs);
425
426         if (user_mode(regs))
427                 goto bad_area;
428
429         index = pgd_index(addr);
430
431         /*
432          * FIXME: CP15 C1 is write only on ARMv3 architectures.
433          */
434         pgd = cpu_get_pgd() + index;
435         pgd_k = init_mm.pgd + index;
436
437         if (pgd_none(*pgd_k))
438                 goto bad_area;
439         if (!pgd_present(*pgd))
440                 set_pgd(pgd, *pgd_k);
441
442         pud = pud_offset(pgd, addr);
443         pud_k = pud_offset(pgd_k, addr);
444
445         if (pud_none(*pud_k))
446                 goto bad_area;
447         if (!pud_present(*pud)) 
448                 set_pud(pud, *pud_k);
449
450         pmd = pmd_offset(pud, addr);
451         pmd_k = pmd_offset(pud_k, addr);
452
453 #ifdef CONFIG_ARM_LPAE
454         /*
455          * Only one hardware entry per PMD with LPAE.
456          */
457         index = 0;
458 #else
459         /*
460          * On ARM one Linux PGD entry contains two hardware entries (see page
461          * tables layout in pgtable.h). We normally guarantee that we always
462          * fill both L1 entries. But create_mapping() doesn't follow the rule.
463          * It can create inidividual L1 entries, so here we have to call
464          * pmd_none() check for the entry really corresponded to address, not
465          * for the first of pair.
466          */
467         index = (addr >> SECTION_SHIFT) & 1;
468 #endif
469         if (pmd_none(pmd_k[index]))
470                 goto bad_area;
471
472         copy_pmd(pmd, pmd_k);
473         return 0;
474
475 bad_area:
476         do_bad_area(addr, fsr, regs);
477         return 0;
478 }
4

1 に答える 1

0

この範囲は、カーネル メモリ用に予約されており、vmalloc.

カーネル メモリは通常、IRQ (ソフトまたはハード) が無効になっているときにアクセスされ、ページ フォールトは処理できません。
関数はvmalloc事前にマッピングを作成するように注意するため、アクセス時にエラーが発生することはありません。
障害があった場合は、割り当てられていない (または解放された) メモリへのアクセスであるため、処理できないためです。

于 2012-06-18T13:04:47.667 に答える