ARM Linux 的TLB miss和page fault的异常解决
发布时间:2021-11-22 11:15:59 所属栏目:PHP教程 来源:互联网
导读:ARMLinux的TLB miss处理过程Heron(2012.11.23) 在ARM架构下,TLB miss后的工作绝大多数情况是由hardwarepage table walk完成,特殊情况下hardware page table walk可以被关闭,此时发生TLB miss后CPU就会产生一个translationfault,剩下的工作由OS接管,完
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函数中就读取了IFSR和IFAR两个寄存器的值: //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函数中就读取了IFSR和IFAR两个寄存器的值: //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)进行处理。 ![]() (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |