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; }
static int __init xen_init_events(void) { if (!xen_domain() || xen_events_irq < 0) return -ENODEV; xen_init_IRQ(); if (request_percpu_irq(xen_events_irq, xen_arm_callback, "events", &xen_vcpu)) { pr_err("Error requesting IRQ %d\n", xen_events_irq); return -EINVAL; } on_each_cpu(xen_percpu_init, NULL, 0); return 0; }
static int __init xen_guest_init(void) { struct xen_add_to_physmap xatp; static struct shared_info *shared_info_page = 0; struct device_node *node; int len; const char *s = NULL; const char *version = NULL; const char *xen_prefix = "xen,xen-"; struct resource res; phys_addr_t grant_frames; node = of_find_compatible_node(NULL, NULL, "xen,xen"); if (!node) { pr_debug("No Xen support\n"); return 0; } s = of_get_property(node, "compatible", &len); if (strlen(xen_prefix) + 3 < len && !strncmp(xen_prefix, s, strlen(xen_prefix))) version = s + strlen(xen_prefix); if (version == NULL) { pr_debug("Xen version not found\n"); return 0; } if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res)) return 0; grant_frames = res.start; xen_events_irq = irq_of_parse_and_map(node, 0); pr_info("Xen %s support found, events_irq=%d gnttab_frame=%pa\n", version, xen_events_irq, &grant_frames); if (xen_events_irq < 0) return -ENODEV; xen_domain_type = XEN_HVM_DOMAIN; xen_setup_features(); if (xen_feature(XENFEAT_dom0)) xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED; else xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED); if (!shared_info_page) shared_info_page = (struct shared_info *) get_zeroed_page(GFP_KERNEL); if (!shared_info_page) { pr_err("not enough memory\n"); return -ENOMEM; } xatp.domid = DOMID_SELF; xatp.idx = 0; xatp.space = XENMAPSPACE_shared_info; xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) BUG(); HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info * page, we use it in the event channel upcall and in some pvclock * related functions. * The shared info contains exactly 1 CPU (the boot CPU). The guest * is required to use VCPUOP_register_vcpu_info to place vcpu info * for secondary CPUs as they are brought up. * For uniformity we use VCPUOP_register_vcpu_info even on cpu0. */ xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info), sizeof(struct vcpu_info)); if (xen_vcpu_info == NULL) return -ENOMEM; if (gnttab_setup_auto_xlat_frames(grant_frames)) { free_percpu(xen_vcpu_info); return -ENOMEM; } gnttab_init(); if (!xen_initial_domain()) xenbus_probe(NULL); /* * Making sure board specific code will not set up ops for * cpu idle and cpu freq. */ disable_cpuidle(); disable_cpufreq(); xen_init_IRQ(); if (request_percpu_irq(xen_events_irq, xen_arm_callback, "events", &xen_vcpu)) { pr_err("Error request IRQ %d\n", xen_events_irq); return -EINVAL; } xen_percpu_init(); register_cpu_notifier(&xen_cpu_notifier); return 0; }
void __init init_IRQ(void) { irq_ctx_init(0); xen_init_IRQ(); }