aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-26 17:11:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-26 17:11:54 -0500
commit02fc87b117a9b9ec325089d098fce86ed11966bd (patch)
tree537176c1c32b25c781bf8974af854a4ee4dbc77a
parent6830c8db58c2616d8ba2bf45e7d98dca5f69b07f (diff)
parent12a78d43de767eaf8fb272facb7a7b6f2dc6a9df (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull misc x86 fixes from Ingo Molnar: - topology enumeration fixes - KASAN fix - two entry fixes (not yet the big series related to KASLR) - remove obsolete code - instruction decoder fix - better /dev/mem sanity checks, hopefully working better this time - pkeys fixes - two ACPI fixes - 5-level paging related fixes - UMIP fixes that should make application visible faults more debuggable - boot fix for weird virtualization environment * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) x86/decoder: Add new TEST instruction pattern x86/PCI: Remove unused HyperTransport interrupt support x86/umip: Fix insn_get_code_seg_params()'s return value x86/boot/KASLR: Remove unused variable x86/entry/64: Add missing irqflags tracing to native_load_gs_index() x86/mm/kasan: Don't use vmemmap_populate() to initialize shadow x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing x86/pkeys/selftests: Fix protection keys write() warning x86/pkeys/selftests: Rename 'si_pkey' to 'siginfo_pkey' x86/mpx/selftests: Fix up weird arrays x86/pkeys: Update documentation about availability x86/umip: Print a warning into the syslog if UMIP-protected instructions are used x86/smpboot: Fix __max_logical_packages estimate x86/topology: Avoid wasting 128k for package id array perf/x86/intel/uncore: Cache logical pkg id in uncore driver x86/acpi: Reduce code duplication in mp_override_legacy_irq() x86/acpi: Handle SCI interrupts above legacy space gracefully x86/boot: Fix boot failure when SMP MP-table is based at 0 x86/mm: Limit mmap() of /dev/mem to valid physical addresses x86/selftests: Add test for mapping placement for 5-level paging ...
-rw-r--r--Documentation/x86/protection-keys.txt9
-rw-r--r--arch/x86/Kconfig12
-rw-r--r--arch/x86/boot/compressed/kaslr.c5
-rw-r--r--arch/x86/entry/entry_64.S14
-rw-r--r--arch/x86/events/intel/uncore.c4
-rw-r--r--arch/x86/events/intel/uncore.h2
-rw-r--r--arch/x86/events/intel/uncore_snbep.c2
-rw-r--r--arch/x86/include/asm/elf.h1
-rw-r--r--arch/x86/include/asm/hw_irq.h8
-rw-r--r--arch/x86/include/asm/hypertransport.h46
-rw-r--r--arch/x86/include/asm/insn-eval.h2
-rw-r--r--arch/x86/include/asm/io.h4
-rw-r--r--arch/x86/include/asm/irqdomain.h6
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/kernel/acpi/boot.c61
-rw-r--r--arch/x86/kernel/apic/Makefile1
-rw-r--r--arch/x86/kernel/apic/htirq.c198
-rw-r--r--arch/x86/kernel/apic/vector.c5
-rw-r--r--arch/x86/kernel/cpu/common.c2
-rw-r--r--arch/x86/kernel/mpparse.c6
-rw-r--r--arch/x86/kernel/smpboot.c128
-rw-r--r--arch/x86/kernel/sys_x86_64.c10
-rw-r--r--arch/x86/kernel/umip.c88
-rw-r--r--arch/x86/lib/insn-eval.c4
-rw-r--r--arch/x86/lib/x86-opcode-map.txt2
-rw-r--r--arch/x86/mm/hugetlbpage.c11
-rw-r--r--arch/x86/mm/mmap.c62
-rw-r--r--drivers/char/mem.c4
-rw-r--r--drivers/pci/Kconfig9
-rw-r--r--drivers/pci/Makefile3
-rw-r--r--drivers/pci/htirq.c135
-rw-r--r--include/linux/htirq.h39
-rw-r--r--include/linux/pci.h6
-rw-r--r--tools/testing/selftests/x86/5lvl.c177
-rw-r--r--tools/testing/selftests/x86/Makefile2
-rw-r--r--tools/testing/selftests/x86/mpx-hw.h4
-rw-r--r--tools/testing/selftests/x86/pkey-helpers.h5
-rw-r--r--tools/testing/selftests/x86/protection_keys.c10
38 files changed, 472 insertions, 616 deletions
diff --git a/Documentation/x86/protection-keys.txt b/Documentation/x86/protection-keys.txt
index fa46dcb347bc..ecb0d2dadfb7 100644
--- a/Documentation/x86/protection-keys.txt
+++ b/Documentation/x86/protection-keys.txt
@@ -1,5 +1,10 @@
1Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature 1Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature
2which will be found on future Intel CPUs. 2which is found on Intel's Skylake "Scalable Processor" Server CPUs.
3It will be avalable in future non-server parts.
4
5For anyone wishing to test or use this feature, it is available in
6Amazon's EC2 C5 instances and is known to work there using an Ubuntu
717.04 image.
3 8
4Memory Protection Keys provides a mechanism for enforcing page-based 9Memory Protection Keys provides a mechanism for enforcing page-based
5protections, but without requiring modification of the page tables 10protections, but without requiring modification of the page tables
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index df3276d6bfe3..8eed3f94bfc7 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1804,14 +1804,20 @@ config X86_SMAP
1804 If unsure, say Y. 1804 If unsure, say Y.
1805 1805
1806config X86_INTEL_UMIP 1806config X86_INTEL_UMIP
1807 def_bool n 1807 def_bool y
1808 depends on CPU_SUP_INTEL 1808 depends on CPU_SUP_INTEL
1809 prompt "Intel User Mode Instruction Prevention" if EXPERT 1809 prompt "Intel User Mode Instruction Prevention" if EXPERT
1810 ---help--- 1810 ---help---
1811 The User Mode Instruction Prevention (UMIP) is a security 1811 The User Mode Instruction Prevention (UMIP) is a security
1812 feature in newer Intel processors. If enabled, a general 1812 feature in newer Intel processors. If enabled, a general
1813 protection fault is issued if the instructions SGDT, SLDT, 1813 protection fault is issued if the SGDT, SLDT, SIDT, SMSW
1814 SIDT, SMSW and STR are executed in user mode. 1814 or STR instructions are executed in user mode. These instructions
1815 unnecessarily expose information about the hardware state.
1816
1817 The vast majority of applications do not use these instructions.
1818 For the very few that do, software emulation is provided in
1819 specific cases in protected and virtual-8086 modes. Emulated
1820 results are dummy.
1815 1821
1816config X86_INTEL_MPX 1822config X86_INTEL_MPX
1817 prompt "Intel MPX (Memory Protection Extensions)" 1823 prompt "Intel MPX (Memory Protection Extensions)"
diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index a63fbc25ce84..8199a6187251 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -171,7 +171,6 @@ parse_memmap(char *p, unsigned long long *start, unsigned long long *size)
171static void mem_avoid_memmap(char *str) 171static void mem_avoid_memmap(char *str)
172{ 172{
173 static int i; 173 static int i;
174 int rc;
175 174
176 if (i >= MAX_MEMMAP_REGIONS) 175 if (i >= MAX_MEMMAP_REGIONS)
177 return; 176 return;
@@ -219,7 +218,7 @@ static int handle_mem_memmap(void)
219 return 0; 218 return 0;
220 219
221 tmp_cmdline = malloc(len + 1); 220 tmp_cmdline = malloc(len + 1);
222 if (!tmp_cmdline ) 221 if (!tmp_cmdline)
223 error("Failed to allocate space for tmp_cmdline"); 222 error("Failed to allocate space for tmp_cmdline");
224 223
225 memcpy(tmp_cmdline, args, len); 224 memcpy(tmp_cmdline, args, len);
@@ -363,7 +362,7 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size,
363 cmd_line |= boot_params->hdr.cmd_line_ptr; 362 cmd_line |= boot_params->hdr.cmd_line_ptr;
364 /* Calculate size of cmd_line. */ 363 /* Calculate size of cmd_line. */
365 ptr = (char *)(unsigned long)cmd_line; 364 ptr = (char *)(unsigned long)cmd_line;
366 for (cmd_line_size = 0; ptr[cmd_line_size++]; ) 365 for (cmd_line_size = 0; ptr[cmd_line_size++];)
367 ; 366 ;
368 mem_avoid[MEM_AVOID_CMDLINE].start = cmd_line; 367 mem_avoid[MEM_AVOID_CMDLINE].start = cmd_line;
369 mem_avoid[MEM_AVOID_CMDLINE].size = cmd_line_size; 368 mem_avoid[MEM_AVOID_CMDLINE].size = cmd_line_size;
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index a2b30ec69497..f81d50d7ceac 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -51,15 +51,19 @@ ENTRY(native_usergs_sysret64)
51END(native_usergs_sysret64) 51END(native_usergs_sysret64)
52#endif /* CONFIG_PARAVIRT */ 52#endif /* CONFIG_PARAVIRT */
53 53
54.macro TRACE_IRQS_IRETQ 54.macro TRACE_IRQS_FLAGS flags:req
55#ifdef CONFIG_TRACE_IRQFLAGS 55#ifdef CONFIG_TRACE_IRQFLAGS
56 bt $9, EFLAGS(%rsp) /* interrupts off? */ 56 bt $9, \flags /* interrupts off? */
57 jnc 1f 57 jnc 1f
58 TRACE_IRQS_ON 58 TRACE_IRQS_ON
591: 591:
60#endif 60#endif
61.endm 61.endm
62 62
63.macro TRACE_IRQS_IRETQ
64 TRACE_IRQS_FLAGS EFLAGS(%rsp)
65.endm
66
63/* 67/*
64 * When dynamic function tracer is enabled it will add a breakpoint 68 * When dynamic function tracer is enabled it will add a breakpoint
65 * to all locations that it is about to modify, sync CPUs, update 69 * to all locations that it is about to modify, sync CPUs, update
@@ -148,8 +152,6 @@ ENTRY(entry_SYSCALL_64)
148 movq %rsp, PER_CPU_VAR(rsp_scratch) 152 movq %rsp, PER_CPU_VAR(rsp_scratch)
149 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp 153 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
150 154
151 TRACE_IRQS_OFF
152
153 /* Construct struct pt_regs on stack */ 155 /* Construct struct pt_regs on stack */
154 pushq $__USER_DS /* pt_regs->ss */ 156 pushq $__USER_DS /* pt_regs->ss */
155 pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */ 157 pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */
@@ -170,6 +172,8 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
170 sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */ 172 sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */
171 UNWIND_HINT_REGS extra=0 173 UNWIND_HINT_REGS extra=0
172 174
175 TRACE_IRQS_OFF
176
173 /* 177 /*
174 * If we need to do entry work or if we guess we'll need to do 178 * If we need to do entry work or if we guess we'll need to do
175 * exit work, go straight to the slow path. 179 * exit work, go straight to the slow path.
@@ -943,11 +947,13 @@ ENTRY(native_load_gs_index)
943 FRAME_BEGIN 947 FRAME_BEGIN
944 pushfq 948 pushfq
945 DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI) 949 DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI)
950 TRACE_IRQS_OFF
946 SWAPGS 951 SWAPGS
947.Lgs_change: 952.Lgs_change:
948 movl %edi, %gs 953 movl %edi, %gs
9492: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE 9542: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE
950 SWAPGS 955 SWAPGS
956 TRACE_IRQS_FLAGS (%rsp)
951 popfq 957 popfq
952 FRAME_END 958 FRAME_END
953 ret 959 ret
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index d45e06346f14..7874c980d569 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -975,10 +975,10 @@ static void uncore_pci_remove(struct pci_dev *pdev)
975 int i, phys_id, pkg; 975 int i, phys_id, pkg;
976 976
977 phys_id = uncore_pcibus_to_physid(pdev->bus); 977 phys_id = uncore_pcibus_to_physid(pdev->bus);
978 pkg = topology_phys_to_logical_pkg(phys_id);
979 978
980 box = pci_get_drvdata(pdev); 979 box = pci_get_drvdata(pdev);
981 if (!box) { 980 if (!box) {
981 pkg = topology_phys_to_logical_pkg(phys_id);
982 for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) { 982 for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
983 if (uncore_extra_pci_dev[pkg].dev[i] == pdev) { 983 if (uncore_extra_pci_dev[pkg].dev[i] == pdev) {
984 uncore_extra_pci_dev[pkg].dev[i] = NULL; 984 uncore_extra_pci_dev[pkg].dev[i] = NULL;
@@ -994,7 +994,7 @@ static void uncore_pci_remove(struct pci_dev *pdev)
994 return; 994 return;
995 995
996 pci_set_drvdata(pdev, NULL); 996 pci_set_drvdata(pdev, NULL);
997 pmu->boxes[pkg] = NULL; 997 pmu->boxes[box->pkgid] = NULL;
998 if (atomic_dec_return(&pmu->activeboxes) == 0) 998 if (atomic_dec_return(&pmu->activeboxes) == 0)
999 uncore_pmu_unregister(pmu); 999 uncore_pmu_unregister(pmu);
1000 uncore_box_exit(box); 1000 uncore_box_exit(box);
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index 4364191e7c6b..414dc7e7c950 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -100,7 +100,7 @@ struct intel_uncore_extra_reg {
100 100
101struct intel_uncore_box { 101struct intel_uncore_box {
102 int pci_phys_id; 102 int pci_phys_id;
103 int pkgid; 103 int pkgid; /* Logical package ID */
104 int n_active; /* number of active events */ 104 int n_active; /* number of active events */
105 int n_events; 105 int n_events;
106 int cpu; /* cpu to collect events */ 106 int cpu; /* cpu to collect events */
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index f4e4168455a8..6d8044ab1060 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -1057,7 +1057,7 @@ static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_eve
1057 1057
1058 if (reg1->idx != EXTRA_REG_NONE) { 1058 if (reg1->idx != EXTRA_REG_NONE) {
1059 int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER; 1059 int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER;
1060 int pkg = topology_phys_to_logical_pkg(box->pci_phys_id); 1060 int pkg = box->pkgid;
1061 struct pci_dev *filter_pdev = uncore_extra_pci_dev[pkg].dev[idx]; 1061 struct pci_dev *filter_pdev = uncore_extra_pci_dev[pkg].dev[idx];
1062 1062
1063 if (filter_pdev) { 1063 if (filter_pdev) {
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 3a091cea36c5..0d157d2a1e2a 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -309,6 +309,7 @@ static inline int mmap_is_ia32(void)
309extern unsigned long task_size_32bit(void); 309extern unsigned long task_size_32bit(void);
310extern unsigned long task_size_64bit(int full_addr_space); 310extern unsigned long task_size_64bit(int full_addr_space);
311extern unsigned long get_mmap_base(int is_legacy); 311extern unsigned long get_mmap_base(int is_legacy);
312extern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
312 313
313#ifdef CONFIG_X86_32 314#ifdef CONFIG_X86_32
314 315
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index b80e46733909..2851077b6051 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -99,14 +99,6 @@ struct irq_alloc_info {
99 void *dmar_data; 99 void *dmar_data;
100 }; 100 };
101#endif 101#endif
102#ifdef CONFIG_HT_IRQ
103 struct {
104 int ht_pos;
105 int ht_idx;
106 struct pci_dev *ht_dev;
107 void *ht_update;
108 };
109#endif
110#ifdef CONFIG_X86_UV 102#ifdef CONFIG_X86_UV
111 struct { 103 struct {
112 int uv_limit; 104 int uv_limit;
diff --git a/arch/x86/include/asm/hypertransport.h b/arch/x86/include/asm/hypertransport.h
deleted file mode 100644
index 5d55df352879..000000000000
--- a/arch/x86/include/asm/hypertransport.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_X86_HYPERTRANSPORT_H
3#define _ASM_X86_HYPERTRANSPORT_H
4
5/*
6 * Constants for x86 Hypertransport Interrupts.
7 */
8
9#define HT_IRQ_LOW_BASE 0xf8000000
10
11#define HT_IRQ_LOW_VECTOR_SHIFT 16
12#define HT_IRQ_LOW_VECTOR_MASK 0x00ff0000
13#define HT_IRQ_LOW_VECTOR(v) \
14 (((v) << HT_IRQ_LOW_VECTOR_SHIFT) & HT_IRQ_LOW_VECTOR_MASK)
15
16#define HT_IRQ_LOW_DEST_ID_SHIFT 8
17#define HT_IRQ_LOW_DEST_ID_MASK 0x0000ff00
18#define HT_IRQ_LOW_DEST_ID(v) \
19 (((v) << HT_IRQ_LOW_DEST_ID_SHIFT) & HT_IRQ_LOW_DEST_ID_MASK)
20
21#define HT_IRQ_LOW_DM_PHYSICAL 0x0000000
22#define HT_IRQ_LOW_DM_LOGICAL 0x0000040
23
24#define HT_IRQ_LOW_RQEOI_EDGE 0x0000000
25#define HT_IRQ_LOW_RQEOI_LEVEL 0x0000020
26
27
28#define HT_IRQ_LOW_MT_FIXED 0x0000000
29#define HT_IRQ_LOW_MT_ARBITRATED 0x0000004
30#define HT_IRQ_LOW_MT_SMI 0x0000008
31#define HT_IRQ_LOW_MT_NMI 0x000000c
32#define HT_IRQ_LOW_MT_INIT 0x0000010
33#define HT_IRQ_LOW_MT_STARTUP 0x0000014
34#define HT_IRQ_LOW_MT_EXTINT 0x0000018
35#define HT_IRQ_LOW_MT_LINT1 0x000008c
36#define HT_IRQ_LOW_MT_LINT0 0x0000098
37
38#define HT_IRQ_LOW_IRQ_MASKED 0x0000001
39
40
41#define HT_IRQ_HIGH_DEST_ID_SHIFT 0
42#define HT_IRQ_HIGH_DEST_ID_MASK 0x00ffffff
43#define HT_IRQ_HIGH_DEST_ID(v) \
44 ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
45
46#endif /* _ASM_X86_HYPERTRANSPORT_H */
diff --git a/arch/x86/include/asm/insn-eval.h b/arch/x86/include/asm/insn-eval.h
index e1d3b4ce8a92..2b6ccf2c49f1 100644
--- a/arch/x86/include/asm/insn-eval.h
+++ b/arch/x86/include/asm/insn-eval.h
@@ -18,6 +18,6 @@
18void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs); 18void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs);
19int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs); 19int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs);
20unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); 20unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx);
21char insn_get_code_seg_params(struct pt_regs *regs); 21int insn_get_code_seg_params(struct pt_regs *regs);
22 22
23#endif /* _ASM_X86_INSN_EVAL_H */ 23#endif /* _ASM_X86_INSN_EVAL_H */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 93ae8aee1780..95e948627fd0 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -111,6 +111,10 @@ build_mmio_write(__writeq, "q", unsigned long, "r", )
111 111
112#endif 112#endif
113 113
114#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
115extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
116extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
117
114/** 118/**
115 * virt_to_phys - map virtual addresses to physical 119 * virt_to_phys - map virtual addresses to physical
116 * @address: address to remap 120 * @address: address to remap
diff --git a/arch/x86/include/asm/irqdomain.h b/arch/x86/include/asm/irqdomain.h
index f695cc6b8e1f..139feef467f7 100644
--- a/arch/x86/include/asm/irqdomain.h
+++ b/arch/x86/include/asm/irqdomain.h
@@ -56,10 +56,4 @@ extern void arch_init_msi_domain(struct irq_domain *domain);
56static inline void arch_init_msi_domain(struct irq_domain *domain) { } 56static inline void arch_init_msi_domain(struct irq_domain *domain) { }
57#endif 57#endif
58 58
59#ifdef CONFIG_HT_IRQ
60extern void arch_init_htirq_domain(struct irq_domain *domain);
61#else
62static inline void arch_init_htirq_domain(struct irq_domain *domain) { }
63#endif
64
65#endif 59#endif
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2db7cf720b04..cc16fa882e3e 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -132,6 +132,7 @@ struct cpuinfo_x86 {
132 /* Index into per_cpu list: */ 132 /* Index into per_cpu list: */
133 u16 cpu_index; 133 u16 cpu_index;
134 u32 microcode; 134 u32 microcode;
135 unsigned initialized : 1;
135} __randomize_layout; 136} __randomize_layout;
136 137
137struct cpuid_regs { 138struct cpuid_regs {
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index ef9e02e614d0..f4c463df8b08 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -342,13 +342,12 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e
342#ifdef CONFIG_X86_IO_APIC 342#ifdef CONFIG_X86_IO_APIC
343#define MP_ISA_BUS 0 343#define MP_ISA_BUS 0
344 344
345static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
346 u8 trigger, u32 gsi);
347
345static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, 348static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
346 u32 gsi) 349 u32 gsi)
347{ 350{
348 int ioapic;
349 int pin;
350 struct mpc_intsrc mp_irq;
351
352 /* 351 /*
353 * Check bus_irq boundary. 352 * Check bus_irq boundary.
354 */ 353 */
@@ -358,14 +357,6 @@ static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
358 } 357 }
359 358
360 /* 359 /*
361 * Convert 'gsi' to 'ioapic.pin'.
362 */
363 ioapic = mp_find_ioapic(gsi);
364 if (ioapic < 0)
365 return;
366 pin = mp_find_ioapic_pin(ioapic, gsi);
367
368 /*
369 * TBD: This check is for faulty timer entries, where the override 360 * TBD: This check is for faulty timer entries, where the override
370 * erroneously sets the trigger to level, resulting in a HUGE 361 * erroneously sets the trigger to level, resulting in a HUGE
371 * increase of timer interrupts! 362 * increase of timer interrupts!
@@ -373,16 +364,8 @@ static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
373 if ((bus_irq == 0) && (trigger == 3)) 364 if ((bus_irq == 0) && (trigger == 3))
374 trigger = 1; 365 trigger = 1;
375 366
376 mp_irq.type = MP_INTSRC; 367 if (mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi) < 0)
377 mp_irq.irqtype = mp_INT; 368 return;
378 mp_irq.irqflag = (trigger << 2) | polarity;
379 mp_irq.srcbus = MP_ISA_BUS;
380 mp_irq.srcbusirq = bus_irq; /* IRQ */
381 mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */
382 mp_irq.dstirq = pin; /* INTIN# */
383
384 mp_save_irq(&mp_irq);
385
386 /* 369 /*
387 * Reset default identity mapping if gsi is also an legacy IRQ, 370 * Reset default identity mapping if gsi is also an legacy IRQ,
388 * otherwise there will be more than one entry with the same GSI 371 * otherwise there will be more than one entry with the same GSI
@@ -429,6 +412,34 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,
429 return 0; 412 return 0;
430} 413}
431 414
415static int __init mp_register_ioapic_irq(u8 bus_irq, u8 polarity,
416 u8 trigger, u32 gsi)
417{
418 struct mpc_intsrc mp_irq;
419 int ioapic, pin;
420
421 /* Convert 'gsi' to 'ioapic.pin'(INTIN#) */
422 ioapic = mp_find_ioapic(gsi);
423 if (ioapic < 0) {
424 pr_warn("Failed to find ioapic for gsi : %u\n", gsi);
425 return ioapic;
426 }
427
428 pin = mp_find_ioapic_pin(ioapic, gsi);
429
430 mp_irq.type = MP_INTSRC;
431 mp_irq.irqtype = mp_INT;
432 mp_irq.irqflag = (trigger << 2) | polarity;
433 mp_irq.srcbus = MP_ISA_BUS;
434 mp_irq.srcbusirq = bus_irq;
435 mp_irq.dstapic = mpc_ioapic_id(ioapic);
436 mp_irq.dstirq = pin;
437
438 mp_save_irq(&mp_irq);
439
440 return 0;
441}
442
432static int __init 443static int __init
433acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end) 444acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
434{ 445{
@@ -473,7 +484,11 @@ static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger,
473 if (acpi_sci_flags & ACPI_MADT_POLARITY_MASK) 484 if (acpi_sci_flags & ACPI_MADT_POLARITY_MASK)
474 polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK; 485 polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK;
475 486
476 mp_override_legacy_irq(bus_irq, polarity, trigger, gsi); 487 if (bus_irq < NR_IRQS_LEGACY)
488 mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
489 else
490 mp_register_ioapic_irq(bus_irq, polarity, trigger, gsi);
491
477 acpi_penalize_sci_irq(bus_irq, trigger, polarity); 492 acpi_penalize_sci_irq(bus_irq, trigger, polarity);
478 493
479 /* 494 /*
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile
index a9e08924927e..a6fcaf16cdbf 100644
--- a/arch/x86/kernel/apic/Makefile
+++ b/arch/x86/kernel/apic/Makefile
@@ -12,7 +12,6 @@ obj-y += hw_nmi.o
12 12
13obj-$(CONFIG_X86_IO_APIC) += io_apic.o 13obj-$(CONFIG_X86_IO_APIC) += io_apic.o
14obj-$(CONFIG_PCI_MSI) += msi.o 14obj-$(CONFIG_PCI_MSI) += msi.o
15obj-$(CONFIG_HT_IRQ) += htirq.o
16obj-$(CONFIG_SMP) += ipi.o 15obj-$(CONFIG_SMP) += ipi.o
17 16
18ifeq ($(CONFIG_X86_64),y) 17ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/apic/htirq.c b/arch/x86/kernel/apic/htirq.c
deleted file mode 100644
index b07075dce8b7..000000000000
--- a/arch/x86/kernel/apic/htirq.c
+++ /dev/null
@@ -1,198 +0,0 @@
1/*
2 * Support Hypertransport IRQ
3 *
4 * Copyright (C) 1997, 1998, 1999, 2000, 2009 Ingo Molnar, Hajnalka Szabo
5 * Moved from arch/x86/kernel/apic/io_apic.c.
6 * Jiang Liu <jiang.liu@linux.intel.com>
7 * Add support of hierarchical irqdomain
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/mm.h>
14#include <linux/interrupt.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <linux/pci.h>
18#include <linux/htirq.h>
19#include <asm/irqdomain.h>
20#include <asm/hw_irq.h>
21#include <asm/apic.h>
22#include <asm/hypertransport.h>
23
24static struct irq_domain *htirq_domain;
25
26/*
27 * Hypertransport interrupt support
28 */
29static int
30ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
31{
32 struct irq_data *parent = data->parent_data;
33 int ret;
34
35 ret = parent->chip->irq_set_affinity(parent, mask, force);
36 if (ret >= 0) {
37 struct ht_irq_msg msg;
38 struct irq_cfg *cfg = irqd_cfg(data);
39
40 fetch_ht_irq_msg(data->irq, &msg);
41 msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK |
42 HT_IRQ_LOW_DEST_ID_MASK);
43 msg.address_lo |= HT_IRQ_LOW_VECTOR(cfg->vector) |
44 HT_IRQ_LOW_DEST_ID(cfg->dest_apicid);
45 msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
46 msg.address_hi |= HT_IRQ_HIGH_DEST_ID(cfg->dest_apicid);
47 write_ht_irq_msg(data->irq, &msg);
48 }
49
50 return ret;
51}
52
53static struct irq_chip ht_irq_chip = {
54 .name = "PCI-HT",
55 .irq_mask = mask_ht_irq,
56 .irq_unmask = unmask_ht_irq,
57 .irq_ack = irq_chip_ack_parent,
58 .irq_set_affinity = ht_set_affinity,
59 .irq_retrigger = irq_chip_retrigger_hierarchy,
60 .flags = IRQCHIP_SKIP_SET_WAKE,
61};
62
63static int htirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
64 unsigned int nr_irqs, void *arg)
65{
66 struct ht_irq_cfg *ht_cfg;
67 struct irq_alloc_info *info = arg;
68 struct pci_dev *dev;
69 irq_hw_number_t hwirq;
70 int ret;
71
72 if (nr_irqs > 1 || !info)
73 return -EINVAL;
74
75 dev = info->ht_dev;
76 hwirq = (info->ht_idx & 0xFF) |
77 PCI_DEVID(dev->bus->number, dev->devfn) << 8 |
78 (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 24;
79 if (irq_find_mapping(domain, hwirq) > 0)
80 return -EEXIST;
81
82 ht_cfg = kmalloc(sizeof(*ht_cfg), GFP_KERNEL);
83 if (!ht_cfg)
84 return -ENOMEM;
85
86 ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info);
87 if (ret < 0) {
88 kfree(ht_cfg);
89 return ret;
90 }
91
92 /* Initialize msg to a value that will never match the first write. */
93 ht_cfg->msg.address_lo = 0xffffffff;
94 ht_cfg->msg.address_hi = 0xffffffff;
95 ht_cfg->dev = info->ht_dev;
96 ht_cfg->update = info->ht_update;
97 ht_cfg->pos = info->ht_pos;
98 ht_cfg->idx = 0x10 + (info->ht_idx * 2);
99 irq_domain_set_info(domain, virq, hwirq, &ht_irq_chip, ht_cfg,
100 handle_edge_irq, ht_cfg, "edge");
101
102 return 0;
103}
104
105static void htirq_domain_free(struct irq_domain *domain, unsigned int virq,
106 unsigned int nr_irqs)
107{
108 struct irq_data *irq_data = irq_domain_get_irq_data(domain, virq);
109
110 BUG_ON(nr_irqs != 1);
111 kfree(irq_data->chip_data);
112 irq_domain_free_irqs_top(domain, virq, nr_irqs);
113}
114
115static int htirq_domain_activate(struct irq_domain *domain,
116 struct irq_data *irq_data, bool early)
117{
118 struct ht_irq_msg msg;
119 struct irq_cfg *cfg = irqd_cfg(irq_data);
120
121 msg.address_hi = HT_IRQ_HIGH_DEST_ID(cfg->dest_apicid);
122 msg.address_lo =
123 HT_IRQ_LOW_BASE |
124 HT_IRQ_LOW_DEST_ID(cfg->dest_apicid) |
125 HT_IRQ_LOW_VECTOR(cfg->vector) |
126 ((apic->irq_dest_mode == 0) ?
127 HT_IRQ_LOW_DM_PHYSICAL :
128 HT_IRQ_LOW_DM_LOGICAL) |
129 HT_IRQ_LOW_RQEOI_EDGE |
130 ((apic->irq_delivery_mode != dest_LowestPrio) ?
131 HT_IRQ_LOW_MT_FIXED :
132 HT_IRQ_LOW_MT_ARBITRATED) |
133 HT_IRQ_LOW_IRQ_MASKED;
134 write_ht_irq_msg(irq_data->irq, &msg);
135 return 0;
136}
137
138static void htirq_domain_deactivate(struct irq_domain *domain,
139 struct irq_data *irq_data)
140{
141 struct ht_irq_msg msg;
142
143 memset(&msg, 0, sizeof(msg));
144 write_ht_irq_msg(irq_data->irq, &msg);
145}
146
147static const struct irq_domain_ops htirq_domain_ops = {
148 .alloc = htirq_domain_alloc,
149 .free = htirq_domain_free,
150 .activate = htirq_domain_activate,
151 .deactivate = htirq_domain_deactivate,
152};
153
154void __init arch_init_htirq_domain(struct irq_domain *parent)
155{
156 struct fwnode_handle *fn;
157
158 if (disable_apic)
159 return;
160
161 fn = irq_domain_alloc_named_fwnode("PCI-HT");
162 if (!fn)
163 goto warn;
164
165 htirq_domain = irq_domain_create_tree(fn, &htirq_domain_ops, NULL);
166 irq_domain_free_fwnode(fn);
167 if (!htirq_domain)
168 goto warn;
169
170 htirq_domain->parent = parent;
171 return;
172
173warn:
174 pr_warn("Failed to initialize irqdomain for HTIRQ.\n");
175}
176
177int arch_setup_ht_irq(int idx, int pos, struct pci_dev *dev,
178 ht_irq_update_t *update)
179{
180 struct irq_alloc_info info;
181
182 if (!htirq_domain)
183 return -ENOSYS;
184
185 init_irq_alloc_info(&info, NULL);
186 info.ht_idx = idx;
187 info.ht_pos = pos;
188 info.ht_dev = dev;
189 info.ht_update = update;
190
191 return irq_domain_alloc_irqs(htirq_domain, 1, dev_to_node(&dev->dev),
192 &info);
193}
194
195void arch_teardown_ht_irq(unsigned int irq)
196{
197 irq_domain_free_irqs(irq, 1);
198}
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 05c85e693a5d..6a823a25eaff 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Local APIC related interfaces to support IOAPIC, MSI, HT_IRQ etc. 2 * Local APIC related interfaces to support IOAPIC, MSI, etc.
3 * 3 *
4 * Copyright (C) 1997, 1998, 1999, 2000, 2009 Ingo Molnar, Hajnalka Szabo 4 * Copyright (C) 1997, 1998, 1999, 2000, 2009 Ingo Molnar, Hajnalka Szabo
5 * Moved from arch/x86/kernel/apic/io_apic.c. 5 * Moved from arch/x86/kernel/apic/io_apic.c.
@@ -601,7 +601,7 @@ int __init arch_probe_nr_irqs(void)
601 nr_irqs = NR_VECTORS * nr_cpu_ids; 601 nr_irqs = NR_VECTORS * nr_cpu_ids;
602 602
603 nr = (gsi_top + nr_legacy_irqs()) + 8 * nr_cpu_ids; 603 nr = (gsi_top + nr_legacy_irqs()) + 8 * nr_cpu_ids;
604#if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ) 604#if defined(CONFIG_PCI_MSI)
605 /* 605 /*
606 * for MSI and HT dyn irq 606 * for MSI and HT dyn irq
607 */ 607 */
@@ -663,7 +663,6 @@ int __init arch_early_irq_init(void)
663 irq_set_default_host(x86_vector_domain); 663 irq_set_default_host(x86_vector_domain);
664 664
665 arch_init_msi_domain(x86_vector_domain); 665 arch_init_msi_domain(x86_vector_domain);
666 arch_init_htirq_domain(x86_vector_domain);
667 666
668 BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL)); 667 BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL));
669 668
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 13ae9e5eec2f..fa998ca8aa5a 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -341,6 +341,8 @@ static __always_inline void setup_umip(struct cpuinfo_x86 *c)
341 341
342 cr4_set_bits(X86_CR4_UMIP); 342 cr4_set_bits(X86_CR4_UMIP);
343 343
344 pr_info("x86/cpu: Activated the Intel User Mode Instruction Prevention (UMIP) CPU feature\n");
345
344 return; 346 return;
345 347
346out: 348out:
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 410c5dadcee3..3a4b12809ab5 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -431,6 +431,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
431} 431}
432 432
433static unsigned long mpf_base; 433static unsigned long mpf_base;
434static bool mpf_found;
434 435
435static unsigned long __init get_mpc_size(unsigned long physptr) 436static unsigned long __init get_mpc_size(unsigned long physptr)
436{ 437{
@@ -504,7 +505,7 @@ void __init default_get_smp_config(unsigned int early)
504 if (!smp_found_config) 505 if (!smp_found_config)
505 return; 506 return;
506 507
507 if (!mpf_base) 508 if (!mpf_found)
508 return; 509 return;
509 510
510 if (acpi_lapic && early) 511 if (acpi_lapic && early)
@@ -593,6 +594,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
593 smp_found_config = 1; 594 smp_found_config = 1;
594#endif 595#endif
595 mpf_base = base; 596 mpf_base = base;
597 mpf_found = true;
596 598
597 pr_info("found SMP MP-table at [mem %#010lx-%#010lx] mapped at [%p]\n", 599 pr_info("found SMP MP-table at [mem %#010lx-%#010lx] mapped at [%p]\n",
598 base, base + sizeof(*mpf) - 1, mpf); 600 base, base + sizeof(*mpf) - 1, mpf);
@@ -858,7 +860,7 @@ static int __init update_mp_table(void)
858 if (!enable_update_mptable) 860 if (!enable_update_mptable)
859 return 0; 861 return 0;
860 862
861 if (!mpf_base) 863 if (!mpf_found)
862 return 0; 864 return 0;
863 865
864 mpf = early_memremap(mpf_base, sizeof(*mpf)); 866 mpf = early_memremap(mpf_base, sizeof(*mpf));
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 5f59e6bee123..3d01df7d7cf6 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -101,9 +101,6 @@ DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
101EXPORT_PER_CPU_SYMBOL(cpu_info); 101EXPORT_PER_CPU_SYMBOL(cpu_info);
102 102
103/* Logical package management. We might want to allocate that dynamically */ 103/* Logical package management. We might want to allocate that dynamically */
104static int *physical_to_logical_pkg __read_mostly;
105static unsigned long *physical_package_map __read_mostly;;
106static unsigned int max_physical_pkg_id __read_mostly;
107unsigned int __max_logical_packages __read_mostly; 104unsigned int __max_logical_packages __read_mostly;
108EXPORT_SYMBOL(__max_logical_packages); 105EXPORT_SYMBOL(__max_logical_packages);
109static unsigned int logical_packages __read_mostly; 106static unsigned int logical_packages __read_mostly;
@@ -281,108 +278,48 @@ static void notrace start_secondary(void *unused)
281} 278}
282 279
283/** 280/**
281 * topology_phys_to_logical_pkg - Map a physical package id to a logical
282 *
283 * Returns logical package id or -1 if not found
284 */
285int topology_phys_to_logical_pkg(unsigned int phys_pkg)
286{
287 int cpu;
288
289 for_each_possible_cpu(cpu) {
290 struct cpuinfo_x86 *c = &cpu_data(cpu);
291
292 if (c->initialized && c->phys_proc_id == phys_pkg)
293 return c->logical_proc_id;
294 }
295 return -1;
296}
297EXPORT_SYMBOL(topology_phys_to_logical_pkg);
298
299/**
284 * topology_update_package_map - Update the physical to logical package map 300 * topology_update_package_map - Update the physical to logical package map
285 * @pkg: The physical package id as retrieved via CPUID 301 * @pkg: The physical package id as retrieved via CPUID
286 * @cpu: The cpu for which this is updated 302 * @cpu: The cpu for which this is updated
287 */ 303 */
288int topology_update_package_map(unsigned int pkg, unsigned int cpu) 304int topology_update_package_map(unsigned int pkg, unsigned int cpu)
289{ 305{
290 unsigned int new; 306 int new;
291 307
292 /* Called from early boot ? */ 308 /* Already available somewhere? */
293 if (!physical_package_map) 309 new = topology_phys_to_logical_pkg(pkg);
294 return 0; 310 if (new >= 0)
295
296 if (pkg >= max_physical_pkg_id)
297 return -EINVAL;
298
299 /* Set the logical package id */
300 if (test_and_set_bit(pkg, physical_package_map))
301 goto found; 311 goto found;
302 312
303 if (logical_packages >= __max_logical_packages) {
304 pr_warn("Package %u of CPU %u exceeds BIOS package data %u.\n",
305 logical_packages, cpu, __max_logical_packages);
306 return -ENOSPC;
307 }
308
309 new = logical_packages++; 313 new = logical_packages++;
310 if (new != pkg) { 314 if (new != pkg) {
311 pr_info("CPU %u Converting physical %u to logical package %u\n", 315 pr_info("CPU %u Converting physical %u to logical package %u\n",
312 cpu, pkg, new); 316 cpu, pkg, new);
313 } 317 }
314 physical_to_logical_pkg[pkg] = new;
315
316found: 318found:
317 cpu_data(cpu).logical_proc_id = physical_to_logical_pkg[pkg]; 319 cpu_data(cpu).logical_proc_id = new;
318 return 0; 320 return 0;
319} 321}
320 322
321/**
322 * topology_phys_to_logical_pkg - Map a physical package id to a logical
323 *
324 * Returns logical package id or -1 if not found
325 */
326int topology_phys_to_logical_pkg(unsigned int phys_pkg)
327{
328 if (phys_pkg >= max_physical_pkg_id)
329 return -1;
330 return physical_to_logical_pkg[phys_pkg];
331}
332EXPORT_SYMBOL(topology_phys_to_logical_pkg);
333
334static void __init smp_init_package_map(struct cpuinfo_x86 *c, unsigned int cpu)
335{
336 unsigned int ncpus;
337 size_t size;
338
339 /*
340 * Today neither Intel nor AMD support heterogenous systems. That
341 * might change in the future....
342 *
343 * While ideally we'd want '* smp_num_siblings' in the below @ncpus
344 * computation, this won't actually work since some Intel BIOSes
345 * report inconsistent HT data when they disable HT.
346 *
347 * In particular, they reduce the APIC-IDs to only include the cores,
348 * but leave the CPUID topology to say there are (2) siblings.
349 * This means we don't know how many threads there will be until
350 * after the APIC enumeration.
351 *
352 * By not including this we'll sometimes over-estimate the number of
353 * logical packages by the amount of !present siblings, but this is
354 * still better than MAX_LOCAL_APIC.
355 *
356 * We use total_cpus not nr_cpu_ids because nr_cpu_ids can be limited
357 * on the command line leading to a similar issue as the HT disable
358 * problem because the hyperthreads are usually enumerated after the
359 * primary cores.
360 */
361 ncpus = boot_cpu_data.x86_max_cores;
362 if (!ncpus) {
363 pr_warn("x86_max_cores == zero !?!?");
364 ncpus = 1;
365 }
366
367 __max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus);
368 logical_packages = 0;
369
370 /*
371 * Possibly larger than what we need as the number of apic ids per
372 * package can be smaller than the actual used apic ids.
373 */
374 max_physical_pkg_id = DIV_ROUND_UP(MAX_LOCAL_APIC, ncpus);
375 size = max_physical_pkg_id * sizeof(unsigned int);
376 physical_to_logical_pkg = kmalloc(size, GFP_KERNEL);
377 memset(physical_to_logical_pkg, 0xff, size);
378 size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long);
379 physical_package_map = kzalloc(size, GFP_KERNEL);
380
381 pr_info("Max logical packages: %u\n", __max_logical_packages);
382
383 topology_update_package_map(c->phys_proc_id, cpu);
384}
385
386void __init smp_store_boot_cpu_info(void) 323void __init smp_store_boot_cpu_info(void)
387{ 324{
388 int id = 0; /* CPU 0 */ 325 int id = 0; /* CPU 0 */
@@ -390,7 +327,8 @@ void __init smp_store_boot_cpu_info(void)
390 327
391 *c = boot_cpu_data; 328 *c = boot_cpu_data;
392 c->cpu_index = id; 329 c->cpu_index = id;
393 smp_init_package_map(c, id); 330 topology_update_package_map(c->phys_proc_id, id);
331 c->initialized = true;
394} 332}
395 333
396/* 334/*
@@ -401,13 +339,16 @@ void smp_store_cpu_info(int id)
401{ 339{
402 struct cpuinfo_x86 *c = &cpu_data(id); 340 struct cpuinfo_x86 *c = &cpu_data(id);
403 341
404 *c = boot_cpu_data; 342 /* Copy boot_cpu_data only on the first bringup */
343 if (!c->initialized)
344 *c = boot_cpu_data;
405 c->cpu_index = id; 345 c->cpu_index = id;
406 /* 346 /*
407 * During boot time, CPU0 has this setup already. Save the info when 347 * During boot time, CPU0 has this setup already. Save the info when
408 * bringing up AP or offlined CPU0. 348 * bringing up AP or offlined CPU0.
409 */ 349 */
410 identify_secondary_cpu(c); 350 identify_secondary_cpu(c);
351 c->initialized = true;
411} 352}
412 353
413static bool 354static bool
@@ -1356,7 +1297,16 @@ void __init native_smp_prepare_boot_cpu(void)
1356 1297
1357void __init native_smp_cpus_done(unsigned int max_cpus) 1298void __init native_smp_cpus_done(unsigned int max_cpus)
1358{ 1299{
1300 int ncpus;
1301
1359 pr_debug("Boot done\n"); 1302 pr_debug("Boot done\n");
1303 /*
1304 * Today neither Intel nor AMD support heterogenous systems so
1305 * extrapolate the boot cpu's data to all packages.
1306 */
1307 ncpus = cpu_data(0).booted_cores * smp_num_siblings;
1308 __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus);
1309 pr_info("Max logical packages: %u\n", __max_logical_packages);
1360 1310
1361 if (x86_has_numa_in_package) 1311 if (x86_has_numa_in_package)
1362 set_sched_topology(x86_numa_in_package_topology); 1312 set_sched_topology(x86_numa_in_package_topology);
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index a63fe77b3217..676774b9bb8d 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -188,6 +188,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
188 if (len > TASK_SIZE) 188 if (len > TASK_SIZE)
189 return -ENOMEM; 189 return -ENOMEM;
190 190
191 /* No address checking. See comment at mmap_address_hint_valid() */
191 if (flags & MAP_FIXED) 192 if (flags & MAP_FIXED)
192 return addr; 193 return addr;
193 194
@@ -197,12 +198,15 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
197 198
198 /* requesting a specific address */ 199 /* requesting a specific address */
199 if (addr) { 200 if (addr) {
200 addr = PAGE_ALIGN(addr); 201 addr &= PAGE_MASK;
202 if (!mmap_address_hint_valid(addr, len))
203 goto get_unmapped_area;
204
201 vma = find_vma(mm, addr); 205 vma = find_vma(mm, addr);
202 if (TASK_SIZE - len >= addr && 206 if (!vma || addr + len <= vm_start_gap(vma))
203 (!vma || addr + len <= vm_start_gap(vma)))
204 return addr; 207 return addr;
205 } 208 }
209get_unmapped_area:
206 210
207 info.flags = VM_UNMAPPED_AREA_TOPDOWN; 211 info.flags = VM_UNMAPPED_AREA_TOPDOWN;
208 info.length = len; 212 info.length = len;
diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c
index 6ba82be68cff..f44ce0fb3583 100644
--- a/arch/x86/kernel/umip.c
+++ b/arch/x86/kernel/umip.c
@@ -78,7 +78,60 @@
78 78
79#define UMIP_INST_SGDT 0 /* 0F 01 /0 */ 79#define UMIP_INST_SGDT 0 /* 0F 01 /0 */
80#define UMIP_INST_SIDT 1 /* 0F 01 /1 */ 80#define UMIP_INST_SIDT 1 /* 0F 01 /1 */
81#define UMIP_INST_SMSW 3 /* 0F 01 /4 */ 81#define UMIP_INST_SMSW 2 /* 0F 01 /4 */
82#define UMIP_INST_SLDT 3 /* 0F 00 /0 */
83#define UMIP_INST_STR 4 /* 0F 00 /1 */
84
85const char * const umip_insns[5] = {
86 [UMIP_INST_SGDT] = "SGDT",
87 [UMIP_INST_SIDT] = "SIDT",
88 [UMIP_INST_SMSW] = "SMSW",
89 [UMIP_INST_SLDT] = "SLDT",
90 [UMIP_INST_STR] = "STR",
91};
92
93#define umip_pr_err(regs, fmt, ...) \
94 umip_printk(regs, KERN_ERR, fmt, ##__VA_ARGS__)
95#define umip_pr_warning(regs, fmt, ...) \
96 umip_printk(regs, KERN_WARNING, fmt, ##__VA_ARGS__)
97
98/**
99 * umip_printk() - Print a rate-limited message
100 * @regs: Register set with the context in which the warning is printed
101 * @log_level: Kernel log level to print the message
102 * @fmt: The text string to print
103 *
104 * Print the text contained in @fmt. The print rate is limited to bursts of 5
105 * messages every two minutes. The purpose of this customized version of
106 * printk() is to print messages when user space processes use any of the
107 * UMIP-protected instructions. Thus, the printed text is prepended with the
108 * task name and process ID number of the current task as well as the
109 * instruction and stack pointers in @regs as seen when entering kernel mode.
110 *
111 * Returns:
112 *
113 * None.
114 */
115static __printf(3, 4)
116void umip_printk(const struct pt_regs *regs, const char *log_level,
117 const char *fmt, ...)
118{
119 /* Bursts of 5 messages every two minutes */
120 static DEFINE_RATELIMIT_STATE(ratelimit, 2 * 60 * HZ, 5);
121 struct task_struct *tsk = current;
122 struct va_format vaf;
123 va_list args;
124
125 if (!__ratelimit(&ratelimit))
126 return;
127
128 va_start(args, fmt);
129 vaf.fmt = fmt;
130 vaf.va = &args;
131 printk("%s" pr_fmt("%s[%d] ip:%lx sp:%lx: %pV"), log_level, tsk->comm,
132 task_pid_nr(tsk), regs->ip, regs->sp, &vaf);
133 va_end(args);
134}
82 135
83/** 136/**
84 * identify_insn() - Identify a UMIP-protected instruction 137 * identify_insn() - Identify a UMIP-protected instruction
@@ -118,10 +171,16 @@ static int identify_insn(struct insn *insn)
118 default: 171 default:
119 return -EINVAL; 172 return -EINVAL;
120 } 173 }
174 } else if (insn->opcode.bytes[1] == 0x0) {
175 if (X86_MODRM_REG(insn->modrm.value) == 0)
176 return UMIP_INST_SLDT;
177 else if (X86_MODRM_REG(insn->modrm.value) == 1)
178 return UMIP_INST_STR;
179 else
180 return -EINVAL;
181 } else {
182 return -EINVAL;
121 } 183 }
122
123 /* SLDT AND STR are not emulated */
124 return -EINVAL;
125} 184}
126 185
127/** 186/**
@@ -228,10 +287,8 @@ static void force_sig_info_umip_fault(void __user *addr, struct pt_regs *regs)
228 if (!(show_unhandled_signals && unhandled_signal(tsk, SIGSEGV))) 287 if (!(show_unhandled_signals && unhandled_signal(tsk, SIGSEGV)))
229 return; 288 return;
230 289
231 pr_err_ratelimited("%s[%d] umip emulation segfault ip:%lx sp:%lx error:%x in %lx\n", 290 umip_pr_err(regs, "segfault in emulation. error%x\n",
232 tsk->comm, task_pid_nr(tsk), regs->ip, 291 X86_PF_USER | X86_PF_WRITE);
233 regs->sp, X86_PF_USER | X86_PF_WRITE,
234 regs->ip);
235} 292}
236 293
237/** 294/**
@@ -262,15 +319,11 @@ bool fixup_umip_exception(struct pt_regs *regs)
262 unsigned char buf[MAX_INSN_SIZE]; 319 unsigned char buf[MAX_INSN_SIZE];
263 void __user *uaddr; 320 void __user *uaddr;
264 struct insn insn; 321 struct insn insn;
265 char seg_defs; 322 int seg_defs;
266 323
267 if (!regs) 324 if (!regs)
268 return false; 325 return false;
269 326
270 /* Do not emulate 64-bit processes. */
271 if (user_64bit_mode(regs))
272 return false;
273
274 /* 327 /*
275 * If not in user-space long mode, a custom code segment could be in 328 * If not in user-space long mode, a custom code segment could be in
276 * use. This is true in protected mode (if the process defined a local 329 * use. This is true in protected mode (if the process defined a local
@@ -322,6 +375,15 @@ bool fixup_umip_exception(struct pt_regs *regs)
322 if (umip_inst < 0) 375 if (umip_inst < 0)
323 return false; 376 return false;
324 377
378 umip_pr_warning(regs, "%s instruction cannot be used by applications.\n",
379 umip_insns[umip_inst]);
380
381 /* Do not emulate SLDT, STR or user long mode processes. */
382 if (umip_inst == UMIP_INST_STR || umip_inst == UMIP_INST_SLDT || user_64bit_mode(regs))
383 return false;
384
385 umip_pr_warning(regs, "For now, expensive software emulation returns the result.\n");
386
325 if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size)) 387 if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size))
326 return false; 388 return false;
327 389
diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
index 35625d279458..9119d8e41f1f 100644
--- a/arch/x86/lib/insn-eval.c
+++ b/arch/x86/lib/insn-eval.c
@@ -733,11 +733,11 @@ static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx)
733 * 733 *
734 * Returns: 734 * Returns:
735 * 735 *
736 * A signed 8-bit value containing the default parameters on success. 736 * An int containing ORed-in default parameters on success.
737 * 737 *
738 * -EINVAL on error. 738 * -EINVAL on error.
739 */ 739 */
740char insn_get_code_seg_params(struct pt_regs *regs) 740int insn_get_code_seg_params(struct pt_regs *regs)
741{ 741{
742 struct desc_struct *desc; 742 struct desc_struct *desc;
743 short sel; 743 short sel;
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 12e377184ee4..c4d55919fac1 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -896,7 +896,7 @@ EndTable
896 896
897GrpTable: Grp3_1 897GrpTable: Grp3_1
8980: TEST Eb,Ib 8980: TEST Eb,Ib
8991: 8991: TEST Eb,Ib
9002: NOT Eb 9002: NOT Eb
9013: NEG Eb 9013: NEG Eb
9024: MUL AL,Eb 9024: MUL AL,Eb
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 8ae0000cbdb3..00b296617ca4 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -158,6 +158,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
158 if (len > TASK_SIZE) 158 if (len > TASK_SIZE)
159 return -ENOMEM; 159 return -ENOMEM;
160 160
161 /* No address checking. See comment at mmap_address_hint_valid() */
161 if (flags & MAP_FIXED) { 162 if (flags & MAP_FIXED) {
162 if (prepare_hugepage_range(file, addr, len)) 163 if (prepare_hugepage_range(file, addr, len))
163 return -EINVAL; 164 return -EINVAL;
@@ -165,12 +166,16 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
165 } 166 }
166 167
167 if (addr) { 168 if (addr) {
168 addr = ALIGN(addr, huge_page_size(h)); 169 addr &= huge_page_mask(h);
170 if (!mmap_address_hint_valid(addr, len))
171 goto get_unmapped_area;
172
169 vma = find_vma(mm, addr); 173 vma = find_vma(mm, addr);
170 if (TASK_SIZE - len >= addr && 174 if (!vma || addr + len <= vm_start_gap(vma))
171 (!vma || addr + len <= vm_start_gap(vma)))
172 return addr; 175 return addr;
173 } 176 }
177
178get_unmapped_area:
174 if (mm->get_unmapped_area == arch_get_unmapped_area) 179 if (mm->get_unmapped_area == arch_get_unmapped_area)
175 return hugetlb_get_unmapped_area_bottomup(file, addr, len, 180 return hugetlb_get_unmapped_area_bottomup(file, addr, len,
176 pgoff, flags); 181 pgoff, flags);
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index a99679826846..155ecbac9e28 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -33,6 +33,8 @@
33#include <linux/compat.h> 33#include <linux/compat.h>
34#include <asm/elf.h> 34#include <asm/elf.h>
35 35
36#include "physaddr.h"
37
36struct va_alignment __read_mostly va_align = { 38struct va_alignment __read_mostly va_align = {
37 .flags = -1, 39 .flags = -1,
38}; 40};
@@ -174,3 +176,63 @@ const char *arch_vma_name(struct vm_area_struct *vma)
174 return "[mpx]"; 176 return "[mpx]";
175 return NULL; 177 return NULL;
176} 178}
179
180/**
181 * mmap_address_hint_valid - Validate the address hint of mmap
182 * @addr: Address hint
183 * @len: Mapping length
184 *
185 * Check whether @addr and @addr + @len result in a valid mapping.
186 *
187 * On 32bit this only checks whether @addr + @len is <= TASK_SIZE.
188 *
189 * On 64bit with 5-level page tables another sanity check is required
190 * because mappings requested by mmap(@addr, 0) which cross the 47-bit
191 * virtual address boundary can cause the following theoretical issue:
192 *
193 * An application calls mmap(addr, 0), i.e. without MAP_FIXED, where @addr
194 * is below the border of the 47-bit address space and @addr + @len is
195 * above the border.
196 *
197 * With 4-level paging this request succeeds, but the resulting mapping
198 * address will always be within the 47-bit virtual address space, because
199 * the hint address does not result in a valid mapping and is
200 * ignored. Hence applications which are not prepared to handle virtual
201 * addresses above 47-bit work correctly.
202 *
203 * With 5-level paging this request would be granted and result in a
204 * mapping which crosses the border of the 47-bit virtual address
205 * space. If the application cannot handle addresses above 47-bit this
206 * will lead to misbehaviour and hard to diagnose failures.
207 *
208 * Therefore ignore address hints which would result in a mapping crossing
209 * the 47-bit virtual address boundary.
210 *
211 * Note, that in the same scenario with MAP_FIXED the behaviour is
212 * different. The request with @addr < 47-bit and @addr + @len > 47-bit
213 * fails on a 4-level paging machine but succeeds on a 5-level paging
214 * machine. It is reasonable to expect that an application does not rely on
215 * the failure of such a fixed mapping request, so the restriction is not
216 * applied.
217 */
218bool mmap_address_hint_valid(unsigned long addr, unsigned long len)
219{
220 if (TASK_SIZE - len < addr)
221 return false;
222
223 return (addr > DEFAULT_MAP_WINDOW) == (addr + len > DEFAULT_MAP_WINDOW);
224}
225
226/* Can we access it for direct reading/writing? Must be RAM: */
227int valid_phys_addr_range(phys_addr_t addr, size_t count)
228{
229 return addr + count <= __pa(high_memory);
230}
231
232/* Can we access it through mmap? Must be a valid physical address: */
233int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
234{
235 phys_addr_t addr = (phys_addr_t)pfn << PAGE_SHIFT;
236
237 return phys_addr_valid(addr + count - 1);
238}
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 970e1242a282..6aefe5370e5b 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -343,6 +343,10 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma)
343 size_t size = vma->vm_end - vma->vm_start; 343 size_t size = vma->vm_end - vma->vm_start;
344 phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; 344 phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
345 345
346 /* Does it even fit in phys_addr_t? */
347 if (offset >> PAGE_SHIFT != vma->vm_pgoff)
348 return -EINVAL;
349
346 /* It's illegal to wrap around the end of the physical address space. */ 350 /* It's illegal to wrap around the end of the physical address space. */
347 if (offset + (phys_addr_t)size - 1 < offset) 351 if (offset + (phys_addr_t)size - 1 < offset)
348 return -EINVAL; 352 return -EINVAL;
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 90944667ccea..bda151788f3f 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -80,15 +80,6 @@ config XEN_PCIDEV_FRONTEND
80 The PCI device frontend driver allows the kernel to import arbitrary 80 The PCI device frontend driver allows the kernel to import arbitrary
81 PCI devices from a PCI backend to support PCI driver domains. 81 PCI devices from a PCI backend to support PCI driver domains.
82 82
83config HT_IRQ
84 bool "Interrupts on hypertransport devices"
85 default y
86 depends on PCI && X86_LOCAL_APIC
87 help
88 This allows native hypertransport devices to use interrupts.
89
90 If unsure say Y.
91
92config PCI_ATS 83config PCI_ATS
93 bool 84 bool
94 85
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 3d5e047f0a32..c7819b973df7 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -21,9 +21,6 @@ obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
21# Build the PCI MSI interrupt support 21# Build the PCI MSI interrupt support
22obj-$(CONFIG_PCI_MSI) += msi.o 22obj-$(CONFIG_PCI_MSI) += msi.o
23 23
24# Build the Hypertransport interrupt support
25obj-$(CONFIG_HT_IRQ) += htirq.o
26
27obj-$(CONFIG_PCI_ATS) += ats.o 24obj-$(CONFIG_PCI_ATS) += ats.o
28obj-$(CONFIG_PCI_IOV) += iov.o 25obj-$(CONFIG_PCI_IOV) += iov.o
29 26
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
deleted file mode 100644
index bb88c26f5144..000000000000
--- a/drivers/pci/htirq.c
+++ /dev/null
@@ -1,135 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * File: htirq.c
4 * Purpose: Hypertransport Interrupt Capability
5 *
6 * Copyright (C) 2006 Linux Networx
7 * Copyright (C) Eric Biederman <ebiederman@lnxi.com>
8 */
9
10#include <linux/irq.h>
11#include <linux/pci.h>
12#include <linux/spinlock.h>
13#include <linux/export.h>
14#include <linux/slab.h>
15#include <linux/htirq.h>
16
17/* Global ht irq lock.
18 *
19 * This is needed to serialize access to the data port in hypertransport
20 * irq capability.
21 *
22 * With multiple simultaneous hypertransport irq devices it might pay
23 * to make this more fine grained. But start with simple, stupid, and correct.
24 */
25static DEFINE_SPINLOCK(ht_irq_lock);
26
27void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
28{
29 struct ht_irq_cfg *cfg = irq_get_handler_data(irq);
30 unsigned long flags;
31
32 spin_lock_irqsave(&ht_irq_lock, flags);
33 if (cfg->msg.address_lo != msg->address_lo) {
34 pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx);
35 pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_lo);
36 }
37 if (cfg->msg.address_hi != msg->address_hi) {
38 pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
39 pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi);
40 }
41 if (cfg->update)
42 cfg->update(cfg->dev, irq, msg);
43 spin_unlock_irqrestore(&ht_irq_lock, flags);
44 cfg->msg = *msg;
45}
46
47void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
48{
49 struct ht_irq_cfg *cfg = irq_get_handler_data(irq);
50
51 *msg = cfg->msg;
52}
53
54void mask_ht_irq(struct irq_data *data)
55{
56 struct ht_irq_cfg *cfg = irq_data_get_irq_handler_data(data);
57 struct ht_irq_msg msg = cfg->msg;
58
59 msg.address_lo |= 1;
60 write_ht_irq_msg(data->irq, &msg);
61}
62
63void unmask_ht_irq(struct irq_data *data)
64{
65 struct ht_irq_cfg *cfg = irq_data_get_irq_handler_data(data);
66 struct ht_irq_msg msg = cfg->msg;
67
68 msg.address_lo &= ~1;
69 write_ht_irq_msg(data->irq, &msg);
70}
71
72/**
73 * __ht_create_irq - create an irq and attach it to a device.
74 * @dev: The hypertransport device to find the irq capability on.
75 * @idx: Which of the possible irqs to attach to.
76 * @update: Function to be called when changing the htirq message
77 *
78 * The irq number of the new irq or a negative error value is returned.
79 */
80int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
81{
82 int max_irq, pos, irq;
83 unsigned long flags;
84 u32 data;
85
86 pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
87 if (!pos)
88 return -EINVAL;
89
90 /* Verify the idx I want to use is in range */
91 spin_lock_irqsave(&ht_irq_lock, flags);
92 pci_write_config_byte(dev, pos + 2, 1);
93 pci_read_config_dword(dev, pos + 4, &data);
94 spin_unlock_irqrestore(&ht_irq_lock, flags);
95
96 max_irq = (data >> 16) & 0xff;
97 if (idx > max_irq)
98 return -EINVAL;
99
100 irq = arch_setup_ht_irq(idx, pos, dev, update);
101 if (irq > 0)
102 dev_dbg(&dev->dev, "irq %d for HT\n", irq);
103
104 return irq;
105}
106EXPORT_SYMBOL(__ht_create_irq);
107
108/**
109 * ht_create_irq - create an irq and attach it to a device.
110 * @dev: The hypertransport device to find the irq capability on.
111 * @idx: Which of the possible irqs to attach to.
112 *
113 * ht_create_irq needs to be called for all hypertransport devices
114 * that generate irqs.
115 *
116 * The irq number of the new irq or a negative error value is returned.
117 */
118int ht_create_irq(struct pci_dev *dev, int idx)
119{
120 return __ht_create_irq(dev, idx, NULL);
121}
122EXPORT_SYMBOL(ht_create_irq);
123
124/**
125 * ht_destroy_irq - destroy an irq created with ht_create_irq
126 * @irq: irq to be destroyed
127 *
128 * This reverses ht_create_irq removing the specified irq from
129 * existence. The irq should be free before this happens.
130 */
131void ht_destroy_irq(unsigned int irq)
132{
133 arch_teardown_ht_irq(irq);
134}
135EXPORT_SYMBOL(ht_destroy_irq);
diff --git a/include/linux/htirq.h b/include/linux/htirq.h
deleted file mode 100644
index 127c39d815ba..000000000000
--- a/include/linux/htirq.h
+++ /dev/null
@@ -1,39 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef LINUX_HTIRQ_H
3#define LINUX_HTIRQ_H
4
5struct pci_dev;
6struct irq_data;
7
8struct ht_irq_msg {
9 u32 address_lo; /* low 32 bits of the ht irq message */
10 u32 address_hi; /* high 32 bits of the it irq message */
11};
12
13typedef void (ht_irq_update_t)(struct pci_dev *dev, int irq,
14 struct ht_irq_msg *msg);
15
16struct ht_irq_cfg {
17 struct pci_dev *dev;
18 /* Update callback used to cope with buggy hardware */
19 ht_irq_update_t *update;
20 unsigned pos;
21 unsigned idx;
22 struct ht_irq_msg msg;
23};
24
25/* Helper functions.. */
26void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
27void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg);
28void mask_ht_irq(struct irq_data *data);
29void unmask_ht_irq(struct irq_data *data);
30
31/* The arch hook for getting things started */
32int arch_setup_ht_irq(int idx, int pos, struct pci_dev *dev,
33 ht_irq_update_t *update);
34void arch_teardown_ht_irq(unsigned int irq);
35
36/* For drivers of buggy hardware */
37int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update);
38
39#endif /* LINUX_HTIRQ_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 96c94980d1ff..0403894147a3 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1485,12 +1485,6 @@ static inline void pcie_set_ecrc_checking(struct pci_dev *dev) { }
1485static inline void pcie_ecrc_get_policy(char *str) { } 1485static inline void pcie_ecrc_get_policy(char *str) { }
1486#endif 1486#endif
1487 1487
1488#ifdef CONFIG_HT_IRQ
1489/* The functions a driver should call */
1490int ht_create_irq(struct pci_dev *dev, int idx);
1491void ht_destroy_irq(unsigned int irq);
1492#endif /* CONFIG_HT_IRQ */
1493
1494#ifdef CONFIG_PCI_ATS 1488#ifdef CONFIG_PCI_ATS
1495/* Address Translation Service */ 1489/* Address Translation Service */
1496void pci_ats_init(struct pci_dev *dev); 1490void pci_ats_init(struct pci_dev *dev);
diff --git a/tools/testing/selftests/x86/5lvl.c b/tools/testing/selftests/x86/5lvl.c
new file mode 100644
index 000000000000..2eafdcd4c2b3
--- /dev/null
+++ b/tools/testing/selftests/x86/5lvl.c
@@ -0,0 +1,177 @@
1#include <stdio.h>
2#include <sys/mman.h>
3
4#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
5
6#define PAGE_SIZE 4096
7#define LOW_ADDR ((void *) (1UL << 30))
8#define HIGH_ADDR ((void *) (1UL << 50))
9
10struct testcase {
11 void *addr;
12 unsigned long size;
13 unsigned long flags;
14 const char *msg;
15 unsigned int low_addr_required:1;
16 unsigned int keep_mapped:1;
17};
18
19static struct testcase testcases[] = {
20 {
21 .addr = NULL,
22 .size = 2 * PAGE_SIZE,
23 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
24 .msg = "mmap(NULL)",
25 .low_addr_required = 1,
26 },
27 {
28 .addr = LOW_ADDR,
29 .size = 2 * PAGE_SIZE,
30 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
31 .msg = "mmap(LOW_ADDR)",
32 .low_addr_required = 1,
33 },
34 {
35 .addr = HIGH_ADDR,
36 .size = 2 * PAGE_SIZE,
37 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
38 .msg = "mmap(HIGH_ADDR)",
39 .keep_mapped = 1,
40 },
41 {
42 .addr = HIGH_ADDR,
43 .size = 2 * PAGE_SIZE,
44 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
45 .msg = "mmap(HIGH_ADDR) again",
46 .keep_mapped = 1,
47 },
48 {
49 .addr = HIGH_ADDR,
50 .size = 2 * PAGE_SIZE,
51 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
52 .msg = "mmap(HIGH_ADDR, MAP_FIXED)",
53 },
54 {
55 .addr = (void*) -1,
56 .size = 2 * PAGE_SIZE,
57 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
58 .msg = "mmap(-1)",
59 .keep_mapped = 1,
60 },
61 {
62 .addr = (void*) -1,
63 .size = 2 * PAGE_SIZE,
64 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
65 .msg = "mmap(-1) again",
66 },
67 {
68 .addr = (void *)((1UL << 47) - PAGE_SIZE),
69 .size = 2 * PAGE_SIZE,
70 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
71 .msg = "mmap((1UL << 47), 2 * PAGE_SIZE)",
72 .low_addr_required = 1,
73 .keep_mapped = 1,
74 },
75 {
76 .addr = (void *)((1UL << 47) - PAGE_SIZE / 2),
77 .size = 2 * PAGE_SIZE,
78 .flags = MAP_PRIVATE | MAP_ANONYMOUS,
79 .msg = "mmap((1UL << 47), 2 * PAGE_SIZE / 2)",
80 .low_addr_required = 1,
81 .keep_mapped = 1,
82 },
83 {
84 .addr = (void *)((1UL << 47) - PAGE_SIZE),
85 .size = 2 * PAGE_SIZE,
86 .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
87 .msg = "mmap((1UL << 47) - PAGE_SIZE, 2 * PAGE_SIZE, MAP_FIXED)",
88 },
89 {
90 .addr = NULL,
91 .size = 2UL << 20,
92 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
93 .msg = "mmap(NULL, MAP_HUGETLB)",
94 .low_addr_required = 1,
95 },
96 {
97 .addr = LOW_ADDR,
98 .size = 2UL << 20,
99 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
100 .msg = "mmap(LOW_ADDR, MAP_HUGETLB)",
101 .low_addr_required = 1,
102 },
103 {
104 .addr = HIGH_ADDR,
105 .size = 2UL << 20,
106 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
107 .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)",
108 .keep_mapped = 1,
109 },
110 {
111 .addr = HIGH_ADDR,
112 .size = 2UL << 20,
113 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
114 .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again",
115 .keep_mapped = 1,
116 },
117 {
118 .addr = HIGH_ADDR,
119 .size = 2UL << 20,
120 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
121 .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)",
122 },
123 {
124 .addr = (void*) -1,
125 .size = 2UL << 20,
126 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
127 .msg = "mmap(-1, MAP_HUGETLB)",
128 .keep_mapped = 1,
129 },
130 {
131 .addr = (void*) -1,
132 .size = 2UL << 20,
133 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
134 .msg = "mmap(-1, MAP_HUGETLB) again",
135 },
136 {
137 .addr = (void *)((1UL << 47) - PAGE_SIZE),
138 .size = 4UL << 20,
139 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
140 .msg = "mmap((1UL << 47), 4UL << 20, MAP_HUGETLB)",
141 .low_addr_required = 1,
142 .keep_mapped = 1,
143 },
144 {
145 .addr = (void *)((1UL << 47) - (2UL << 20)),
146 .size = 4UL << 20,
147 .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
148 .msg = "mmap((1UL << 47) - (2UL << 20), 4UL << 20, MAP_FIXED | MAP_HUGETLB)",
149 },
150};
151
152int main(int argc, char **argv)
153{
154 int i;
155 void *p;
156
157 for (i = 0; i < ARRAY_SIZE(testcases); i++) {
158 struct testcase *t = testcases + i;
159
160 p = mmap(t->addr, t->size, PROT_NONE, t->flags, -1, 0);
161
162 printf("%s: %p - ", t->msg, p);
163
164 if (p == MAP_FAILED) {
165 printf("FAILED\n");
166 continue;
167 }
168
169 if (t->low_addr_required && p >= (void *)(1UL << 47))
170 printf("FAILED\n");
171 else
172 printf("OK\n");
173 if (!t->keep_mapped)
174 munmap(p, t->size);
175 }
176 return 0;
177}
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 7b1adeee4b0f..939a337128db 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -11,7 +11,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_sysc
11TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ 11TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
12 test_FCMOV test_FCOMI test_FISTTP \ 12 test_FCMOV test_FCOMI test_FISTTP \
13 vdso_restorer 13 vdso_restorer
14TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip 14TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip 5lvl
15 15
16TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) 16TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
17TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) 17TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)
diff --git a/tools/testing/selftests/x86/mpx-hw.h b/tools/testing/selftests/x86/mpx-hw.h
index 3f0093911f03..d1b61ab870f8 100644
--- a/tools/testing/selftests/x86/mpx-hw.h
+++ b/tools/testing/selftests/x86/mpx-hw.h
@@ -52,14 +52,14 @@
52struct mpx_bd_entry { 52struct mpx_bd_entry {
53 union { 53 union {
54 char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES]; 54 char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES];
55 void *contents[1]; 55 void *contents[0];
56 }; 56 };
57} __attribute__((packed)); 57} __attribute__((packed));
58 58
59struct mpx_bt_entry { 59struct mpx_bt_entry {
60 union { 60 union {
61 char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES]; 61 char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES];
62 unsigned long contents[1]; 62 unsigned long contents[0];
63 }; 63 };
64} __attribute__((packed)); 64} __attribute__((packed));
65 65
diff --git a/tools/testing/selftests/x86/pkey-helpers.h b/tools/testing/selftests/x86/pkey-helpers.h
index 3818f25391c2..b3cb7670e026 100644
--- a/tools/testing/selftests/x86/pkey-helpers.h
+++ b/tools/testing/selftests/x86/pkey-helpers.h
@@ -30,6 +30,7 @@ static inline void sigsafe_printf(const char *format, ...)
30 if (!dprint_in_signal) { 30 if (!dprint_in_signal) {
31 vprintf(format, ap); 31 vprintf(format, ap);
32 } else { 32 } else {
33 int ret;
33 int len = vsnprintf(dprint_in_signal_buffer, 34 int len = vsnprintf(dprint_in_signal_buffer,
34 DPRINT_IN_SIGNAL_BUF_SIZE, 35 DPRINT_IN_SIGNAL_BUF_SIZE,
35 format, ap); 36 format, ap);
@@ -39,7 +40,9 @@ static inline void sigsafe_printf(const char *format, ...)
39 */ 40 */
40 if (len > DPRINT_IN_SIGNAL_BUF_SIZE) 41 if (len > DPRINT_IN_SIGNAL_BUF_SIZE)
41 len = DPRINT_IN_SIGNAL_BUF_SIZE; 42 len = DPRINT_IN_SIGNAL_BUF_SIZE;
42 write(1, dprint_in_signal_buffer, len); 43 ret = write(1, dprint_in_signal_buffer, len);
44 if (ret < 0)
45 abort();
43 } 46 }
44 va_end(ap); 47 va_end(ap);
45} 48}
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c
index 7a1cc0e56d2d..bc1b0735bb50 100644
--- a/tools/testing/selftests/x86/protection_keys.c
+++ b/tools/testing/selftests/x86/protection_keys.c
@@ -250,7 +250,7 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
250 unsigned long ip; 250 unsigned long ip;
251 char *fpregs; 251 char *fpregs;
252 u32 *pkru_ptr; 252 u32 *pkru_ptr;
253 u64 si_pkey; 253 u64 siginfo_pkey;
254 u32 *si_pkey_ptr; 254 u32 *si_pkey_ptr;
255 int pkru_offset; 255 int pkru_offset;
256 fpregset_t fpregset; 256 fpregset_t fpregset;
@@ -292,9 +292,9 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
292 si_pkey_ptr = (u32 *)(((u8 *)si) + si_pkey_offset); 292 si_pkey_ptr = (u32 *)(((u8 *)si) + si_pkey_offset);
293 dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr); 293 dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr);
294 dump_mem(si_pkey_ptr - 8, 24); 294 dump_mem(si_pkey_ptr - 8, 24);
295 si_pkey = *si_pkey_ptr; 295 siginfo_pkey = *si_pkey_ptr;
296 pkey_assert(si_pkey < NR_PKEYS); 296 pkey_assert(siginfo_pkey < NR_PKEYS);
297 last_si_pkey = si_pkey; 297 last_si_pkey = siginfo_pkey;
298 298
299 if ((si->si_code == SEGV_MAPERR) || 299 if ((si->si_code == SEGV_MAPERR) ||
300 (si->si_code == SEGV_ACCERR) || 300 (si->si_code == SEGV_ACCERR) ||
@@ -306,7 +306,7 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
306 dprintf1("signal pkru from xsave: %08x\n", *pkru_ptr); 306 dprintf1("signal pkru from xsave: %08x\n", *pkru_ptr);
307 /* need __rdpkru() version so we do not do shadow_pkru checking */ 307 /* need __rdpkru() version so we do not do shadow_pkru checking */
308 dprintf1("signal pkru from pkru: %08x\n", __rdpkru()); 308 dprintf1("signal pkru from pkru: %08x\n", __rdpkru());
309 dprintf1("si_pkey from siginfo: %jx\n", si_pkey); 309 dprintf1("pkey from siginfo: %jx\n", siginfo_pkey);
310 *(u64 *)pkru_ptr = 0x00000000; 310 *(u64 *)pkru_ptr = 0x00000000;
311 dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n"); 311 dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n");
312 pkru_faults++; 312 pkru_faults++;