Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346642
  • 博文数量: 167
  • 博客积分: 2867
  • 博客等级: 少校
  • 技术积分: 1306
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-12 00:08
文章分类

全部博文(167)

文章存档

2017年(10)

2016年(5)

2015年(9)

2014年(10)

2013年(5)

2012年(17)

2011年(110)

2010年(1)

我的朋友

分类: LINUX

2011-02-20 19:31:02

    Like the system call in Linux, XEN also offer this mechanism named HYPERCALL, 
hypercall page is a memory page which store the hypercall code, every hypercall 
code segment should not larger than 32B, every hypercall has a number to identify 
itself, so use this number we can locate the hypercall code segment in the 
hypercall page, such as the number is 13, ok , the code segment address is:
             address = hypercall_page + 13*32 
    In this document we will talk about the process of how to establish the hypercall page,
so we can comprehend the hypercall.

    In the source of xen we can find the function named: hypercall_page_initialise:
  1. //xen/arch/x86/x86_32/traps.c
  2. void hypercall_page_initialise(struct domain *d, void *hypercall_page)
  3.     memset(hypercall_page, 0xCC, PAGE_SIZE);
  4.     if ( is_hvm_domain(d) )
  5.         hvm_hypercall_page_initialise(d, hypercall_page);
  6.     else if ( supervisor_mode_kernel )
  7.         hypercall_page_initialise_ring0_kernel(hypercall_page);
  8.     else
  9.         hypercall_page_initialise_ring1_kernel(hypercall_page);
  10. }
According to the parameter this function to initialize the hypercall_page separately, 
we'll not analyse it at present, at first, we will see who call this function, from
the source code, there are two branch:
1:--->libxl_create_xenpv_qemu--->libxl_create_device_model
--->libxl_create_stubdom--->libxl_domain_build
--->build_pv--->xc_dom_linux_build--->xc_linux_build_internal--->xc_dom_boot_image
--->(./tools/libxc/xc_dom_boot.c)setup_hypercall_page--->do_domctl
--->arch_do_domctl(XEN_DOMCTL_hypercall_init)--->hypercall_page_initialise
2:xen/arch/x86/boot/x86_32.S -->__start_xen--->construct_dom0--->hypercall_page_initialise
    
    From the call path, we can know the first call path was called when XEN want to create 
a domU, while the second was called when the dom0 was created.
    Secondly, let's analyse the hypercall_page_initialise itself. The first branch is for HVM domU.
     hvm_hypercall_page_initialise(d, hypercall_page);

  1. xen/arch/x86/hvm/hvm.c
  2. /* Initialise a hypercall transfer page for a VMX domain using paravirtualised drivers. */
  3. void hvm_hypercall_page_initialise(struct domain *d,
  4.                                    void *hypercall_page)
  5. {
  6.     hvm_latch_shinfo_size(d);
  7.     hvm_funcs.init_hypercall_page(d, hypercall_page);
  8. }
./xen/arch/x86/cpu/intel.c
__start_xen--->early_cpu_init--->intel_cpu_init--->init_intel--->start_vmx--->hvm_enable(set up the hvm_function_table, in this 
struct, there is an init_hypercall_page function, in this context that is 
initialized with vmx_init_hypercall_page):
  1. //one of the implementation of init_hypercall_page
  2. static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page)
  3. {
  4.     char *p;
  5.     int i;

  6.     for ( i = 0; i < (PAGE_SIZE / 32); i++ )
  7.     {    
  8.         p = (char *)(hypercall_page + (i * 32));
  9.         *(u8  *)(p + 0) = 0xb8; /* mov imm32, %eax */
  10.         *(u32 *)(p + 1) = i; 
  11.         *(u8  *)(p + 5) = 0x0f; /* vmcall */
  12.         *(u8  *)(p + 6) = 0x01;
  13.         *(u8  *)(p + 7) = 0xc1;
  14.         *(u8  *)(p + 8) = 0xc3; /* ret */
  15.     }    

  16.     /* Don't support HYPERVISOR_iret at the moment */
  17.     *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
  18. }
阅读(879) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

fangtuo902015-08-07 09:50:45

在hypercall page初始化的过程中如何获取hypercall page的地址呢?