[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH]xen new latest version mp_register_lapic can't register disabled CPU, patch attempt to fix



Hi all,

 

I have found a minor problem in Xen 4.6 unstable

 

When xen booted up and parsed all cpus by acpi_parse_x2apic,

 

if the number of “Processor Local x2APIC Structure”(struct acpi_madt_local_x2apic) parsed from acpi table bigger than the number of host cpu.

for all extra acpi_madt_local_x2apic structure,  

struct acpi_madt_local_x2apic {

         struct acpi_subtable_header header;

         u16 reserved;           /* Reserved - must be zero */

         u32 local_apic_id;    /* Processor x2APIC ID  */

         u32 lapic_flags;

         u32 uid;             /* ACPI processor UID */

};

member local_apic_id has default value FFFFFFFF.

 

90 static int __init

91 acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)

92 {

93         struct acpi_madt_local_x2apic *processor =

94                 container_of(header, struct acpi_madt_local_x2apic, header);

95         bool_t enabled = 0;

96

97         if (BAD_MADT_ENTRY(processor, end))

98                 return -EINVAL;

99

100         acpi_table_print_madt_entry(header);

101

102         /* Record local apic id only when enabled and fitting. */

103         if (processor->local_apic_id >= MAX_APICS ||

104             processor->uid >= MAX_MADT_ENTRIES) {

105                 printk("%sAPIC ID %#x and/or ACPI ID %#x beyond limit"

106                        " - processor ignored\n",

107                        processor->lapic_flags & ACPI_MADT_ENABLED ?

108                                 KERN_WARNING "WARNING: " : KERN_INFO,

109                        processor->local_apic_id, processor->uid);

110                 /*

111                  * Must not return an error here, to prevent

112                  * acpi_table_parse_entries() from terminating early.

113                  */

114                 return 0 /* -ENOSPC */;

115         }

116         if (processor->lapic_flags & ACPI_MADT_ENABLED) {

117                 x86_acpiid_to_apicid[processor->uid] =

118                         processor->local_apic_id;

119                 enabled = 1;

120         }

121

122         /*

123          * We need to register disabled CPU as well to permit

124          * counting disabled CPUs. This allows us to size

125          * cpus_possible_map more accurately, to permit

126          * to not preallocating memory for all NR_CPUS

127          * when we use CPU hotplug.

128          */

129         mp_register_lapic(processor->local_apic_id, enabled, 0);

130

131         return 0;

 

 

based on the above code, “processor->local_apic_id >= MAX_APICS”(line:103) and return ,caused each disabled CPU can’t be registered.

 

the following patch may fix the bug.

diff --git a/b/xen/arch/x86/acpi/boot.c b/a/xen/arch/x86/acpi/boot.c

index 9a8904b..6fad341 100644

--- a/b/xen/arch/x86/acpi/boot.c

+++ b/a/xen/arch/x86/acpi/boot.c

@@ -93,20 +93,23 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)

        struct acpi_madt_local_x2apic *processor =

                container_of(header, struct acpi_madt_local_x2apic, header);

        bool_t enabled = 0;

+       int apic_id = 0;

 

        if (BAD_MADT_ENTRY(processor, end))

                return -EINVAL;

 

        acpi_table_print_madt_entry(header);

+

+       apic_id = processor->local_apic_id;

 

        /* Record local apic id only when enabled and fitting. */

-       if (processor->local_apic_id >= MAX_APICS ||

+       if (apic_id >= MAX_APICS ||

            processor->uid >= MAX_MADT_ENTRIES) {

                printk("%sAPIC ID %#x and/or ACPI ID %#x beyond limit"

                       " - processor ignored\n",

                       processor->lapic_flags & ACPI_MADT_ENABLED ?

                                KERN_WARNING "WARNING: " : KERN_INFO,

-                      processor->local_apic_id, processor->uid);

+                      apic_id, processor->uid);

                /*

                 * Must not return an error here, to prevent

                 * acpi_table_parse_entries() from terminating early.

@@ -126,7 +129,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)

         * to not preallocating memory for all NR_CPUS

         * when we use CPU hotplug.

         */

-       mp_register_lapic(processor->local_apic_id, enabled, 0);

+       mp_register_lapic(apic_id, enabled, 0);

 

        return 0;

}

diff --git a/b/xen/arch/x86/mpparse.c b/a/xen/arch/x86/mpparse.c

index 003c56e..e45854b 100644

--- a/b/xen/arch/x86/mpparse.c

+++ b/a/xen/arch/x86/mpparse.c

@@ -759,7 +759,7 @@ void __init mp_register_lapic_address (

 

 

int __devinit mp_register_lapic (

-       u32                     id,

+       int                     id,

        bool_t                  enabled,

        bool_t                  hotplug)

{

diff --git a/b/xen/include/asm-x86/mpspec.h b/a/xen/include/asm-x86/mpspec.h

index 8ae3cd5..2c718db 100644

--- a/b/xen/include/asm-x86/mpspec.h

+++ b/a/xen/include/asm-x86/mpspec.h

@@ -20,7 +20,7 @@ extern unsigned long mp_lapic_addr;

extern bool_t pic_mode;

 

#ifdef CONFIG_ACPI

-extern int mp_register_lapic(u32 id, bool_t enabled, bool_t hotplug);

+extern int mp_register_lapic(int id, bool_t enabled, bool_t hotplug);

extern void mp_unregister_lapic(uint32_t apic_id, uint32_t cpu);

extern void mp_register_lapic_address (u64 address);

extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);                        

 

 

 

 

 

Thanks

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.