[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] x86/ioapic: Add register level checks to detect bogus io-apic entries
On 17/04/2012 13:49, "Jan Beulich" <JBeulich@xxxxxxxx> wrote: > With the recent changes to clear_IO_APIC_pin() which tries to > clear remoteIRR bit explicitly, some of the users started to see > "Unable to reset IRR for apic .." messages. > > Close look shows that these are related to bogus IO-APIC entries > which returns all 1s for their io-apic registers. And the > above mentioned error messages are benign. But kernel should > have ignored such io-apic's in the first place. > > Check if register 0, 1, 2 of the listed io-apic are all 1s and > ignore such io-apic. > > [original Linux patch:] > Signed-off-by: Suresh Siddha <suresh.b.siddha@xxxxxxxxx> > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Keir Fraser <keir@xxxxxxx> > --- a/xen/arch/x86/io_apic.c > +++ b/xen/arch/x86/io_apic.c > @@ -185,7 +185,7 @@ struct IO_APIC_route_entry **alloc_ioapi > ioapic_entries[apic] = > xmalloc_array(struct IO_APIC_route_entry, > nr_ioapic_entries[apic]); > - if (!ioapic_entries[apic]) > + if (!ioapic_entries[apic] && nr_ioapic_entries[apic]) > goto nomem; > } > > @@ -310,6 +310,9 @@ int save_IO_APIC_setup(struct IO_APIC_ro > return -ENOMEM; > > for (apic = 0; apic < nr_ioapics; apic++) { > + if (!nr_ioapic_entries[apic]) > + continue; > + > if (!ioapic_entries[apic]) > return -ENOMEM; > > @@ -331,6 +334,9 @@ void mask_IO_APIC_setup(struct IO_APIC_r > return; > > for (apic = 0; apic < nr_ioapics; apic++) { > + if (!nr_ioapic_entries[apic]) > + continue; > + > if (!ioapic_entries[apic]) > break; > > @@ -358,6 +364,9 @@ int restore_IO_APIC_setup(struct IO_APIC > return -ENOMEM; > > for (apic = 0; apic < nr_ioapics; apic++) { > + if (!nr_ioapic_entries[apic]) > + continue; > + > if (!ioapic_entries[apic]) > return -ENOMEM; > > @@ -610,6 +619,8 @@ static int __init find_isa_irq_apic(int > if (i < mp_irq_entries) { > int apic; > for(apic = 0; apic < nr_ioapics; apic++) { > + if (!nr_ioapic_entries[apic]) > + continue; > if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic) > return apic; > } > @@ -1080,6 +1091,8 @@ static void /*__init*/ __print_IO_APIC(v > printk(KERN_INFO "testing the IO APIC.......................\n"); > > for (apic = 0; apic < nr_ioapics; apic++) { > + if (!nr_ioapic_entries[apic]) > + continue; > > spin_lock_irqsave(&ioapic_lock, flags); > reg_00.raw = io_apic_read(apic, 0); > @@ -1229,6 +1242,8 @@ static void __init enable_IO_APIC(void) > > if (directed_eoi_enabled) { > for (apic = 0; apic < nr_ioapics; apic++) { > + if (!nr_ioapic_entries[apic]) > + continue; > vector_map[apic] = xzalloc(vmask_t); > BUG_ON(!vector_map[apic]); > } > @@ -1354,6 +1369,8 @@ static void __init setup_ioapic_ids_from > * Set the IOAPIC ID to the value stored in the MPC table. > */ > for (apic = 0; apic < nr_ioapics; apic++) { > + if (!nr_ioapic_entries[apic]) > + continue; > > /* Read the register 0 value */ > spin_lock_irqsave(&ioapic_lock, flags); > @@ -2038,6 +2055,8 @@ void ioapic_resume(void) > > spin_lock_irqsave(&ioapic_lock, flags); > for (apic = 0; apic < nr_ioapics; apic++){ > + if (!nr_ioapic_entries[apic]) > + continue; > reg_00.raw = __io_apic_read(apic, 0); > if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) { > reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; > @@ -2225,8 +2244,12 @@ static int ioapic_physbase_to_id(unsigne > { > int apic; > for ( apic = 0; apic < nr_ioapics; apic++ ) > + { > + if ( !nr_ioapic_entries[apic] ) > + continue; > if ( mp_ioapics[apic].mpc_apicaddr == physbase ) > return apic; > + } > return -EINVAL; > } > > @@ -2444,6 +2467,22 @@ void dump_ioapic_irq_info(void) > static unsigned int __initdata max_gsi_irqs; > integer_param("max_gsi_irqs", max_gsi_irqs); > > +static __init bool_t bad_ioapic_register(unsigned int idx) > +{ > + union IO_APIC_reg_00 reg_00 = { .raw = io_apic_read(idx, 0) }; > + union IO_APIC_reg_01 reg_01 = { .raw = io_apic_read(idx, 1) }; > + union IO_APIC_reg_02 reg_02 = { .raw = io_apic_read(idx, 2) }; > + > + if ( reg_00.raw == -1 && reg_01.raw == -1 && reg_02.raw == -1 ) > + { > + printk(KERN_WARNING "I/O APIC %#x registers return all ones, > skipping!\n", > + mp_ioapics[idx].mpc_apicaddr); > + return 1; > + } > + > + return 0; > +} > + > void __init init_ioapic_mappings(void) > { > unsigned long ioapic_phys; > @@ -2477,6 +2516,12 @@ void __init init_ioapic_mappings(void) > __fix_to_virt(idx), ioapic_phys); > idx++; > > + if ( bad_ioapic_register(i) ) > + { > + __set_fixmap(idx, 0, 0); > + continue; > + } > + > if ( smp_found_config ) > { > /* The number of IO-APIC IRQ registers (== #pins): */ > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |