Liuw's Thinkpad

想要赢就先学会输,想要成功就先学会失败

Archive for the ‘xen’ tag

Xen中的Continuation

with 2 comments

我个人理解的计算机科学中的Continuation,即是把一个计算过程具体化(reifier),得到一组可以用来重构这个计算过程的结构。通常情况下,它包含了处理器的栈,还包含了当前的执行点(具体化一点,就是所有寄存器的值),这样处理器就可以在任何时候重构这个计算过程。

一些高级语言,如Python、Ruby、Haskell、LISP等,在VM中对Continuation提供了支持。目前使用的计算机,还是必须手工编写代码才能支持Continuation。

Xen提供了一个hypercall_create_continuation函数,用来resume当前的hypercall。具体做的事情无非就是为客户虚拟机准备好上下文(栈及寄存器),然后重新执行陷入指令。要让虚拟重新执行陷入指令的处理又分为再种情况:假如是PV的虚拟机,把EIP减2,重新执行int 0×82或者syscall指令;假如是HVM,那么不需要对EIP作处理,因为vmcall产生的是fault,指令会重新自动执行。

Xen中的Continuation仅仅用于重新执行hypercall,对栈和寄存器的操作比较少,速度是有保证的。

那么,Xen在什么时候需要创建Continuation呢?常见的代码形式是:

if ( hypercall_preempt_check() )
    hypercall_create_continuation(...)

hypercall_preempt_check又是干什么的呢?假如当前物理CPU有等待处理的softirq,或者PV中的VCPU中有可投递的upcall(pending且!masked),那么它的返回值就为真。(HVM这里先不讨论)

即是说,Xen在执行某些Hypercall的时候,有可能处于一种不能抢占CPU的状态,所以必须让客户虚拟机重新再执行一次Hypercall。

受影响的Hypercall有:

__HYPERVISOR_hvm_op
__HYPERVISOR_mmuext_op
__HYPERVISOR_mmu_update
__HYPERVISOR_domctl
__HYPERVISOR_set_trap_table
__HYPERVISOR_memory_op
__HYPERVISOR_multicall
__HYPERVISOR_console_io

本人目前的看法是,这些Hypercall在有upcall或者softirq处于pending的状态时候执行的话,都会有影响虚拟机状态一致性的可能。以console io为例,虚拟机和consoled之间的事件通知,就是用的event channel机制。处于pending状态的event很可能就是IO通信产生的。假如虚拟机在调用__HYPERVISOR_console_io之前没有先把所有的event都处理完,那么就会造成数据的丢失。

但是其他的Hypercall为什么不会有这样的问题呢?那自然是因为其他的Hypercall在执行的时候可以保证当时所处的状态是“干净”的。

草草看了一下代码,写下了上面的文字。水平所限,错误在所难免,欢迎指正。

Written by liuw

February 28th, 2011 at 2:33 pm

Posted in Tech

Tagged with , ,

特权高就是好

without comments

Virtual Machine Introspection就是说只看不改。要是改一下数据会怎么样?

今天就干了这事,在Xen的层面把程序的代码内容给改掉了。简单点说,这就是一种代码注入。

有趣的地方是,改了的机器码最后反映到程序映像之中了。想了一下,大概是因为代码段是以文件映射的方式映射到内存之中的,程序退出的时候会让磁盘上的文件和内存中的内容同步。

往好的方面想,这样的功能是目前最强的hot patch方式。一方面可以on the fly地改进程,另一方面顺带把映像也改了。

往不好的方面想,这样的功能就太可怕了,自己的程序被改了也不知道,重新启动也不成。

不过我原来没有料到会有映像的同步。我一向的理解是这样的只读映射最后只需要把内容丢弃就可以了,代码以后有机会再看吧。

Written by liuw

December 30th, 2010 at 4:11 pm

Posted in Tech

Tagged with ,

Xen更新页表的几个入口

without comments

这屁事搞了好几天了,这里记一下。

三个入口:

  1. do_mmu_update,个是最正规的ParaVirt入口,可以更新任何一级页表。
  2. do_update_va_mapping,直接更新virtual address对应的L1页表,只能用于L1页表。
  3. writable page table,实际上这是一个Xen的特性,不是一个具体的函数,也只能用于L1页表。Xen先把L1页表unhook让guest可写,然后ptwr_emulated_update为guest模拟写操作,Xen验证写入数据的合法性后再把页表重新hook上。

这是这几天看代码的一些小总结,不能保证完全正确。以后再写代码验证。

XenoLinux内核上面的方面都有采用。比如在Dom0进程要更新页表的时候(创建也好,销毁也好),通常是用do_mmu_update,效率比较高;但是在munmap单个页面的时候,通常是使用writable page table模式。

Written by liuw

December 10th, 2010 at 4:55 pm

Posted in Tech

Tagged with , , ,

Milestone 2 is coming

without comments

New release, new features.

New stubdom target domb.

Working Dom0 daemon dombd, responsible for communicating with DomB.

Usable domain builder inside DomB.

Coming soon…

Written by liuw

April 7th, 2010 at 7:45 pm

Posted in Programming,Security

Tagged with , ,