Skip to content

Commit f4e5b30

Browse files
committed
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 updates and fixes from Thomas Gleixner: - Fix the (late) fallout from the vector management rework causing hlist corruption and irq descriptor reference leaks caused by a missing sanity check. The straight forward fix triggered another long standing issue to surface. The pre rework code hid the issue due to being way slower, but now the chance that user space sees an EBUSY error return when updating irq affinities is way higher, though quite a bunch of userspace tools do not handle it properly despite the fact that EBUSY could be returned for at least 10 years. It turned out that the EBUSY return can be avoided completely by utilizing the existing delayed affinity update mechanism for irq remapped scenarios as well. That's a bit more error handling in the kernel, but avoids fruitless fingerpointing discussions with tool developers. - Decouple PHYSICAL_MASK from AMD SME as its going to be required for the upcoming Intel memory encryption support as well. - Handle legacy device ACPI detection properly for newer platforms - Fix the wrong argument ordering in the vector allocation tracepoint - Simplify the IDT setup code for the APIC=n case - Use the proper string helpers in the MTRR code - Remove a stale unused VDSO source file - Convert the microcode update lock to a raw spinlock as its used in atomic context. * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/intel_rdt: Enable CMT and MBM on new Skylake stepping x86/apic/vector: Print APIC control bits in debugfs genirq/affinity: Defer affinity setting if irq chip is busy x86/platform/uv: Use apic_ack_irq() x86/ioapic: Use apic_ack_irq() irq_remapping: Use apic_ack_irq() x86/apic: Provide apic_ack_irq() genirq/migration: Avoid out of line call if pending is not set genirq/generic_pending: Do not lose pending affinity update x86/apic/vector: Prevent hlist corruption and leaks x86/vector: Fix the args of vector_alloc tracepoint x86/idt: Simplify the idt_setup_apic_and_irq_gates() x86/platform/uv: Remove extra parentheses x86/mm: Decouple dynamic __PHYSICAL_MASK from AMD SME x86: Mark native_set_p4d() as __always_inline x86/microcode: Make the late update update_lock a raw lock for RT x86/mtrr: Convert to use strncpy_from_user() helper x86/mtrr: Convert to use match_string() helper x86/vdso: Remove unused file x86/i8237: Register device based on FADT legacy boot flag
2 parents a2211de + 1d9f3e2 commit f4e5b30

File tree

26 files changed

+176
-80
lines changed

26 files changed

+176
-80
lines changed

arch/x86/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ config ARCH_SUPPORTS_UPROBES
334334
config FIX_EARLYCON_MEM
335335
def_bool y
336336

337+
config DYNAMIC_PHYSICAL_MASK
338+
bool
339+
337340
config PGTABLE_LEVELS
338341
int
339342
default 5 if X86_5LEVEL
@@ -1486,6 +1489,7 @@ config ARCH_HAS_MEM_ENCRYPT
14861489
config AMD_MEM_ENCRYPT
14871490
bool "AMD Secure Memory Encryption (SME) support"
14881491
depends on X86_64 && CPU_SUP_AMD
1492+
select DYNAMIC_PHYSICAL_MASK
14891493
---help---
14901494
Say yes to enable support for the encryption of system memory.
14911495
This requires an AMD processor that supports Secure Memory

arch/x86/boot/compressed/kaslr_64.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ static struct alloc_pgt_data pgt_data;
6969
/* The top level page table entry pointer. */
7070
static unsigned long top_level_pgt;
7171

72+
phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1;
73+
7274
/*
7375
* Mapping information structure passed to kernel_ident_mapping_init().
7476
* Due to relocation, pointers must be assigned at run time not build time.
@@ -81,6 +83,9 @@ void initialize_identity_maps(void)
8183
/* If running as an SEV guest, the encryption mask is required. */
8284
set_sev_encryption_mask();
8385

86+
/* Exclude the encryption mask from __PHYSICAL_MASK */
87+
physical_mask &= ~sme_me_mask;
88+
8489
/* Init mapping_info with run-time function/buffer pointers. */
8590
mapping_info.alloc_pgt_page = alloc_pgt_page;
8691
mapping_info.context = &pgt_data;

arch/x86/include/asm/apic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,8 @@ static inline void apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v)) {}
436436

437437
#endif /* CONFIG_X86_LOCAL_APIC */
438438

