Chinaunix

标题: 请问完全内存虚拟化处理缺页异常的流程是什么? [打印本页]

作者: kikanjuu    时间: 2008-02-22 18:33
标题: 请问完全内存虚拟化处理缺页异常的流程是什么?
请问在完全内存虚拟化(Full Memory Virtualization,包括使用影子页表Shadow Page Table)中,处理缺页异常的流程是什么?

例如,KVM, VMWare都是使用完全内存虚拟化技术来虚拟化物理内存的。请问它们处理缺页异常的流程是什么样的呢?

3x
作者: zx_wing    时间: 2008-02-22 19:21
原帖由 kikanjuu 于 2008-2-22 18:33 发表
请问在完全内存虚拟化(Full Memory Virtualization,包括使用影子页表Shadow Page Table)中,处理缺页异常的流程是什么?

例如,KVM, VMWare都是使用完全内存虚拟化技术来虚拟化物理内存的。请问它们处理缺页 ...

LZ这个问题问了x86虚拟技术中最核心、最复杂的部分,相当于问操作系统是如何进行内存管理的。
我不懂,但知道一些。

VMWare具体不清楚,但机制应该差不多。像KVM这样的,page fault分为两种:客户机page fault和shadow page fault(影子页表错误)。
对于前者,直接返回注入(虚拟机中一个术语,通知中断、异常等事件的发生,实质是跳转到客户操作系统对应的handler去执行)给客户机,由客户机自己的page fault handler处理。对于shadow fault,是由于客户机页表和影子页表不一致产生的,此时根据客户机页表项,重新生成影子页表对应条目。
作者: kikanjuu    时间: 2008-02-22 19:37
嗯,楼上的说得很对,这我知道的。
我想知道详细的VMM的page fualt handler的流程,包括根据客户机操作系统的当前页表设置相应的影子页表的R/W Dirty位等,或反过来的详细流程。
作者: kikanjuu    时间: 2008-02-22 19:38
哪里可以找到使用这种技术的某种VMM产品中的Page Fault Handler的源代码?
例如,KVM中相关的源代码在哪里?
作者: zx_wing    时间: 2008-02-22 19:50
KVM代码明天给你翻翻。
如果LZ想详细了解,可以花钱下载
http://www.cqvip.com/QK/83538A/2006011/23161565.html
一文。
国内做shadow的应该没有比此文作者更权威的了。
尽管写的是XEN,不过没关系,KVM的实现是抄XEN的
作者: kikanjuu    时间: 2008-02-22 19:59
好,拜托老兄了。
Xen是Para-virtualization的,不用影子页表Shadow Page Table机制的吧?
作者: zx_wing    时间: 2008-02-22 20:04
原帖由 kikanjuu 于 2008-2-22 19:59 发表
好,拜托老兄了。
Xen是Para-virtualization的,不用影子页表Shadow Page Table机制的吧?

那是在有intel的VT技术出现之前。
现在的XEN完全支持full virtualization。KVM嘛,最初的时候基本上抄XEN
作者: kikanjuu    时间: 2008-02-22 20:07
Xen从那一版开始,代码里包含了Full Virtualization的实现?
我有Xen 3.0.2的代码的,貌似没看到过。
作者: zx_wing    时间: 2008-02-22 20:10
原帖由 kikanjuu 于 2008-2-22 20:07 发表
Xen从那一版开始,代码里包含了Full Virtualization的实现?
我有Xen 3.0.2的代码的,貌似没看到过。

3.0.2已经支持了啊
你想,不支持full virtualization,如何启windows
作者: kikanjuu    时间: 2008-02-22 20:12
这样啊,你看过3.0.2的代码吗?
若看过,可不可以告诉我full virtualization的do_page_fault在哪里有?
或者告诉我怎么搜到也行。
3x
作者: zx_wing    时间: 2008-02-22 20:18
原帖由 kikanjuu 于 2008-2-22 20:12 发表
这样啊,你看过3.0.2的代码吗?
若看过,可不可以告诉我full virtualization的do_page_fault在哪里有?
或者告诉我怎么搜到也行。
3x

