TLB基础建设

TLB基础建设

问题背景

用户对内存页配置页属性成功,但页属性未生效。

例如:对分配到的某块内存进行memset(),然后设置只读属性,再进行memset()时不触发写保护。

int ret;

int x[DEFAULT_PAGE_SIZE] __attribute__((aligned(DEFAULT_PAGE_SIZE))) = { 0 };

memset(x, 0x10, sizeof(x));

ret = os_set_attribute(x, sizeof(x); USER_ONLY_READ);

if (ret != 0) {

       printk("%s[%d]: os_set_attribute() failed!!!\n", __FUNCTION__, __LINE__);

}

memset(x, 0x10, sizeof(x));

return 0

简介

ls2k芯片采用MIPS架构,32位,可参考GS264文档中对核心寄存器介绍,本问题的根因是由于配置页属性后未及时刷新TLB,导致在未触发换页等置换页表属性的操作时,TLB中的内容与以配置到内存中的页属性不同步引起。ls2k与TLB相关的主要是协处理器C0中的寄存器,均在GS264。

页属性的检测,读写权限等是通过MMU实现的,MMU在将虚拟地址(逻辑地址)映射物理地址过程中会检测虚拟内存页属性。

ls2k芯片TLB表项总共64项,可通过index寄存器,结合tlbr/tlbwi/tlbp/tlbwr等指令对指定TLB表项进行读写操作。

MIPS架构TLB表项用户是可观察的,x86架构TLB似乎不透明。

ls2k芯片TLB表项由固定TLB表项和随机TLB表项两部分组成,总计64项,固定和随机的分界线通过wired寄存器低位划分。

TLB亦称为快表 (页表缓冲)(转换后备缓冲器)TLB:translation lookaside buffer。

https://i-blog.csdnimg.cn/blog_migrate/32cdcebc4f0919015962d877fcc2bdbf.png

刷新TLB涉及的寄存器

INDEX: 是TLB访问指令tlbr/tlbwi/tlbp/tlbwr的基础,访问INDEX指向的表项。TLB表项通过虚地址访问,TLB表项总计64项,虚地址为0-63。

ENTRYLO0/ENTRYLO1:低位存放页属性,高位存放物理页框号。

WIRED:划分固定TLB表项和随机TLB表项数量。TLB表项总计64项,以WIRED值为分隔,0-WIRED是固定TLB,WIRED-63是随机TLB。固定TLB:不将其从TLB中换出,随机TLB:可能在缺页时被置换。

https://i-blog.csdnimg.cn/blog_migrate/92682b2bcdce0d7124e8c3b9f9981fb3.png

ENTRYHI:低位存放ASID,高位存放虚拟页表号。

STATUS:控制寄存器,控制CPU中断等。

刷新TLB涉及的指令

tlbr:读取INDEX指定TLB表项内容到寄存器。

tlbwi:将寄存器内容写入INDEX指定TLB表项。

刷新指定TLB流程

函数原型:

/*

v_addr[in]: 虚拟地址,用于计算虚拟页号,通过与ENTRYHI中的虚拟页号对比,实现刷新指定虚拟页属性。

attr[in]: 虚拟页属性。

*/

void mmu_update_tlb(uint32 v_addr, uint32 attr);

虚拟地址装虚拟页号VPN:

#define TLB_VPN_MASK 13

#define TLB_VADDR_TO_VPN(v_addr) ((v_addr) >> TLB_VPN_MASK)

寄存器ENTRYHI值转VPN:

// 虚拟页地址是32bit,ENTRYHI是64bit寄存器

#define TLB_ENTRYHI_TO_VPN(entryhi) ((uint32)((entryhi) >> TLB_VPN_MASK) & 0x07ffffff)

刷新TLB流程:

void mmu_update_tlb(uint32 v_addr, uint32 attr)

{

       // 禁止当前CPU所有中断;

       // 保存当前线程ASID

       // 预置参数

       // 遍历TLB项

              // 如果v_addr的虚拟页号与ENTRYHI寄存器中的虚拟页号一致

                     // 更新该TLB

       // 恢复当前线程ASID

       // 恢复当前CPU所有中断;

}

注:可参考Linux配置页属性后的流程,以及刷新MIPS架构TLB流程。

文件:tlb-r3k.c (arch\mips\mm)

结语

TLB不同步是我初入系统领域解决的首个较难问题,一周都在查mmu/cache/内存/tlb/mips/ls2k寄存器/虚拟内存等各种资料,得以实现刷新指定TLB表项,以及新增抓取所有TLB项到内存块的接口,在此过程中还用纯汇编写了一份清理所有TLB表项的接口(最初的解决方案,后来认为设置某页属性清掉整个随机TLB,太暴力以及影响系统性能就否定了,但接口保留了下来。)

备注

配置页属性可以参考Linux的change_protection()接口,配置页属性简单理解就是内存页的读写权限修改,当然不同cpu也会有差异,如:mips的还有工作模式之类的属性。

unsigned long change_protection(struct vm_area_struct *vma, unsigned long start,

                     unsigned long end, pgprot_t newprot,

                     int dirty_accountable, int prot_numa)

{

       unsigned long pages;

       if (is_vm_hugetlb_page(vma))

              pages = hugetlb_change_protection(vma, start, end, newprot);

       else

              pages = change_protection_range(vma, start, end, newprot, dirty_accountable, prot_numa);

       return pages;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值