Pull arm64 fixes from Will Deacon: "The diffstat is a bit spread out thanks to an invasive CPU erratum workaround which missed the merge window and also a bunch of fixes to the recently added MTE selftests. - Fixes to MTE kselftests - Fix return code from KVM Spectre-v2 hypercall - Build fixes for ld.lld and Clang's infamous integrated assembler - Ensure RCU is up and running before we use printk() - Workaround for Cortex-A77 erratum 1508412 - Fix linker warnings from unexpected ELF sections - Ensure PE/COFF sections are 64k aligned" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: Change .weak to SYM_FUNC_START_WEAK_PI for arch/arm64/lib/mem*.S arm64/smp: Move rcu_cpu_starting() earlier arm64: Add workaround for Arm Cortex-A77 erratum 1508412 arm64: Add part number for Arm Cortex-A77 arm64: mte: Document that user PSTATE.TCO is ignored by kernel uaccess module: use hidden visibility for weak symbol references arm64: efi: increase EFI PE/COFF header padding to 64 KB arm64: vmlinux.lds: account for spurious empty .igot.plt sections kselftest/arm64: Fix check_user_mem test kselftest/arm64: Fix check_ksm_options test kselftest/arm64: Fix check_mmap_options test kselftest/arm64: Fix check_child_memory test kselftest/arm64: Fix check_tags_inclusion test kselftest/arm64: Fix check_buffer_fill test arm64: avoid -Woverride-init warning KVM: arm64: ARM_SMCCC_ARCH_WORKAROUND_1 doesn't return SMCCC_RET_NOT_REQUIRED arm64: vdso32: Allow ld.lld to properly link the VDSO
Unified · Split
| @@ -102,7 +102,9 @@ applications. · 101 unmodified lines | |||
| 102 | system call) are not checked if the user thread tag checking mode is | 102 | system call) are not checked if the user thread tag checking mode is |
| 103 | ``PR_MTE_TCF_NONE`` or ``PR_MTE_TCF_ASYNC``. If the tag checking mode is | 103 | ``PR_MTE_TCF_NONE`` or ``PR_MTE_TCF_ASYNC``. If the tag checking mode is |
| 104 | ``PR_MTE_TCF_SYNC``, the kernel makes a best effort to check its user | 104 | ``PR_MTE_TCF_SYNC``, the kernel makes a best effort to check its user |
| 105 | address accesses, however it cannot always guarantee it. | 105 | address accesses, however it cannot always guarantee it. Kernel accesses |
| 106 | to user addresses are always performed with an effective ``PSTATE.TCO`` | ||
| 107 | value of zero, regardless of the user configuration. | ||
| 106 | 108 | ||
| 107 | Excluding Tags in the ``IRG``, ``ADDG`` and ``SUBG`` instructions | 109 | Excluding Tags in the ``IRG``, ``ADDG`` and ``SUBG`` instructions |
| 108 | ----------------------------------------------------------------- | 110 | ----------------------------------------------------------------- |
| @@ -90,6 +90,8 @@ stable kernels. · 89 unmodified lines | |||
| 90 | +----------------+-----------------+-----------------+-----------------------------+ | 90 | +----------------+-----------------+-----------------+-----------------------------+ |
| 91 | | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | | 91 | | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | |
| 92 | +----------------+-----------------+-----------------+-----------------------------+ | 92 | +----------------+-----------------+-----------------+-----------------------------+ |
| 93 | | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | | ||
| 94 | +----------------+-----------------+-----------------+-----------------------------+ | ||
| 93 | | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | | 95 | | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | |
| 94 | +----------------+-----------------+-----------------+-----------------------------+ | 96 | +----------------+-----------------+-----------------+-----------------------------+ |
| 95 | | ARM | Neoverse-N1 | #1349291 | N/A | | 97 | | ARM | Neoverse-N1 | #1349291 | N/A | |
| @@ -636,6 +636,26 @@ config ARM64_ERRATUM_1542419 · 635 unmodified lines | |||
| 636 | 636 | ||
| 637 | If unsure, say Y. | 637 | If unsure, say Y. |
| 638 | 638 | ||
| 639 | config ARM64_ERRATUM_1508412 | ||
| 640 | bool "Cortex-A77: 1508412: workaround deadlock on sequence of NC/Device load and store exclusive or PAR read" | ||
| 641 | default y | ||
| 642 | help | ||
| 643 | This option adds a workaround for Arm Cortex-A77 erratum 1508412. | ||
| 644 | |||
| 645 | Affected Cortex-A77 cores (r0p0, r1p0) could deadlock on a sequence | ||
| 646 | of a store-exclusive or read of PAR_EL1 and a load with device or | ||
| 647 | non-cacheable memory attributes. The workaround depends on a firmware | ||
| 648 | counterpart. | ||
| 649 | |||
| 650 | KVM guests must also have the workaround implemented or they can | ||
| 651 | deadlock the system. | ||
| 652 | |||
| 653 | Work around the issue by inserting DMB SY barriers around PAR_EL1 | ||
| 654 | register reads and warning KVM users. The DMB barrier is sufficient | ||
| 655 | to prevent a speculative PAR_EL1 read. | ||
| 656 | |||
| 657 | If unsure, say Y. | ||
| 658 | |||
| 639 | config CAVIUM_ERRATUM_22375 | 659 | config CAVIUM_ERRATUM_22375 |
| 640 | bool "Cavium erratum 22375, 24313" | 660 | bool "Cavium erratum 22375, 24313" |
| 641 | default y | 661 | default y |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | #define CTR_L1IP(ctr) (((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK) | 24 | #define CTR_L1IP(ctr) (((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK) |
| 25 | 25 | ||
| 26 | #define ICACHE_POLICY_VPIPT 0 | 26 | #define ICACHE_POLICY_VPIPT 0 |
| 27 | #define ICACHE_POLICY_RESERVED 1 | ||
| 27 | #define ICACHE_POLICY_VIPT 2 | 28 | #define ICACHE_POLICY_VIPT 2 |
| 28 | #define ICACHE_POLICY_PIPT 3 | 29 | #define ICACHE_POLICY_PIPT 3 |
| 29 | 30 | ||
| @@ -65,7 +65,8 @@ · 64 unmodified lines | |||
| 65 | #define ARM64_HAS_ARMv8_4_TTL 55 | 65 | #define ARM64_HAS_ARMv8_4_TTL 55 |
| 66 | #define ARM64_HAS_TLB_RANGE 56 | 66 | #define ARM64_HAS_TLB_RANGE 56 |
| 67 | #define ARM64_MTE 57 | 67 | #define ARM64_MTE 57 |
| 68 | #define ARM64_WORKAROUND_1508412 58 | ||
| 68 | 69 | ||
| 69 | #define ARM64_NCAPS 58 | 70 | #define ARM64_NCAPS 59 |
| 70 | 71 | ||
| 71 | #endif /* __ASM_CPUCAPS_H */ | 72 | #endif /* __ASM_CPUCAPS_H */ |
| @@ -71,6 +71,7 @@ · 70 unmodified lines | |||
| 71 | #define ARM_CPU_PART_CORTEX_A55 0xD05 | 71 | #define ARM_CPU_PART_CORTEX_A55 0xD05 |
| 72 | #define ARM_CPU_PART_CORTEX_A76 0xD0B | 72 | #define ARM_CPU_PART_CORTEX_A76 0xD0B |
| 73 | #define ARM_CPU_PART_NEOVERSE_N1 0xD0C | 73 | #define ARM_CPU_PART_NEOVERSE_N1 0xD0C |
| 74 | #define ARM_CPU_PART_CORTEX_A77 0xD0D | ||
| 74 | 75 | ||
| 75 | #define APM_CPU_PART_POTENZA 0x000 | 76 | #define APM_CPU_PART_POTENZA 0x000 |
| 76 | 77 | ||
| @@ -105,6 +106,7 @@ · 28 unmodified lines | |||
| 105 | #define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55) | 106 | #define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55) |
| 106 | #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) | 107 | #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) |
| 107 | #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) | 108 | #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) |
| 109 | #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) | ||
| 108 | #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) | 110 | #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) |
| 109 | #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) | 111 | #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) |
| 110 | #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) | 112 | #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) |
| @@ -1007,6 +1007,7 @@ · 1006 unmodified lines | |||
| 1007 | 1007 | ||
| 1008 | #include <linux/build_bug.h> | 1008 | #include <linux/build_bug.h> |
| 1009 | #include <linux/types.h> | 1009 | #include <linux/types.h> |
| 1010 | #include <asm/alternative.h> | ||
| 1010 | 1011 | ||
| 1011 | #define __DEFINE_MRS_MSR_S_REGNUM \ | 1012 | #define __DEFINE_MRS_MSR_S_REGNUM \ |
| 1012 | " .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30\n" \ | 1013 | " .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30\n" \ |
| @@ -1095,6 +1096,14 @@ · 82 unmodified lines | |||
| 1095 | write_sysreg_s(__scs_new, sysreg); \ | 1096 | write_sysreg_s(__scs_new, sysreg); \ |
| 1096 | } while (0) | 1097 | } while (0) |
| 1097 | 1098 | ||
| 1099 | #define read_sysreg_par() ({ \ | ||
| 1100 | u64 par; \ | ||
| 1101 | asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412)); \ | ||
| 1102 | par = read_sysreg(par_el1); \ | ||
| 1103 | asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412)); \ | ||
| 1104 | par; \ | ||
| 1105 | }) | ||
| 1106 | |||
| 1098 | #endif | 1107 | #endif |
| 1099 | 1108 | ||
| 1100 | #endif /* __ASM_SYSREG_H */ | 1109 | #endif /* __ASM_SYSREG_H */ |
| @@ -522,6 +522,16 @@ const struct arm64_cpu_capabilities arm64_errata[] = { · 521 unmodified lines | |||
| 522 | .matches = has_neoverse_n1_erratum_1542419, | 522 | .matches = has_neoverse_n1_erratum_1542419, |
| 523 | .cpu_enable = cpu_enable_trap_ctr_access, | 523 | .cpu_enable = cpu_enable_trap_ctr_access, |
| 524 | }, | 524 | }, |
| 525 | #endif | ||
| 526 | #ifdef CONFIG_ARM64_ERRATUM_1508412 | ||
| 527 | { | ||
| 528 | /* we depend on the firmware portion for correctness */ | ||
| 529 | .desc = "ARM erratum 1508412 (kernel portion)", | ||
| 530 | .capability = ARM64_WORKAROUND_1508412, | ||
| 531 | ERRATA_MIDR_RANGE(MIDR_CORTEX_A77, | ||
| 532 | 0, 0, | ||
| 533 | 1, 0), | ||
| 534 | }, | ||
| 525 | #endif | 535 | #endif |
| 526 | { | 536 | { |
| 527 | } | 537 | } |
| @@ -34,10 +34,10 @@ DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); · 33 unmodified lines | |||
| 34 | static struct cpuinfo_arm64 boot_cpu_data; | 34 | static struct cpuinfo_arm64 boot_cpu_data; |
| 35 | 35 | ||
| 36 | static const char *icache_policy_str[] = { | 36 | static const char *icache_policy_str[] = { |
| 37 | [0 ... ICACHE_POLICY_PIPT] = "RESERVED/UNKNOWN", | 37 | [ICACHE_POLICY_VPIPT] = "VPIPT", |
| 38 | [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN", | ||
| 38 | [ICACHE_POLICY_VIPT] = "VIPT", | 39 | [ICACHE_POLICY_VIPT] = "VIPT", |
| 39 | [ICACHE_POLICY_PIPT] = "PIPT", | 40 | [ICACHE_POLICY_PIPT] = "PIPT", |
| 40 | [ICACHE_POLICY_VPIPT] = "VPIPT", | ||
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | unsigned long __icache_flags; | 43 | unsigned long __icache_flags; |
| @@ -334,10 +334,11 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) · 290 unmodified lines | |||
| 334 | case ICACHE_POLICY_VPIPT: | 334 | case ICACHE_POLICY_VPIPT: |
| 335 | set_bit(ICACHEF_VPIPT, &__icache_flags); | 335 | set_bit(ICACHEF_VPIPT, &__icache_flags); |
| 336 | break; | 336 | break; |
| 337 | default: | 337 | case ICACHE_POLICY_RESERVED: |
| 338 | case ICACHE_POLICY_VIPT: | 338 | case ICACHE_POLICY_VIPT: |
| 339 | /* Assume aliasing */ | 339 | /* Assume aliasing */ |
| 340 | set_bit(ICACHEF_ALIASING, &__icache_flags); | 340 | set_bit(ICACHEF_ALIASING, &__icache_flags); |
| 341 | break; | ||
| 341 | } | 342 | } |
| 342 | 343 | ||
| 343 | pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); | 344 | pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); |
| @@ -147,6 +147,6 @@ efi_debug_entry: · 146 unmodified lines | |||
| 147 | * correctly at this alignment, we must ensure that .text is | 147 | * correctly at this alignment, we must ensure that .text is |
| 148 | * placed at a 4k boundary in the Image to begin with. | 148 | * placed at a 4k boundary in the Image to begin with. |
| 149 | */ | 149 | */ |
| 150 | .align 12 | 150 | .balign SEGMENT_ALIGN |
| 151 | efi_header_end: | 151 | efi_header_end: |
| 152 | .endm | 152 | .endm |
| @@ -365,6 +365,9 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 · 364 unmodified lines | |||
| 365 | br x30 | 365 | br x30 |
| 366 | #endif | 366 | #endif |
| 367 | .else | 367 | .else |
| 368 | /* Ensure any device/NC reads complete */ | ||
| 369 | alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412 | ||
| 370 | |||
| 368 | eret | 371 | eret |
| 369 | .endif | 372 | .endif |
| 370 | sb | 373 | sb |
| @@ -135,8 +135,6 @@ static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void) · 134 unmodified lines | |||
| 135 | return SPECTRE_VULNERABLE; | 135 | return SPECTRE_VULNERABLE; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED (1) | ||
| 139 | |||
| 140 | static enum mitigation_state spectre_v2_get_cpu_fw_mitigation_state(void) | 138 | static enum mitigation_state spectre_v2_get_cpu_fw_mitigation_state(void) |
| 141 | { | 139 | { |
| 142 | int ret; | 140 | int ret; |
| @@ -222,6 +222,7 @@ asmlinkage notrace void secondary_start_kernel(void) · 221 unmodified lines | |||
| 222 | if (system_uses_irq_prio_masking()) | 222 | if (system_uses_irq_prio_masking()) |
| 223 | init_gic_priority_masking(); | 223 | init_gic_priority_masking(); |
| 224 | 224 | ||
| 225 | rcu_cpu_starting(cpu); | ||
| 225 | preempt_disable(); | 226 | preempt_disable(); |
| 226 | trace_hardirqs_off(); | 227 | trace_hardirqs_off(); |
| 227 | 228 | ||
| @@ -22,16 +22,21 @@ endif · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | CC_COMPAT ?= $(CC) | 23 | CC_COMPAT ?= $(CC) |
| 24 | CC_COMPAT += $(CC_COMPAT_CLANG_FLAGS) | 24 | CC_COMPAT += $(CC_COMPAT_CLANG_FLAGS) |
| 25 | |||
| 26 | ifneq ($(LLVM),) | ||
| 27 | LD_COMPAT ?= $(LD) | ||
| 28 | else | ||
| 29 | LD_COMPAT ?= $(CROSS_COMPILE_COMPAT)ld | ||
| 30 | endif | ||
| 25 | else | 31 | else |
| 26 | CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc | 32 | CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc |
| 33 | LD_COMPAT ?= $(CROSS_COMPILE_COMPAT)ld | ||
| 27 | endif | 34 | endif |
| 28 | 35 | ||
| 29 | cc32-option = $(call try-run,\ | 36 | cc32-option = $(call try-run,\ |
| 30 | $(CC_COMPAT) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) | 37 | $(CC_COMPAT) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) |
| 31 | cc32-disable-warning = $(call try-run,\ | 38 | cc32-disable-warning = $(call try-run,\ |
| 32 | $(CC_COMPAT) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) | 39 | $(CC_COMPAT) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) |
| 33 | cc32-ldoption = $(call try-run,\ | ||
| 34 | $(CC_COMPAT) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) | ||
| 35 | cc32-as-instr = $(call try-run,\ | 40 | cc32-as-instr = $(call try-run,\ |
| 36 | printf "%b\n" "$(1)" | $(CC_COMPAT) $(VDSO_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) | 41 | printf "%b\n" "$(1)" | $(CC_COMPAT) $(VDSO_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) |
| 37 | 42 | ||
| @@ -122,14 +127,10 @@ dmbinstr := $(call cc32-as-instr,dmb ishld,-DCONFIG_AS_DMB_ISHLD=1) · 84 unmodified lines | |||
| 122 | VDSO_CFLAGS += $(dmbinstr) | 127 | VDSO_CFLAGS += $(dmbinstr) |
| 123 | VDSO_AFLAGS += $(dmbinstr) | 128 | VDSO_AFLAGS += $(dmbinstr) |
| 124 | 129 | ||
| 125 | VDSO_LDFLAGS := $(VDSO_CPPFLAGS) | ||
| 126 | # From arm vDSO Makefile | 130 | # From arm vDSO Makefile |
| 127 | VDSO_LDFLAGS += -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 | 131 | VDSO_LDFLAGS += -Bsymbolic --no-undefined -soname=linux-vdso.so.1 |
| 128 | VDSO_LDFLAGS += -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 | 132 | VDSO_LDFLAGS += -z max-page-size=4096 -z common-page-size=4096 |
| 129 | VDSO_LDFLAGS += -nostdlib -shared -mfloat-abi=soft | 133 | VDSO_LDFLAGS += -nostdlib -shared --hash-style=sysv --build-id=sha1 |
| 130 | VDSO_LDFLAGS += -Wl,--hash-style=sysv | ||
| 131 | VDSO_LDFLAGS += -Wl,--build-id=sha1 | ||
| 132 | VDSO_LDFLAGS += $(call cc32-ldoption,-fuse-ld=bfd) | ||
| 133 | 134 | ||
| 134 | 135 | ||
| 135 | # Borrow vdsomunge.c from the arm vDSO | 136 | # Borrow vdsomunge.c from the arm vDSO |
| @@ -189,8 +190,8 @@ quiet_cmd_vdsold_and_vdso_check = LD32 $@ · 53 unmodified lines | |||
| 189 | cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check) | 190 | cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check) |
| 190 | 191 | ||
| 191 | quiet_cmd_vdsold = LD32 $@ | 192 | quiet_cmd_vdsold = LD32 $@ |
| 192 | cmd_vdsold = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_LDFLAGS) \ | 193 | cmd_vdsold = $(LD_COMPAT) $(VDSO_LDFLAGS) \ |
| 193 | -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ | 194 | -T $(filter %.lds,$^) $(filter %.o,$^) -o $@ |
| 194 | quiet_cmd_vdsocc = CC32 $@ | 195 | quiet_cmd_vdsocc = CC32 $@ |
| 195 | cmd_vdsocc = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $< | 196 | cmd_vdsocc = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $< |
| 196 | quiet_cmd_vdsocc_gettimeofday = CC32 $@ | 197 | quiet_cmd_vdsocc_gettimeofday = CC32 $@ |
| @@ -278,7 +278,7 @@ SECTIONS · 277 unmodified lines | |||
| 278 | * explicitly check instead of blindly discarding. | 278 | * explicitly check instead of blindly discarding. |
| 279 | */ | 279 | */ |
| 280 | .plt : { | 280 | .plt : { |
| 281 | *(.plt) *(.plt.*) *(.iplt) *(.igot) | 281 | *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt) |
| 282 | } | 282 | } |
| 283 | ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!") | 283 | ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!") |
| 284 | 284 | ||
| @@ -1719,7 +1719,8 @@ int kvm_arch_init(void *opaque) · 1718 unmodified lines | |||
| 1719 | return -ENODEV; | 1719 | return -ENODEV; |
| 1720 | } | 1720 | } |
| 1721 | 1721 | ||
| 1722 | if (cpus_have_final_cap(ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)) | 1722 | if (cpus_have_final_cap(ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE) || |
| 1723 | cpus_have_final_cap(ARM64_WORKAROUND_1508412)) | ||
| 1723 | kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \ | 1724 | kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \ |
| 1724 | "Only trusted guests should be used on this system.\n"); | 1725 | "Only trusted guests should be used on this system.\n"); |
| 1725 | 1726 | ||
| @@ -140,9 +140,9 @@ static inline bool __translate_far_to_hpfar(u64 far, u64 *hpfar) · 139 unmodified lines | |||
| 140 | * We do need to save/restore PAR_EL1 though, as we haven't | 140 | * We do need to save/restore PAR_EL1 though, as we haven't |
| 141 | * saved the guest context yet, and we may return early... | 141 | * saved the guest context yet, and we may return early... |
| 142 | */ | 142 | */ |
| 143 | par = read_sysreg(par_el1); | 143 | par = read_sysreg_par(); |
| 144 | if (!__kvm_at("s1e1r", far)) | 144 | if (!__kvm_at("s1e1r", far)) |
| 145 | tmp = read_sysreg(par_el1); | 145 | tmp = read_sysreg_par(); |
| 146 | else | 146 | else |
| 147 | tmp = SYS_PAR_EL1_F; /* back to the guest */ | 147 | tmp = SYS_PAR_EL1_F; /* back to the guest */ |
| 148 | write_sysreg(par, par_el1); | 148 | write_sysreg(par, par_el1); |
| @@ -421,7 +421,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) · 272 unmodified lines | |||
| 421 | if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) && | 421 | if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) && |
| 422 | kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 && | 422 | kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 && |
| 423 | handle_tx2_tvm(vcpu)) | 423 | handle_tx2_tvm(vcpu)) |
| 424 | return true; | 424 | goto guest; |
| 425 | 425 | ||
| 426 | /* | 426 | /* |
| 427 | * We trap the first access to the FP/SIMD to save the host context | 427 | * We trap the first access to the FP/SIMD to save the host context |
| @@ -431,13 +431,13 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) · 3 unmodified lines | |||
| 431 | * Similarly for trapped SVE accesses. | 431 | * Similarly for trapped SVE accesses. |
| 432 | */ | 432 | */ |
| 433 | if (__hyp_handle_fpsimd(vcpu)) | 433 | if (__hyp_handle_fpsimd(vcpu)) |
| 434 | return true; | 434 | goto guest; |
| 435 | 435 | ||
| 436 | if (__hyp_handle_ptrauth(vcpu)) | 436 | if (__hyp_handle_ptrauth(vcpu)) |
| 437 | return true; | 437 | goto guest; |
| 438 | 438 | ||
| 439 | if (!__populate_fault_info(vcpu)) | 439 | if (!__populate_fault_info(vcpu)) |
| 440 | return true; | 440 | goto guest; |
| 441 | 441 | ||
| 442 | if (static_branch_unlikely(&vgic_v2_cpuif_trap)) { | 442 | if (static_branch_unlikely(&vgic_v2_cpuif_trap)) { |
| 443 | bool valid; | 443 | bool valid; |
| @@ -452,7 +452,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) · 8 unmodified lines | |||
| 452 | int ret = __vgic_v2_perform_cpuif_access(vcpu); | 452 | int ret = __vgic_v2_perform_cpuif_access(vcpu); |
| 453 | 453 | ||
| 454 | if (ret == 1) | 454 | if (ret == 1) |
| 455 | return true; | 455 | goto guest; |
| 456 | 456 | ||
| 457 | /* Promote an illegal access to an SError.*/ | 457 | /* Promote an illegal access to an SError.*/ |
| 458 | if (ret == -1) | 458 | if (ret == -1) |
| @@ -468,12 +468,17 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) · 9 unmodified lines | |||
| 468 | int ret = __vgic_v3_perform_cpuif_access(vcpu); | 468 | int ret = __vgic_v3_perform_cpuif_access(vcpu); |
| 469 | 469 | ||
| 470 | if (ret == 1) | 470 | if (ret == 1) |
| 471 | return true; | 471 | goto guest; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | exit: | 474 | exit: |
| 475 | /* Return to the host kernel and handle the exit */ | 475 | /* Return to the host kernel and handle the exit */ |
| 476 | return false; | 476 | return false; |
| 477 | |||
| 478 | guest: | ||
| 479 | /* Re-enter the guest */ | ||
| 480 | asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412)); | ||
| 481 | return true; | ||
| 477 | } | 482 | } |
| 478 | 483 | ||
| 479 | static inline void __kvm_unexpected_el2_exception(void) | 484 | static inline void __kvm_unexpected_el2_exception(void) |
| @@ -43,7 +43,7 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) · 42 unmodified lines | |||
| 43 | ctxt_sys_reg(ctxt, CONTEXTIDR_EL1) = read_sysreg_el1(SYS_CONTEXTIDR); | 43 | ctxt_sys_reg(ctxt, CONTEXTIDR_EL1) = read_sysreg_el1(SYS_CONTEXTIDR); |
| 44 | ctxt_sys_reg(ctxt, AMAIR_EL1) = read_sysreg_el1(SYS_AMAIR); | 44 | ctxt_sys_reg(ctxt, AMAIR_EL1) = read_sysreg_el1(SYS_AMAIR); |
| 45 | ctxt_sys_reg(ctxt, CNTKCTL_EL1) = read_sysreg_el1(SYS_CNTKCTL); | 45 | ctxt_sys_reg(ctxt, CNTKCTL_EL1) = read_sysreg_el1(SYS_CNTKCTL); |
| 46 | ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg(par_el1); | 46 | ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg_par(); |
| 47 | ctxt_sys_reg(ctxt, TPIDR_EL1) = read_sysreg(tpidr_el1); | 47 | ctxt_sys_reg(ctxt, TPIDR_EL1) = read_sysreg(tpidr_el1); |
| 48 | 48 | ||
| 49 | ctxt_sys_reg(ctxt, SP_EL1) = read_sysreg(sp_el1); | 49 | ctxt_sys_reg(ctxt, SP_EL1) = read_sysreg(sp_el1); |
| @@ -250,7 +250,7 @@ void __noreturn hyp_panic(void) · 249 unmodified lines | |||
| 250 | { | 250 | { |
| 251 | u64 spsr = read_sysreg_el2(SYS_SPSR); | 251 | u64 spsr = read_sysreg_el2(SYS_SPSR); |
| 252 | u64 elr = read_sysreg_el2(SYS_ELR); | 252 | u64 elr = read_sysreg_el2(SYS_ELR); |
| 253 | u64 par = read_sysreg(par_el1); | 253 | u64 par = read_sysreg_par(); |
| 254 | bool restore_host = true; | 254 | bool restore_host = true; |
| 255 | struct kvm_cpu_context *host_ctxt; | 255 | struct kvm_cpu_context *host_ctxt; |
| 256 | struct kvm_vcpu *vcpu; | 256 | struct kvm_vcpu *vcpu; |
| @@ -215,7 +215,7 @@ void __noreturn hyp_panic(void) · 214 unmodified lines | |||
| 215 | { | 215 | { |
| 216 | u64 spsr = read_sysreg_el2(SYS_SPSR); | 216 | u64 spsr = read_sysreg_el2(SYS_SPSR); |
| 217 | u64 elr = read_sysreg_el2(SYS_ELR); | 217 | u64 elr = read_sysreg_el2(SYS_ELR); |
| 218 | u64 par = read_sysreg(par_el1); | 218 | u64 par = read_sysreg_par(); |
| 219 | 219 | ||
| 220 | __hyp_call_panic(spsr, elr, par); | 220 | __hyp_call_panic(spsr, elr, par); |
| 221 | unreachable(); | 221 | unreachable(); |
| @@ -31,7 +31,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) · 30 unmodified lines | |||
| 31 | val = SMCCC_RET_SUCCESS; | 31 | val = SMCCC_RET_SUCCESS; |
| 32 | break; | 32 | break; |
| 33 | case SPECTRE_UNAFFECTED: | 33 | case SPECTRE_UNAFFECTED: |
| 34 | val = SMCCC_RET_NOT_REQUIRED; | 34 | val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; |
| 35 | break; | 35 | break; |
| 36 | } | 36 | } |
| 37 | break; | 37 | break; |
| @@ -95,7 +95,7 @@ static bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val) · 94 unmodified lines | |||
| 95 | case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break; | 95 | case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break; |
| 96 | case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break; | 96 | case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break; |
| 97 | case ELR_EL1: *val = read_sysreg_s(SYS_ELR_EL12); break; | 97 | case ELR_EL1: *val = read_sysreg_s(SYS_ELR_EL12); break; |
| 98 | case PAR_EL1: *val = read_sysreg_s(SYS_PAR_EL1); break; | 98 | case PAR_EL1: *val = read_sysreg_par(); break; |
| 99 | case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break; | 99 | case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break; |
| 100 | case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break; | 100 | case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break; |
| 101 | case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break; | 101 | case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break; |
| @@ -56,9 +56,8 @@ · 55 unmodified lines | |||
| 56 | stp \reg1, \reg2, [\ptr], \val | 56 | stp \reg1, \reg2, [\ptr], \val |
| 57 | .endm | 57 | .endm |
| 58 | 58 | ||
| 59 | .weak memcpy | ||
| 60 | SYM_FUNC_START_ALIAS(__memcpy) | 59 | SYM_FUNC_START_ALIAS(__memcpy) |
| 61 | SYM_FUNC_START_PI(memcpy) | 60 | SYM_FUNC_START_WEAK_PI(memcpy) |
| 62 | #include "copy_template.S" | 61 | #include "copy_template.S" |
| 63 | ret | 62 | ret |
| 64 | SYM_FUNC_END_PI(memcpy) | 63 | SYM_FUNC_END_PI(memcpy) |
| @@ -45,9 +45,8 @@ C_h .req x12 · 44 unmodified lines | |||
| 45 | D_l .req x13 | 45 | D_l .req x13 |
| 46 | D_h .req x14 | 46 | D_h .req x14 |
| 47 | 47 | ||
| 48 | .weak memmove | ||
| 49 | SYM_FUNC_START_ALIAS(__memmove) | 48 | SYM_FUNC_START_ALIAS(__memmove) |
| 50 | SYM_FUNC_START_PI(memmove) | 49 | SYM_FUNC_START_WEAK_PI(memmove) |
| 51 | cmp dstin, src | 50 | cmp dstin, src |
| 52 | b.lo __memcpy | 51 | b.lo __memcpy |
| 53 | add tmp1, src, count | 52 | add tmp1, src, count |
| @@ -42,9 +42,8 @@ dst .req x8 · 41 unmodified lines | |||
| 42 | tmp3w .req w9 | 42 | tmp3w .req w9 |
| 43 | tmp3 .req x9 | 43 | tmp3 .req x9 |
| 44 | 44 | ||
| 45 | .weak memset | ||
| 46 | SYM_FUNC_START_ALIAS(__memset) | 45 | SYM_FUNC_START_ALIAS(__memset) |
| 47 | SYM_FUNC_START_PI(memset) | 46 | SYM_FUNC_START_WEAK_PI(memset) |
| 48 | mov dst, dstin /* Preserve return value. */ | 47 | mov dst, dstin /* Preserve return value. */ |
| 49 | and A_lw, val, #255 | 48 | and A_lw, val, #255 |
| 50 | orr A_lw, A_lw, A_lw, lsl #8 | 49 | orr A_lw, A_lw, A_lw, lsl #8 |
| @@ -262,7 +262,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr, · 261 unmodified lines | |||
| 262 | local_irq_save(flags); | 262 | local_irq_save(flags); |
| 263 | asm volatile("at s1e1r, %0" :: "r" (addr)); | 263 | asm volatile("at s1e1r, %0" :: "r" (addr)); |
| 264 | isb(); | 264 | isb(); |
| 265 | par = read_sysreg(par_el1); | 265 | par = read_sysreg_par(); |
| 266 | local_irq_restore(flags); | 266 | local_irq_restore(flags); |
| 267 | 267 | ||
| 268 | /* | 268 | /* |
| @@ -87,6 +87,8 @@ · 86 unmodified lines | |||
| 87 | ARM_SMCCC_SMC_32, \ | 87 | ARM_SMCCC_SMC_32, \ |
| 88 | 0, 0x7fff) | 88 | 0, 0x7fff) |
| 89 | 89 | ||
| 90 | #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1 | ||
| 91 | |||
| 90 | /* Paravirtualised time calls (defined by ARM DEN0057A) */ | 92 | /* Paravirtualised time calls (defined by ARM DEN0057A) */ |
| 91 | #define ARM_SMCCC_HV_PV_TIME_FEATURES \ | 93 | #define ARM_SMCCC_HV_PV_TIME_FEATURES \ |
| 92 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | 94 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ |
| @@ -740,7 +740,7 @@ static inline bool within_module(unsigned long addr, const struct module *mod) · 739 unmodified lines | |||
| 740 | } | 740 | } |
| 741 | 741 | ||
| 742 | /* Get/put a kernel symbol (calls should be symmetric) */ | 742 | /* Get/put a kernel symbol (calls should be symmetric) */ |
| 743 | #define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) | 743 | #define symbol_get(x) ({ extern typeof(x) x __attribute__((weak,visibility("hidden"))); &(x); }) |
| 744 | #define symbol_put(x) do { } while (0) | 744 | #define symbol_put(x) do { } while (0) |
| 745 | #define symbol_put_addr(x) do { } while (0) | 745 | #define symbol_put_addr(x) do { } while (0) |
| 746 | 746 | ||
| @@ -417,6 +417,9 @@ int main(int argc, char *argv[]) · 416 unmodified lines | |||
| 417 | /* Register SIGSEGV handler */ | 417 | /* Register SIGSEGV handler */ |
| 418 | mte_register_signal(SIGSEGV, mte_default_handler); | 418 | mte_register_signal(SIGSEGV, mte_default_handler); |
| 419 | 419 | ||
| 420 | /* Set test plan */ | ||
| 421 | ksft_set_plan(20); | ||
| 422 | |||
| 420 | /* Buffer by byte tests */ | 423 | /* Buffer by byte tests */ |
| 421 | evaluate_test(check_buffer_by_byte(USE_MMAP, MTE_SYNC_ERR), | 424 | evaluate_test(check_buffer_by_byte(USE_MMAP, MTE_SYNC_ERR), |
| 422 | "Check buffer correctness by byte with sync err mode and mmap memory\n"); | 425 | "Check buffer correctness by byte with sync err mode and mmap memory\n"); |
| @@ -163,6 +163,9 @@ int main(int argc, char *argv[]) · 162 unmodified lines | |||
| 163 | mte_register_signal(SIGSEGV, mte_default_handler); | 163 | mte_register_signal(SIGSEGV, mte_default_handler); |
| 164 | mte_register_signal(SIGBUS, mte_default_handler); | 164 | mte_register_signal(SIGBUS, mte_default_handler); |
| 165 | 165 | ||
| 166 | /* Set test plan */ | ||
| 167 | ksft_set_plan(12); | ||
| 168 | |||
| 166 | evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE), | 169 | evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE), |
| 167 | "Check child anonymous memory with private mapping, precise mode and mmap memory\n"); | 170 | "Check child anonymous memory with private mapping, precise mode and mmap memory\n"); |
| 168 | evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED), | 171 | evaluate_test(check_child_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED), |
| @@ -140,6 +140,10 @@ int main(int argc, char *argv[]) · 139 unmodified lines | |||
| 140 | /* Register signal handlers */ | 140 | /* Register signal handlers */ |
| 141 | mte_register_signal(SIGBUS, mte_default_handler); | 141 | mte_register_signal(SIGBUS, mte_default_handler); |
| 142 | mte_register_signal(SIGSEGV, mte_default_handler); | 142 | mte_register_signal(SIGSEGV, mte_default_handler); |
| 143 | |||
| 144 | /* Set test plan */ | ||
| 145 | ksft_set_plan(4); | ||
| 146 | |||
| 143 | /* Enable KSM */ | 147 | /* Enable KSM */ |
| 144 | mte_ksm_setup(); | 148 | mte_ksm_setup(); |
| 145 | 149 | ||
| @@ -205,7 +205,11 @@ int main(int argc, char *argv[]) · 204 unmodified lines | |||
| 205 | mte_register_signal(SIGBUS, mte_default_handler); | 205 | mte_register_signal(SIGBUS, mte_default_handler); |
| 206 | mte_register_signal(SIGSEGV, mte_default_handler); | 206 | mte_register_signal(SIGSEGV, mte_default_handler); |
| 207 | 207 | ||
| 208 | /* Set test plan */ | ||
| 209 | ksft_set_plan(22); | ||
| 210 | |||
| 208 | mte_enable_pstate_tco(); | 211 | mte_enable_pstate_tco(); |
| 212 | |||
| 209 | evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF), | 213 | evaluate_test(check_anonymous_memory_mapping(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF), |
| 210 | "Check anonymous memory with private mapping, sync error mode, mmap memory and tag check off\n"); | 214 | "Check anonymous memory with private mapping, sync error mode, mmap memory and tag check off\n"); |
| 211 | evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF), | 215 | evaluate_test(check_file_memory_mapping(USE_MPROTECT, MTE_SYNC_ERR, MAP_PRIVATE, TAG_CHECK_OFF), |
| @@ -170,6 +170,9 @@ int main(int argc, char *argv[]) · 169 unmodified lines | |||
| 170 | /* Register SIGSEGV handler */ | 170 | /* Register SIGSEGV handler */ |
| 171 | mte_register_signal(SIGSEGV, mte_default_handler); | 171 | mte_register_signal(SIGSEGV, mte_default_handler); |
| 172 | 172 | ||
| 173 | /* Set test plan */ | ||
| 174 | ksft_set_plan(4); | ||
| 175 | |||
| 173 | evaluate_test(check_single_included_tags(USE_MMAP, MTE_SYNC_ERR), | 176 | evaluate_test(check_single_included_tags(USE_MMAP, MTE_SYNC_ERR), |
| 174 | "Check an included tag value with sync mode\n"); | 177 | "Check an included tag value with sync mode\n"); |
| 175 | evaluate_test(check_multiple_included_tags(USE_MMAP, MTE_SYNC_ERR), | 178 | evaluate_test(check_multiple_included_tags(USE_MMAP, MTE_SYNC_ERR), |
| @@ -92,9 +92,13 @@ int main(int argc, char *argv[]) · 91 unmodified lines | |||
| 92 | err = mte_default_setup(); | 92 | err = mte_default_setup(); |
| 93 | if (err) | 93 | if (err) |
| 94 | return err; | 94 | return err; |
| 95 | |||
| 95 | /* Register signal handlers */ | 96 | /* Register signal handlers */ |
| 96 | mte_register_signal(SIGSEGV, mte_default_handler); | 97 | mte_register_signal(SIGSEGV, mte_default_handler); |
| 97 | 98 | ||
| 99 | /* Set test plan */ | ||
| 100 | ksft_set_plan(4); | ||
| 101 | |||
| 98 | evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE), | 102 | evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE), |
| 99 | "Check memory access from kernel in sync mode, private mapping and mmap memory\n"); | 103 | "Check memory access from kernel in sync mode, private mapping and mmap memory\n"); |
| 100 | evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED), | 104 | evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED), |