shadow代码见\xen\arch\x86\mm\shadow目录
作者: kikanjuu    时间: 2008-02-23 12:55
谢谢,找到了。看了遇到什么问题在本帖请教你?
作者: zx_wing    时间: 2008-02-23 14:07
原帖由 kikanjuu 于 2008-2-23 12:55 发表
谢谢,找到了。看了遇到什么问题在本帖请教你?

shadow我是不懂的,最多大家共同探讨一下,我也学习一下
作者: kikanjuu    时间: 2008-02-23 14:18
恩,好。前面基本原理你说得对的。
作者: sirouni    时间: 2008-02-23 17:47
目前的全虚拟化内存主要有两种解决方案:
1 完全使用软件实现的shadow page table 方案,已经在Xen/KVM中实现,性能比较令人满意
2 使用硬件辅助的全虚拟化方案如 AMD处理器支持的Nesting Page,在Xen中已经得到支持并成为(Hardware Assist Paging,简称HAP),在浏览相关源代码树时可以看到相关的文件,根据Xen summit的slide, HAP性能通常比SPT(shadow page table)高10%

下面我简单说一下影子页表的原理:
Xen/KVM 为客户操作系统提供一个虚拟的物理地址空间,称之为客户物理地址空间。运行在Xen domain中的客户操作系统(Guest Operating System,GOS)认为自己在物理机器上运行并使用该客户物理地址空间中的客户物理地址(Guest Physical Address, GPA)进行寻址。
GOS的页表(Guest Page talbe,GPT)维护的是线性地址(Linear Address,LA)到GPA的映射,但这也页表并不能给硬件使用,因为硬件需要使用从LA到机器物理地址(Host Physical Address,HPA)的映射。
Xen/KVM将GPA到HPA的映射记录在P2M表中(Physical to Machine Mapping, P2M),并为GPT的每个页表维护一个与其对应的硬件使用的页表,其中保存LA->HPA的映射,我们称之为SPT。

映射示意:
GPT:  LA->GPA  (由GOS维护)
SPT:  LA->HPA (由Xen/KVM维护,由GPT派生(同步)得到)
P2M: GPA->HPA

SPT正常工作的一个关键问题是SPT的映射项如何得到,专业上称作如何使GPT与SPT同步:
以Xen为例:
1) 早期的Xen shadow代码(成为shadowI)采用的是Lazy同步的方式,也就是说:
当客户操作系统修改了GPT,如果是权限下降,比如W->R,则当客户操作系统作出修改后会立即使用INVLPG,使TLB无效,这时Xen捕获INVLPG指令并根据其线性地址对SPT/GPT进行同步
当客户操作系统修改了GPT,如果是权限上升,比如R->W,则但客户操作系统访问该页面时会引发#PF,这时Xen捕获#PF,根据线性地址同步SPT/GPT
2) 现在的Xen shadow代码(shadowII),采用的Eager同步方式:
Xen监控对客户页表的操作(所有客户页所在页面对应的SPT项只读),当客户操作系统试图修改GPT时会捕获#PF,模拟该指令的执行并且同步SPT/GPT,
相比较shaodwI,减少了一次Trap

Xen实现SPT的关键入口是:
sh_page_fault()
具体情况很复杂,参考我上传的slide(2007格式的ppt,因为论坛附件上限的原因)
大致的流程:

sh_page_fault()
1 检查是否由客户操作系统本身引发的#PF,如果是则向客户操作系统注入#PF, 并返回
2 遍历GPT,将每级GPT记录在某结构中以便之后查询
3 根据之前记录的每级GPT, 同步或者创建相应的SPT
4 判断是否客户操作系统要对GPT进行修改,如果不是就返回
5 模拟客户操作系统对GPT的修改,并且同步相应的SPT
6 返回

另一个入口点是对INVLPG指令的处理,
sh_invlpg()
不再详细说明

shadow_present_CU.rar

175.11 KB, 下载次数: 886


