Commit 3346c566 authored by Catalin Marinas's avatar Catalin Marinas

Merge branches 'for-next/cpufeature', 'for-next/misc', 'for-next/kselftest',...

Merge branches 'for-next/cpufeature', 'for-next/misc', 'for-next/kselftest', 'for-next/mte', 'for-next/errata', 'for-next/acpi', 'for-next/gic-v3-pmr' and 'for-next/doc', remote-tracking branch 'arm64/for-next/perf' into for-next/core

* arm64/for-next/perf:
  perf: add missing MODULE_DESCRIPTION() macros
  perf: arm_pmuv3: Include asm/arm_pmuv3.h from linux/perf/arm_pmuv3.h
  perf: arm_v6/7_pmu: Drop non-DT probe support
  perf/arm: Move 32-bit PMU drivers to drivers/perf/
  perf: arm_pmuv3: Drop unnecessary IS_ENABLED(CONFIG_ARM64) check
  perf: arm_pmuv3: Avoid assigning fixed cycle counter with threshold
  perf: imx_perf: add support for i.MX95 platform
  perf: imx_perf: fix counter start and config sequence
  perf: imx_perf: refactor driver for imx93
  perf: imx_perf: let the driver manage the counter usage rather the user
  perf: imx_perf: add macro definitions for parsing config attr
  dt-bindings: perf: fsl-imx-ddr: Add i.MX95 compatible
  perf: pmuv3: Add new Cortex and Neoverse PMUs
  dt-bindings: arm: pmu: Add new Cortex and Neoverse cores
  perf/arm-cmn: Enable support for tertiary match group
  perf/arm-cmn: Decouple wp_config registers from filter group number

* for-next/cpufeature:
  : Various cpufeature infrastructure patches
  arm64/cpufeature: Replace custom macros with fields from ID_AA64PFR0_EL1
  KVM: arm64: Replace custom macros with fields from ID_AA64PFR0_EL1
  arm64/cpufeatures/kvm: Add ARMv8.9 FEAT_ECBHB bits in ID_AA64MMFR1 register

* for-next/misc:
  : Miscellaneous patches
  arm64: smp: Fix missing IPI statistics
  arm64: Cleanup __cpu_set_tcr_t0sz()
  arm64/mm: Stop using ESR_ELx_FSC_TYPE during fault
  arm64: Kconfig: fix typo in __builtin_return_adddress
  ARM64: reloc_test: add missing MODULE_DESCRIPTION() macro
  arm64: implement raw_smp_processor_id() using thread_info
  arm64/arch_timer: include <linux/percpu.h>

* for-next/kselftest:
  : arm64 kselftest updates
  selftests: arm64: tags: remove the result script
  selftests: arm64: tags_test: conform test to TAP output
  kselftest/arm64: Fix a couple of spelling mistakes
  kselftest/arm64: Fix redundancy of a testcase
  kselftest/arm64: Include kernel mode NEON in fp-stress

* for-next/mte:
  : MTE updates
  arm64: mte: Make mte_check_tfsr_*() conditional on KASAN instead of MTE

* for-next/errata:
  : Arm CPU errata workarounds
  arm64: errata: Expand speculative SSBS workaround
  arm64: errata: Unify speculative SSBS errata logic
  arm64: cputype: Add Cortex-X925 definitions
  arm64: cputype: Add Cortex-A720 definitions
  arm64: cputype: Add Cortex-X3 definitions

* for-next/acpi:
  : arm64 ACPI patches
  ACPI: Add acpi=nospcr to disable ACPI SPCR as default console on ARM64
  ACPI / amba: Drop unnecessary check for registered amba_dummy_clk
  arm64: FFH: Move ACPI specific code into drivers/acpi/arm64/
  arm64: cpuidle: Move ACPI specific code into drivers/acpi/arm64/
  ACPI: arm64: Sort entries alphabetically

* for-next/gic-v3-pmr:
  : arm64: irqchip/gic-v3: Use compiletime constant PMR values
  arm64: irqchip/gic-v3: Select priorities at boot time
  irqchip/gic-v3: Detect GICD_CTRL.DS and SCR_EL3.FIQ earlier
  irqchip/gic-v3: Make distributor priorities variables
  irqchip/gic-common: Remove sync_access callback
  wordpart.h: Add REPEAT_BYTE_U32()

