Skip to content

Commit 4fe34d6

Browse files
committed
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "A small set of x86 fixes: - Prevent a NULL pointer dereference in the X2APIC code in case of a CPU hotplug failure. - Prevent boot failures on HP superdome machines by invalidating the level2 kernel pagetable entries outside of the kernel area as invalid so BIOS reserved space won't be touched unintentionally. Also ensure that memory holes are rounded up to the next PMD boundary correctly. - Enable X2APIC support on Hyper-V to prevent boot failures. - Set the paravirt name when running on Hyper-V for consistency - Move a function under the appropriate ifdef guard to prevent build warnings" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/boot/acpi: Move get_cmdline_acpi_rsdp() under #ifdef guard x86/hyperv: Set pv_info.name to "Hyper-V" x86/apic/x2apic: Fix a NULL pointer deref when handling a dying cpu x86/hyperv: Make vapic support x2apic mode x86/boot/64: Round memory hole size up to next PMD page x86/boot/64: Make level2_kernel_pgt pages invalid outside kernel area
2 parents 81c4bc3 + 228d120 commit 4fe34d6

File tree

6 files changed

+84
-38
lines changed

6 files changed

+84
-38
lines changed

arch/x86/boot/compressed/acpi.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,6 @@
2020
*/
2121
struct mem_vector immovable_mem[MAX_NUMNODES*2];
2222

23-
/*
24-
* Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
25-
* digits, and '\0' for termination.
26-
*/
27-
#define MAX_ADDR_LEN 19
28-
29-
static acpi_physical_address get_cmdline_acpi_rsdp(void)
30-
{
31-
acpi_physical_address addr = 0;
32-
33-
#ifdef CONFIG_KEXEC
34-
char val[MAX_ADDR_LEN] = { };
35-
int ret;
36-
37-
ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN);
38-
if (ret < 0)
39-
return 0;
40-
41-
if (kstrtoull(val, 16, &addr))
42-
return 0;
43-
#endif
44-
return addr;
45-
}
46-
4723
/*
4824
* Search EFI system tables for RSDP. If both ACPI_20_TABLE_GUID and
4925
* ACPI_TABLE_GUID are found, take the former, which has more features.
@@ -298,6 +274,30 @@ acpi_physical_address get_rsdp_addr(void)
298274
}
299275

300276
#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE)
277+
/*
278+
* Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
279+
* digits, and '\0' for termination.
280+
*/
281+
#define MAX_ADDR_LEN 19
282+
283+
static acpi_physical_address get_cmdline_acpi_rsdp(void)
284+
{
285+
acpi_physical_address addr = 0;
286+
287+
#ifdef CONFIG_KEXEC
288+
char val[MAX_ADDR_LEN] = { };
289+
int ret;
290+
291+
ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN);
292+
if (ret < 0)
293+
return 0;
294+
295+
if (kstrtoull(val, 16, &addr))
296+
return 0;
297+
#endif
298+
return addr;
299+
}
300+
301301
/* Compute SRAT address from RSDP. */
302302
static unsigned long get_acpi_srat_table(void)
303303
{

arch/x86/boot/compressed/misc.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
345345
{
346346
const unsigned long kernel_total_size = VO__end - VO__text;
347347
unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
348+
unsigned long needed_size;
348349

349350
/* Retain x86 boot parameters pointer passed from startup_32/64. */
350351
boot_params = rmode;
@@ -379,26 +380,38 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
379380
free_mem_ptr = heap; /* Heap */
380381
free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
381382

383+
/*
384+
* The memory hole needed for the kernel is the larger of either
385+
* the entire decompressed kernel plus relocation table, or the
386+
* entire decompressed kernel plus .bss and .brk sections.
387+
*
388+
* On X86_64, the memory is mapped with PMD pages. Round the
389+
* size up so that the full extent of PMD pages mapped is
390+
* included in the check against the valid memory table
391+
* entries. This ensures the full mapped area is usable RAM
392+
* and doesn't include any reserved areas.
393+
*/
394+
needed_size = max(output_len, kernel_total_size);
395+
#ifdef CONFIG_X86_64
396+
needed_size = ALIGN(needed_size, MIN_KERNEL_ALIGN);
397+
#endif
398+
382399
/* Report initial kernel position details. */
383400
debug_putaddr(input_data);
384401
debug_putaddr(input_len);
385402
debug_putaddr(output);
386403
debug_putaddr(output_len);
387404
debug_putaddr(kernel_total_size);
405+
debug_putaddr(needed_size);
388406

389407
#ifdef CONFIG_X86_64
390408
/* Report address of 32-bit trampoline */
391409
debug_putaddr(trampoline_32bit);
392410
#endif
393411

394-
/*
395-
* The memory hole needed for the kernel is the larger of either
396-
* the entire decompressed kernel plus relocation table, or the
397-
* entire decompressed kernel plus .bss and .brk sections.
398-
*/
399412
choose_random_location((unsigned long)input_data, input_len,
400413
(unsigned long *)&output,
401-
max(output_len, kernel_total_size),
414+
needed_size,
402415
&virt_addr);
403416

404417
/* Validate memory location choices. */

arch/x86/hyperv/hv_apic.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,21 @@ void __init hv_apic_init(void)
260260
}
261261

262262
if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
263-
pr_info("Hyper-V: Using MSR based APIC access\n");
263+
pr_info("Hyper-V: Using enlightened APIC (%s mode)",
264+
x2apic_enabled() ? "x2apic" : "xapic");
265+
/*
266+
* With x2apic, architectural x2apic MSRs are equivalent to the
267+
* respective synthetic MSRs, so there's no need to override
268+
* the apic accessors. The only exception is
269+
* hv_apic_eoi_write, because it benefits from lazy EOI when
270+
* available, but it works for both xapic and x2apic modes.
271+
*/
264272
apic_set_eoi_write(hv_apic_eoi_write);
265-
apic->read = hv_apic_read;
266-
apic->write = hv_apic_write;
267-
apic->icr_write = hv_apic_icr_write;
268-
apic->icr_read = hv_apic_icr_read;
273+
if (!x2apic_enabled()) {
274+
apic->read = hv_apic_read;
275+
apic->write = hv_apic_write;
276+
apic->icr_write = hv_apic_icr_write;
277+
apic->icr_read = hv_apic_icr_read;
278+
}
269279
}
270280
}