作者: sirouni    时间: 2008-02-23 17:50
shadow的代码我注释过,不知大家需不需要?
作者: kikanjuu    时间: 2008-02-25 14:53
标题: 回复 #16 sirouni 的帖子
要!多谢啦。
请发到我的邮箱hyjshanghai@hotmail.com吧。

ps: 可以告诉我你的MSN吗?

sirouni好像是大牛嘛
作者: kikanjuu    时间: 2008-02-25 15:08
标题: 回复 #17 kikanjuu 的帖子
Sirouni你看的是什么版本的Xen?
我的是3.0.2,Shadow Page Fault的入口貌似是shadow_fault(),没有sh_page_fault()
作者: kikanjuu    时间: 2008-02-25 15:57
代码里的gmfn是至包含Guest Page Table数据的硬件物理内存的frame number吗?即machine frame number for guest page table page?
作者: sirouni    时间: 2008-02-25 19:15
回19楼,你说的没错
gpfn/gfn: guset page frame number 客户物理页面号(客户操作系统使用gpfn/gfn对客户物理地址空间寻址)
mfn: machine page frame number 机器页面号
smfn: machine page frame number for shadow pages shadow页面所在的机器页面号
l1e: level 1 page table entry
gl1e: level 1 guest page table entry
sl1e: level 1 shadow page table entry 一级shadow页表项
PV: para-virtualization
HVM: Hardware assistant Virtual Machine

回17楼:
我不牛,大家共同进步

sh_page_fault()注释已经发到我的blog中
作者: kikanjuu    时间: 2008-02-26 09:08
标题: 回复 #20 sirouni 的帖子
谢谢!可以把您注释过的整个Shadow.c作为附件贴在这里吗?
作者: kikanjuu    时间: 2008-02-26 09:55
你在博客里说的有问题可以问Xen的邮件列表是指  xen-devel@lists.xensource.com 这个邮件列表吗?
它里面都是强人,不适合我问小白问题。
请问有没有适合初级Xen开发者的邮件列表呢?
作者: sirouni    时间: 2008-02-26 10:32
我也没提过问,但是可以通过搜索邮件列表得到很多问题的答案。
附件是整个shaodw目录的注释。

shadow.rar

174.46 KB, 下载次数: 221


作者: kikanjuu    时间: 2008-02-26 10:42
万分感谢!
3x!
作者: kikanjuu    时间: 2008-02-26 10:45
弱问什么是super page啊?
作者: sirouni    时间: 2008-02-26 10:50
原帖由 kikanjuu 于 2008-2-26 10:45 发表
弱问什么是super page啊?

就是大页面,2MB/4MB的页面
作者: kikanjuu    时间: 2008-02-26 10:58
另外,为什么要在guest_walk_tables()中把Guest Page Table (GPT)设为只读?
并且,当前这次将GPT设为只读所在的Page Fault又是如何触发的呢?

[ 本帖最后由 kikanjuu 于 2008-2-26 12:32 编辑 ]
作者: sirouni    时间: 2008-02-26 13:17
原帖由 kikanjuu 于 2008-2-26 10:58 发表
另外,为什么要在guest_walk_tables()中把Guest Page Table (GPT)设为只读?
并且,当前这次将GPT设为只读所在的Page Fault又是如何触发的呢?

监控客户操作系统对客户页表的写操作,一旦客户操作系统试图修改客户页表,Xen回捕获#PF,模拟这个指令的执行同时同步GPT与SPT
作者: kikanjuu    时间: 2008-02-26 14:14
是不是客户操作系统修改客户页表会引发两次Page Fault?

第一次:
因为还没有建立起客户页表对应的影子页表,即客户页表的guest physical frame还没有对应的machine frame for guest page table,所以引起Page Fault
在这次PF中VMM为客户页表页分配machine frame,并在影子页表中相应地建立起虚拟地址到machine frame的映射。
并且在这次PF中,在guest_walk_pagetables()中将客户页表中对应PF的虚拟地址的pde和pte写保护。