439+
extern void apic_ack_irq(struct irq_data *data);
440+
439441
static inline void ack_APIC_irq(void)
440442
{
441443
/*

arch/x86/include/asm/page_types.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
1818
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
1919

20-
#define __PHYSICAL_MASK ((phys_addr_t)(__sme_clr((1ULL << __PHYSICAL_MASK_SHIFT) - 1)))
2120
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
2221

2322
/* Cast *PAGE_MASK to a signed type so that it is sign-extended if
@@ -55,6 +54,13 @@
5554

5655
#ifndef __ASSEMBLY__
5756

57+
#ifdef CONFIG_DYNAMIC_PHYSICAL_MASK
58+
extern phys_addr_t physical_mask;
59+
#define __PHYSICAL_MASK physical_mask
60+
#else
61+
#define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1))
62+
#endif
63+
5864
extern int devmem_is_allowed(unsigned long pagenr);
5965

6066
extern unsigned long max_low_pfn_mapped;

arch/x86/include/asm/pgtable_64.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ static inline pgd_t pti_set_user_pgd(pgd_t *pgdp, pgd_t pgd)
216216
}
217217
#endif
218218

219-
static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d)
219+
static __always_inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d)
220220
{
221221
pgd_t pgd;
222222

@@ -230,7 +230,7 @@ static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d)
230230
*p4dp = native_make_p4d(native_pgd_val(pgd));
231231
}
232232

233-
static inline void native_p4d_clear(p4d_t *p4d)
233+
static __always_inline void native_p4d_clear(p4d_t *p4d)
234234
{
235235
native_set_p4d(p4d, native_make_p4d(0));
236236
}

arch/x86/include/asm/trace/irq_vectors.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ TRACE_EVENT(vector_alloc,
236236
TP_PROTO(unsigned int irq, unsigned int vector, bool reserved,
237237
int ret),
238238

239-
TP_ARGS(irq, vector, ret, reserved),
239+
TP_ARGS(irq, vector, reserved, ret),
240240

241241
TP_STRUCT__entry(
242242
__field( unsigned int, irq )

arch/x86/include/asm/x86_init.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,5 +301,6 @@ extern struct x86_apic_ops x86_apic_ops;
301301
extern void x86_early_init_platform_quirks(void);
302302
extern void x86_init_noop(void);
303303
extern void x86_init_uint_noop(unsigned int unused);
304+
extern bool x86_pnpbios_disabled(void);
304305

305306
#endif

arch/x86/kernel/apic/io_apic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1851,7 +1851,7 @@ static void ioapic_ir_ack_level(struct irq_data *irq_data)
18511851
* intr-remapping table entry. Hence for the io-apic
18521852
* EOI we use the pin number.
18531853
*/
1854-
ack_APIC_irq();
1854+
apic_ack_irq(irq_data);
18551855
eoi_ioapic_pin(data->entry.vector, data);
18561856
}
18571857

arch/x86/kernel/apic/vector.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,15 @@ static int allocate_vector(struct irq_data *irqd, const struct cpumask *dest)
235235
if (vector && cpu_online(cpu) && cpumask_test_cpu(cpu, dest))
236236
return 0;
237237

238+
/*
239+
* Careful here. @apicd might either have move_in_progress set or
240+
* be enqueued for cleanup. Assigning a new vector would either
241+
* leave a stale vector on some CPU around or in case of a pending
242+
* cleanup corrupt the hlist.
243+
*/
244+
if (apicd->move_in_progress || !hlist_unhashed(&apicd->clist))
245+
return -EBUSY;
246+
238247
vector = irq_matrix_alloc(vector_matrix, dest, resvd, &cpu);
239248
if (vector > 0)
240249
apic_update_vector(irqd, vector, cpu);
@@ -579,8 +588,7 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
579588
static void x86_vector_debug_show(struct seq_file *m, struct irq_domain *d,
580589
struct irq_data *irqd, int ind)
581590
{
582-
unsigned int cpu, vector, prev_cpu, prev_vector;
583-
struct apic_chip_data *apicd;
591+
struct apic_chip_data apicd;
584592
unsigned long flags;
585593
int irq;
586594

@@ -596,24 +604,26 @@ static void x86_vector_debug_show(struct seq_file *m, struct irq_domain *d,
596604
return;
597605
}
598606

599-
apicd = irqd->chip_data;
600-
if (!apicd) {
607+
if (!irqd->chip_data) {
601608
seq_printf(m, "%*sVector: Not assigned\n", ind, "");
602609
return;
603610
}
604611

605612
raw_spin_lock_irqsave(&vector_lock, flags);
606-
cpu = apicd->cpu;
607-
vector = apicd->vector;
608-
prev_cpu = apicd->prev_cpu;
609-
prev_vector = apicd->prev_vector;
613+
memcpy(&apicd, irqd->chip_data, sizeof(apicd));
610614
raw_spin_unlock_irqrestore(&vector_lock, flags);
611-
seq_printf(m, "%*sVector: %5u\n", ind, "", vector);
612-
seq_printf(m, "%*sTarget: %5u\n", ind, "", cpu);
613-
if (prev_vector) {
614-
seq_printf(m, "%*sPrevious vector: %5u\n", ind, "", prev_vector);
615-
seq_printf(m, "%*sPrevious target: %5u\n", ind, "", prev_cpu);
615+
616+
seq_printf(m, "%*sVector: %5u\n", ind, "", apicd.vector);
617+
seq_printf(m, "%*sTarget: %5u\n", ind, "", apicd.cpu);
618+
if (apicd.prev_vector) {
619+
seq_printf(m, "%*sPrevious vector: %5u\n", ind, "", apicd.prev_vector);
620+
seq_printf(m, "%*sPrevious target: %5u\n", ind, "", apicd.prev_cpu);
616621
}
622+
seq_printf(m, "%*smove_in_progress: %u\n", ind, "", apicd.move_in_progress ? 1 : 0);
623+
seq_printf(m, "%*sis_managed: %u\n", ind, "", apicd.is_managed ? 1 : 0);
624+
seq_printf(m, "%*scan_reserve: %u\n", ind, "", apicd.can_reserve ? 1 : 0);
625+
seq_printf(m, "%*shas_reserved: %u\n", ind, "", apicd.has_reserved ? 1 : 0);
626+
seq_printf(m, "%*scleanup_pending: %u\n", ind, "", !hlist_unhashed(&apicd.clist));
617627
}
618628
#endif
619629

@@ -800,13 +810,18 @@ static int apic_retrigger_irq(struct irq_data *irqd)
800810
return 1;
801811
}
802812

803-
void apic_ack_edge(struct irq_data *irqd)
813+
void apic_ack_irq(struct irq_data *irqd)
804814
{
805-
irq_complete_move(irqd_cfg(irqd));
806815
irq_move_irq(irqd);
807816
ack_APIC_irq();
808817
}
809818

819+
void apic_ack_edge(struct irq_data *irqd)
820+
{
821+
irq_complete_move(irqd_cfg(irqd));
822+
apic_ack_irq(irqd);
823+
}
824+
810825
static struct irq_chip lapic_controller = {
811826
.name = "APIC",
812827
.irq_ack = apic_ack_edge,

arch/x86/kernel/cpu/intel_rdt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,8 @@ static __init void rdt_quirks(void)
845845
case INTEL_FAM6_SKYLAKE_X:
846846
if (boot_cpu_data.x86_stepping <= 4)
847847
set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat");
848+
else
849+
set_rdt_options("!l3cat");
848850
}
849851
}
850852

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static DEFINE_MUTEX(microcode_mutex);
7070
/*
7171
* Serialize late loading so that CPUs get updated one-by-one.
7272
*/
73-
static DEFINE_SPINLOCK(update_lock);
73+
static DEFINE_RAW_SPINLOCK(update_lock);
7474

7575
struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
7676

@@ -560,9 +560,9 @@ static int __reload_late(void *info)
560560
if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC))
561561
return -1;
562562

563-
spin_lock(&update_lock);
563+
raw_spin_lock(&update_lock);
564564
apply_microcode_local(&err);
565-
spin_unlock(&update_lock);
565+
raw_spin_unlock(&update_lock);
566566

567567
/* siblings return UCODE_OK because their engine got updated already */
568568
if (err > UCODE_NFOUND) {

arch/x86/kernel/cpu/mtrr/if.c

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,9 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
106106

107107
memset(line, 0, LINE_SIZE);
108108

109-
length = len;
110-
length--;
111-
112-
if (length > LINE_SIZE - 1)
113-
length = LINE_SIZE - 1;
114-
109+
length = strncpy_from_user(line, buf, LINE_SIZE - 1);
115110
if (length < 0)
116-
return -EINVAL;
117-
118-
if (copy_from_user(line, buf, length))
119-
return -EFAULT;
111+
return length;
120112

121113
linelen = strlen(line);
122114
ptr = line + linelen - 1;
@@ -149,17 +141,16 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
149141
return -EINVAL;
150142
ptr = skip_spaces(ptr + 5);
151143

152-
for (i = 0; i < MTRR_NUM_TYPES; ++i) {
153-
if (strcmp(ptr, mtrr_strings[i]))
154-
continue;
155-
base >>= PAGE_SHIFT;
156-
size >>= PAGE_SHIFT;
157-
err = mtrr_add_page((unsigned long)base, (unsigned long)size, i, true);
158-
if (err < 0)
159-
return err;
160-
return len;
161-
}
162-
return -EINVAL;
144+
i = match_string(mtrr_strings, MTRR_NUM_TYPES, ptr);
145+
if (i < 0)
146+
return i;
147+
148+
base >>= PAGE_SHIFT;
149+
size >>= PAGE_SHIFT;
150+
err = mtrr_add_page((unsigned long)base, (unsigned long)size, i, true);
151+
if (err < 0)
152+
return err;
153+
return len;
163154
}
164155

165156
static long

arch/x86/kernel/i8237.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
* your option) any later version.
1010
*/
1111

12+
#include <linux/dmi.h>
1213
#include <linux/init.h>
1314
#include <linux/syscore_ops.h>
1415

1516
#include <asm/dma.h>
17+
#include <asm/x86_init.h>
1618

1719
/*
1820
* This module just handles suspend/resume issues with the
@@ -49,6 +51,29 @@ static struct syscore_ops i8237_syscore_ops = {
4951

5052
static int __init i8237A_init_ops(void)
5153
{
54+
/*
55+
* From SKL PCH onwards, the legacy DMA device is removed in which the
56+
* I/O ports (81h-83h, 87h, 89h-8Bh, 8Fh) related to it are removed
57+
* as well. All removed ports must return 0xff for a inb() request.
58+
*
59+
* Note: DMA_PAGE_2 (port 0x81) should not be checked for detecting
60+
* the presence of DMA device since it may be used by BIOS to decode
61+
* LPC traffic for POST codes. Original LPC only decodes one byte of
62+
* port 0x80 but some BIOS may choose to enhance PCH LPC port 0x8x
63+
* decoding.
64+
*/
65+
if (dma_inb(DMA_PAGE_0) == 0xFF)
66+
return -ENODEV;
67+
68+
/*
69+
* It is not required to load this driver as newer SoC may not
70+
* support 8237 DMA or bus mastering from LPC. Platform firmware
71+
* must announce the support for such legacy devices via
72+
* ACPI_FADT_LEGACY_DEVICES field in FADT table.
73+
*/
74+
if (x86_pnpbios_disabled() && dmi_get_bios_year() >= 2017)
75+
return -ENODEV;
76+
5277
register_syscore_ops(&i8237_syscore_ops);
5378
return 0;
5479
}

arch/x86/kernel/idt.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,12 @@ void __init idt_setup_apic_and_irq_gates(void)
317317
set_intr_gate(i, entry);
318318
}
319319

320-
for_each_clear_bit_from(i, system_vectors, NR_VECTORS) {
321320
#ifdef CONFIG_X86_LOCAL_APIC
321+
for_each_clear_bit_from(i, system_vectors, NR_VECTORS) {
322322
set_bit(i, system_vectors);
323323
set_intr_gate(i, spurious_interrupt);
324-
#else
325-
entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR);
326-
set_intr_gate(i, entry);
327-
#endif
328324
}
325+
#endif
329326
}
330327

331328
/**

arch/x86/kernel/platform-quirks.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ void __init x86_early_init_platform_quirks(void)
3333
x86_platform.set_legacy_features();
3434
}
3535

36+
bool __init x86_pnpbios_disabled(void)
37+
{
38+
return x86_platform.legacy.devices.pnpbios == 0;
39+
}
40+
3641
#if defined(CONFIG_PNPBIOS)
3742
bool __init arch_pnpbios_disabled(void)
3843
{
39-
return x86_platform.legacy.devices.pnpbios == 0;
44+
return x86_pnpbios_disabled();
4045
}
4146
#endif

arch/x86/mm/mem_encrypt_identity.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ void __init sme_enable(struct boot_params *bp)
527527
/* SEV state cannot be controlled by a command line option */
528528
sme_me_mask = me_mask;
529529
sev_enabled = true;
530+
physical_mask &= ~sme_me_mask;
530531
return;
531532
}
532533

@@ -561,4 +562,6 @@ void __init sme_enable(struct boot_params *bp)
561562
sme_me_mask = 0;
562563
else
563564
sme_me_mask = active_by_default ? me_mask : 0;
565+
566+
physical_mask &= ~sme_me_mask;
564567
}

arch/x86/mm/pgtable.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
#include <asm/fixmap.h>
99
#include <asm/mtrr.h>
1010

11+
#ifdef CONFIG_DYNAMIC_PHYSICAL_MASK
12+
phys_addr_t physical_mask __ro_after_init = (1ULL << __PHYSICAL_MASK_SHIFT) - 1;
13+
EXPORT_SYMBOL(physical_mask);
14+
#endif
15+
1116
#define PGALLOC_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
1217

1318
#ifdef CONFIG_HIGHPTE

arch/x86/platform/uv/tlb_uv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ static int uv2_3_wait_completion(struct bau_desc *bau_desc,
615615

616616
/* spin on the status MMR, waiting for it to go idle */
617617
while (descriptor_stat != UV2H_DESC_IDLE) {
618-
if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT)) {
618+
if (descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) {
619619
/*
620620
* A h/w bug on the destination side may
621621
* have prevented the message being marked

0 commit comments

Comments
 (0)