* for-next/doc:
  : arm64 documentation updates
  Documentation: arm64: Update memory.rst for TBI
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
acpi= [HW,ACPI,X86,ARM64,RISCV64,EARLY] acpi= [HW,ACPI,X86,ARM64,RISCV64,EARLY]
Advanced Configuration and Power Interface Advanced Configuration and Power Interface
Format: { force | on | off | strict | noirq | rsdt | Format: { force | on | off | strict | noirq | rsdt |
copy_dsdt } copy_dsdt | nospcr }
force -- enable ACPI if default was off force -- enable ACPI if default was off
on -- enable ACPI but allow fallback to DT [arm64,riscv64] on -- enable ACPI but allow fallback to DT [arm64,riscv64]
off -- disable ACPI if default was on off -- disable ACPI if default was on
...@@ -21,8 +21,12 @@ ...@@ -21,8 +21,12 @@
strictly ACPI specification compliant. strictly ACPI specification compliant.
rsdt -- prefer RSDT over (default) XSDT rsdt -- prefer RSDT over (default) XSDT
copy_dsdt -- copy DSDT to memory copy_dsdt -- copy DSDT to memory
For ARM64 and RISCV64, ONLY "acpi=off", "acpi=on" or nospcr -- disable console in ACPI SPCR table as
"acpi=force" are available default _serial_ console on ARM64
For ARM64, ONLY "acpi=off", "acpi=on", "acpi=force" or
"acpi=nospcr" are available
For RISCV64, ONLY "acpi=off", "acpi=on" or "acpi=force"
are available
See also Documentation/power/runtime_pm.rst, pci=noacpi See also Documentation/power/runtime_pm.rst, pci=noacpi
......
...@@ -18,12 +18,10 @@ ARMv8.2 adds optional support for Large Virtual Address space. This is ...@@ -18,12 +18,10 @@ ARMv8.2 adds optional support for Large Virtual Address space. This is
only available when running with a 64KB page size and expands the only available when running with a 64KB page size and expands the
number of descriptors in the first level of translation. number of descriptors in the first level of translation.
User addresses have bits 63:48 set to 0 while the kernel addresses have TTBRx selection is given by bit 55 of the virtual address. The
the same bits set to 1. TTBRx selection is given by bit 63 of the swapper_pg_dir contains only kernel (global) mappings while the user pgd
virtual address. The swapper_pg_dir contains only kernel (global) contains only user (non-global) mappings. The swapper_pg_dir address is
mappings while the user pgd contains only user (non-global) mappings. written to TTBR1 and never written to TTBR0.
The swapper_pg_dir address is written to TTBR1 and never written to
TTBR0.
AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit)::
...@@ -65,14 +63,14 @@ Translation table lookup with 4KB pages:: ...@@ -65,14 +63,14 @@ Translation table lookup with 4KB pages::
+--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| |63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | | | | | | | |
| | | | | v | | | | | v
| | | | | [11:0] in-page offset | | | | | [11:0] in-page offset
| | | | +-> [20:12] L3 index | | | | +-> [20:12] L3 index
| | | +-----------> [29:21] L2 index | | | +-----------> [29:21] L2 index
| | +---------------------> [38:30] L1 index | | +---------------------> [38:30] L1 index
| +-------------------------------> [47:39] L0 index | +-------------------------------> [47:39] L0 index
+-------------------------------------------------> [63] TTBR0/1 +----------------------------------------> [55] TTBR0/1
Translation table lookup with 64KB pages:: Translation table lookup with 64KB pages::
...@@ -80,14 +78,14 @@ Translation table lookup with 64KB pages:: ...@@ -80,14 +78,14 @@ Translation table lookup with 64KB pages::
+--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| |63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | | | | | |
| | | | v | | | | v
| | | | [15:0] in-page offset | | | | [15:0] in-page offset
| | | +----------> [28:16] L3 index | | | +----------> [28:16] L3 index
| | +--------------------------> [41:29] L2 index | | +--------------------------> [41:29] L2 index
| +-------------------------------> [47:42] L1 index (48-bit) | +-------------------------------> [47:42] L1 index (48-bit)
| [51:42] L1 index (52-bit) | [51:42] L1 index (52-bit)
+-------------------------------------------------> [63] TTBR0/1 +----------------------------------------> [55] TTBR0/1
When using KVM without the Virtualization Host Extensions, the When using KVM without the Virtualization Host Extensions, the
......
...@@ -132,16 +132,26 @@ stable kernels. ...@@ -132,16 +132,26 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 | | ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 | | ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #1502854 | N/A | | ARM | Cortex-X1 | #1502854 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 | | ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 | | ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 | | ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1349291 | N/A | | ARM | Neoverse-N1 | #1349291 | N/A |
...@@ -156,9 +166,13 @@ stable kernels. ...@@ -156,9 +166,13 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #2253138 | ARM64_ERRATUM_2253138 | | ARM | Neoverse-N2 | #2253138 | ARM64_ERRATUM_2253138 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #1619801 | N/A | | ARM | Neoverse-V1 | #1619801 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3312417 | | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-500 | #841119,826419 | N/A | | ARM | MMU-500 | #841119,826419 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
......
...@@ -381,7 +381,7 @@ config BROKEN_GAS_INST ...@@ -381,7 +381,7 @@ config BROKEN_GAS_INST
config BUILTIN_RETURN_ADDRESS_STRIPS_PAC config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
bool bool
# Clang's __builtin_return_adddress() strips the PAC since 12.0.0 # Clang's __builtin_return_address() strips the PAC since 12.0.0
# https://github.com/llvm/llvm-project/commit/2a96f47c5ffca84cd774ad402cacd137f4bf45e2 # https://github.com/llvm/llvm-project/commit/2a96f47c5ffca84cd774ad402cacd137f4bf45e2
default y if CC_IS_CLANG default y if CC_IS_CLANG
# GCC's __builtin_return_address() strips the PAC since 11.1.0, # GCC's __builtin_return_address() strips the PAC since 11.1.0,
...@@ -1067,34 +1067,21 @@ config ARM64_ERRATUM_3117295 ...@@ -1067,34 +1067,21 @@ config ARM64_ERRATUM_3117295
If unsure, say Y. If unsure, say Y.
config ARM64_WORKAROUND_SPECULATIVE_SSBS
bool
config ARM64_ERRATUM_3194386 config ARM64_ERRATUM_3194386
bool "Cortex-X4: 3194386: workaround for MSR SSBS not self-synchronizing" bool "Cortex-{A720,X4,X925}/Neoverse-V3: workaround for MSR SSBS not self-synchronizing"
select ARM64_WORKAROUND_SPECULATIVE_SSBS
default y default y
help help
This option adds the workaround for ARM Cortex-X4 erratum 3194386. This option adds the workaround for the following errata:
On affected cores "MSR SSBS, #0" instructions may not affect * ARM Cortex-A710 erratam 3324338
subsequent speculative instructions, which may permit unexepected * ARM Cortex-A720 erratum 3456091
speculative store bypassing. * ARM Cortex-X2 erratum 3324338
* ARM Cortex-X3 erratum 3324335
Work around this problem by placing a speculation barrier after * ARM Cortex-X4 erratum 3194386
kernel changes to SSBS. The presence of the SSBS special-purpose * ARM Cortex-X925 erratum 3324334
register is hidden from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such * ARM Neoverse N2 erratum 3324339
that userspace will use the PR_SPEC_STORE_BYPASS prctl to change * ARM Neoverse V2 erratum 3324336
SSBS. * ARM Neoverse-V3 erratum 3312417
If unsure, say Y.
config ARM64_ERRATUM_3312417
bool "Neoverse-V3: 3312417: workaround for MSR SSBS not self-synchronizing"
select ARM64_WORKAROUND_SPECULATIVE_SSBS
default y
help
This option adds the workaround for ARM Neoverse-V3 erratum 3312417.
On affected cores "MSR SSBS, #0" instructions may not affect On affected cores "MSR SSBS, #0" instructions may not affect
subsequent speculative instructions, which may permit unexepected subsequent speculative instructions, which may permit unexepected
...@@ -1108,7 +1095,6 @@ config ARM64_ERRATUM_3312417 ...@@ -1108,7 +1095,6 @@ config ARM64_ERRATUM_3312417
If unsure, say Y. If unsure, say Y.
config CAVIUM_ERRATUM_22375 config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313" bool "Cavium erratum 22375, 24313"
default y default y
......
...@@ -175,21 +175,6 @@ static inline bool gic_prio_masking_enabled(void) ...@@ -175,21 +175,6 @@ static inline bool gic_prio_masking_enabled(void)
static inline void gic_pmr_mask_irqs(void) static inline void gic_pmr_mask_irqs(void)
{ {
BUILD_BUG_ON(GICD_INT_DEF_PRI < (__GIC_PRIO_IRQOFF |
GIC_PRIO_PSR_I_SET));
BUILD_BUG_ON(GICD_INT_DEF_PRI >= GIC_PRIO_IRQON);
/*
* Need to make sure IRQON allows IRQs when SCR_EL3.FIQ is cleared
* and non-secure PMR accesses are not subject to the shifts that
* are applied to IRQ priorities
*/
BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) >= GIC_PRIO_IRQON);
/*
* Same situation as above, but now we make sure that we can mask
* regular interrupts.
*/
BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) < (__GIC_PRIO_IRQOFF_NS |
GIC_PRIO_PSR_I_SET));
gic_write_pmr(GIC_PRIO_IRQOFF); gic_write_pmr(GIC_PRIO_IRQOFF);
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <linux/smp.h> #include <linux/percpu.h>
#include <linux/types.h> #include <linux/types.h>
#include <clocksource/arm_arch_timer.h> #include <clocksource/arm_arch_timer.h>
......
...@@ -59,7 +59,7 @@ cpucap_is_possible(const unsigned int cap) ...@@ -59,7 +59,7 @@ cpucap_is_possible(const unsigned int cap)
case ARM64_WORKAROUND_REPEAT_TLBI: case ARM64_WORKAROUND_REPEAT_TLBI:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI); return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
case ARM64_WORKAROUND_SPECULATIVE_SSBS: case ARM64_WORKAROUND_SPECULATIVE_SSBS:
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS); return IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386);
} }
return true; return true;
......
...@@ -588,14 +588,14 @@ static inline bool id_aa64pfr0_32bit_el1(u64 pfr0) ...@@ -588,14 +588,14 @@ static inline bool id_aa64pfr0_32bit_el1(u64 pfr0)
{ {
u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_EL1_SHIFT); u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_EL1_SHIFT);
return val == ID_AA64PFR0_EL1_ELx_32BIT_64BIT; return val == ID_AA64PFR0_EL1_EL1_AARCH32;
} }
static inline bool id_aa64pfr0_32bit_el0(u64 pfr0) static inline bool id_aa64pfr0_32bit_el0(u64 pfr0)
{ {
u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_EL0_SHIFT); u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_EL0_SHIFT);
return val == ID_AA64PFR0_EL1_ELx_32BIT_64BIT; return val == ID_AA64PFR0_EL1_EL0_AARCH32;
} }
static inline bool id_aa64pfr0_sve(u64 pfr0) static inline bool id_aa64pfr0_sve(u64 pfr0)
......
...@@ -86,9 +86,12 @@ ...@@ -86,9 +86,12 @@
#define ARM_CPU_PART_CORTEX_X2 0xD48 #define ARM_CPU_PART_CORTEX_X2 0xD48
#define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define ARM_CPU_PART_NEOVERSE_N2 0xD49
#define ARM_CPU_PART_CORTEX_A78C 0xD4B #define ARM_CPU_PART_CORTEX_A78C 0xD4B
#define ARM_CPU_PART_CORTEX_X3 0xD4E
#define ARM_CPU_PART_NEOVERSE_V2 0xD4F #define ARM_CPU_PART_NEOVERSE_V2 0xD4F
#define ARM_CPU_PART_CORTEX_A720 0xD81
#define ARM_CPU_PART_CORTEX_X4 0xD82 #define ARM_CPU_PART_CORTEX_X4 0xD82
#define ARM_CPU_PART_NEOVERSE_V3 0xD84 #define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define ARM_CPU_PART_CORTEX_X925 0xD85
#define APM_CPU_PART_XGENE 0x000 #define APM_CPU_PART_XGENE 0x000
#define APM_CPU_VAR_POTENZA 0x00 #define APM_CPU_VAR_POTENZA 0x00
...@@ -162,9 +165,12 @@ ...@@ -162,9 +165,12 @@
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)
#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) #define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)
#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) #define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
......
...@@ -121,6 +121,14 @@ ...@@ -121,6 +121,14 @@
#define ESR_ELx_FSC_SECC (0x18) #define ESR_ELx_FSC_SECC (0x18)
#define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n)) #define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n))
/* Status codes for individual page table levels */
#define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + n)
#define ESR_ELx_FSC_PERM_L(n) (ESR_ELx_FSC_PERM + n)
#define ESR_ELx_FSC_FAULT_nL (0x2C)
#define ESR_ELx_FSC_FAULT_L(n) (((n) < 0 ? ESR_ELx_FSC_FAULT_nL : \
ESR_ELx_FSC_FAULT) + (n))
/* ISS field definitions for Data Aborts */ /* ISS field definitions for Data Aborts */
#define ESR_ELx_ISV_SHIFT (24) #define ESR_ELx_ISV_SHIFT (24)
#define ESR_ELx_ISV (UL(1) << ESR_ELx_ISV_SHIFT) #define ESR_ELx_ISV (UL(1) << ESR_ELx_ISV_SHIFT)
...@@ -388,20 +396,33 @@ static inline bool esr_is_data_abort(unsigned long esr) ...@@ -388,20 +396,33 @@ static inline bool esr_is_data_abort(unsigned long esr)
static inline bool esr_fsc_is_translation_fault(unsigned long esr) static inline bool esr_fsc_is_translation_fault(unsigned long esr)
{ {
/* Translation fault, level -1 */ esr = esr & ESR_ELx_FSC;
if ((esr & ESR_ELx_FSC) == 0b101011)
return true; return (esr == ESR_ELx_FSC_FAULT_L(3)) ||
return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT; (esr == ESR_ELx_FSC_FAULT_L(2)) ||
(esr == ESR_ELx_FSC_FAULT_L(1)) ||
(esr == ESR_ELx_FSC_FAULT_L(0)) ||
(esr == ESR_ELx_FSC_FAULT_L(-1));
} }
static inline bool esr_fsc_is_permission_fault(unsigned long esr) static inline bool esr_fsc_is_permission_fault(unsigned long esr)
{ {
return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_PERM; esr = esr & ESR_ELx_FSC;
return (esr == ESR_ELx_FSC_PERM_L(3)) ||
(esr == ESR_ELx_FSC_PERM_L(2)) ||
(esr == ESR_ELx_FSC_PERM_L(1)) ||
(esr == ESR_ELx_FSC_PERM_L(0));
} }
static inline bool esr_fsc_is_access_flag_fault(unsigned long esr) static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
{ {
return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_ACCESS; esr = esr & ESR_ELx_FSC;
return (esr == ESR_ELx_FSC_ACCESS_L(3)) ||
(esr == ESR_ELx_FSC_ACCESS_L(2)) ||
(esr == ESR_ELx_FSC_ACCESS_L(1)) ||
(esr == ESR_ELx_FSC_ACCESS_L(0));
} }
/* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */ /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
......
...@@ -72,11 +72,11 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz) ...@@ -72,11 +72,11 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
{ {
unsigned long tcr = read_sysreg(tcr_el1); unsigned long tcr = read_sysreg(tcr_el1);
if ((tcr & TCR_T0SZ_MASK) >> TCR_T0SZ_OFFSET == t0sz) if ((tcr & TCR_T0SZ_MASK) == t0sz)
return; return;
tcr &= ~TCR_T0SZ_MASK; tcr &= ~TCR_T0SZ_MASK;
tcr |= t0sz << TCR_T0SZ_OFFSET; tcr |= t0sz;
write_sysreg(tcr, tcr_el1); write_sysreg(tcr, tcr_el1);
isb(); isb();
} }
......
...@@ -182,7 +182,7 @@ void mte_check_tfsr_el1(void); ...@@ -182,7 +182,7 @@ void mte_check_tfsr_el1(void);
static inline void mte_check_tfsr_entry(void) static inline void mte_check_tfsr_entry(void)
{ {
if (!system_supports_mte()) if (!kasan_hw_tags_enabled())
return; return;
mte_check_tfsr_el1(); mte_check_tfsr_el1();
...@@ -190,7 +190,7 @@ static inline void mte_check_tfsr_entry(void) ...@@ -190,7 +190,7 @@ static inline void mte_check_tfsr_entry(void)
static inline void mte_check_tfsr_exit(void) static inline void mte_check_tfsr_exit(void)
{ {
if (!system_supports_mte()) if (!kasan_hw_tags_enabled())
return; return;
/* /*
......
...@@ -21,35 +21,12 @@ ...@@ -21,35 +21,12 @@
#define INIT_PSTATE_EL2 \ #define INIT_PSTATE_EL2 \
(PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL2h) (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL2h)
/* #include <linux/irqchip/arm-gic-v3-prio.h>
* PMR values used to mask/unmask interrupts.
* #define GIC_PRIO_IRQON GICV3_PRIO_UNMASKED
* GIC priority masking works as follows: if an IRQ's priority is a higher value #define GIC_PRIO_IRQOFF GICV3_PRIO_IRQ
* than the value held in PMR, that IRQ is masked. Lowering the value of PMR
* means masking more IRQs (or at least that the same IRQs remain masked). #define GIC_PRIO_PSR_I_SET GICV3_PRIO_PSR_I_SET
*
* To mask interrupts, we clear the most significant bit of PMR.
*
* Some code sections either automatically switch back to PSR.I or explicitly
* require to not use priority masking. If bit GIC_PRIO_PSR_I_SET is included
* in the priority mask, it indicates that PSR.I should be set and
* interrupt disabling temporarily does not rely on IRQ priorities.
*/
#define GIC_PRIO_IRQON 0xe0
#define __GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80)
#define __GIC_PRIO_IRQOFF_NS 0xa0
#define GIC_PRIO_PSR_I_SET (1 << 4)
#define GIC_PRIO_IRQOFF \
({ \
extern struct static_key_false gic_nonsecure_priorities;\
u8 __prio = __GIC_PRIO_IRQOFF; \
\
if (static_branch_unlikely(&gic_nonsecure_priorities)) \
__prio = __GIC_PRIO_IRQOFF_NS; \
\
__prio; \
})
/* Additional SPSR bits not exposed in the UABI */ /* Additional SPSR bits not exposed in the UABI */
#define PSR_MODE_THREAD_BIT (1 << 0) #define PSR_MODE_THREAD_BIT (1 << 0)
......
...@@ -25,22 +25,11 @@ ...@@ -25,22 +25,11 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/percpu.h>
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/thread_info.h> #include <linux/thread_info.h>
DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number); #define raw_smp_processor_id() (current_thread_info()->cpu)
/*
* We don't use this_cpu_read(cpu_number) as that has implicit writes to
* preempt_count, and associated (compiler) barriers, that we'd like to avoid
* the expense of. If we're preemptible, the value can be stale at use anyway.
* And we can't use this_cpu_ptr() either, as that winds up recursing back
* here under CONFIG_DEBUG_PREEMPT=y.
*/
#define raw_smp_processor_id() (*raw_cpu_ptr(&cpu_number))
/* /*
* Logical CPU mapping. * Logical CPU mapping.
......
...@@ -872,10 +872,6 @@ ...@@ -872,10 +872,6 @@
/* Position the attr at the correct index */ /* Position the attr at the correct index */
#define MAIR_ATTRIDX(attr, idx) ((attr) << ((idx) * 8)) #define MAIR_ATTRIDX(attr, idx) ((attr) << ((idx) * 8))
/* id_aa64pfr0 */
#define ID_AA64PFR0_EL1_ELx_64BIT_ONLY 0x1
#define ID_AA64PFR0_EL1_ELx_32BIT_64BIT 0x2
/* id_aa64mmfr0 */ /* id_aa64mmfr0 */
#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN 0x0 #define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED_MIN 0x0
#define ID_AA64MMFR0_EL1_TGRAN4_LPA2 ID_AA64MMFR0_EL1_TGRAN4_52_BIT #define ID_AA64MMFR0_EL1_TGRAN4_LPA2 ID_AA64MMFR0_EL1_TGRAN4_52_BIT
......
...@@ -46,7 +46,6 @@ obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o ...@@ -46,7 +46,6 @@ obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_CPU_PM) += sleep.o suspend.o obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o obj-$(CONFIG_EFI) += efi.o efi-rt-wrapper.o
......
...@@ -45,6 +45,7 @@ EXPORT_SYMBOL(acpi_pci_disabled); ...@@ -45,6 +45,7 @@ EXPORT_SYMBOL(acpi_pci_disabled);
static bool param_acpi_off __initdata; static bool param_acpi_off __initdata;
static bool param_acpi_on __initdata; static bool param_acpi_on __initdata;
static bool param_acpi_force __initdata; static bool param_acpi_force __initdata;
static bool param_acpi_nospcr __initdata;
static int __init parse_acpi(char *arg) static int __init parse_acpi(char *arg)
{ {
...@@ -58,6 +59,8 @@ static int __init parse_acpi(char *arg) ...@@ -58,6 +59,8 @@ static int __init parse_acpi(char *arg)
param_acpi_on = true; param_acpi_on = true;
else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */ else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */
param_acpi_force = true; param_acpi_force = true;
else if (strcmp(arg, "nospcr") == 0) /* disable SPCR as default console */
param_acpi_nospcr = true;
else else
return -EINVAL; /* Core will print when we return error */ return -EINVAL; /* Core will print when we return error */
...@@ -237,7 +240,20 @@ void __init acpi_boot_table_init(void) ...@@ -237,7 +240,20 @@ void __init acpi_boot_table_init(void)
acpi_put_table(facs); acpi_put_table(facs);
} }
#endif #endif
acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
/*
* For varying privacy and security reasons, sometimes need
* to completely silence the serial console output, and only
* enable it when needed.
* But there are many existing systems that depend on this
* behaviour, use acpi=nospcr to disable console in ACPI SPCR
* table as default serial console.
*/
acpi_parse_spcr(earlycon_acpi_spcr_enable,
!param_acpi_nospcr);
pr_info("Use ACPI SPCR as default console: %s\n",
param_acpi_nospcr ? "No" : "Yes");
if (IS_ENABLED(CONFIG_ACPI_BGRT)) if (IS_ENABLED(CONFIG_ACPI_BGRT))
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
} }
...@@ -422,108 +438,3 @@ void arch_reserve_mem_area(acpi_physical_address addr, size_t size) ...@@ -422,108 +438,3 @@ void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
{ {
memblock_mark_nomap(addr, size); memblock_mark_nomap(addr, size);
} }
#ifdef CONFIG_ACPI_FFH
/*
* Implements ARM64 specific callbacks to support ACPI FFH Operation Region as
* specified in https://developer.arm.com/docs/den0048/latest
*/
struct acpi_ffh_data {
struct acpi_ffh_info info;
void (*invoke_ffh_fn)(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3,
unsigned long a4, unsigned long a5,
unsigned long a6, unsigned long a7,
struct arm_smccc_res *args,
struct arm_smccc_quirk *res);
void (*invoke_ffh64_fn)(const struct arm_smccc_1_2_regs *args,
struct arm_smccc_1_2_regs *res);
};
int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt)
{
enum arm_smccc_conduit conduit;
struct acpi_ffh_data *ffh_ctxt;
if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
return -EOPNOTSUPP;
conduit = arm_smccc_1_1_get_conduit();
if (conduit == SMCCC_CONDUIT_NONE) {
pr_err("%s: invalid SMCCC conduit\n", __func__);
return -EOPNOTSUPP;
}
ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL);
if (!ffh_ctxt)
return -ENOMEM;
if (conduit == SMCCC_CONDUIT_SMC) {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_smc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_smc;
} else {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_hvc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_hvc;
}
memcpy(ffh_ctxt, handler_ctxt, sizeof(ffh_ctxt->info));
*region_ctxt = ffh_ctxt;
return AE_OK;
}
static bool acpi_ffh_smccc_owner_allowed(u32 fid)
{
int owner = ARM_SMCCC_OWNER_NUM(fid);
if (owner == ARM_SMCCC_OWNER_STANDARD ||
owner == ARM_SMCCC_OWNER_SIP || owner == ARM_SMCCC_OWNER_OEM)
return true;
return false;
}
int acpi_ffh_address_space_arch_handler(acpi_integer *value, void *region_context)
{
int ret = 0;
struct acpi_ffh_data *ffh_ctxt = region_context;
if (ffh_ctxt->info.offset == 0) {
/* SMC/HVC 32bit call */
struct arm_smccc_res res;
u32 a[8] = { 0 }, *ptr = (u32 *)value;
if (!ARM_SMCCC_IS_FAST_CALL(*ptr) || ARM_SMCCC_IS_64(*ptr) ||
!acpi_ffh_smccc_owner_allowed(*ptr) ||
ffh_ctxt->info.length > 32) {
ret = AE_ERROR;
} else {
int idx, len = ffh_ctxt->info.length >> 2;
for (idx = 0; idx < len; idx++)
a[idx] = *(ptr + idx);
ffh_ctxt->invoke_ffh_fn(a[0], a[1], a[2], a[3], a[4],
a[5], a[6], a[7], &res, NULL);
memcpy(value, &res, sizeof(res));
}
} else if (ffh_ctxt->info.offset == 1) {
/* SMC/HVC 64bit call */
struct arm_smccc_1_2_regs *r = (struct arm_smccc_1_2_regs *)value;
if (!ARM_SMCCC_IS_FAST_CALL(r->a0) || !ARM_SMCCC_IS_64(r->a0) ||
!acpi_ffh_smccc_owner_allowed(r->a0) ||
ffh_ctxt->info.length > sizeof(*r)) {
ret = AE_ERROR;
} else {
ffh_ctxt->invoke_ffh64_fn(r, r);
memcpy(value, r, ffh_ctxt->info.length);
}
} else {
ret = AE_ERROR;
}
return ret;
}
#endif /* CONFIG_ACPI_FFH */
...@@ -432,14 +432,17 @@ static const struct midr_range erratum_spec_unpriv_load_list[] = { ...@@ -432,14 +432,17 @@ static const struct midr_range erratum_spec_unpriv_load_list[] = {
}; };
#endif #endif
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS
static const struct midr_range erratum_spec_ssbs_list[] = {
#ifdef CONFIG_ARM64_ERRATUM_3194386 #ifdef CONFIG_ARM64_ERRATUM_3194386
static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
#endif MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
#ifdef CONFIG_ARM64_ERRATUM_3312417 MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
#endif MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
{} {}
}; };
#endif #endif
...@@ -741,9 +744,9 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ...@@ -741,9 +744,9 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)), MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)),
}, },
#endif #endif
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS #ifdef CONFIG_ARM64_ERRATUM_3194386
{ {
.desc = "ARM errata 3194386, 3312417", .desc = "SSBS not fully self-synchronizing",
.capability = ARM64_WORKAROUND_SPECULATIVE_SSBS, .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list), ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
}, },
......
...@@ -285,8 +285,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { ...@@ -285,8 +285,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_FP_SHIFT, 4, ID_AA64PFR0_EL1_FP_NI), S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_FP_SHIFT, 4, ID_AA64PFR0_EL1_FP_NI),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL3_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL3_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL2_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL2_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL1_SHIFT, 4, ID_AA64PFR0_EL1_ELx_64BIT_ONLY), ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL1_SHIFT, 4, ID_AA64PFR0_EL1_EL1_IMP),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL0_SHIFT, 4, ID_AA64PFR0_EL1_ELx_64BIT_ONLY), ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_EL0_SHIFT, 4, ID_AA64PFR0_EL1_EL0_IMP),
ARM64_FTR_END, ARM64_FTR_END,
}; };
...@@ -429,6 +429,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { ...@@ -429,6 +429,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
}; };
static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_ECBHB_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_TIDCP1_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_TIDCP1_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_AFP_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_AFP_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_HCX_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_EL1_HCX_SHIFT, 4, 0),
......
...@@ -105,11 +105,6 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors); ...@@ -105,11 +105,6 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
KVM_NVHE_ALIAS(vgic_v2_cpuif_trap); KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
KVM_NVHE_ALIAS(vgic_v3_cpuif_trap); KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
#ifdef CONFIG_ARM64_PSEUDO_NMI
/* Static key checked in GIC_PRIO_IRQOFF. */
KVM_NVHE_ALIAS(gic_nonsecure_priorities);
#endif
/* EL2 exception handling */ /* EL2 exception handling */
KVM_NVHE_ALIAS(__start___kvm_ex_table); KVM_NVHE_ALIAS(__start___kvm_ex_table);
KVM_NVHE_ALIAS(__stop___kvm_ex_table); KVM_NVHE_ALIAS(__stop___kvm_ex_table);
......
...@@ -567,7 +567,7 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void) ...@@ -567,7 +567,7 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void)
* Mitigate this with an unconditional speculation barrier, as CPUs * Mitigate this with an unconditional speculation barrier, as CPUs
* could mis-speculate branches and bypass a conditional barrier. * could mis-speculate branches and bypass a conditional barrier.
*/ */
if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS)) if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386))
spec_bar(); spec_bar();
return SPECTRE_MITIGATED; return SPECTRE_MITIGATED;
......
...@@ -74,4 +74,5 @@ static void __exit reloc_test_exit(void) ...@@ -74,4 +74,5 @@ static void __exit reloc_test_exit(void)
module_init(reloc_test_init); module_init(reloc_test_init);
module_exit(reloc_test_exit); module_exit(reloc_test_exit);
MODULE_DESCRIPTION("Relocation testing module");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -55,9 +55,6 @@ ...@@ -55,9 +55,6 @@
#include <trace/events/ipi.h> #include <trace/events/ipi.h>
DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
EXPORT_PER_CPU_SYMBOL(cpu_number);
/* /*
* as from 2.5, kernels no longer have an init_tasks structure * as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core * so we need some other way of telling a new secondary core
...@@ -749,8 +746,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -749,8 +746,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
*/ */
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
per_cpu(cpu_number, cpu) = cpu;
if (cpu == smp_processor_id()) if (cpu == smp_processor_id())
continue; continue;
...@@ -767,13 +762,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -767,13 +762,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
} }
} }
static const char *ipi_types[NR_IPI] __tracepoint_string = { static const char *ipi_types[MAX_IPI] __tracepoint_string = {
[IPI_RESCHEDULE] = "Rescheduling interrupts", [IPI_RESCHEDULE] = "Rescheduling interrupts",
[IPI_CALL_FUNC] = "Function call interrupts", [IPI_CALL_FUNC] = "Function call interrupts",
[IPI_CPU_STOP] = "CPU stop interrupts", [IPI_CPU_STOP] = "CPU stop interrupts",
[IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts", [IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts",
[IPI_TIMER] = "Timer broadcast interrupts", [IPI_TIMER] = "Timer broadcast interrupts",
[IPI_IRQ_WORK] = "IRQ work interrupts", [IPI_IRQ_WORK] = "IRQ work interrupts",
[IPI_CPU_BACKTRACE] = "CPU backtrace interrupts",
[IPI_KGDB_ROUNDUP] = "KGDB roundup interrupts",
}; };
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
...@@ -784,7 +781,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) ...@@ -784,7 +781,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
{ {
unsigned int cpu, i; unsigned int cpu, i;
for (i = 0; i < NR_IPI; i++) { for (i = 0; i < MAX_IPI; i++) {
seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
prec >= 4 ? " " : ""); prec >= 4 ? " " : "");
for_each_online_cpu(cpu) for_each_online_cpu(cpu)
...@@ -1028,12 +1025,12 @@ void __init set_smp_ipi_range(int ipi_base, int n) ...@@ -1028,12 +1025,12 @@ void __init set_smp_ipi_range(int ipi_base, int n)
if (ipi_should_be_nmi(i)) { if (ipi_should_be_nmi(i)) {
err = request_percpu_nmi(ipi_base + i, ipi_handler, err = request_percpu_nmi(ipi_base + i, ipi_handler,
"IPI", &cpu_number); "IPI", &irq_stat);
WARN(err, "Could not request IPI %d as NMI, err=%d\n", WARN(err, "Could not request IPI %d as NMI, err=%d\n",
i, err); i, err);
} else { } else {
err = request_percpu_irq(ipi_base + i, ipi_handler, err = request_percpu_irq(ipi_base + i, ipi_handler,
"IPI", &cpu_number); "IPI", &irq_stat);
WARN(err, "Could not request IPI %d as IRQ, err=%d\n", WARN(err, "Could not request IPI %d as IRQ, err=%d\n",
i, err); i, err);
} }
......
...@@ -52,11 +52,11 @@ ...@@ -52,11 +52,11 @@
* Supported by KVM * Supported by KVM
*/ */
#define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\ #define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL0, IMP) | \
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL1, IMP) | \
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL2), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL2, IMP) | \
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL3), ID_AA64PFR0_EL1_ELx_64BIT_ONLY) | \ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, EL3, IMP) | \
FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_RAS), ID_AA64PFR0_EL1_RAS_IMP) \ SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, RAS, IMP) \
) )
/* /*
......
...@@ -33,9 +33,9 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu) ...@@ -33,9 +33,9 @@ static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
/* Protected KVM does not support AArch32 guests. */ /* Protected KVM does not support AArch32 guests. */
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0),
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_ELx_64BIT_ONLY); PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL0_IMP);
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1), BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_ELx_64BIT_ONLY); PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) != ID_AA64PFR0_EL1_EL1_IMP);
/* /*
* Linux guests assume support for floating-point and Advanced SIMD. Do * Linux guests assume support for floating-point and Advanced SIMD. Do
......
...@@ -276,7 +276,7 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu, ...@@ -276,7 +276,7 @@ static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
* of AArch32 feature id registers. * of AArch32 feature id registers.
*/ */
BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1), BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL1),
PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) > ID_AA64PFR0_EL1_ELx_64BIT_ONLY); PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) > ID_AA64PFR0_EL1_EL1_IMP);
return pvm_access_raz_wi(vcpu, p, r); return pvm_access_raz_wi(vcpu, p, r);
} }
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_ACPI_AGDI) += agdi.o obj-$(CONFIG_ACPI_AGDI) += agdi.o
obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
obj-$(CONFIG_ACPI_APMT) += apmt.o obj-$(CONFIG_ACPI_APMT) += apmt.o
obj-$(CONFIG_ACPI_FFH) += ffh.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_PROCESSOR_IDLE) += cpuidle.o
obj-$(CONFIG_ARM_AMBA) += amba.o obj-$(CONFIG_ARM_AMBA) += amba.o
obj-y += dma.o init.o obj-y += dma.o init.o
obj-y += thermal_cpufreq.o obj-y += thermal_cpufreq.o
...@@ -27,11 +27,7 @@ static const struct acpi_device_id amba_id_list[] = { ...@@ -27,11 +27,7 @@ static const struct acpi_device_id amba_id_list[] = {
static void amba_register_dummy_clk(void) static void amba_register_dummy_clk(void)
{ {
static struct clk *amba_dummy_clk; struct clk *amba_dummy_clk;
/* If clock already registered */
if (amba_dummy_clk)
return;
amba_dummy_clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0); amba_dummy_clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0);
clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL); clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
#include <linux/cpu_pm.h> #include <linux/cpu_pm.h>
#include <linux/psci.h> #include <linux/psci.h>
#ifdef CONFIG_ACPI_PROCESSOR_IDLE
#include <acpi/processor.h> #include <acpi/processor.h>
#define ARM64_LPI_IS_RETENTION_STATE(arch_flags) (!(arch_flags)) #define ARM64_LPI_IS_RETENTION_STATE(arch_flags) (!(arch_flags))
...@@ -71,4 +68,3 @@ __cpuidle int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi) ...@@ -71,4 +68,3 @@ __cpuidle int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
return CPU_PM_CPU_IDLE_ENTER_PARAM_RCU(psci_cpu_suspend_enter, return CPU_PM_CPU_IDLE_ENTER_PARAM_RCU(psci_cpu_suspend_enter,
lpi->index, state); lpi->index, state);
} }
#endif
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/acpi.h>
#include <linux/arm-smccc.h>
#include <linux/slab.h>
/*
* Implements ARM64 specific callbacks to support ACPI FFH Operation Region as
* specified in https://developer.arm.com/docs/den0048/latest
*/
struct acpi_ffh_data {
struct acpi_ffh_info info;
void (*invoke_ffh_fn)(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3,
unsigned long a4, unsigned long a5,
unsigned long a6, unsigned long a7,
struct arm_smccc_res *args,
struct arm_smccc_quirk *res);
void (*invoke_ffh64_fn)(const struct arm_smccc_1_2_regs *args,
struct arm_smccc_1_2_regs *res);
};
int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt)
{
enum arm_smccc_conduit conduit;
struct acpi_ffh_data *ffh_ctxt;
if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
return -EOPNOTSUPP;
conduit = arm_smccc_1_1_get_conduit();
if (conduit == SMCCC_CONDUIT_NONE) {
pr_err("%s: invalid SMCCC conduit\n", __func__);
return -EOPNOTSUPP;
}
ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL);
if (!ffh_ctxt)
return -ENOMEM;
if (conduit == SMCCC_CONDUIT_SMC) {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_smc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_smc;
} else {
ffh_ctxt->invoke_ffh_fn = __arm_smccc_hvc;
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_hvc;
}
memcpy(ffh_ctxt, handler_ctxt, sizeof(ffh_ctxt->info));
*region_ctxt = ffh_ctxt;
return AE_OK;
}
static bool acpi_ffh_smccc_owner_allowed(u32 fid)
{
int owner = ARM_SMCCC_OWNER_NUM(fid);
if (owner == ARM_SMCCC_OWNER_STANDARD ||
owner == ARM_SMCCC_OWNER_SIP || owner == ARM_SMCCC_OWNER_OEM)
return true;
return false;
}
int acpi_ffh_address_space_arch_handler(acpi_integer *value, void *region_context)
{
int ret = 0;
struct acpi_ffh_data *ffh_ctxt = region_context;
if (ffh_ctxt->info.offset == 0) {
/* SMC/HVC 32bit call */
struct arm_smccc_res res;
u32 a[8] = { 0 }, *ptr = (u32 *)value;
if (!ARM_SMCCC_IS_FAST_CALL(*ptr) || ARM_SMCCC_IS_64(*ptr) ||
!acpi_ffh_smccc_owner_allowed(*ptr) ||
ffh_ctxt->info.length > 32) {
ret = AE_ERROR;
} else {
int idx, len = ffh_ctxt->info.length >> 2;
for (idx = 0; idx < len; idx++)
a[idx] = *(ptr + idx);
ffh_ctxt->invoke_ffh_fn(a[0], a[1], a[2], a[3], a[4],
a[5], a[6], a[7], &res, NULL);
memcpy(value, &res, sizeof(res));
}
} else if (ffh_ctxt->info.offset == 1) {
/* SMC/HVC 64bit call */
struct arm_smccc_1_2_regs *r = (struct arm_smccc_1_2_regs *)value;
if (!ARM_SMCCC_IS_FAST_CALL(r->a0) || !ARM_SMCCC_IS_64(r->a0) ||
!acpi_ffh_smccc_owner_allowed(r->a0) ||
ffh_ctxt->info.length > sizeof(*r)) {
ret = AE_ERROR;
} else {
ffh_ctxt->invoke_ffh64_fn(r, r);
memcpy(value, r, ffh_ctxt->info.length);
}
} else {
ret = AE_ERROR;
}
return ret;
}
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqchip/arm-gic.h> #include <linux/irqchip/arm-gic.h>
#include <linux/kernel.h>
#include "irq-gic-common.h" #include "irq-gic-common.h"
...@@ -45,7 +46,7 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks, ...@@ -45,7 +46,7 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
} }
int gic_configure_irq(unsigned int irq, unsigned int type, int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void)) void __iomem *base)
{ {
u32 confmask = 0x2 << ((irq % 16) * 2); u32 confmask = 0x2 << ((irq % 16) * 2);
u32 confoff = (irq / 16) * 4; u32 confoff = (irq / 16) * 4;
...@@ -84,14 +85,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, ...@@ -84,14 +85,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
raw_spin_unlock_irqrestore(&irq_controller_lock, flags); raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
if (sync_access)
sync_access();
return ret; return ret;
} }
void gic_dist_config(void __iomem *base, int gic_irqs, void gic_dist_config(void __iomem *base, int gic_irqs, u8 priority)
void (*sync_access)(void))
{ {
unsigned int i; unsigned int i;
...@@ -106,7 +103,8 @@ void gic_dist_config(void __iomem *base, int gic_irqs, ...@@ -106,7 +103,8 @@ void gic_dist_config(void __iomem *base, int gic_irqs,
* Set priority on all global interrupts. * Set priority on all global interrupts.
*/ */
for (i = 32; i < gic_irqs; i += 4) for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i); writel_relaxed(REPEAT_BYTE_U32(priority),
base + GIC_DIST_PRI + i);
/* /*
* Deactivate and disable all SPIs. Leave the PPI and SGIs * Deactivate and disable all SPIs. Leave the PPI and SGIs
...@@ -118,12 +116,9 @@ void gic_dist_config(void __iomem *base, int gic_irqs, ...@@ -118,12 +116,9 @@ void gic_dist_config(void __iomem *base, int gic_irqs,
writel_relaxed(GICD_INT_EN_CLR_X32, writel_relaxed(GICD_INT_EN_CLR_X32,
base + GIC_DIST_ENABLE_CLEAR + i / 8); base + GIC_DIST_ENABLE_CLEAR + i / 8);
} }
if (sync_access)
sync_access();
} }
void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void)) void gic_cpu_config(void __iomem *base, int nr, u8 priority)
{ {
int i; int i;
...@@ -142,9 +137,6 @@ void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void)) ...@@ -142,9 +137,6 @@ void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void))
* Set priority on PPI and SGI interrupts * Set priority on PPI and SGI interrupts
*/ */
for (i = 0; i < nr; i += 4) for (i = 0; i < nr; i += 4)
writel_relaxed(GICD_INT_DEF_PRI_X4, writel_relaxed(REPEAT_BYTE_U32(priority),
base + GIC_DIST_PRI + i * 4 / 4); base + GIC_DIST_PRI + i * 4 / 4);
if (sync_access)
sync_access();
} }
...@@ -20,10 +20,9 @@ struct gic_quirk { ...@@ -20,10 +20,9 @@ struct gic_quirk {
}; };
int gic_configure_irq(unsigned int irq, unsigned int type, int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void)); void __iomem *base);
void gic_dist_config(void __iomem *base, int gic_irqs, void gic_dist_config(void __iomem *base, int gic_irqs, u8 priority);
void (*sync_access)(void)); void gic_cpu_config(void __iomem *base, int nr, u8 priority);
void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void));
void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks, void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
void *data); void *data);
void gic_enable_of_quirks(const struct device_node *np, void gic_enable_of_quirks(const struct device_node *np,
......
...@@ -59,7 +59,7 @@ static u32 lpi_id_bits; ...@@ -59,7 +59,7 @@ static u32 lpi_id_bits;
#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K) #define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K)
#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K) #define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K)
#define LPI_PROP_DEFAULT_PRIO GICD_INT_DEF_PRI static u8 __ro_after_init lpi_prop_prio;
/* /*
* Collection structure - just an ID, and a redistributor address to * Collection structure - just an ID, and a redistributor address to
...@@ -1926,7 +1926,7 @@ static int its_vlpi_unmap(struct irq_data *d) ...@@ -1926,7 +1926,7 @@ static int its_vlpi_unmap(struct irq_data *d)
/* and restore the physical one */ /* and restore the physical one */
irqd_clr_forwarded_to_vcpu(d); irqd_clr_forwarded_to_vcpu(d);
its_send_mapti(its_dev, d->hwirq, event); its_send_mapti(its_dev, d->hwirq, event);
lpi_update_config(d, 0xff, (LPI_PROP_DEFAULT_PRIO | lpi_update_config(d, 0xff, (lpi_prop_prio |
LPI_PROP_ENABLED | LPI_PROP_ENABLED |
LPI_PROP_GROUP1)); LPI_PROP_GROUP1));
...@@ -2181,8 +2181,8 @@ static void its_lpi_free(unsigned long *bitmap, u32 base, u32 nr_ids) ...@@ -2181,8 +2181,8 @@ static void its_lpi_free(unsigned long *bitmap, u32 base, u32 nr_ids)
static void gic_reset_prop_table(void *va) static void gic_reset_prop_table(void *va)
{ {
/* Priority 0xa0, Group-1, disabled */ /* Regular IRQ priority, Group-1, disabled */
memset(va, LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1, LPI_PROPBASE_SZ); memset(va, lpi_prop_prio | LPI_PROP_GROUP1, LPI_PROPBASE_SZ);
/* Make sure the GIC will observe the written configuration */ /* Make sure the GIC will observe the written configuration */
gic_flush_dcache_to_poc(va, LPI_PROPBASE_SZ); gic_flush_dcache_to_poc(va, LPI_PROPBASE_SZ);
...@@ -5650,7 +5650,7 @@ int __init its_lpi_memreserve_init(void) ...@@ -5650,7 +5650,7 @@ int __init its_lpi_memreserve_init(void)
} }
int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
struct irq_domain *parent_domain) struct irq_domain *parent_domain, u8 irq_prio)
{ {
struct device_node *of_node; struct device_node *of_node;
struct its_node *its; struct its_node *its;
...@@ -5660,6 +5660,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, ...@@ -5660,6 +5660,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
gic_rdists = rdists; gic_rdists = rdists;
lpi_prop_prio = irq_prio;
its_parent = parent_domain; its_parent = parent_domain;
of_node = to_of_node(handle); of_node = to_of_node(handle);
if (of_node) if (of_node)
......
This diff is collapsed.
...@@ -303,7 +303,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) ...@@ -303,7 +303,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
type != IRQ_TYPE_EDGE_RISING) type != IRQ_TYPE_EDGE_RISING)
return -EINVAL; return -EINVAL;
ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL); ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG);
if (ret && gicirq < 32) { if (ret && gicirq < 32) {
/* Misconfigured PPIs are usually not fatal */ /* Misconfigured PPIs are usually not fatal */
pr_warn("GIC: PPI%ld is secure or misconfigured\n", gicirq - 16); pr_warn("GIC: PPI%ld is secure or misconfigured\n", gicirq - 16);
...@@ -479,7 +479,7 @@ static void gic_dist_init(struct gic_chip_data *gic) ...@@ -479,7 +479,7 @@ static void gic_dist_init(struct gic_chip_data *gic)
for (i = 32; i < gic_irqs; i += 4) for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
gic_dist_config(base, gic_irqs, NULL); gic_dist_config(base, gic_irqs, GICD_INT_DEF_PRI);
writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
} }
...@@ -516,7 +516,7 @@ static int gic_cpu_init(struct gic_chip_data *gic) ...@@ -516,7 +516,7 @@ static int gic_cpu_init(struct gic_chip_data *gic)
gic_cpu_map[i] &= ~cpu_mask; gic_cpu_map[i] &= ~cpu_mask;
} }
gic_cpu_config(dist_base, 32, NULL); gic_cpu_config(dist_base, 32, GICD_INT_DEF_PRI);
writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
gic_cpu_if_up(gic); gic_cpu_if_up(gic);
...@@ -608,7 +608,7 @@ void gic_dist_restore(struct gic_chip_data *gic) ...@@ -608,7 +608,7 @@ void gic_dist_restore(struct gic_chip_data *gic)
dist_base + GIC_DIST_CONFIG + i * 4); dist_base + GIC_DIST_CONFIG + i * 4);
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
writel_relaxed(GICD_INT_DEF_PRI_X4, writel_relaxed(REPEAT_BYTE_U32(GICD_INT_DEF_PRI),
dist_base + GIC_DIST_PRI + i * 4); dist_base + GIC_DIST_PRI + i * 4);
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
...@@ -697,7 +697,7 @@ void gic_cpu_restore(struct gic_chip_data *gic) ...@@ -697,7 +697,7 @@ void gic_cpu_restore(struct gic_chip_data *gic)
writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
for (i = 0; i < DIV_ROUND_UP(32, 4); i++) for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
writel_relaxed(GICD_INT_DEF_PRI_X4, writel_relaxed(REPEAT_BYTE_U32(GICD_INT_DEF_PRI),
dist_base + GIC_DIST_PRI + i * 4); dist_base + GIC_DIST_PRI + i * 4);
writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);
......
...@@ -130,7 +130,7 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -130,7 +130,7 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type)
raw_spin_lock(&irq_controller_lock); raw_spin_lock(&irq_controller_lock);
ret = gic_configure_irq(irq, type, base + GIC_DIST_CONFIG, NULL); ret = gic_configure_irq(irq, type, base + GIC_DIST_CONFIG);
if (ret && irq < 32) { if (ret && irq < 32) {
/* Misconfigured PPIs are usually not fatal */ /* Misconfigured PPIs are usually not fatal */
pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
...@@ -260,7 +260,7 @@ static void __init hip04_irq_dist_init(struct hip04_irq_data *intc) ...@@ -260,7 +260,7 @@ static void __init hip04_irq_dist_init(struct hip04_irq_data *intc)
for (i = 32; i < nr_irqs; i += 2) for (i = 32; i < nr_irqs; i += 2)
writel_relaxed(cpumask, base + GIC_DIST_TARGET + ((i * 2) & ~3)); writel_relaxed(cpumask, base + GIC_DIST_TARGET + ((i * 2) & ~3));
gic_dist_config(base, nr_irqs, NULL); gic_dist_config(base, nr_irqs, GICD_INT_DEF_PRI);
writel_relaxed(1, base + GIC_DIST_CTRL); writel_relaxed(1, base + GIC_DIST_CTRL);
} }
...@@ -287,7 +287,7 @@ static void hip04_irq_cpu_init(struct hip04_irq_data *intc) ...@@ -287,7 +287,7 @@ static void hip04_irq_cpu_init(struct hip04_irq_data *intc)
if (i != cpu) if (i != cpu)
hip04_cpu_map[i] &= ~cpu_mask; hip04_cpu_map[i] &= ~cpu_mask;
gic_cpu_config(dist_base, 32, NULL); gic_cpu_config(dist_base, 32, GICD_INT_DEF_PRI);
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
writel_relaxed(1, base + GIC_CPU_CTRL); writel_relaxed(1, base + GIC_CPU_CTRL);
......
...@@ -10,10 +10,6 @@ ...@@ -10,10 +10,6 @@
#include <linux/irqchip/arm-vgic-info.h> #include <linux/irqchip/arm-vgic-info.h>
#define GICD_INT_DEF_PRI 0xa0 #define GICD_INT_DEF_PRI 0xa0
#define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\
(GICD_INT_DEF_PRI << 16) |\
(GICD_INT_DEF_PRI << 8) |\
GICD_INT_DEF_PRI)
struct irq_domain; struct irq_domain;
struct fwnode_handle; struct fwnode_handle;
......
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __LINUX_IRQCHIP_ARM_GIC_V3_PRIO_H
#define __LINUX_IRQCHIP_ARM_GIC_V3_PRIO_H
/*
* GIC priorities from the view of the PMR/RPR.
*
* These values are chosen to be valid in either the absolute priority space or
* the NS view of the priority space. The value programmed into the distributor
* and ITS will be chosen at boot time such that these values appear in the
* PMR/RPR.
*
* GICV3_PRIO_UNMASKED is the PMR view of the priority to use to permit both
* IRQs and pseudo-NMIs.
*
* GICV3_PRIO_IRQ is the PMR view of the priority of regular interrupts. This
* can be written to the PMR to mask regular IRQs.
*
* GICV3_PRIO_NMI is the PMR view of the priority of pseudo-NMIs. This can be
* written to the PMR to mask pseudo-NMIs.
*
* On arm64 some code sections either automatically switch back to PSR.I or
* explicitly require to not use priority masking. If bit GICV3_PRIO_PSR_I_SET
* is included in the priority mask, it indicates that PSR.I should be set and
* interrupt disabling temporarily does not rely on IRQ priorities.
*/
#define GICV3_PRIO_UNMASKED 0xe0
#define GICV3_PRIO_IRQ 0xc0
#define GICV3_PRIO_NMI 0x80
#define GICV3_PRIO_PSR_I_SET (1 << 4)
#ifndef __ASSEMBLER__
#define __gicv3_prio_to_ns(p) (0xff & ((p) << 1))
#define __gicv3_ns_to_prio(ns) (0x80 | ((ns) >> 1))
#define __gicv3_prio_valid_ns(p) \
(__gicv3_ns_to_prio(__gicv3_prio_to_ns(p)) == (p))
static_assert(__gicv3_prio_valid_ns(GICV3_PRIO_NMI));
static_assert(__gicv3_prio_valid_ns(GICV3_PRIO_IRQ));
static_assert(GICV3_PRIO_NMI < GICV3_PRIO_IRQ);
static_assert(GICV3_PRIO_IRQ < GICV3_PRIO_UNMASKED);
static_assert(GICV3_PRIO_IRQ < (GICV3_PRIO_IRQ | GICV3_PRIO_PSR_I_SET));
#endif /* __ASSEMBLER */
#endif /* __LINUX_IRQCHIP_ARM_GIC_V3_PRIO_H */
...@@ -638,7 +638,7 @@ struct fwnode_handle; ...@@ -638,7 +638,7 @@ struct fwnode_handle;
int __init its_lpi_memreserve_init(void); int __init its_lpi_memreserve_init(void);
int its_cpu_init(void); int its_cpu_init(void);
int its_init(struct fwnode_handle *handle, struct rdists *rdists, int its_init(struct fwnode_handle *handle, struct rdists *rdists,
struct irq_domain *domain); struct irq_domain *domain, u8 irq_prio);
int mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent); int mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent);
static inline bool gic_enable_sre(void) static inline bool gic_enable_sre(void)
......
...@@ -39,6 +39,14 @@ ...@@ -39,6 +39,14 @@
*/ */
#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) #define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
/**
* REPEAT_BYTE_U32 - repeat the value @x multiple times as a u32 value
* @x: value to repeat
*
* NOTE: @x is not checked for > 0xff; larger values produce odd results.
*/
#define REPEAT_BYTE_U32(x) lower_32_bits(REPEAT_BYTE(x))
/* Set bits in the first 'n' bytes when loaded from memory */ /* Set bits in the first 'n' bytes when loaded from memory */
#ifdef __LITTLE_ENDIAN #ifdef __LITTLE_ENDIAN
# define aligned_byte_mask(n) ((1UL << 8*(n))-1) # define aligned_byte_mask(n) ((1UL << 8*(n))-1)
......
...@@ -47,7 +47,7 @@ static void test_tpidr(pid_t child) ...@@ -47,7 +47,7 @@ static void test_tpidr(pid_t child)
/* ...write a new value.. */ /* ...write a new value.. */
write_iov.iov_len = sizeof(uint64_t); write_iov.iov_len = sizeof(uint64_t);
write_val[0] = read_val[0]++; write_val[0] = read_val[0] + 1;
ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_TLS, &write_iov); ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_TLS, &write_iov);
ksft_test_result(ret == 0, "write_tpidr_one\n"); ksft_test_result(ret == 0, "write_tpidr_one\n");
......
...@@ -2,6 +2,7 @@ fp-pidbench ...@@ -2,6 +2,7 @@ fp-pidbench
fp-ptrace fp-ptrace
fp-stress fp-stress
fpsimd-test fpsimd-test
kernel-test
rdvl-sme rdvl-sme
rdvl-sve rdvl-sve
sve-probe-vls sve-probe-vls
......
...@@ -12,6 +12,7 @@ TEST_GEN_PROGS := \ ...@@ -12,6 +12,7 @@ TEST_GEN_PROGS := \
vec-syscfg \ vec-syscfg \
za-fork za-ptrace za-fork za-ptrace
TEST_GEN_PROGS_EXTENDED := fp-pidbench fpsimd-test \ TEST_GEN_PROGS_EXTENDED := fp-pidbench fpsimd-test \
kernel-test \
rdvl-sme rdvl-sve \ rdvl-sme rdvl-sve \
sve-test \ sve-test \
ssve-test \ ssve-test \
......
...@@ -319,6 +319,19 @@ static void start_fpsimd(struct child_data *child, int cpu, int copy) ...@@ -319,6 +319,19 @@ static void start_fpsimd(struct child_data *child, int cpu, int copy)
ksft_print_msg("Started %s\n", child->name); ksft_print_msg("Started %s\n", child->name);
} }
static void start_kernel(struct child_data *child, int cpu, int copy)
{
int ret;
ret = asprintf(&child->name, "KERNEL-%d-%d", cpu, copy);
if (ret == -1)
ksft_exit_fail_msg("asprintf() failed\n");
child_start(child, "./kernel-test");
ksft_print_msg("Started %s\n", child->name);
}
static void start_sve(struct child_data *child, int vl, int cpu) static void start_sve(struct child_data *child, int vl, int cpu)
{ {
int ret; int ret;
...@@ -438,7 +451,7 @@ int main(int argc, char **argv) ...@@ -438,7 +451,7 @@ int main(int argc, char **argv)
int ret; int ret;
int timeout = 10; int timeout = 10;
int cpus, i, j, c; int cpus, i, j, c;
int sve_vl_count, sme_vl_count, fpsimd_per_cpu; int sve_vl_count, sme_vl_count;
bool all_children_started = false; bool all_children_started = false;
int seen_children; int seen_children;
int sve_vls[MAX_VLS], sme_vls[MAX_VLS]; int sve_vls[MAX_VLS], sme_vls[MAX_VLS];
...@@ -482,12 +495,7 @@ int main(int argc, char **argv) ...@@ -482,12 +495,7 @@ int main(int argc, char **argv)
have_sme2 = false; have_sme2 = false;
} }
/* Force context switching if we only have FPSIMD */ tests += cpus * 2;
if (!sve_vl_count && !sme_vl_count)
fpsimd_per_cpu = 2;
else
fpsimd_per_cpu = 1;
tests += cpus * fpsimd_per_cpu;
ksft_print_header(); ksft_print_header();
ksft_set_plan(tests); ksft_set_plan(tests);
...@@ -542,8 +550,8 @@ int main(int argc, char **argv) ...@@ -542,8 +550,8 @@ int main(int argc, char **argv)
tests); tests);
for (i = 0; i < cpus; i++) { for (i = 0; i < cpus; i++) {
for (j = 0; j < fpsimd_per_cpu; j++) start_fpsimd(&children[num_children++], i, 0);
start_fpsimd(&children[num_children++], i, j); start_kernel(&children[num_children++], i, 0);
for (j = 0; j < sve_vl_count; j++) for (j = 0; j < sve_vl_count; j++)
start_sve(&children[num_children++], sve_vls[j], i); start_sve(&children[num_children++], sve_vls[j], i);
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2024 ARM Limited.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/kernel.h>
#include <linux/if_alg.h>
#define DATA_SIZE (16 * 4096)
static int base, sock;
static int digest_len;
static char *ref;
static char *digest;
static char *alg_name;
static struct iovec data_iov;
static int zerocopy[2];
static int sigs;
static int iter;
static void handle_exit_signal(int sig, siginfo_t *info, void *context)
{
printf("Terminated by signal %d, iterations=%d, signals=%d\n",
sig, iter, sigs);
exit(0);
}
static void handle_kick_signal(int sig, siginfo_t *info, void *context)
{
sigs++;
}
static char *drivers[] = {
"crct10dif-arm64-ce",
/* "crct10dif-arm64-neon", - Same priority as generic */
"sha1-ce",
"sha224-arm64",
"sha224-arm64-neon",
"sha224-ce",
"sha256-arm64",
"sha256-arm64-neon",
"sha256-ce",
"sha384-ce",
"sha512-ce",
"sha3-224-ce",
"sha3-256-ce",
"sha3-384-ce",
"sha3-512-ce",
"sm3-ce",
"sm3-neon",
};
static bool create_socket(void)
{
FILE *proc;
struct sockaddr_alg addr;
char buf[1024];
char *c, *driver_name;
bool is_shash, match;
int ret, i;
ret = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (ret < 0) {
if (errno == EAFNOSUPPORT) {
printf("AF_ALG not supported\n");
return false;
}
printf("Failed to create AF_ALG socket: %s (%d)\n",
strerror(errno), errno);
return false;
}
base = ret;
memset(&addr, 0, sizeof(addr));
addr.salg_family = AF_ALG;
strncpy((char *)addr.salg_type, "hash", sizeof(addr.salg_type));
proc = fopen("/proc/crypto", "r");
if (!proc) {
printf("Unable to open /proc/crypto\n");
return false;
}
driver_name = NULL;
is_shash = false;
match = false;
/* Look through /proc/crypto for a driver with kernel mode FP usage */
while (!match) {
c = fgets(buf, sizeof(buf), proc);
if (!c) {
if (feof(proc)) {
printf("Nothing found in /proc/crypto\n");
return false;
}
continue;
}
/* Algorithm descriptions are separated by a blank line */
if (*c == '\n') {
if (is_shash && driver_name) {
for (i = 0; i < ARRAY_SIZE(drivers); i++) {
if (strcmp(drivers[i],
driver_name) == 0) {
match = true;
}
}
}
if (!match) {
digest_len = 0;
free(driver_name);
driver_name = NULL;
free(alg_name);
alg_name = NULL;
is_shash = false;
}
continue;
}
/* Remove trailing newline */
c = strchr(buf, '\n');
if (c)
*c = '\0';
/* Find the field/value separator and start of the value */
c = strchr(buf, ':');
if (!c)
continue;
c += 2;
if (strncmp(buf, "digestsize", strlen("digestsize")) == 0)
sscanf(c, "%d", &digest_len);
if (strncmp(buf, "name", strlen("name")) == 0)
alg_name = strdup(c);
if (strncmp(buf, "driver", strlen("driver")) == 0)
driver_name = strdup(c);
if (strncmp(buf, "type", strlen("type")) == 0)
if (strncmp(c, "shash", strlen("shash")) == 0)
is_shash = true;
}
strncpy((char *)addr.salg_name, alg_name,
sizeof(addr.salg_name) - 1);
ret = bind(base, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
printf("Failed to bind %s: %s (%d)\n",
addr.salg_name, strerror(errno), errno);
return false;
}
ret = accept(base, NULL, 0);
if (ret < 0) {
printf("Failed to accept %s: %s (%d)\n",
addr.salg_name, strerror(errno), errno);
return false;
}
sock = ret;
ret = pipe(zerocopy);
if (ret != 0) {
printf("Failed to create zerocopy pipe: %s (%d)\n",
strerror(errno), errno);
return false;
}
ref = malloc(digest_len);
if (!ref) {
printf("Failed to allocated %d byte reference\n", digest_len);
return false;
}
digest = malloc(digest_len);
if (!digest) {
printf("Failed to allocated %d byte digest\n", digest_len);
return false;
}
return true;
}
static bool compute_digest(void *buf)
{
struct iovec iov;
int ret, wrote;
iov = data_iov;
while (iov.iov_len) {
ret = vmsplice(zerocopy[1], &iov, 1, SPLICE_F_GIFT);
if (ret < 0) {
printf("Failed to send buffer: %s (%d)\n",
strerror(errno), errno);
return false;
}
wrote = ret;
ret = splice(zerocopy[0], NULL, sock, NULL, wrote, 0);
if (ret < 0) {
printf("Failed to splice buffer: %s (%d)\n",
strerror(errno), errno);
} else if (ret != wrote) {
printf("Short splice: %d < %d\n", ret, wrote);
}
iov.iov_len -= wrote;
iov.iov_base += wrote;
}
reread:
ret = recv(sock, buf, digest_len, 0);
if (ret == 0) {
printf("No digest returned\n");
return false;
}
if (ret != digest_len) {
if (errno == -EAGAIN)
goto reread;
printf("Failed to get digest: %s (%d)\n",
strerror(errno), errno);
return false;
}
return true;
}
int main(void)
{
char *data;
struct sigaction sa;
int ret;
/* Ensure we have unbuffered output */
setvbuf(stdout, NULL, _IOLBF, 0);
/* The parent will communicate with us via signals */
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handle_exit_signal;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigemptyset(&sa.sa_mask);
ret = sigaction(SIGTERM, &sa, NULL);
if (ret < 0)
printf("Failed to install SIGTERM handler: %s (%d)\n",
strerror(errno), errno);
sa.sa_sigaction = handle_kick_signal;
ret = sigaction(SIGUSR2, &sa, NULL);
if (ret < 0)
printf("Failed to install SIGUSR2 handler: %s (%d)\n",
strerror(errno), errno);
data = malloc(DATA_SIZE);
if (!data) {
printf("Failed to allocate data buffer\n");
return EXIT_FAILURE;
}
memset(data, 0, DATA_SIZE);
data_iov.iov_base = data;
data_iov.iov_len = DATA_SIZE;
/*
* If we can't create a socket assume it's a lack of system
* support and fall back to a basic FPSIMD test for the
* benefit of fp-stress.
*/
if (!create_socket()) {
execl("./fpsimd-test", "./fpsimd-test", NULL);
printf("Failed to fall back to fspimd-test: %d (%s)\n",
errno, strerror(errno));
return EXIT_FAILURE;
}
/*
* Compute a reference digest we hope is repeatable, we do
* this at runtime partly to make it easier to play with
* parameters.
*/
if (!compute_digest(ref)) {
printf("Failed to compute reference digest\n");
return EXIT_FAILURE;
}
printf("AF_ALG using %s\n", alg_name);
while (true) {
if (!compute_digest(digest)) {
printf("Failed to compute digest, iter=%d\n", iter);
return EXIT_FAILURE;
}
if (memcmp(ref, digest, digest_len) != 0) {
printf("Digest mismatch, iter=%d\n", iter);
return EXIT_FAILURE;
}
iter++;
}
return EXIT_FAILURE;
}
...@@ -2,6 +2,5 @@ ...@@ -2,6 +2,5 @@
CFLAGS += $(KHDR_INCLUDES) CFLAGS += $(KHDR_INCLUDES)
TEST_GEN_PROGS := tags_test TEST_GEN_PROGS := tags_test
TEST_PROGS := run_tags_test.sh
include ../../lib.mk include ../../lib.mk
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
echo "--------------------"
echo "running tags test"
echo "--------------------"
./tags_test
if [ $? -ne 0 ]; then
echo "[FAIL]"
else
echo "[PASS]"
fi
...@@ -17,19 +17,21 @@ int main(void) ...@@ -17,19 +17,21 @@ int main(void)
static int tbi_enabled = 0; static int tbi_enabled = 0;
unsigned long tag = 0; unsigned long tag = 0;
struct utsname *ptr; struct utsname *ptr;
int err;
ksft_print_header();
ksft_set_plan(1);
if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0)
tbi_enabled = 1; tbi_enabled = 1;
ptr = (struct utsname *)malloc(sizeof(*ptr)); ptr = (struct utsname *)malloc(sizeof(*ptr));
if (!ptr) if (!ptr)
ksft_exit_fail_msg("Failed to allocate utsname buffer\n"); ksft_exit_fail_perror("Failed to allocate utsname buffer");
if (tbi_enabled) if (tbi_enabled)
tag = 0x42; tag = 0x42;
ptr = (struct utsname *)SET_TAG(ptr, tag); ptr = (struct utsname *)SET_TAG(ptr, tag);
err = uname(ptr); ksft_test_result(!uname(ptr), "Syscall successful with tagged address\n");
free(ptr); free(ptr);
return err; ksft_finished();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment