Phil Winterfield (winterfi)
2008-May-28 18:48 UTC
[Xen-devel] Question on do_event_channel_op()
Is it possible that a ''HYPERVISOR_event_channel_op(EVTCHNOP_send, &op)'' call can be handled in the hypervisor in any place other than in do_event_channel_op() in xen/common/event_channel.c ? I am seeing a failure that completely contradicts the results of the printk''s that I have placed in the do_event_channel_op() handler, i.e. they show no failure but the result when seen from gdb running in the guest shows -EFAULT returned. Is there an alternate or asynchronous path through the event channel handlers that I should know about? This result really baffles me. Thanks, Phil /************************* Printk''s in do_event_channel_op() ************************************/ long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg) { long rc; switch ( cmd ) { . case EVTCHNOP_send: { struct evtchn_send send; int xn; if ((xn=xcopy_from_guest(&send, arg, 1)) != 0 ) { printk("EVTCHNOP_send: EFAULT !!! bytes remaining = %x \n", xn); return -EFAULT; } rc = evtchn_send(send.port); printk("EVTCHNOP_send: evtchn_send : rc = %lu port = %lu \n", (unsigned long)rc,(unsigned long)send.port); break; } static inline unsigned long xcopy_from_user(void *to, const void __user *from, unsigned n) { printk("EVTCHNOP_send1: n = %x access_ok = %lu is_hvm_vcpu= %x \n", n,access_ok(from,n),is_hvm_vcpu(current)); if ( access_ok(from, n) ) n = __copy_from_user(to, from, n); else memset(to, 0, n); printk("EVTCHNOP_send2: n = %x \n", n); return n; } #define xcopy_from_guest_offset(ptr, hnd, off, nr) ({ \ const typeof(*(ptr)) *_s = (hnd).p; \ typeof(*(ptr)) *_d = (ptr); \ if(is_hvm_vcpu(current)) printk("EVTCHNOP_send0: is_hvm_vcpu= %x \n",is_hvm_vcpu(current)); \ is_hvm_vcpu(current) ? \ copy_from_user_hvm(_d, _s+(off), sizeof(*_d)*(nr)) :\ xcopy_from_user(_d, _s+(off), sizeof(*_d)*(nr)); \ }) #define xcopy_from_guest(ptr, hnd, nr) \ xcopy_from_guest_offset(ptr, hnd, 0, nr) /************************* OUTPUT ************************************/ (XEN) EVTCHNOP_send1: n = 4 access_ok = 1 is_hvm_vcpu= 0 (XEN) EVTCHNOP_send2: n = 0 (XEN) EVTCHNOP_send: evtchn_send : rc = 0 port = 2 <=======returns zero /************************* GDB Showing what is actually returned ************/ (gdb) c Continuing. Breakpoint 1, HYPERVISOR_event_channel_op (cmd=4, op=0xf61fd8) at ../src-xen-mini/hypervisor.c:211 211 return _hypercall2(int, xen_version, cmd, arg); (gdb) bt #0 HYPERVISOR_event_channel_op (cmd=4, op=0xf61fd8) at ../src-xen-mini/hypervisor.c:211 #1 0x0037f2b9 in xencons_ring_init () at ../src-xen-mini/xencons_ring.c:100 #2 0x003853db in init_console () at ../src-xen-mini/xen_console.c:174 #3 0x00383ef6 in start_kernel (si=0x1002000) at ../src-xen-mini/kernel.c:158 #4 0x00000014 in _start () (gdb) b *0x0037f2b9 Breakpoint 2 at 0x37f2b9: file ../src-xen-mini/xencons_ring.c, line 100. (gdb) c Continuing. Breakpoint 2, 0x0037f2b9 in xencons_ring_init () at ../src-xen-mini/xencons_ring.c:100 100 { (gdb) i r eax 0xfffffff2 -14 <========= -EFAULT ecx 0xf61fd8 16130008 edx 0xf61fd8 16130008 ebx 0x2 2 esp 0xf61fd0 0xf61fd0 ebp 0xf61fe0 0xf61fe0 esi 0x1002000 16785408 edi 0x1002050 16785488 eip 0x37f2b9 0x37f2b9 <xencons_ring_init+65> eflags 0x202 [ IF ] cs 0xe019 57369 ss 0xe021 57377 ds 0xe021 57377 es 0xe021 57377 fs 0xe021 57377 gs 0xe021 57377 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel