Skip to content

Commit d4e860e

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 set of fixes for x86: - Make Xen PV guest deal with speculative store bypass correctly - Address more fallout from the 5-Level pagetable handling. Undo an __initdata annotation to avoid section mismatch and malfunction when post init code would touch the freed variable. - Handle exception fixup in math_error() before calling notify_die(). The reverse call order incorrectly triggers notify_die() listeners for soemthing which is handled correctly at the site which issues the floating point instruction. - Fix an off by one in the LLC topology calculation on AMD - Handle non standard memory block sizes gracefully un UV platforms - Plug a memory leak in the microcode loader - Sanitize the purgatory build magic - Add the x86 specific device tree bindings directory to the x86 MAINTAINER file patterns" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mm: Fix 'no5lvl' handling Revert "x86/mm: Mark __pgtable_l5_enabled __initdata" x86/CPU/AMD: Fix LLC ID bit-shift calculation MAINTAINERS: Add file patterns for x86 device tree bindings x86/microcode/intel: Fix memleak in save_microcode_patch() x86/platform/UV: Add kernel parameter to set memory block size x86/platform/UV: Use new set memory block size function x86/platform/UV: Add adjustable set memory block size function x86/build: Remove unnecessary preparation for purgatory Revert "kexec/purgatory: Add clean-up for purgatory directory" x86/xen: Add call of speculative_store_bypass_ht_init() to PV paths x86: Call fixup_exception() before notify_die() in math_error()
2 parents 177d363 + 2458e53 commit d4e860e

File tree

11 files changed

+97
-22
lines changed

11 files changed

+97
-22
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15572,6 +15572,7 @@ M: [email protected]
1557215572
1557315573
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
1557415574
S: Maintained
15575+
F: Documentation/devicetree/bindings/x86/
1557515576
F: Documentation/x86/
1557615577
F: arch/x86/
1557715578

arch/x86/Makefile

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,6 @@ archscripts: scripts_basic
258258
archheaders:
259259
$(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
260260

261-
archprepare:
262-
ifeq ($(CONFIG_KEXEC_FILE),y)
263-
$(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c
264-
endif
265-
266261
###
267262
# Kernel objects
268263

@@ -327,7 +322,6 @@ archclean:
327322
$(Q)rm -rf $(objtree)/arch/x86_64
328323
$(Q)$(MAKE) $(clean)=$(boot)
329324
$(Q)$(MAKE) $(clean)=arch/x86/tools
330-
$(Q)$(MAKE) $(clean)=arch/x86/purgatory
331325

332326
define archhelp
333327
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <linux/delay.h>
2727
#include <linux/crash_dump.h>
2828
#include <linux/reboot.h>
29+
#include <linux/memory.h>
2930

3031
#include <asm/uv/uv_mmrs.h>
3132
#include <asm/uv/uv_hub.h>
@@ -392,6 +393,51 @@ extern int uv_hub_info_version(void)
392393
}
393394
EXPORT_SYMBOL(uv_hub_info_version);
394395

396+
/* Default UV memory block size is 2GB */
397+
static unsigned long mem_block_size = (2UL << 30);
398+
399+
/* Kernel parameter to specify UV mem block size */
400+
static int parse_mem_block_size(char *ptr)
401+
{
402+
unsigned long size = memparse(ptr, NULL);
403+
404+
/* Size will be rounded down by set_block_size() below */
405+
mem_block_size = size;
406+
return 0;
407+
}
408+
early_param("uv_memblksize", parse_mem_block_size);
409+
410+
static __init int adj_blksize(u32 lgre)
411+
{
412+
unsigned long base = (unsigned long)lgre << UV_GAM_RANGE_SHFT;
413+
unsigned long size;
414+
415+
for (size = mem_block_size; size > MIN_MEMORY_BLOCK_SIZE; size >>= 1)
416+
if (IS_ALIGNED(base, size))
417+
break;
418+
419+
if (size >= mem_block_size)
420+
return 0;
421+
422+
mem_block_size = size;
423+
return 1;
424+
}
425+
426+
static __init void set_block_size(void)
427+
{
428+
unsigned int order = ffs(mem_block_size);
429+
430+
if (order) {
431+
/* adjust for ffs return of 1..64 */
432+
set_memory_block_size_order(order - 1);
433+
pr_info("UV: mem_block_size set to 0x%lx\n", mem_block_size);
434+
} else {
435+
/* bad or zero value, default to 1UL << 31 (2GB) */
436+
pr_err("UV: mem_block_size error with 0x%lx\n", mem_block_size);
437+
set_memory_block_size_order(31);
438+
}
439+
}
440+
395441
/* Build GAM range lookup table: */
396442
static __init void build_uv_gr_table(void)
397443
{
@@ -1180,23 +1226,30 @@ static void __init decode_gam_rng_tbl(unsigned long ptr)
11801226
<< UV_GAM_RANGE_SHFT);
11811227
int order = 0;
11821228
char suffix[] = " KMGTPE";
1229+
int flag = ' ';
11831230

11841231
while (size > 9999 && order < sizeof(suffix)) {
11851232
size /= 1024;
11861233
order++;
11871234
}
11881235

1236+
/* adjust max block size to current range start */
1237+
if (gre->type == 1 || gre->type == 2)
1238+
if (adj_blksize(lgre))
1239+
flag = '*';
1240+
11891241
if (!index) {
11901242
pr_info("UV: GAM Range Table...\n");
1191-
pr_info("UV: # %20s %14s %5s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN");
1243+
pr_info("UV: # %20s %14s %6s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN");
11921244
}
1193-
pr_info("UV: %2d: 0x%014lx-0x%014lx %5lu%c %3d %04x %02x %02x\n",
1245+
pr_info("UV: %2d: 0x%014lx-0x%014lx%c %5lu%c %3d %04x %02x %02x\n",
11941246
index++,
11951247
(unsigned long)lgre << UV_GAM_RANGE_SHFT,
11961248
(unsigned long)gre->limit << UV_GAM_RANGE_SHFT,
1197-
size, suffix[order],
1249+
flag, size, suffix[order],
11981250
gre->type, gre->nasid, gre->sockid, gre->pnode);
11991251

1252+
/* update to next range start */
12001253
lgre = gre->limit;
12011254
if (sock_min > gre->sockid)
12021255
sock_min = gre->sockid;
@@ -1427,6 +1480,7 @@ static void __init uv_system_init_hub(void)
14271480

14281481
build_socket_tables();
14291482
build_uv_gr_table();
1483+
set_block_size();
14301484
uv_init_hub_info(&hub_info);
14311485
uv_possible_blades = num_possible_nodes();
14321486
if (!_node_to_pnode)

arch/x86/kernel/cpu/cacheinfo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
671671
num_sharing_cache = ((eax >> 14) & 0xfff) + 1;
672672

673673
if (num_sharing_cache) {
674-
int bits = get_count_order(num_sharing_cache) - 1;
674+
int bits = get_count_order(num_sharing_cache);
675675

676676
per_cpu(cpu_llc_id, cpu) = c->apicid >> bits;
677677
}

arch/x86/kernel/cpu/common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/* cpu_feature_enabled() cannot be used this early */
2+
#define USE_EARLY_PGTABLE_L5
3+
14
#include <linux/bootmem.h>
25
#include <linux/linkage.h>
36
#include <linux/bitops.h>

arch/x86/kernel/cpu/microcode/intel.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,11 @@ static void save_microcode_patch(void *data, unsigned int size)
190190
p = memdup_patch(data, size);
191191
if (!p)
192192
pr_err("Error allocating buffer %p\n", data);
193-
else
193+
else {
194194
list_replace(&iter->plist, &p->plist);
195+
kfree(iter->data);
196+
kfree(iter);
197+
}
195198
}
196199
}
197200

arch/x86/kernel/head64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static unsigned int __initdata next_early_pgt;
4444
pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX);
4545

4646
#ifdef CONFIG_X86_5LEVEL
47-
unsigned int __pgtable_l5_enabled __initdata;
47+
unsigned int __pgtable_l5_enabled __ro_after_init;
4848
unsigned int pgdir_shift __ro_after_init = 39;
4949
EXPORT_SYMBOL(pgdir_shift);
5050
unsigned int ptrs_per_p4d __ro_after_init = 1;

arch/x86/kernel/traps.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -835,16 +835,18 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
835835
char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" :
836836
"simd exception";
837837

838-
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
839-
return;
840838
cond_local_irq_enable(regs);
841839

842840
if (!user_mode(regs)) {
843-
if (!fixup_exception(regs, trapnr)) {
844-
task->thread.error_code = error_code;
845-
task->thread.trap_nr = trapnr;
841+
if (fixup_exception(regs, trapnr))
842+
return;
843+
844+
task->thread.error_code = error_code;
845+
task->thread.trap_nr = trapnr;
846+
847+
if (notify_die(DIE_TRAP, str, regs, error_code,
848+
trapnr, SIGFPE) != NOTIFY_STOP)
846849
die(str, regs, error_code);
847-
}
848850
return;
849851
}
850852

arch/x86/mm/init_64.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,16 +1350,28 @@ int kern_addr_valid(unsigned long addr)
13501350
/* Amount of ram needed to start using large blocks */
13511351
#define MEM_SIZE_FOR_LARGE_BLOCK (64UL << 30)
13521352

1353+
/* Adjustable memory block size */
1354+
static unsigned long set_memory_block_size;
1355+
int __init set_memory_block_size_order(unsigned int order)
1356+
{
1357+
unsigned long size = 1UL << order;
1358+
1359+
if (size > MEM_SIZE_FOR_LARGE_BLOCK || size < MIN_MEMORY_BLOCK_SIZE)
1360+
return -EINVAL;
1361+
1362+
set_memory_block_size = size;
1363+
return 0;
1364+
}
1365+
13531366
static unsigned long probe_memory_block_size(void)
13541367
{
13551368
unsigned long boot_mem_end = max_pfn << PAGE_SHIFT;
13561369
unsigned long bz;
13571370

1358-
/* If this is UV system, always set 2G block size */
1359-
if (is_uv_system()) {
1360-
bz = MAX_BLOCK_SIZE;
1371+
/* If memory block size has been set, then use it */
1372+
bz = set_memory_block_size;
1373+
if (bz)
13611374
goto done;
1362-
}
13631375

13641376
/* Use regular block if RAM is smaller than MEM_SIZE_FOR_LARGE_BLOCK */
13651377
if (boot_mem_end < MEM_SIZE_FOR_LARGE_BLOCK) {

arch/x86/xen/smp_pv.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <xen/interface/vcpu.h>
3333
#include <xen/interface/xenpmu.h>
3434

35+
#include <asm/spec-ctrl.h>
3536
#include <asm/xen/interface.h>
3637
#include <asm/xen/hypercall.h>
3738

@@ -70,6 +71,8 @@ static void cpu_bringup(void)
7071
cpu_data(cpu).x86_max_cores = 1;
7172
set_cpu_sibling_map(cpu);
7273

74+
speculative_store_bypass_ht_init();
75+
7376
xen_setup_cpu_clockevents();
7477

7578
notify_cpu_starting(cpu);
@@ -250,6 +253,8 @@ static void __init xen_pv_smp_prepare_cpus(unsigned int max_cpus)
250253
}
251254
set_cpu_sibling_map(0);
252255

256+
speculative_store_bypass_ht_init();
257+
253258
xen_pmu_init(0);
254259

255260
if (xen_smp_intr_init(0) || xen_smp_intr_init_pv(0))

include/linux/memory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct memory_block {
3838

3939
int arch_get_memory_phys_device(unsigned long start_pfn);
4040
unsigned long memory_block_size_bytes(void);
41+
int set_memory_block_size_order(unsigned int order);
4142

4243
/* These states are exposed to userspace as text strings in sysfs */
4344
#define MEM_ONLINE (1<<0) /* exposed to userspace */

0 commit comments

Comments
 (0)