arch/x86/kernel/apic/x2apic_cluster.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ static int x2apic_dead_cpu(unsigned int dead_cpu)
156156
{
157157
struct cluster_mask *cmsk = per_cpu(cluster_masks, dead_cpu);
158158

159-
cpumask_clear_cpu(dead_cpu, &cmsk->mask);
159+
if (cmsk)
160+
cpumask_clear_cpu(dead_cpu, &cmsk->mask);
160161
free_cpumask_var(per_cpu(ipi_mask, dead_cpu));
161162
return 0;
162163
}

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ static void __init ms_hyperv_init_platform(void)
216216
int hv_host_info_ecx;
217217
int hv_host_info_edx;
218218

219+
#ifdef CONFIG_PARAVIRT
220+
pv_info.name = "Hyper-V";
221+
#endif
222+
219223
/*
220224
* Extract the features and hints
221225
*/

arch/x86/kernel/head64.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,31 @@ unsigned long __head __startup_64(unsigned long physaddr,
222222
* we might write invalid pmds, when the kernel is relocated
223223
* cleanup_highmap() fixes this up along with the mappings
224224
* beyond _end.
225+
*
226+
* Only the region occupied by the kernel image has so far
227+
* been checked against the table of usable memory regions
228+
* provided by the firmware, so invalidate pages outside that
229+
* region. A page table entry that maps to a reserved area of
230+
* memory would allow processor speculation into that area,
231+
* and on some hardware (particularly the UV platform) even
232+
* speculative access to some reserved areas is caught as an
233+
* error, causing the BIOS to halt the system.
225234
*/
226235

227236
pmd = fixup_pointer(level2_kernel_pgt, physaddr);
228-
for (i = 0; i < PTRS_PER_PMD; i++) {
237+
238+
/* invalidate pages before the kernel image */
239+
for (i = 0; i < pmd_index((unsigned long)_text); i++)
240+
pmd[i] &= ~_PAGE_PRESENT;
241+
242+
/* fixup pages that are part of the kernel image */
243+
for (; i <= pmd_index((unsigned long)_end); i++)
229244
if (pmd[i] & _PAGE_PRESENT)
230245
pmd[i] += load_delta;
231-
}
246+
247+
/* invalidate pages after the kernel image */
248+
for (; i < PTRS_PER_PMD; i++)
249+
pmd[i] &= ~_PAGE_PRESENT;
232250

233251
/*
234252
* Fixup phys_base - remove the memory encryption mask to obtain

0 commit comments

Comments
 (0)