接着,系统从ring0回到ring1,客户操作系统再次执行企图修改客户页表的指令。因为客户页表在第一次PF中对应虚拟地址的pde/pte已被写保护,所以再次发生PF。
第二次:
在第二次PF中,VMM模拟执行客户操作系统修改该客户页表,并同步相应的影子页表。

以上是我的理解,客户操作系统修改客户页表需要如上的两次Page Fault吗?

[ 本帖最后由 kikanjuu 于 2008-2-26 14:20 编辑 ]
作者: sirouni    时间: 2008-02-26 19:06
原帖由 kikanjuu 于 2008-2-26 14:14 发表
是不是客户操作系统修改客户页表会引发两次Page Fault?

第一次:
因为还没有建立起客户页表对应的影子页表,即客户页表的guest physical frame还没有对应的machine frame for guest page table,所以引起Pa ...


以32位下4KB页面及HVM为例:
初始情况下HVM运行在virtual 8086模式用于模拟实地址模式,
这时SPT指针位于P2M表,
此时客户操作系统引导代码会准备页表,
此时客户操作系统对页表的操作无法进行监控。
当客户操作系统页表准备完毕准备切换的保护模式时,
客户操作系统会使用mov to cr3指令,此指令由VT捕获,
被传递到影子页表的sh_update_cr3()函数,
这个函数负责所有HVM中客户操作系统更改CR3时的处理。

这个函数会首先会查询客户页表对应的机器地址
        gmfn = pagetable_get_mfn(v->arch.guest_table);

之后会扫描domain所有的shadow page table,将gmfn对应的shadow页面设置为只读,如果没有对应的shadow,则创建一个
代码来自sh_update_cr3()
#if GUEST_PAGING_LEVELS == 2
    if ( sh_remove_write_access(v, gmfn, 2, 0) != 0 )
        flush_tlb_mask(v->domain->domain_dirty_cpumask);
    sh_set_toplevel_shadow(v, 0, gmfn, SH_type_l2_shadow);
#elif GUEST_PAGING_LEVELS == 3

由此保证了当前domain所有顶级页表对应的页面,在SPT中只读。
之后每次捕获#PF进行的客户页表遍历时,Xen总是同时将遍历客户页表对应的机器页面设置为只读,
代码来自guest_walk_tables():
    if ( guest_op && sh_remove_write_access(v, gw->l2mfn, 2, va) != 0 )
        flush_tlb_mask(v->domain->domain_dirty_cpumask);

通过这种渐进的方式确保了所有客户页表所在页面在SPT中的映射项都是只读的,
之后如果客户操作系统试图修改客户页表会引发#PF,
此时由Xen捕获并模拟其执行,在模拟的同时同步SPT与GPT:
代码来自sh_page_fault()
    /* Need to emulate accesses to page tables */
    /* 需要模拟对客户页表的写操作 */
    if ( sh_mfn_is_a_page_table(gmfn) )
    {
        if ( ft == ft_demand_write )
        {
            perfc_incr(shadow_fault_emulate_write);
            goto emulate;
        }
        else if ( shadow_mode_trap_reads(d) && ft == ft_demand_read )
        { /* Xen  暂时不支持读页表的模拟 */
            perfc_incr(shadow_fault_emulate_read);
            goto emulate;
        }
    }

由此可见,客户操作系统修改客户页表仅会产生一次#PF,
Xen捕获#PF并模拟其执行,同时进行同步.
作者: kikanjuu    时间: 2008-02-27 09:44
由此保证了当前domain所有顶级页表对应的页面,在SPT中只读。
之后每次捕获#PF进行的客户页表遍历时,Xen总是同时将遍历客户页表对应的机器页面设置为只读,
代码来自guest_walk_tables():
    if ( guest_op && sh_remove_write_access(v, gw->l2mfn, 2, va) != 0 )
        flush_tlb_mask(v->domain->domain_dirty_cpumask);

写保护的是客户页表页对应的影子页表页的机器物理页,而不是客户页表页本身的机器物理页,对吗?
在这里guest_walk_tables()之前,客户页表页对应的影子页表页的机器页尚未被写保护,那么这个导致执行guest_walk_tables()的PF是怎么发生的呢?



