日期:2014-05-16  浏览次数:20867 次

ARM Linux 的TLB miss和page fault的异常处理

ARMLinux的TLB miss处理过程

——Heron(2012.11.23)

在ARM架构下,TLB miss后的工作绝大多数情况是由hardwarepage table walk完成,特殊情况下hardware page table walk可以被关闭,此时发生TLB miss后CPU就会产生一个translationfault,剩下的工作由OS接管,完成对于translation fault的异常处理。

默认情况下,发生TLB miss后,hardware page table walk自动启动开始扫描内存中的pagetable,若找到相应PTE(page table entry),则自动完成TLB entry的重填工作;如果找不到,则发出一个page fault异常,然后OS接管处理page fault。内核中有do_page_fault函数,该函数从硬盘中调换页面进内存,更新页表,然后重新执行发生TLB miss的那条指令,hardware page table walk重新执行,完成TLB重填的工作。

这里关心的是关闭hardware pagetable walk后,再发生TLB miss后的处理例程。如果发生这种情况,ARM CPU会发出一个translation fault(If translation table walksare disabled, for example, PD0 or EPD0 is set to 1 for TTBR0, or PD1 or EPD1 isset to 1 for TTBR1, the processor returns a Translation fault.见cortex-A15TRM p 5-5)。OS处理该异常的流程如下。

 

首先发生translation fault后,CPU会发出一个abort异常,然后跳转到该异常地址处(以发生指令预取中止异常为例,跳转到0x00000010)去执行,该地址处存放的是一个跳转指令 (W(b)         vector_pabt +stubs_offset),然后,通过判断,若发生该异常的指令处于usr模式,则跳转到__pabt_usr函数去执行,该函数中有条跳转指令bl CPU_PABORT_HANDLER,CPU_PABORT_HANDLER是个宏定义,对于ARMv7,该定义是:# define CPU_PABORT_HANDLER v7_pabort,

v7_pabort函数中就读取了IFSRIFAR两个寄存器的值:

//pabort-v7.S

/*

 *Function: v6_pabort

 *

 *Params  : r0 = address of aborted instruction

 *

 *Returns : r0 = address of abort

 *         : r1 = IFSR

 *

 *Purpose : obtain information about current prefetch abort.

 */

         .align        5

ENTRY(v7_pabort)

         mrc  p15,0, r0, c6, c0, 2         @ get IFAR

         mrc  p15,0, r1, c5, c0, 1         @ get IFSR

         mov pc,lr

ENDPROC(v7_pabort)

 

IFAR中存储了发生异常的指令地址,IFSR中存储的是一个32位数,其中某些位表明异常类型等(参考Cortex-A15TRM p4-76

 

         剩余的工作就是根据以上两个寄存器提取出来的信息,调用相应函数(do_PrefetchAbort——>do_translation_fault)进行处理。OS接管后的操作是(do_translation_fault函数),首先判断发生TLBmiss的那条指令是用户指令还是系统指令,如果是系统指令则剩余工作是对页全局目录(pgd),页上级目录(pud)