static const struct jailhouse_irqchip * irqchip_find_config(struct jailhouse_cell_desc *config) { const struct jailhouse_irqchip *irq_config = jailhouse_cell_irqchips(config); if (config->num_irqchips) return irq_config; else return NULL; }
int ioapic_cell_init(struct cell *cell) { const struct jailhouse_irqchip *irqchip = jailhouse_cell_irqchips(cell->config); struct cell_ioapic *ioapic, *root_ioapic; struct phys_ioapic *phys_ioapic; unsigned int n; if (cell->config->num_irqchips == 0) return 0; if (cell->config->num_irqchips > IOAPIC_MAX_CHIPS) return trace_error(-ERANGE); cell->arch.ioapics = page_alloc(&mem_pool, 1); if (!cell->arch.ioapics) return -ENOMEM; for (n = 0; n < cell->config->num_irqchips; n++, irqchip++) { phys_ioapic = ioapic_get_or_add_phys(irqchip); if (!phys_ioapic) { ioapic_cell_exit(cell); return -ENOMEM; } ioapic = &cell->arch.ioapics[n]; ioapic->info = irqchip; ioapic->cell = cell; ioapic->phys_ioapic = phys_ioapic; ioapic->pin_bitmap = (u32)irqchip->pin_bitmap; cell->arch.num_ioapics++; mmio_region_register(cell, irqchip->address, PAGE_SIZE, ioapic_access_handler, ioapic); if (cell != &root_cell) { root_ioapic = ioapic_find_by_address(&root_cell, irqchip->address); if (root_ioapic) { root_ioapic->pin_bitmap &= ~ioapic->pin_bitmap; ioapic_mask_cell_pins(ioapic, PINS_MASKED); } } } return 0; }