event-channel代码分析

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)
295do_IRQ(irq, regs);
296 else
297evtchn_device_upcall(port);
.......................

316 irq_exit();
317 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值