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