void __init xen_arch_setup(void) { int ret; static const struct callback_register __initconst event = { .type = CALLBACKTYPE_event, .address = CALLBACK_ADDR(hypervisor_callback) }; static const struct callback_register __initconst failsafe = { .type = CALLBACKTYPE_failsafe, .address = CALLBACK_ADDR(failsafe_callback) }; #ifdef CONFIG_X86_64 static const struct callback_register __initconst syscall = { .type = CALLBACKTYPE_syscall, .address = CALLBACK_ADDR(system_call) }; #endif static const struct callback_register __initconst nmi_cb = { .type = CALLBACKTYPE_nmi, .address = CALLBACK_ADDR(nmi) }; ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event); if (ret == 0) ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe); #ifdef CONFIG_X86_64 if (ret == 0) ret = HYPERVISOR_callback_op(CALLBACKOP_register, &syscall); #endif #if CONFIG_XEN_COMPAT <= 0x030002 #ifdef CONFIG_X86_32 if (ret == -ENOSYS) ret = HYPERVISOR_set_callbacks( event.address.cs, event.address.eip, failsafe.address.cs, failsafe.address.eip); #else ret = HYPERVISOR_set_callbacks( event.address, failsafe.address, syscall.address); #endif #endif BUG_ON(ret); ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb); #if CONFIG_XEN_COMPAT <= 0x030002 if (ret == -ENOSYS) { static struct xennmi_callback __initdata cb = { .handler_address = (unsigned long)nmi }; HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); } #endif }
static int __cpuinit register_callback(unsigned type, const void *func) { struct callback_register callback = { .type = type, .address = XEN_CALLBACK(__KERNEL_CS, func), .flags = CALLBACKF_mask_events, }; return HYPERVISOR_callback_op(CALLBACKOP_register, &callback); } void __cpuinit xen_enable_sysenter(void) { int ret; unsigned sysenter_feature; #ifdef CONFIG_X86_32 sysenter_feature = X86_FEATURE_SEP; #else sysenter_feature = X86_FEATURE_SYSENTER32; #endif if (!boot_cpu_has(sysenter_feature)) return; ret = register_callback(CALLBACKTYPE_sysenter, xen_sysenter_target); if(ret != 0) setup_clear_cpu_cap(sysenter_feature); }
void __init xen_irq_init(void) { struct callback_register event = { .type = CALLBACKTYPE_event, .address = { .ip = (unsigned long)&xen_event_callback }, }; xen_init_IRQ(); BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event)); late_time_init = xen_bind_early_percpu_irq; }
void xen_set_callback(void (*func)(void), uint_t type, uint_t flags) { struct callback_register cb; bzero(&cb, sizeof (cb)); #if defined(__amd64) cb.address = (ulong_t)func; #elif defined(__i386) cb.address.cs = KCS_SEL; cb.address.eip = (ulong_t)func; #endif cb.type = type; cb.flags = flags; /* * XXPV always ignore return value for NMI */ if (HYPERVISOR_callback_op(CALLBACKOP_register, &cb) != 0 && type != CALLBACKTYPE_nmi) panic("HYPERVISOR_callback_op failed"); }
void xen_smp_intr_init(void) { #ifdef CONFIG_SMP unsigned int cpu = smp_processor_id(); struct callback_register event = { .type = CALLBACKTYPE_event, .address = { .ip = (unsigned long)&xen_event_callback }, }; if (cpu == 0) { /* Initialization was already done for boot cpu. */ #ifdef CONFIG_HOTPLUG_CPU /* Register the notifier only once. */ register_cpu_notifier(&unbind_evtchn_notifier); #endif return; } /* This should be piggyback when setup vcpu guest context */ BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event)); #endif /* CONFIG_SMP */ }
void xen_smp_intr_init(void) { #ifdef CONFIG_SMP unsigned int cpu = smp_processor_id(); struct callback_register event = { .type = CALLBACKTYPE_event, .address = { .ip = (unsigned long)&xen_event_callback }, }; if (cpu == 0) { /* */ #ifdef CONFIG_HOTPLUG_CPU /* */ register_cpu_notifier(&unbind_evtchn_notifier); #endif return; } /* */ BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event)); #endif /* */ }