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