Home > other >  About Xen Hypercall about Xen source about do_memory_op ()
About Xen Hypercall about Xen source about do_memory_op ()

Time:10-03

In Xen source code, there is a function long do_memory_op (unsigned long CMD, XEN_GUEST_HANDLE (void) arg), which invokes the rc=memory_exchange (guest_handle_cast (arg, xen_memory_exchange_t)), I don't understand is XEN_GUEST_HANDLE and guest_handle_cast what is this? I look at the source, the former is only a macro definition, although the latter has specific content, but can't read,
In addition, the memory address is how to transfer? Or, xen_memory_exchange_t this structure is how the assignment?
Thank humbly!!!!!

CodePudding user response:

I'll try to answer the memory address is how to transfer? Or, xen_memory_exchange_t this structure is how the assignment? The this problem.

The console of the hypercall should be mostly in Dom0, calls the libxc interface

Do_memory_op (XCH XENMEM_exchange, & amp; Exchange, sizeof (exchange));
Set in do_memory_op hypercall value, and then call do_xen_hypercall, the following code
Hypercall. Op=__HYPERVISOR_memory_op;
Hypercall. Arg [0]=(unsigned long) CMD.
Hypercall. Arg [1]=HYPERCALL_BUFFER_AS_ARG (arg);
Ret=do_xen_hypercall (XCH, & amp; Hypercall);

For Linux support Xen, do_xen_hypercall finally call linux_privcmd_hypercall, this function is to/dev/Xen/privcmd equipment made an ioctl (fd, IOCTL_PRIVCMD_HYPERCALL, hypercall) operation (here actually can know, why to the Linux kernel patch at Xen can support Xen, support Linux Xen based on/dev/Xen/privcmd to perform the hypercall)
Look at/dev/xen/privcmd this device drivers provide ioctl interface (xen here to jump to the Linux kernel code, not xen source code)
The static long privcmd_ioctl (struct file, the file *
Unsigned int CMD, unsigned long data)
{
Int ret=- ENOSYS;
Void the __user * udata=https://bbs.csdn.net/topics/(void the __user *) data;

The switch (CMD) {
Case IOCTL_PRIVCMD_HYPERCALL:
Ret=privcmd_ioctl_hypercall (udata);
break;
}
Continue to enter privcmd_ioctl_hypercall (udata)
The static long privcmd_ioctl_hypercall (void the __user * udata)
{
Struct privcmd_hypercall hypercall;
Long ret.

If (the copy_from_user (& amp; Hypercall udata, sizeof (hypercall)))
The return - EFAULT;

Ret=privcmd_call (hypercall. Op,
Hypercall. Arg [0], hypercall. Arg [1],
Hypercall. Arg [2], the hypercall. Arg [3],
Hypercall. Arg [4]);
}
Hypercall content has been copied into the kernel space, and then continue to follow up privcmd_call
This function calls for some inline assembly
__HYPERCALL_DECLS;
__HYPERCALL_5ARG (a1, a2, a3, a4, a5);
Asm volatile (" call * % [call] "
: __HYPERCALL_5PARAM
: [call] "a" (& amp; Hypercall_page [call])
: __HYPERCALL_CLOBBER5);
although I look very confused... But through macro can guess the op in eax, arg0-4 five arguments on the ebx, ecx, edx, esi, edi (x86 32), and then directly according to the hypercall op, call the corresponding interface (Linux 3.0 code directly to the call?? Didn't pass the int 0 x82??? Hypercall_page should establish Dom0 (Linux) when mapping) (if you have, please teach... )

Back to xen code
ENTRY (compat_hypercall_table)
The quad compat_set_trap_table/* 0 */
The quad do_mmu_update
The quad compat_set_gdt
The quad do_stack_switch
The quad compat_set_callbacks
The quad do_fpu_taskswitch/* 5 */
The quad do_sched_op_compat
The quad compat_platform_op
The quad do_set_debugreg
The quad do_get_debugreg
The quad compat_update_descriptor/* 10 */
The quad compat_ni_hypercall
. The quad compat_memory_op /* __HYPERVISOR_memory_op=12 */
Long do_memory_op (unsigned long CMD, XEN_GUEST_HANDLE_PARAM (void) arg)
Don't understand, why the two parameters can register ebx, ecx in... The CMD=& gt; Arg [0]=& gt; Ebx, arg=& gt; Arg [1]=& gt; Ecx...

The

CodePudding user response:

If it is through the int 0 x82 to invoke the hypercall is better understood, from exit into the VMX vm, call
Vmx_asm_vmexit_handler,
Register stack,
Then call vmx_asm_vmexit_handler, according to exit the cause of the vm
Should be EXIT_REASON_VMCALL, which in turn calls
Rc=hvm_do_hypercall (regs); Reg point is just the content of the pressure of the stack that register
The last call:
Regs - & gt; Eax=hvm_hypercall32_table [eax] ((uint32_t) regs - & gt; Ebx,
(uint32_t) regs - & gt; Ecx,
(uint32_t) regs - & gt; Edx,
(uint32_t) regs - & gt; Esi,
(uint32_t) regs - & gt; Edi,
(uint32_t) regs - & gt; Ebp);
The static hvm_hypercall_t * const hvm_hypercall32_table [NR_hypercalls]={
[__HYPERVISOR_memory_op]=(hvm_hypercall_t *) hvm_memory_op_compat32,
[__HYPERVISOR_grant_table_op]=(hvm_hypercall_t *) hvm_grant_table_op_compat32,
[__HYPERVISOR_vcpu_op]=(hvm_hypercall_t *) hvm_vcpu_op_compat32,
[__HYPERVISOR_physdev_op]=(hvm_hypercall_t *) hvm_physdev_op_compat32,
COMPAT_CALL (xen_version),
HYPERCALL (console_io),
HYPERCALL (event_channel_op),
COMPAT_CALL (sched_op),
COMPAT_CALL (set_timer_op),
HYPERCALL (xsm_op),
HYPERCALL (hvm_op),
HYPERCALL (sysctl),
HYPERCALL (domctl),
HYPERCALL (tmem_op)
};

CodePudding user response:

The above said is wrong, not int 0 x82, is through vmcall instruction...

CodePudding user response:

Xen source where there is

CodePudding user response:

Still to answer their own questions
Dom0 Linux hypercall stored in the table is not a specific hypercallcode, but
The static void vmx_init_hypercall_page (struct domain * d, void * hypercall_page)
{
Char * p;
int i;

For (I=0; I & lt; (PAGE_SIZE/32); I++)
{
If (I==__HYPERVISOR_iret)
continue;

P=(char *) (hypercall_page + * 32) (I);
* (u8 *) (p=0 xb8 + 0);/* mov imm32, % eax */
* (u32 *) (p=I + 1);
* (u8 *) (p=0 x0f + 5); nullnullnullnullnullnullnullnullnullnullnull
  • Related