diff options
| -rw-r--r-- | arch/arm64/kernel/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm64/kernel/bpi.S | 86 | ||||
| -rw-r--r-- | arch/arm64/kernel/cpu_errata.c | 4 | ||||
| -rw-r--r-- | arch/arm64/kvm/hyp/hyp-entry.S | 64 |
4 files changed, 65 insertions, 91 deletions
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 9b55a3f24be7..bf825f38d206 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
| @@ -55,8 +55,6 @@ arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o | |||
| 55 | arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 55 | arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
| 56 | arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o | 56 | arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o |
| 57 | 57 | ||
| 58 | arm64-obj-$(CONFIG_KVM_INDIRECT_VECTORS)+= bpi.o | ||
| 59 | |||
| 60 | obj-y += $(arm64-obj-y) vdso/ probes/ | 58 | obj-y += $(arm64-obj-y) vdso/ probes/ |
| 61 | obj-m += $(arm64-obj-m) | 59 | obj-m += $(arm64-obj-m) |
| 62 | head-y := head.o | 60 | head-y := head.o |
diff --git a/arch/arm64/kernel/bpi.S b/arch/arm64/kernel/bpi.S deleted file mode 100644 index 279e6ced7611..000000000000 --- a/arch/arm64/kernel/bpi.S +++ /dev/null | |||
| @@ -1,86 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Contains CPU specific branch predictor invalidation sequences | ||
| 3 | * | ||
| 4 | * Copyright (C) 2018 ARM Ltd. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/linkage.h> | ||
| 20 | #include <linux/arm-smccc.h> | ||
| 21 | |||
| 22 | #include <asm/alternative.h> | ||
| 23 | #include <asm/mmu.h> | ||
| 24 | |||
| 25 | .macro hyp_ventry | ||
| 26 | .align 7 | ||
| 27 | 1: .rept 27 | ||
| 28 | nop | ||
| 29 | .endr | ||
| 30 | /* | ||
| 31 | * The default sequence is to directly branch to the KVM vectors, | ||
| 32 | * using the computed offset. This applies for VHE as well as | ||
| 33 | * !ARM64_HARDEN_EL2_VECTORS. | ||
| 34 | * | ||
| 35 | * For ARM64_HARDEN_EL2_VECTORS configurations, this gets replaced | ||
| 36 | * with: | ||
| 37 | * | ||
| 38 | * stp x0, x1, [sp, #-16]! | ||
| 39 | * movz x0, #(addr & 0xffff) | ||
| 40 | * movk x0, #((addr >> 16) & 0xffff), lsl #16 | ||
| 41 | * movk x0, #((addr >> 32) & 0xffff), lsl #32 | ||
| 42 | * br x0 | ||
| 43 | * | ||
| 44 | * Where addr = kern_hyp_va(__kvm_hyp_vector) + vector-offset + 4. | ||
| 45 | * See kvm_patch_vector_branch for details. | ||
| 46 | */ | ||
| 47 | alternative_cb kvm_patch_vector_branch | ||
| 48 | b __kvm_hyp_vector + (1b - 0b) | ||
| 49 | nop | ||
| 50 | nop | ||
| 51 | nop | ||
| 52 | nop | ||
| 53 | alternative_cb_end | ||
| 54 | .endm | ||
| 55 | |||
| 56 | .macro generate_vectors | ||
| 57 | 0: | ||
| 58 | .rept 16 | ||
| 59 | hyp_ventry | ||
| 60 | .endr | ||
| 61 | .org 0b + SZ_2K // Safety measure | ||
| 62 | .endm | ||
| 63 | |||
| 64 | |||
| 65 | .text | ||
| 66 | .pushsection .hyp.text, "ax" | ||
| 67 | |||
| 68 | .align 11 | ||
| 69 | ENTRY(__bp_harden_hyp_vecs_start) | ||
| 70 | .rept BP_HARDEN_EL2_SLOTS | ||
| 71 | generate_vectors | ||
| 72 | .endr | ||
| 73 | ENTRY(__bp_harden_hyp_vecs_end) | ||
| 74 | |||
| 75 | .popsection | ||
| 76 | |||
| 77 | ENTRY(__smccc_workaround_1_smc_start) | ||
| 78 | sub sp, sp, #(8 * 4) | ||
| 79 | stp x2, x3, [sp, #(8 * 0)] | ||
| 80 | stp x0, x1, [sp, #(8 * 2)] | ||
| 81 | mov w0, #ARM_SMCCC_ARCH_WORKAROUND_1 | ||
| 82 | smc #0 | ||
| 83 | ldp x2, x3, [sp, #(8 * 0)] | ||
| 84 | ldp x0, x1, [sp, #(8 * 2)] | ||
| 85 | add sp, sp, #(8 * 4) | ||
| 86 | ENTRY(__smccc_workaround_1_smc_end) | ||
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index fc9d017f2d33..a900befadfe8 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c | |||
| @@ -86,7 +86,7 @@ atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1); | |||
| 86 | 86 | ||
| 87 | DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); | 87 | DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); |
| 88 | 88 | ||
| 89 | #ifdef CONFIG_KVM | 89 | #ifdef CONFIG_KVM_INDIRECT_VECTORS |
| 90 | extern char __smccc_workaround_1_smc_start[]; | 90 | extern char __smccc_workaround_1_smc_start[]; |
| 91 | extern char __smccc_workaround_1_smc_end[]; | 91 | extern char __smccc_workaround_1_smc_end[]; |
| 92 | 92 | ||
| @@ -137,7 +137,7 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn, | |||
| 137 | { | 137 | { |
| 138 | __this_cpu_write(bp_hardening_data.fn, fn); | 138 | __this_cpu_write(bp_hardening_data.fn, fn); |
| 139 | } | 139 | } |
| 140 | #endif /* CONFIG_KVM */ | 140 | #endif /* CONFIG_KVM_INDIRECT_VECTORS */ |
| 141 | 141 | ||
| 142 | static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry, | 142 | static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry, |
| 143 | bp_hardening_cb_t fn, | 143 | bp_hardening_cb_t fn, |
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index 87dfecce82b1..bffece27b5c1 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2015 - ARM Ltd | 2 | * Copyright (C) 2015-2018 - ARM Ltd |
| 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> | 3 | * Author: Marc Zyngier <marc.zyngier@arm.com> |
| 4 | * | 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <asm/kvm_arm.h> | 24 | #include <asm/kvm_arm.h> |
| 25 | #include <asm/kvm_asm.h> | 25 | #include <asm/kvm_asm.h> |
| 26 | #include <asm/kvm_mmu.h> | 26 | #include <asm/kvm_mmu.h> |
| 27 | #include <asm/mmu.h> | ||
| 27 | 28 | ||
| 28 | .text | 29 | .text |
| 29 | .pushsection .hyp.text, "ax" | 30 | .pushsection .hyp.text, "ax" |
| @@ -237,3 +238,64 @@ ENTRY(__kvm_hyp_vector) | |||
| 237 | invalid_vect el1_fiq_invalid // FIQ 32-bit EL1 | 238 | invalid_vect el1_fiq_invalid // FIQ 32-bit EL1 |
| 238 | valid_vect el1_error // Error 32-bit EL1 | 239 | valid_vect el1_error // Error 32-bit EL1 |
| 239 | ENDPROC(__kvm_hyp_vector) | 240 | ENDPROC(__kvm_hyp_vector) |
| 241 | |||
| 242 | #ifdef CONFIG_KVM_INDIRECT_VECTORS | ||
| 243 | .macro hyp_ventry | ||
| 244 | .align 7 | ||
| 245 | 1: .rept 27 | ||
| 246 | nop | ||
| 247 | .endr | ||
| 248 | /* | ||
| 249 | * The default sequence is to directly branch to the KVM vectors, | ||
| 250 | * using the computed offset. This applies for VHE as well as | ||
| 251 | * !ARM64_HARDEN_EL2_VECTORS. | ||
| 252 | * | ||
| 253 | * For ARM64_HARDEN_EL2_VECTORS configurations, this gets replaced | ||
| 254 | * with: | ||
| 255 | * | ||
| 256 | * stp x0, x1, [sp, #-16]! | ||
| 257 | * movz x0, #(addr & 0xffff) | ||
| 258 | * movk x0, #((addr >> 16) & 0xffff), lsl #16 | ||
| 259 | * movk x0, #((addr >> 32) & 0xffff), lsl #32 | ||
| 260 | * br x0 | ||
| 261 | * | ||
| 262 | * Where addr = kern_hyp_va(__kvm_hyp_vector) + vector-offset + 4. | ||
| 263 | * See kvm_patch_vector_branch for details. | ||
| 264 | */ | ||
| 265 | alternative_cb kvm_patch_vector_branch | ||
| 266 | b __kvm_hyp_vector + (1b - 0b) | ||
| 267 | nop | ||
| 268 | nop | ||
| 269 | nop | ||
| 270 | nop | ||
| 271 | alternative_cb_end | ||
| 272 | .endm | ||
| 273 | |||
| 274 | .macro generate_vectors | ||
| 275 | 0: | ||
| 276 | .rept 16 | ||
| 277 | hyp_ventry | ||
| 278 | .endr | ||
| 279 | .org 0b + SZ_2K // Safety measure | ||
| 280 | .endm | ||
| 281 | |||
| 282 | .align 11 | ||
| 283 | ENTRY(__bp_harden_hyp_vecs_start) | ||
| 284 | .rept BP_HARDEN_EL2_SLOTS | ||
| 285 | generate_vectors | ||
| 286 | .endr | ||
| 287 | ENTRY(__bp_harden_hyp_vecs_end) | ||
| 288 | |||
| 289 | .popsection | ||
| 290 | |||
| 291 | ENTRY(__smccc_workaround_1_smc_start) | ||
| 292 | sub sp, sp, #(8 * 4) | ||
| 293 | stp x2, x3, [sp, #(8 * 0)] | ||
| 294 | stp x0, x1, [sp, #(8 * 2)] | ||
| 295 | mov w0, #ARM_SMCCC_ARCH_WORKAROUND_1 | ||
| 296 | smc #0 | ||
| 297 | ldp x2, x3, [sp, #(8 * 0)] | ||
| 298 | ldp x0, x1, [sp, #(8 * 2)] | ||
| 299 | add sp, sp, #(8 * 4) | ||
| 300 | ENTRY(__smccc_workaround_1_smc_end) | ||
| 301 | #endif | ||
