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),页中间目录(pmd)进行操作;如果是用户指令,则调用do_page_fault函数,剩下的工作就是page fault的处理过程,根据不同情况判断,包括权限检查,分配页面,发送SIGSEGV信号给进程,直接杀死进程等。不管哪种操作,OS都没有对TLB进行重填。

 

 

 

 

对于page fault的处理过程如下:在取数或者取指令时,发生指令或者数据的地址不存在的情况,则发生中止异常。

 

      以取指发生异常为例。发生指令预取中止异常后,CPU自动跳转到0x0000000C(可配置成0xfffffffc,这里不考虑)去执行,该地址处是一个跳转指令 (W(b)        vector_pabt + stubs_offset),然后,通过判断,若发生该异常的指令处于usr模式,则跳转到__pabt_usr函数去执行,该函数中有条跳转指令bl      CPU_PABORT_HANDLER,CPU_PABORT_HANDLER是个宏定义,对于ARMv7,该定义是:#  defineCPU_PABORT_HANDLER v7_pabort,v7_pabort函数中就读取了IFSRIFAR两个寄存器的值:

//pabort-v7.S

/*

 * Function: v6_pabort

 *

 * Params  : r0 = address ofaborted instruction

 *

 * Returns : r0 = address of abort

 *        : r1 = IFSR

 *

 * Purpose : obtain information aboutcurrent 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-A15 TRM p4-76

 

         剩余的工作就是根据以上两个寄存器提取出来的信息,调用相应函数do_PrefetchAbort——>do_page_fault进行处理。

 

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