static void resume_x2apic(void) { struct IO_APIC_route_entry **ioapic_entries = NULL; ASSERT(x2apic_enabled); ioapic_entries = alloc_ioapic_entries(); if ( !ioapic_entries ) { printk("Allocate ioapic_entries failed\n"); goto out; } if ( save_IO_APIC_setup(ioapic_entries) ) { printk("Saving IO-APIC state failed\n"); goto out; } mask_8259A(); mask_IO_APIC_setup(ioapic_entries); iommu_enable_x2apic_IR(); __enable_x2apic(); restore_IO_APIC_setup(ioapic_entries); unmask_8259A(); out: if ( ioapic_entries ) free_ioapic_entries(ioapic_entries); }
void __init x2apic_bsp_setup(void) { struct IO_APIC_route_entry **ioapic_entries = NULL; if ( !cpu_has_x2apic ) return; if ( !opt_x2apic ) { if ( !x2apic_enabled ) { printk("Not enabling x2APIC: disabled by cmdline.\n"); return; } printk("x2APIC: Already enabled by BIOS: Ignoring cmdline disable.\n"); } if ( !iommu_supports_eim() ) { if ( !x2apic_enabled ) { printk("Not enabling x2APIC: depends on iommu_supports_eim.\n"); return; } panic("x2APIC: already enabled by BIOS, but " "iommu_supports_eim failed!\n"); } if ( (ioapic_entries = alloc_ioapic_entries()) == NULL ) { printk("Allocate ioapic_entries failed\n"); goto out; } if ( save_IO_APIC_setup(ioapic_entries) ) { printk("Saving IO-APIC state failed\n"); goto out; } mask_8259A(); mask_IO_APIC_setup(ioapic_entries); if ( iommu_enable_x2apic_IR() ) { if ( x2apic_enabled ) panic("Interrupt remapping could not be enabled while " "x2APIC is already enabled by BIOS!\n"); printk(XENLOG_ERR "Failed to enable Interrupt Remapping: Will not enable x2APIC.\n"); goto restore_out; } force_iommu = 1; genapic = apic_x2apic_probe(); printk("Switched to APIC driver %s.\n", genapic->name); if ( !x2apic_enabled ) { x2apic_enabled = 1; __enable_x2apic(); } restore_out: restore_IO_APIC_setup(ioapic_entries); unmask_8259A(); out: if ( ioapic_entries ) free_ioapic_entries(ioapic_entries); }
static int lapic_resume(struct sys_device *dev) { unsigned int l, h; unsigned long flags; int maxlvt; int ret = 0; struct IO_APIC_route_entry **ioapic_entries = NULL; if (!apic_pm_state.active) return 0; local_irq_save(flags); if (intr_remapping_enabled) { ioapic_entries = alloc_ioapic_entries(); if (!ioapic_entries) { WARN(1, "Alloc ioapic_entries in lapic resume failed."); ret = -ENOMEM; goto restore; } ret = save_IO_APIC_setup(ioapic_entries); if (ret) { WARN(1, "Saving IO-APIC state failed: %d\n", ret); free_ioapic_entries(ioapic_entries); goto restore; } mask_IO_APIC_setup(ioapic_entries); mask_8259A(); } if (x2apic_mode) enable_x2apic(); else { rdmsr(MSR_IA32_APICBASE, l, h); l &= ~MSR_IA32_APICBASE_BASE; l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; wrmsr(MSR_IA32_APICBASE, l, h); } maxlvt = lapic_get_maxlvt(); apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); apic_write(APIC_ID, apic_pm_state.apic_id); apic_write(APIC_DFR, apic_pm_state.apic_dfr); apic_write(APIC_LDR, apic_pm_state.apic_ldr); apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri); apic_write(APIC_SPIV, apic_pm_state.apic_spiv); apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) if (maxlvt >= 5) apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); #endif if (maxlvt >= 4) apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); apic_write(APIC_TMICT, apic_pm_state.apic_tmict); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); if (intr_remapping_enabled) { reenable_intr_remapping(x2apic_mode); unmask_8259A(); restore_IO_APIC_setup(ioapic_entries); free_ioapic_entries(ioapic_entries); } restore: local_irq_restore(flags); return ret; }
void __init enable_IR_x2apic(void) { unsigned long flags; struct IO_APIC_route_entry **ioapic_entries = NULL; int ret, x2apic_enabled = 0; int dmar_table_init_ret = 0; #ifdef CONFIG_INTR_REMAP dmar_table_init_ret = dmar_table_init(); if (dmar_table_init_ret) pr_debug("dmar_table_init() failed with %d:\n", dmar_table_init_ret); #endif ioapic_entries = alloc_ioapic_entries(); if (!ioapic_entries) { pr_err("Allocate ioapic_entries failed\n"); goto out; } ret = save_IO_APIC_setup(ioapic_entries); if (ret) { pr_info("Saving IO-APIC state failed: %d\n", ret); goto out; } local_irq_save(flags); mask_8259A(); mask_IO_APIC_setup(ioapic_entries); if (dmar_table_init_ret) ret = 0; else ret = enable_IR(); if (!ret) { if (max_physical_apicid > 255 || !kvm_para_available()) goto nox2apic; x2apic_force_phys(); } x2apic_enabled = 1; if (x2apic_supported() && !x2apic_mode) { x2apic_mode = 1; enable_x2apic(); pr_info("Enabled x2apic\n"); } nox2apic: if (!ret) restore_IO_APIC_setup(ioapic_entries); unmask_8259A(); local_irq_restore(flags); out: if (ioapic_entries) free_ioapic_entries(ioapic_entries); if (x2apic_enabled) return; if (x2apic_preenabled) panic("x2apic: enabled by BIOS but kernel init failed."); else if (cpu_has_x2apic) pr_info("Not enabling x2apic, Intr-remapping init failed.\n"); }