event-channel代码分析

来源:互联网 发布:javascript的常用类型 编辑:程序博客网 时间:2024/06/05 15:58

http://hi.baidu.com/%B0%B5%D4%C2%C1%F7%B9%E2/blog/item/1bf581167edaa605c83d6d01.html

 

(记住,event就相当于硬件的interrupt)

 

 

event-channel初始化

/xen/common/event_channel.c

1018 int evtchn_init(struct domain *d)
1019 {
1020     spin_lock_init(&d->event_lock);
1021     if ( get_free_port(d) != 0 )
1022         return -EINVAL;
1023     evtchn_from_port(d, 0)->state = ECS_RESERVED;
1024     return 0;
1025 }

该代码在每个domain创建的时候执行一次

200 struct domain *domain_create(
201     domid_t domid, unsigned int domcr_flags, ssidref_t ssidref)
202 {
           .............

238     if ( !is_idle_domain(d) )
239     {
240         if ( xsm_domain_create(d, ssidref) != 0 )
241             goto fail;
242
243         d->is_paused_by_controller = 1;
244         atomic_inc(&d->pause_count);
245
246         if ( evtchn_init(d) != 0 )
247             goto fail;
248         init_status |= INIT_evtchn;
249
250         if ( grant_table_create(d) != 0 )
251             goto fail;
252         init_status |= INIT_gnttab;
253     }
           ..............

298 }

 

/linux-2.6.18-xen.hg/include/asm-x86_64/mach-xen/asm/hypercall.h

268 static inline int __must_check
269 HYPERVISOR_event_channel_op(
270     int cmd, void *arg)
271 {
272     int rc = _hypercall2(int, event_channel_op, cmd, arg);
273
274 #if CONFIG_XEN_COMPAT <= 0x030002
275     if (unlikely(rc == -ENOSYS)) {
276         struct evtchn_op op;
277         op.cmd = cmd;
278         memcpy(&op.u, arg, sizeof(op.u));
279         rc = _hypercall1(int, event_channel_op_compat, &op);
280         memcpy(arg, &op.u, sizeof(op.u));
281     }
282 #endif
283
284     return rc;
285 }

/linux-2.6.18-xen.hg/include/asm-x86_64/mach-xen/asm/hypercall.h

81 #define _hypercall2(type, name, a1, a2)             /
82 ({                              /
83     type __res;                     /
84     long __ign1, __ign2;                    /
85     asm volatile (                      /
86         HYPERCALL_STR(name)             /
87         : "=a" (__res), "=D" (__ign1), "=S" (__ign2)    /
88         : "1" ((long)(a1)), "2" ((long)(a2))        /
89         : "memory" );                   /
90     __res;                          /
91 })

/linux-2.6.18-xen.hg/include/asm-x86_64/mach-xen/asm/hypercall.h

49 #define HYPERCALL_STR(name)                 /
50     "call hypercall_page + ("__stringify(__HYPERVISOR_##name)" * 32)"

/xen/include/public/xen.h

8 #define __HYPERVISOR_event_channel_op     32

 

 

829 long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
830 {
831     long rc;
832
833     switch ( cmd )
834     {
835     case EVTCHNOP_alloc_unbound: {
836         struct evtchn_alloc_unbound alloc_unbound;
837         if ( copy_from_guest(&alloc_unbound, arg, 1) != 0 )
838             return -EFAULT;
839         rc = evtchn_alloc_unbound(&alloc_unbound);
840         if ( (rc == 0) && (copy_to_guest(arg, &alloc_unbound, 1) != 0) )
841             rc = -EFAULT; /* Cleaning up here would be a mess! */
842         break;
843     }
844
845     case EVTCHNOP_bind_interdomain: {
846         struct evtchn_bind_interdomain bind_interdomain;
847         if ( copy_from_guest(&bind_interdomain, arg, 1) != 0 )
848             return -EFAULT;
849         rc = evtchn_bind_interdomain(&bind_interdomain);
850         if ( (rc == 0) && (copy_to_guest(arg, &bind_interdomain, 1) != 0) )
851             rc = -EFAULT; /* Cleaning up here would be a mess! */
852         break;
853     }
854
855     case EVTCHNOP_bind_virq: {
856         struct evtchn_bind_virq bind_virq;
857         if ( copy_from_guest(&bind_virq, arg, 1) != 0 )
858             return -EFAULT;
859         rc = evtchn_bind_virq(&bind_virq);
860         if ( (rc == 0) && (copy_to_guest(arg, &bind_virq, 1) != 0) )
861             rc = -EFAULT; /* Cleaning up here would be a mess! */
862         break;
863     }
864
865     case EVTCHNOP_bind_ipi: {
866         struct evtchn_bind_ipi bind_ipi;
867         if ( copy_from_guest(&bind_ipi, arg, 1) != 0 )
868             return -EFAULT;
869         rc = evtchn_bind_ipi(&bind_ipi);
870         if ( (rc == 0) && (copy_to_guest(arg, &bind_ipi, 1) != 0) )
871             rc = -EFAULT; /* Cleaning up here would be a mess! */
872         break;
873     }
874
875     case EVTCHNOP_bind_pirq: {
876         struct evtchn_bind_pirq bind_pirq;
877         if ( copy_from_guest(&bind_pirq, arg, 1) != 0 )
878             return -EFAULT;
879         rc = evtchn_bind_pirq(&bind_pirq);
880         if ( (rc == 0) && (copy_to_guest(arg, &bind_pirq, 1) != 0) )
881             rc = -EFAULT; /* Cleaning up here would be a mess! */
882         break;
883     }
884
885     case EVTCHNOP_close: {
886         struct evtchn_close close;
887         if ( copy_from_guest(&close, arg, 1) != 0 )
888             return -EFAULT;
889         rc = evtchn_close(&close);
890         break;
891     }
892
893     case EVTCHNOP_send: {
894         struct evtchn_send send;
895         if ( copy_from_guest(&send, arg, 1) != 0 )
896             return -EFAULT;
897         rc = evtchn_send(current->domain, send.port);
898         break;
899     }
900
901     case EVTCHNOP_status: {
902         struct evtchn_status status;
903         if ( copy_from_guest(&status, arg, 1) != 0 )
904             return -EFAULT;
905         rc = evtchn_status(&status);
906         if ( (rc == 0) && (copy_to_guest(arg, &status, 1) != 0) )
907             rc = -EFAULT;
908         break;
909     }
910
911     case EVTCHNOP_bind_vcpu: {
912         struct evtchn_bind_vcpu bind_vcpu;
913         if ( copy_from_guest(&bind_vcpu, arg, 1) != 0 )
914             return -EFAULT;
915         rc = evtchn_bind_vcpu(bind_vcpu.port, bind_vcpu.vcpu);
916         break;
917     }
918
919     case EVTCHNOP_unmask: {
920         struct evtchn_unmask unmask;
921         if ( copy_from_guest(&unmask, arg, 1) != 0 )
922             return -EFAULT;
923         rc = evtchn_unmask(unmask.port);
924         break;
925     }
926
927     case EVTCHNOP_reset: {
928         struct evtchn_reset reset;
929         if ( copy_from_guest(&reset, arg, 1) != 0 )
930             return -EFAULT;
931         rc = evtchn_reset(&reset);
932         break;
933     }
934
935     default:
936         rc = -ENOSYS;
937         break;
938     }
939
940     return rc;
941 }

 

 

/linux-2.6.18-xen.hg/arch/x86_64/kernel/entry-xen.S

919 ENTRY(do_hypervisor_callback)   # do_hypervisor_callback(struct *pt_regs)
920     CFI_STARTPROC
921 # Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will
922 # see the correct pointer to the pt_regs
923     movq %rdi, %rsp            # we don't return, adjust the stack frame
924     CFI_ENDPROC
925     CFI_DEFAULT_STACK
926 11: incl %gs:pda_irqcount
927     movq %rsp,%rbp
928     CFI_DEF_CFA_REGISTER rbp
929     cmovzq %gs:pda_irqstackptr,%rsp
930     pushq %rbp          # backlink for old unwinder
931     call evtchn_do_upcall
932     popq %rsp
933     CFI_DEF_CFA_REGISTER rsp
934     decl %gs:pda_irqcount
935     jmp error_exit
936     CFI_ENDPROC
937 END(do_hypervisor_callback)

 

/linux-2.6.18-xen.hg/drivers/xen/core/evtchn.c

236 /* NB. Interrupts are disabled on entry. */
237 asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
238 {
......................

294                 if ((irq = evtchn_to_irq[port]) != -1)
295                     do_IRQ(irq, regs);
296                 else
297                     evtchn_device_upcall(port);
.......................

316     irq_exit();
317 }

 

原创粉丝点击