libxc/Linux: Add VM_DONTCOPY flag of the VMA of the hypercall buffer
authorWangzhenguo <wangzhenguo@huawei.com>
Fri, 17 Aug 2012 13:46:48 +0000 (14:46 +0100)
committerWangzhenguo <wangzhenguo@huawei.com>
Fri, 17 Aug 2012 13:46:48 +0000 (14:46 +0100)
commitec5dbe86ae08ecdb2eb3d6b3c15708fd508ddbf5
tree11884e6bd6ca16ff5b414f5ab2e0806aebe838a5
parentae10d8e67da181dce7a6fac33f0c49fd87806b98
libxc/Linux: Add VM_DONTCOPY flag of the VMA of the hypercall buffer

This avoids the hypercall buffer becoming CoW on fork.

In multi-threads and multi-processes environment, e.g. the process has two
threads, thread A may call hypercall, thread B may call fork() to create child
process. After forking, all pages of the process including hypercall buffers
are cow. It will cause a write protection and return EFAULT error if hypervisor
calls copy_to_user in hypercall in thread A context,

Fix:
1. Before hypercall: use MADV_DONTFORK of madvise syscall to make the hypercall
   buffer not to be copied to child process after fork.
2. After hypercall: undo the effect of MADV_DONTFORK for the hypercall buffer
   by using MADV_DOFORK of madvise syscall.
3. Use mmap/nunmap for memory alloc/free instead of malloc/free to bypass libc.

Note:
Child processes must not use the opened xc_{interface,evtchn,gnttab,gntshr}
handle that inherits from parents. They should reopen the handle if they want
to interact with xc. Otherwise, it may cause segment fault to access hypercall
buffer caches of the handle.

Signed-off-by: Zhenguo Wang <wangzhenguo@huawei.com>
Signed-off-by: Xiaowei Yang <xiaowei.yang@huawei.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
[ ijc -- s/ptr/p/ to fix build & tweaked the wording of the comments
         slightly. ]
Committed-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxc/xc_linux_osdep.c
tools/libxc/xenctrl.h