Skip to content

Commit a774635

Browse files
lrq-maxKAGA-KOKO
authored andcommitted
x86/apic: Fix signedness bug in APIC ID validity checks
The APIC ID as parsed from ACPI MADT is validity checked with the apic->apic_id_valid() callback, which depends on the selected APIC type. For non X2APIC types APIC IDs >= 0xFF are invalid, but values > 0x7FFFFFFF are detected as valid. This happens because the 'apicid' argument of the apic_id_valid() callback is type 'int'. So the resulting comparison apicid < 0xFF evaluates to true for all unsigned int values > 0x7FFFFFFF which are handed to default_apic_id_valid(). As a consequence, invalid APIC IDs in !X2APIC mode are considered valid and accounted as possible CPUs. Change the apicid argument type of the apic_id_valid() callback to u32 so the evaluation is unsigned and returns the correct result. [ tglx: Massaged changelog ] Signed-off-by: Li RongQing <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: [email protected] Cc: [email protected] Cc: Dou Liyang <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent d94a155 commit a774635

File tree

8 files changed

+16
-13
lines changed

8 files changed

+16
-13
lines changed

arch/x86/include/asm/apic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ struct apic {
319319
/* Probe, setup and smpboot functions */
320320
int (*probe)(void);
321321
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
322-
int (*apic_id_valid)(int apicid);
322+
int (*apic_id_valid)(u32 apicid);
323323
int (*apic_id_registered)(void);
324324

325325
bool (*check_apicid_used)(physid_mask_t *map, int apicid);
@@ -492,7 +492,7 @@ static inline unsigned int read_apic_id(void)
492492
return apic->get_apic_id(reg);
493493
}
494494

495-
extern int default_apic_id_valid(int apicid);
495+
extern int default_apic_id_valid(u32 apicid);
496496
extern int default_acpi_madt_oem_check(char *, char *);
497497
extern void default_setup_apic_routing(void);
498498

arch/x86/kernel/acpi/boot.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
200200
{
201201
struct acpi_madt_local_x2apic *processor = NULL;
202202
#ifdef CONFIG_X86_X2APIC
203-
int apic_id;
203+
u32 apic_id;
204204
u8 enabled;
205205
#endif
206206

@@ -222,10 +222,13 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
222222
* to not preallocating memory for all NR_CPUS
223223
* when we use CPU hotplug.
224224
*/
225-
if (!apic->apic_id_valid(apic_id) && enabled)
226-
printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
227-
else
228-
acpi_register_lapic(apic_id, processor->uid, enabled);
225+
if (!apic->apic_id_valid(apic_id)) {
226+
if (enabled)
227+
pr_warn(PREFIX "x2apic entry ignored\n");
228+
return 0;
229+
}
230+
231+
acpi_register_lapic(apic_id, processor->uid, enabled);
229232
#else
230233
printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
231234
#endif

arch/x86/kernel/apic/apic_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int default_check_phys_apicid_present(int phys_apicid)
4040
return physid_isset(phys_apicid, phys_cpu_present_map);
4141
}
4242

43-
int default_apic_id_valid(int apicid)
43+
int default_apic_id_valid(u32 apicid)
4444
{
4545
return (apicid < 255);
4646
}

arch/x86/kernel/apic/apic_numachip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static u32 numachip2_set_apic_id(unsigned int id)
5656
return id << 24;
5757
}
5858

59-
static int numachip_apic_id_valid(int apicid)
59+
static int numachip_apic_id_valid(u32 apicid)
6060
{
6161
/* Trust what bootloader passes in MADT */
6262
return 1;

arch/x86/kernel/apic/x2apic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Common bits for X2APIC cluster/physical modes. */
22

3-
int x2apic_apic_id_valid(int apicid);
3+
int x2apic_apic_id_valid(u32 apicid);
44
int x2apic_apic_id_registered(void);
55
void __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest);
66
unsigned int x2apic_get_apic_id(unsigned long id);

arch/x86/kernel/apic/x2apic_phys.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static int x2apic_phys_probe(void)
101101
}
102102

103103
/* Common x2apic functions, also used by x2apic_cluster */
104-
int x2apic_apic_id_valid(int apicid)
104+
int x2apic_apic_id_valid(u32 apicid)
105105
{
106106
return 1;
107107
}

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ static void uv_send_IPI_all(int vector)
557557
uv_send_IPI_mask(cpu_online_mask, vector);
558558
}
559559

560-
static int uv_apic_id_valid(int apicid)
560+
static int uv_apic_id_valid(u32 apicid)
561561
{
562562
return 1;
563563
}

arch/x86/xen/apic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static int xen_madt_oem_check(char *oem_id, char *oem_table_id)
112112
return xen_pv_domain();
113113
}
114114

115-
static int xen_id_always_valid(int apicid)
115+
static int xen_id_always_valid(u32 apicid)
116116
{
117117
return 1;
118118
}

0 commit comments

Comments
 (0)