免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: wth0722
打印 上一主题 下一主题

[内存管理] 更改 page table entry屬性,卻未生效 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2014-06-09 22:42 |只看该作者
本帖最后由 l4rmbr 于 2014-06-09 22:54 编辑

看了楼主的表述,楼主你应该是在更新页表项后忘了冲刷tlb缓存。正确用法应该像这样:

flush_cache_page(vma, addr, pfn);             <--- 冲刷数据/指令缓存
set_pte(pte_pointer, new_pte_val);             <--- 更新页表项
flush_tlb_page(vma, addr);                          <--- 冲刷tlb缓存

此外,多说两点.

1.
set_pte_at() 与 set_pte()功能基本相同,不过前者用来实现钩子,用以
冲刷相应的数据/指令缓存。

在大多数体系架构下,这两个函数一样。不过arm是个例外。因为它是vivt
架构(virtual indexed and virtual tagged), 所以更新了虚拟地址的页表项,
也要相应地刷新缓存。 x86就不用,因为它是pipi(physical indexed and physical tagged)
缓存一致性由cpu内在地保证,不需要程序员干预。

2.
我大概翻了下代码,发现set_pte一般用在第一次创建一个表项时,此时无所谓“更新”一说。
如果是要更新一个旧页表项,则用的是set_pte_at。
这也符合这两个接口的设计目的。

论坛徽章:
0
12 [报告]
发表于 2014-06-09 22:43 |只看该作者
本帖最后由 l4rmbr 于 2014-06-09 22:54 编辑

[非常抱歉,网络原因发了相同内容两次,麻烦版主删除这个帖子吧。谢谢!]

看了楼主的表述,楼主你应该是在更新页表项后忘了冲刷tlb缓存。正确用法应该像这样:

flush_cache_page(vma, addr, pfn);             <--- 冲刷数据/指令缓存
set_pte(pte_pointer, new_pte_val);             <--- 更新页表项
flush_tlb_page(vma, addr);                          <--- 冲刷tlb缓存

此外,多说两点.

1.
set_pte_at() 与 set_pte()功能基本相同,不过前者用来实现钩子,用以
冲刷相应的数据/指令缓存。

在大多数体系架构下,这两个函数一样。不过arm是个例外。因为它是vivt
架构(virtual indexed and virtual tagged), 所以更新了虚拟地址的页表项,
也要相应地刷新缓存。 x86就不用,因为它是pipi(physical indexed and physical tagged)
缓存一致性由cpu内在地保证,不需要程序员干预。

2.
我大概翻了下代码,发现set_pte一般用在第一次创建一个表项时,此时无所谓“更新”一说。
如果是要更新一个旧页表项,则用的是set_pte_at。
这也符合这两个接口的设计目的。

论坛徽章:
0
13 [报告]
发表于 2014-06-10 10:21 |只看该作者
回复 12# l4rmbr

先感謝你的回應

flush_cache_page(vma, addr, pfn);             <--- 沖刷數據/指令緩存
set_pte(pte_pointer, new_pte_val);             <--- 更新頁表項
flush_tlb_page(vma, addr);                          <--- 沖刷tlb緩存

我無法用上面那些,因為ioremap()後,那塊記憶體是沒有vma的
我試過find_vma()是找不到的


我這邊是ARM arch,並沒有set_pte(),只有set_pte_at()
再來其實一開始我是有flush all cache 以及 鎖TLB,但還是沒有解決問題
後來才知道是因為我是只有更改Linux pte,並沒有改道h/w pte
所以才會需要set_pte_at()幫我去修改他


還有其實ARM arch的d-cache 是VIPT non-aliasing
i-cache才是VIVT


   

论坛徽章:
0
14 [报告]
发表于 2014-06-10 11:33 |只看该作者
奇怪,我看的内核是3.13,如果照楼主的流程,用set_pte_at并不会刷cache。

对于set_pte_at,如果是用户态的地址,则尝试刷cache:
  1. static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
  2.                               pte_t *ptep, pte_t pteval)
  3. {
  4.         unsigned long ext = 0;

  5.         if (addr < TASK_SIZE && pte_present_user(pteval)) {
  6.                 __sync_icache_dcache(pteval);
  7.                 ext |= PTE_EXT_NG;
  8.         }

  9. }
复制代码
如果是用户态的地址,并且有可执行属性,就算vipt 没有cache aliase,也需刷icache和dcache:

  1. void __sync_icache_dcache(pte_t pteval)
  2. {
  3.         unsigned long pfn;
  4.         struct page *page;
  5.         struct address_space *mapping;

  6.         if (cache_is_vipt_nonaliasing() && !pte_exec(pteval))
  7.                 /* only flush non-aliasing VIPT caches for exec mappings */
  8.                 return;
复制代码

  1. #define pte_exec(pte)                (!(pte_val(pte) & L_PTE_XN))
复制代码
由于楼主的ioremap带PROT_PTE_DEVICE属性,
#define PROT_PTE_DEVICE                L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
因此pte_exec返回0,从而__sync_icache_dcache直接返回了。

也就是说,不会刷cache,这个跟楼主的描述有点矛盾。

论坛徽章:
0
15 [报告]
发表于 2014-06-10 11:47 |只看该作者
回复 13# wth0722


    你好。我看了下ioremap的实现,确实是没关联vma的。

    还有,你说的hw pte是怎么回事? 页表项不就是在内存中的数据结构吗?还有硬件页表项这一说?不知是什么架构。能不能解释下?谢谢!

    最后,关于vivt, 多谢指正 :)

论坛徽章:
0
16 [报告]
发表于 2014-06-10 11:51 |只看该作者
回复 14# chenyu105

不好意思,請問跟我講哪一點有矛盾?

set_pte_at() -> cpu_v7_set_pte_ext() 這邊若是UP則會flush cache

我從頭到尾就一直說問題的點是在於只有寫入到Linux pte,並沒有寫到h/w pte

TLB、cache的問題我不認為問題點在那邊阿,因為我試過flush也沒用
   

论坛徽章:
0
17 [报告]
发表于 2014-06-10 11:58 |只看该作者
回复 15# l4rmbr


我用是ARM arch的,這邊是有兩份pte的

原因是Linux所要的pte資訊,ARM並沒有提供,所以要多一份保存

請參考arch/arm/include/asm/pgtable-2level.h

31  * This leads to the page tables having the following layout:
32  *
33  *    pgd             pte
34  * |        |
35  * +--------+
36  * |        |                 +------------+ +0
37  * +- - - - +               | Linux pt 0 |
38  * |        |                 +------------+ +1024
39  * +--------+     +0    | Linux pt 1 |
40  * |        |----->       +------------+ +2048
41  * +- - - - + +4          |  h/w pt 0  |
42  * |        |----->       +------------+ +3072
43  * +--------+     +8    |  h/w pt 1  |
44  * |        |                +------------+ +4096
45  *

论坛徽章:
0
18 [报告]
发表于 2014-06-10 12:06 |只看该作者
回复 17# wth0722


    多谢。明白了。 这也是为了弥补linux通用多级页表和硬件支持页表之间的差异。

论坛徽章:
0
19 [报告]
发表于 2014-06-10 12:17 |只看该作者
本帖最后由 chenyu105 于 2014-06-10 12:20 编辑

回复 16# wth0722
明白了。
如果设置了软件pte,应该也会有什么时候会把软件pte更新到硬件pte吧
   

论坛徽章:
0
20 [报告]
发表于 2014-06-10 13:08 |只看该作者
回复 19# chenyu105


set_pte_at()  --->  cpu_v7_set_pte_ext()

cpu_v7_set_pte_ext()這裡面會去寫入到h/w pte


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP