aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-27 14:14:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-27 14:14:25 -0400
commit19b522dbad0d0c35d0741a74aef70ce6fe2d6fb4 (patch)
treea842aba427dfb651790d4e06b7582c42ce8d8879
parent7b87308e710858e95729b9e33c8b79e2a1564d37 (diff)
parent3789c122d0a016b947ce5c05d3f1fbafa5db8f26 (diff)
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Will Deacon: "Nothing too bad, but the spectre updates to smatch identified a few places that may need sanitising so we've got those covered. Details: - Close some potential spectre-v1 vulnerabilities found by smatch - Add missing list sentinel for CPUs that don't require KPTI - Removal of unused 'addr' parameter for I/D cache coherency - Removal of redundant set_fs(KERNEL_DS) calls in ptrace - Fix single-stepping state machine handling in response to kernel traps - Clang support for 128-bit integers - Avoid instrumenting our out-of-line atomics in preparation for enabling LSE atomics by default in 4.18" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: avoid instrumenting atomic_ll_sc.o KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_mmio_read_apr() KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_get_irq() arm64: fix possible spectre-v1 in ptrace_hbp_get_event() arm64: support __int128 with clang arm64: only advance singlestep for user instruction traps arm64/kernel: rename module_emit_adrp_veneer->module_emit_veneer_for_adrp arm64: ptrace: remove addr_limit manipulation arm64: mm: drop addr parameter from sync icache and dcache arm64: add sentinel to kpti_safe_list
-rw-r--r--arch/arm64/Makefile4
-rw-r--r--arch/arm64/include/asm/module.h2
-rw-r--r--arch/arm64/include/asm/pgtable.h4
-rw-r--r--arch/arm64/kernel/cpufeature.c1
-rw-r--r--arch/arm64/kernel/module-plts.c2
-rw-r--r--arch/arm64/kernel/module.c2
-rw-r--r--arch/arm64/kernel/ptrace.c20
-rw-r--r--arch/arm64/kernel/traps.c3
-rw-r--r--arch/arm64/lib/Makefile4
-rw-r--r--arch/arm64/mm/flush.c2
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio-v2.c5
-rw-r--r--virt/kvm/arm/vgic/vgic.c14
12 files changed, 42 insertions, 21 deletions
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 15402861bb59..87f7d2f9f17c 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -56,7 +56,11 @@ KBUILD_AFLAGS += $(lseinstr) $(brokengasinst)
56KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) 56KBUILD_CFLAGS += $(call cc-option,-mabi=lp64)
57KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) 57KBUILD_AFLAGS += $(call cc-option,-mabi=lp64)
58 58
59ifeq ($(cc-name),clang)
60KBUILD_CFLAGS += -DCONFIG_ARCH_SUPPORTS_INT128
61else
59KBUILD_CFLAGS += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128) 62KBUILD_CFLAGS += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128)
63endif
60 64
61ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) 65ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
62KBUILD_CPPFLAGS += -mbig-endian 66KBUILD_CPPFLAGS += -mbig-endian
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index b6dbbe3123a9..97d0ef12e2ff 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -39,7 +39,7 @@ struct mod_arch_specific {
39u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela, 39u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela,
40 Elf64_Sym *sym); 40 Elf64_Sym *sym);
41 41
42u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val); 42u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val);
43 43
44#ifdef CONFIG_RANDOMIZE_BASE 44#ifdef CONFIG_RANDOMIZE_BASE
45extern u64 module_alloc_base; 45extern u64 module_alloc_base;
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7e2c27e63cd8..7c4c8f318ba9 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -230,7 +230,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
230 } 230 }
231} 231}
232 232
233extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); 233extern void __sync_icache_dcache(pte_t pteval);
234 234
235/* 235/*
236 * PTE bits configuration in the presence of hardware Dirty Bit Management 236 * PTE bits configuration in the presence of hardware Dirty Bit Management
@@ -253,7 +253,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
253 pte_t old_pte; 253 pte_t old_pte;
254 254
255 if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) 255 if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
256 __sync_icache_dcache(pte, addr); 256 __sync_icache_dcache(pte);
257 257
258 /* 258 /*
259 * If the existing pte is valid, check for potential race with 259 * If the existing pte is valid, check for potential race with
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 536d572e5596..9d1b06d67c53 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -868,6 +868,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
868 static const struct midr_range kpti_safe_list[] = { 868 static const struct midr_range kpti_safe_list[] = {
869 MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), 869 MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
870 MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), 870 MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
871 { /* sentinel */ }
871 }; 872 };
872 char const *str = "command line option"; 873 char const *str = "command line option";
873 874
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
index fa3637284a3d..f0690c2ca3e0 100644
--- a/arch/arm64/kernel/module-plts.c
+++ b/arch/arm64/kernel/module-plts.c
@@ -43,7 +43,7 @@ u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela,
43} 43}
44 44
45#ifdef CONFIG_ARM64_ERRATUM_843419 45#ifdef CONFIG_ARM64_ERRATUM_843419
46u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val) 46u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val)
47{ 47{
48 struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core : 48 struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
49 &mod->arch.init; 49 &mod->arch.init;
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 719fde8dcc19..155fd91e78f4 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -215,7 +215,7 @@ static int reloc_insn_adrp(struct module *mod, __le32 *place, u64 val)
215 insn &= ~BIT(31); 215 insn &= ~BIT(31);
216 } else { 216 } else {
217 /* out of range for ADR -> emit a veneer */ 217 /* out of range for ADR -> emit a veneer */
218 val = module_emit_adrp_veneer(mod, place, val & ~0xfff); 218 val = module_emit_veneer_for_adrp(mod, place, val & ~0xfff);
219 if (!val) 219 if (!val)
220 return -ENOEXEC; 220 return -ENOEXEC;
221 insn = aarch64_insn_gen_branch_imm((u64)place, val, 221 insn = aarch64_insn_gen_branch_imm((u64)place, val,
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 71d99af24ef2..7ff81fed46e1 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -25,6 +25,7 @@
25#include <linux/sched/signal.h> 25#include <linux/sched/signal.h>
26#include <linux/sched/task_stack.h> 26#include <linux/sched/task_stack.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/nospec.h>
28#include <linux/smp.h> 29#include <linux/smp.h>
29#include <linux/ptrace.h> 30#include <linux/ptrace.h>
30#include <linux/user.h> 31#include <linux/user.h>
@@ -249,15 +250,20 @@ static struct perf_event *ptrace_hbp_get_event(unsigned int note_type,
249 250
250 switch (note_type) { 251 switch (note_type) {
251 case NT_ARM_HW_BREAK: 252 case NT_ARM_HW_BREAK:
252 if (idx < ARM_MAX_BRP) 253 if (idx >= ARM_MAX_BRP)
253 bp = tsk->thread.debug.hbp_break[idx]; 254 goto out;
255 idx = array_index_nospec(idx, ARM_MAX_BRP);
256 bp = tsk->thread.debug.hbp_break[idx];
254 break; 257 break;
255 case NT_ARM_HW_WATCH: 258 case NT_ARM_HW_WATCH:
256 if (idx < ARM_MAX_WRP) 259 if (idx >= ARM_MAX_WRP)
257 bp = tsk->thread.debug.hbp_watch[idx]; 260 goto out;
261 idx = array_index_nospec(idx, ARM_MAX_WRP);
262 bp = tsk->thread.debug.hbp_watch[idx];
258 break; 263 break;
259 } 264 }
260 265
266out:
261 return bp; 267 return bp;
262} 268}
263 269
@@ -1458,9 +1464,7 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
1458{ 1464{
1459 int ret; 1465 int ret;
1460 u32 kdata; 1466 u32 kdata;
1461 mm_segment_t old_fs = get_fs();
1462 1467
1463 set_fs(KERNEL_DS);
1464 /* Watchpoint */ 1468 /* Watchpoint */
1465 if (num < 0) { 1469 if (num < 0) {
1466 ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata); 1470 ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata);
@@ -1471,7 +1475,6 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
1471 } else { 1475 } else {
1472 ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata); 1476 ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata);
1473 } 1477 }
1474 set_fs(old_fs);
1475 1478
1476 if (!ret) 1479 if (!ret)
1477 ret = put_user(kdata, data); 1480 ret = put_user(kdata, data);
@@ -1484,7 +1487,6 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
1484{ 1487{
1485 int ret; 1488 int ret;
1486 u32 kdata = 0; 1489 u32 kdata = 0;
1487 mm_segment_t old_fs = get_fs();
1488 1490
1489 if (num == 0) 1491 if (num == 0)
1490 return 0; 1492 return 0;
@@ -1493,12 +1495,10 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
1493 if (ret) 1495 if (ret)
1494 return ret; 1496 return ret;
1495 1497
1496 set_fs(KERNEL_DS);
1497 if (num < 0) 1498 if (num < 0)
1498 ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata); 1499 ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata);
1499 else 1500 else
1500 ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata); 1501 ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata);
1501 set_fs(old_fs);
1502 1502
1503 return ret; 1503 return ret;
1504} 1504}
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 1cb2749a72bf..8bbdc17e49df 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -277,7 +277,8 @@ void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size)
277 * If we were single stepping, we want to get the step exception after 277 * If we were single stepping, we want to get the step exception after
278 * we return from the trap. 278 * we return from the trap.
279 */ 279 */
280 user_fastforward_single_step(current); 280 if (user_mode(regs))
281 user_fastforward_single_step(current);
281} 282}
282 283
283static LIST_HEAD(undef_hook); 284static LIST_HEAD(undef_hook);
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 0ead8a1d1679..137710f4dac3 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -19,5 +19,9 @@ CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2 \
19 -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15 \ 19 -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15 \
20 -fcall-saved-x18 -fomit-frame-pointer 20 -fcall-saved-x18 -fomit-frame-pointer
21CFLAGS_REMOVE_atomic_ll_sc.o := -pg 21CFLAGS_REMOVE_atomic_ll_sc.o := -pg
22GCOV_PROFILE_atomic_ll_sc.o := n
23KASAN_SANITIZE_atomic_ll_sc.o := n
24KCOV_INSTRUMENT_atomic_ll_sc.o := n
25UBSAN_SANITIZE_atomic_ll_sc.o := n
22 26
23lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o 27lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index e36ed5087b5c..1059884f9a6f 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -58,7 +58,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
58 flush_ptrace_access(vma, page, uaddr, dst, len); 58 flush_ptrace_access(vma, page, uaddr, dst, len);
59} 59}
60 60
61void __sync_icache_dcache(pte_t pte, unsigned long addr) 61void __sync_icache_dcache(pte_t pte)
62{ 62{
63 struct page *page = pte_page(pte); 63 struct page *page = pte_page(pte);
64 64
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
index e21e2f49b005..ffc587bf4742 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
@@ -14,6 +14,8 @@
14#include <linux/irqchip/arm-gic.h> 14#include <linux/irqchip/arm-gic.h>
15#include <linux/kvm.h> 15#include <linux/kvm.h>
16#include <linux/kvm_host.h> 16#include <linux/kvm_host.h>
17#include <linux/nospec.h>
18
17#include <kvm/iodev.h> 19#include <kvm/iodev.h>
18#include <kvm/arm_vgic.h> 20#include <kvm/arm_vgic.h>
19 21
@@ -324,6 +326,9 @@ static unsigned long vgic_mmio_read_apr(struct kvm_vcpu *vcpu,
324 326
325 if (n > vgic_v3_max_apr_idx(vcpu)) 327 if (n > vgic_v3_max_apr_idx(vcpu))
326 return 0; 328 return 0;
329
330 n = array_index_nospec(n, 4);
331
327 /* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */ 332 /* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */
328 return vgicv3->vgic_ap1r[n]; 333 return vgicv3->vgic_ap1r[n];
329 } 334 }
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index e74baec76361..bd125563b15b 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -14,11 +14,13 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include <linux/interrupt.h>
18#include <linux/irq.h>
17#include <linux/kvm.h> 19#include <linux/kvm.h>
18#include <linux/kvm_host.h> 20#include <linux/kvm_host.h>
19#include <linux/list_sort.h> 21#include <linux/list_sort.h>
20#include <linux/interrupt.h> 22#include <linux/nospec.h>
21#include <linux/irq.h> 23
22#include <asm/kvm_hyp.h> 24#include <asm/kvm_hyp.h>
23 25
24#include "vgic.h" 26#include "vgic.h"
@@ -101,12 +103,16 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu,
101 u32 intid) 103 u32 intid)
102{ 104{
103 /* SGIs and PPIs */ 105 /* SGIs and PPIs */
104 if (intid <= VGIC_MAX_PRIVATE) 106 if (intid <= VGIC_MAX_PRIVATE) {
107 intid = array_index_nospec(intid, VGIC_MAX_PRIVATE);
105 return &vcpu->arch.vgic_cpu.private_irqs[intid]; 108 return &vcpu->arch.vgic_cpu.private_irqs[intid];
109 }
106 110
107 /* SPIs */ 111 /* SPIs */
108 if (intid <= VGIC_MAX_SPI) 112 if (intid <= VGIC_MAX_SPI) {
113 intid = array_index_nospec(intid, VGIC_MAX_SPI);
109 return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS]; 114 return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS];
115 }
110 116
111 /* LPIs */ 117 /* LPIs */
112 if (intid >= VGIC_MIN_LPI) 118 if (intid >= VGIC_MIN_LPI)