通过这种渐进的方式确保了所有客户页表所在页面在SPT中的映射项都是只读的,
之后如果客户操作系统试图修改客户页表会引发#PF,
此时由Xen捕获并模拟其执行,在模拟的同时同步SPT与GPT:
代码来自sh_page_fault()

这里的“PF”是客户操作系统写只读的影子页表页引起的。和前面的进行写保护的PF不是一个,对吗?

[ 本帖最后由 kikanjuu 于 2008-2-27 09:51 编辑 ]
作者: sirouni    时间: 2008-02-27 13:48
原帖由 kikanjuu 于 2008-2-27 09:44 发表

写保护的是客户页表页对应的影子页表页的机器物理页,而不是客户页表页本身的机器物理页,对吗?
在这里guest_walk_tables()之前,客户页表页对应的影子页表页的机器页尚未被写保护,那么这个导致执行guest_ ...


VCPU运行在物理CPU时,物理CPU使用SPT进行寻址.
并不存在页面本身被写保护的问题,
比如两个页表项都指向同一个物理页面,
第一个页表项中该物理页面为只读
第二个页表项该物理页面可写,
那么通过第一个线性地址只能进行读操作
通过第二个线性地址可以进行写操作。
对客户操作系统页面的寻址,最终要经过sl1e,
所以只需要将对应的sl1e设为R即可.
int sh_remove_write_accesss(struct vcpu *v, mfn_t gmfn,
                           unsigned int level,
                           unsigned long fault_addr)
{

    /* callbacks与callback_mask都是为hash_foreach()准备的参数 */
    /* Dispatch table for getting per-type functions */
    static hash_callback_t callbacks[SH_type_unused] = {
        NULL, /* none    */

#if CONFIG_PAGING_LEVELS == 2
        SHADOW_INTERNAL_NAME(sh_rm_write_access_from_l1,2,2), /* l1_32   */
        SHADOW_INTERNAL_NAME(sh_rm_write_access_from_l1,2,2), /* fl1_32  */
......
#endif
......
    /* Brute-force search of all the shadows, by walking the hash */
    perfc_incr(shadow_writeable_bf);
    /* 靠遍历hash,蛮力搜索所有的shadows*/
    hash_foreach(v, callback_mask, callbacks, gmfn);
......
    return 1;
}



xen将于gmfn对应的所有sl1e中的R/W位置R.

当VCPU的客户操作系统需要修改客户页表时,物理CPU实际上是用SPT进行寻址。
Xen将客户页表所在物理页面在SPT中相应的映射中的R/W位设为R,
那么客户操作系统修改客户页表时, 会引发#PF。

另外一种可能是,
客户操作系统试图修改客户页表,
但客户页表所在页面在SPT中还没有相关映射,在分配shadow时对应的shadow所有映射项为空:
mfn_t shadow_alloc(struct domain *d,  
                    u32 shadow_type,
                    unsigned long backpointer)
{
.....
        p = sh_map_domain_page(shadow_page_to_mfn(sp+i));   
        ASSERT(p != NULL);
        clear_page(p);
        sh_unmap_domain_page(p);
        INIT_LIST_HEAD(&sp[i].list);
        sp[i].type = shadow_type;
        sp[i].pinned = 0;
        sp[i].count = 0;
        sp[i].backpointer = backpointer;
        sp[i].next_shadow = NULL;
        perfc_incr(shadow_alloc_count);
......
}

这是回由于P位的问题引发#PF,
Xen捕获#PF,通过查询客户页表/P2M表的方式完成同步

注意:VCPU使用SPT寻址,而Xen使用的是monitor_table进行寻址.
作者: kikanjuu    时间: 2008-02-27 15:20
非常感谢!辛苦你了。

对客户操作系统页面的寻址,最终要经过sl1e,
所以只需要将对应的sl1e设为R即可.


我想问的是,设置sl1e为R的这次PF是怎么发生的呢?或者说,Xen在什么时候将系统中所有SPT中映射到gmfn对应的smfn的所有sl1e都设为R?

[ 本帖最后由 kikanjuu 于 2008-2-27 15:21 编辑 ]
作者: sirouni    时间: 2008-02-27 15:44
原帖由 kikanjuu 于 2008-2-27 15:20 发表
非常感谢!辛苦你了。



我想问的是,设置sl1e为R的这次PF是怎么发生的呢?或者说,Xen在什么时候将系统中所有SPT中映射到gmfn对应的smfn的所有sl1e都设为R?


因为sl1e映射的是客户页表对应的物理页面,所以客户操作系统试图修改客户页表会引发#PF,
对于顶级页表,Xen在客户操作系统更改cr3时,将对应的gmfn在SPT中的sl1e置为R
其余通过每次#PF,在对客户页表进行遍历的时候渐进式的将客户操作系统也表对应的sl1e置为R
作者: kikanjuu    时间: 2008-02-27 16:11
哦,就是说GOS改cr3被截获,其cr3对应的客户页表的l2 mfn在SPT中的pte被设为只读。

当GOS想将l1 gfn挂到l2 gfn上时,由于相应的客户页表的l2 mfn在SPT中的映射先前已为只读,所以发生PF被截获,
同理,当GOS想将非页表gfn挂到l1 gfn上时,由于相应的l1 mfn在SPT中的映射先前已为只读,所以发生PF被截获。是这样吧?

在sh_remove_write_accesss()为什么要将所有SPT中映射到gmfn的pte的读写位置为R,
而不是只将当前cr3对应的GPT对应的SPT中映射到gmfn的pte的读写位置为R?

[ 本帖最后由 kikanjuu 于 2008-2-27 16:27 编辑 ]
作者: sirouni    时间: 2008-02-27 19:39
原帖由 kikanjuu 于 2008-2-27 16:11 发表
哦,就是说GOS改cr3被截获,其cr3对应的客户页表的l2 mfn在SPT中的pte被设为只读。

当GOS想将l1 gfn挂到l2 gfn上时,由于相应的客户页表的l2 mfn在SPT中的映射先前已为只读,所以发生PF被截获,
同理,当GO ...


Xen并非对每一个VCPU维护一个与其对应的SPT,而是针对每一个客户页表以及这个客户页表在地址翻译中的层次维护与其对应的一个shadow。
这就是说如果两个VCPU共享某个层次的客户页表,那么其SPT也是共享的。这样可以大大的提升效率。

由于可以使用不同的线性地址访问同一个物理页面,所以在不同的客户页表中可能存在到同一个gmfn的映射,由于Xen要监控对客户页表的写操作做,
所以要将当前gmfn所有的sl1e R/W设为R,以监控各种途径的对客户页表的修改。
作者: kikanjuu    时间: 2008-02-27 20:53
Xen并非对每一个VCPU维护一个与其对应的SPT,而是针对每一个客户页表以及这个客户页表在地址翻译中的层次维护与其对应的一个shadow。

什么是“这个客户页表在地址翻译中的层次”?


由于可以使用不同的线性地址访问同一个物理页面,所以在不同的客户页表中可能存在到同一个gmfn的映射,由于Xen要监控对客户页表的写操作做,

这里的“所以在不同的客户页表中可能存在到同一个gmfn的映射”应该是“所以在不同的影子页表中可能存在到同一个gmfn的映射”吧?
作者: sirouni    时间: 2008-02-28 14:02
原帖由 kikanjuu 于 2008-2-27 20:53 发表

什么是“这个客户页表在地址翻译中的层次”?



这里的“所以在不同的客户页表中可能存在到同一个gmfn的映射”应该是“所以在不同的影子页表中可能存在到同一个gmfn的映射”吧?


你说的对,

由于客户页表中可能存在环路映射(如NetBSD),
主要的作用是为客户操作系统修改自身也表提供方便,
那么就是说,
如果客户操作系统利用环路映射访问自己的页表,
对于某个客户页表来说,
在这次访问中,
即可能做为l2,也要做为l1,
Xen为这个客户页表维护两个shadow,
一个是对应于l2,一个对应于l1

Xen本身也使用环路映射维护自己的页表,
利用objdump可以得到
monitor_talbe的线性地址为(0x FE3F800) (32位下)
换算为PTE/PDE为:
[0x3F8][0x3F8][0x000]
也就是说Xen在自身的PDE中有一个映射到其自身的环路映射,
通过这个环路映射
Xen可以轻松的访问自己的页表.
作者: zx_wing    时间: 2008-02-28 17:10
奉老大旨意,上传此文

Xen硬件虚拟机的内存虚拟化实现.rar

143.26 KB, 下载次数: 451


作者: kikanjuu    时间: 2008-02-28 17:53
真的要谢谢Sirouni和zx_wing!谢谢你们详细的解释和上传的珍贵的资料。能认识国内的熟悉Xen、愿意相互交流的朋友实属不易!
作者: sirouni    时间: 2008-02-28 18:54
希望大家多交流,我说的都是自己的理解,难免有错.
作者: kikanjuu    时间: 2008-03-03 15:14
再问个问题:
对于非最低级的客户机页表项,为什么监控程序提供了哈希表,以客户机物理地址和该页表项所在页表的层次为键值,查找影子页表中相应的影子页表项中的影子页表页的宿主机物理地址?

这里为什么需要用哈希表,而不是通过P2M Table直接从客户机页表页的客户机物理地址,找到相应的影子页表页的宿主机物理地址?
作者: zx_wing    时间: 2008-03-03 16:25
原帖由 kikanjuu 于 2008-3-3 15:14 发表
再问个问题:
对于非最低级的客户机页表项,为什么监控程序提供了哈希表,以客户机物理地址和该页表项所在页表的层次为键值,查找影子页表中相应的影子页表项中的影子页表页的宿主机物理地址?

这里为什么需 ...

这个问题应该是这样的。
x86是CPU自己walk页表,所以shadow页表必须符合CPU要求的页表格式,也就是hash表。
作者: sirouni    时间: 2008-03-03 16:40
原帖由 kikanjuu 于 2008-3-3 15:14 发表
再问个问题:
对于非最低级的客户机页表项,为什么监控程序提供了哈希表,以客户机物理地址和该页表项所在页表的层次为键值,查找影子页表中相应的影子页表项中的影子页表页的宿主机物理地址?

这里为什么需 ...


利用P2M表只能找到GPT对应的机器物理页面,还需要一种从机器物理页面对应到具体SPT的方法,由于一个GPT可能有多个与其对应的SPT
所以需要一种快速定位SPT的方式,所以采用了你说的那种定位方式。
作者: kikanjuu    时间: 2008-03-03 16:54
你是说通过P2M表只能找到页表页的mfn,还需要通过哈希表找到所有指向这个mfn的影子页表的页表项,是吗?
作者: sirouni    时间: 2008-03-03 22:03
原帖由 kikanjuu 于 2008-3-3 16:54 发表
你是说通过P2M表只能找到页表页的mfn,还需要通过哈希表找到所有指向这个mfn的影子页表的页表项,是吗?

是这样的.
作者: albcamus    时间: 2008-03-05 16:04
太高深了,完全不懂
作者: aabb1122    时间: 2008-10-16 17:37
有个问题: 宿主机如何实现监控客户机的内存的读写这个机制的? 也就是说在客户机通过 guest cr3访问物理内存时还要真正的通过HOST_CR3来映射? xen是通过清空HOST cr3页表来实现 hook客户机的内存读写?
作者: aabb1122    时间: 2008-10-17 09:51
应该是这样的吧: vmcs.guest_cr3=shadow page table, vmcs.host_cr3=monitor_table ?
作者: jiangqiangq    时间: 2009-03-11 15:08
原帖由 zx_wing 于 2008-2-22 19:21 发表

VMWare具体不清楚,但机制应该差不多。像KVM这样的,page fault分为两种:客户机page  ...


VMWare在BT模式下的机制应该不太一样吧




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2