Skip to content

Commit

Permalink
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/arm64/linux

Pull arm64 fixes from Will Deacon:
 "A bumper crop of arm64 fixes for -rc3.

  The largest change is fixing our parsing of the 'rodata=full' command
  line option, which kstrtobool() started treating as 'rodata=false'.
  The fix actually makes the parsing of that option much less fragile
  and updates the documentation at the same time.

  We still have a boot issue pending when KASLR is disabled at compile
  time, but there's a fresh fix on the list which I'll send next week if
  it holds up to testing.

  Summary:

   - Fix workaround for Cortex-A76 erratum #1286807

   - Add workaround for AMU erratum #2457168 on Cortex-A510

   - Drop reference to removed CONFIG_ARCH_RANDOM #define

   - Fix parsing of the "rodata=full" cmdline option

   - Fix a bunch of issues in the SME register state switching and sigframe code

   - Fix incorrect extraction of the CTR_EL0.CWG register field

   - Fix ACPI cache topology probing when the PPTT is not present

   - Trivial comment and whitespace fixes"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64/sme: Don't flush SVE register state when handling SME traps
  arm64/sme: Don't flush SVE register state when allocating SME storage
  arm64/signal: Flush FPSIMD register state when disabling streaming mode
  arm64/signal: Raise limit on stack frames
  arm64/cache: Fix cache_type_cwg() for register generation
  arm64/sysreg: Guard SYS_FIELD_ macros for asm
  arm64/sysreg: Directly include bitfield.h
  arm64: cacheinfo: Fix incorrect assignment of signed error value to unsigned fw_level
  arm64: errata: add detection for AMEVCNTR01 incrementing incorrectly
  arm64: fix rodata=full
  arm64: Fix comment typo
  docs/arm64: elf_hwcaps: unify newlines in HWCAP lists
  arm64: adjust KASLR relocation after ARCH_RANDOM removal
  arm64: Fix match_list for erratum 1286807 on Arm Cortex-A76
  • Loading branch information
torvalds committed Aug 26, 2022
2 parents 012bd7e + 714f3cb commit e022620
Show file tree
Hide file tree
Showing 20 changed files with 136 additions and 66 deletions.
2 changes: 2 additions & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5331,6 +5331,8 @@
rodata= [KNL]
on Mark read-only kernel memory as read-only (default).
off Leave read-only kernel memory writable for debugging.
full Mark read-only kernel memory and aliases as read-only
[arm64]

rockchip.usb_uart
Enable the uart passthrough on the designated usb port
Expand Down
10 changes: 0 additions & 10 deletions Documentation/arm64/elf_hwcaps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -242,44 +242,34 @@ HWCAP2_MTE3
by Documentation/arm64/memory-tagging-extension.rst.

HWCAP2_SME

Functionality implied by ID_AA64PFR1_EL1.SME == 0b0001, as described
by Documentation/arm64/sme.rst.

HWCAP2_SME_I16I64

Functionality implied by ID_AA64SMFR0_EL1.I16I64 == 0b1111.

HWCAP2_SME_F64F64

Functionality implied by ID_AA64SMFR0_EL1.F64F64 == 0b1.

HWCAP2_SME_I8I32

Functionality implied by ID_AA64SMFR0_EL1.I8I32 == 0b1111.

HWCAP2_SME_F16F32

Functionality implied by ID_AA64SMFR0_EL1.F16F32 == 0b1.

HWCAP2_SME_B16F32

Functionality implied by ID_AA64SMFR0_EL1.B16F32 == 0b1.

HWCAP2_SME_F32F32

Functionality implied by ID_AA64SMFR0_EL1.F32F32 == 0b1.

HWCAP2_SME_FA64

Functionality implied by ID_AA64SMFR0_EL1.FA64 == 0b1.

HWCAP2_WFXT

Functionality implied by ID_AA64ISAR2_EL1.WFXT == 0b0010.

HWCAP2_EBF16

Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0010.

4. Unused AT_HWCAP bits
Expand Down
2 changes: 2 additions & 0 deletions Documentation/arm64/silicon-errata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ stable kernels.
| Allwinner | A64/R18 | UNKNOWN1 | SUN50I_ERRATUM_UNKNOWN1 |
+----------------+-----------------+-----------------+-----------------------------+
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A510 | #2457168 | ARM64_ERRATUM_2457168 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A510 | #2064142 | ARM64_ERRATUM_2064142 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A510 | #2038923 | ARM64_ERRATUM_2038923 |
Expand Down
17 changes: 17 additions & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,23 @@ config ARM64_ERRATUM_1902691

If unsure, say Y.

config ARM64_ERRATUM_2457168
bool "Cortex-A510: 2457168: workaround for AMEVCNTR01 incrementing incorrectly"
depends on ARM64_AMU_EXTN
default y
help
This option adds the workaround for ARM Cortex-A510 erratum 2457168.

The AMU counter AMEVCNTR01 (constant counter) should increment at the same rate
as the system counter. On affected Cortex-A510 cores AMEVCNTR01 increments
incorrectly giving a significantly higher output value.

Work around this problem by returning 0 when reading the affected counter in
key locations that results in disabling all users of this counter. This effect
is the same to firmware disabling affected counters.

If unsure, say Y.

config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313"
default y
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/include/asm/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static __always_inline int icache_is_vpipt(void)

static inline u32 cache_type_cwg(void)
{
return (read_cpuid_cachetype() >> CTR_EL0_CWG_SHIFT) & CTR_EL0_CWG_MASK;
return SYS_FIELD_GET(CTR_EL0, CWG, read_cpuid_cachetype());
}

#define __read_mostly __section(".data..read_mostly")
Expand Down
4 changes: 2 additions & 2 deletions arch/arm64/include/asm/fpsimd.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ struct vl_info {

#ifdef CONFIG_ARM64_SVE

extern void sve_alloc(struct task_struct *task);
extern void sve_alloc(struct task_struct *task, bool flush);
extern void fpsimd_release_task(struct task_struct *task);
extern void fpsimd_sync_to_sve(struct task_struct *task);
extern void fpsimd_force_sync_to_sve(struct task_struct *task);
Expand Down Expand Up @@ -256,7 +256,7 @@ size_t sve_state_size(struct task_struct const *task);

#else /* ! CONFIG_ARM64_SVE */

static inline void sve_alloc(struct task_struct *task) { }
static inline void sve_alloc(struct task_struct *task, bool flush) { }
static inline void fpsimd_release_task(struct task_struct *task) { }
static inline void sve_sync_to_fpsimd(struct task_struct *task) { }
static inline void sve_sync_from_fpsimd_zeropad(struct task_struct *task) { }
Expand Down
17 changes: 17 additions & 0 deletions arch/arm64/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#ifndef __ARM64_ASM_SETUP_H
#define __ARM64_ASM_SETUP_H

#include <linux/string.h>

#include <uapi/asm/setup.h>

void *get_early_fdt_ptr(void);
Expand All @@ -14,4 +16,19 @@ void early_fdt_map(u64 dt_phys);
extern phys_addr_t __fdt_pointer __initdata;
extern u64 __cacheline_aligned boot_args[4];

static inline bool arch_parse_debug_rodata(char *arg)
{
extern bool rodata_enabled;
extern bool rodata_full;

if (arg && !strcmp(arg, "full")) {
rodata_enabled = true;
rodata_full = true;
return true;
}

return false;
}
#define arch_parse_debug_rodata arch_parse_debug_rodata

#endif
5 changes: 3 additions & 2 deletions arch/arm64/include/asm/sysreg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,7 @@

#else

#include <linux/bitfield.h>
#include <linux/build_bug.h>
#include <linux/types.h>
#include <asm/alternative.h>
Expand Down Expand Up @@ -1209,8 +1210,6 @@
par; \
})

#endif

#define SYS_FIELD_GET(reg, field, val) \
FIELD_GET(reg##_##field##_MASK, val)

Expand All @@ -1220,4 +1219,6 @@
#define SYS_FIELD_PREP_ENUM(reg, field, val) \
FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val)

#endif

#endif /* __ASM_SYSREG_H */
6 changes: 5 additions & 1 deletion arch/arm64/kernel/cacheinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,

int init_cache_level(unsigned int cpu)
{
unsigned int ctype, level, leaves, fw_level;
unsigned int ctype, level, leaves;
int fw_level;
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);

for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) {
Expand All @@ -63,6 +64,9 @@ int init_cache_level(unsigned int cpu)
else
fw_level = acpi_find_last_cache_level(cpu);

if (fw_level < 0)
return fw_level;

if (level < fw_level) {
/*
* some external caches not specified in CLIDR_EL1
Expand Down
12 changes: 12 additions & 0 deletions arch/arm64/kernel/cpu_errata.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
#ifdef CONFIG_ARM64_ERRATUM_1286807
{
ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0),
},
{
/* Kryo4xx Gold (rcpe to rfpe) => (r0p0 to r3p0) */
ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe),
},
Expand Down Expand Up @@ -654,6 +656,16 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2457168
{
.desc = "ARM erratum 2457168",
.capability = ARM64_WORKAROUND_2457168,
.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,

/* Cortex-A510 r0p0-r1p1 */
CAP_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1)
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2038923
{
.desc = "ARM erratum 2038923",
Expand Down
5 changes: 4 additions & 1 deletion arch/arm64/kernel/cpufeature.c
Original file line number Diff line number Diff line change
Expand Up @@ -1870,7 +1870,10 @@ static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap)
pr_info("detected CPU%d: Activity Monitors Unit (AMU)\n",
smp_processor_id());
cpumask_set_cpu(smp_processor_id(), &amu_cpus);
update_freq_counters_refs();

/* 0 reference values signal broken/disabled counters */
if (!this_cpu_has_cap(ARM64_WORKAROUND_2457168))
update_freq_counters_refs();
}
}

Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ tsk .req x28 // current thread_info
SYM_CODE_START(vectors)
kernel_ventry 1, t, 64, sync // Synchronous EL1t
kernel_ventry 1, t, 64, irq // IRQ EL1t
kernel_ventry 1, t, 64, fiq // FIQ EL1h
kernel_ventry 1, t, 64, fiq // FIQ EL1t
kernel_ventry 1, t, 64, error // Error EL1t

kernel_ventry 1, h, 64, sync // Synchronous EL1h
Expand Down
21 changes: 6 additions & 15 deletions arch/arm64/kernel/fpsimd.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,10 +715,12 @@ size_t sve_state_size(struct task_struct const *task)
* do_sve_acc() case, there is no ABI requirement to hide stale data
* written previously be task.
*/
void sve_alloc(struct task_struct *task)
void sve_alloc(struct task_struct *task, bool flush)
{
if (task->thread.sve_state) {
memset(task->thread.sve_state, 0, sve_state_size(task));
if (flush)
memset(task->thread.sve_state, 0,
sve_state_size(task));
return;
}

Expand Down Expand Up @@ -1388,7 +1390,7 @@ void do_sve_acc(unsigned long esr, struct pt_regs *regs)
return;
}

sve_alloc(current);
sve_alloc(current, true);
if (!current->thread.sve_state) {
force_sig(SIGKILL);
return;
Expand Down Expand Up @@ -1439,7 +1441,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
return;
}

sve_alloc(current);
sve_alloc(current, false);
sme_alloc(current);
if (!current->thread.sve_state || !current->thread.za_state) {
force_sig(SIGKILL);
Expand All @@ -1460,17 +1462,6 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
fpsimd_bind_task_to_cpu();
}

/*
* If SVE was not already active initialise the SVE registers,
* any non-shared state between the streaming and regular SVE
* registers is architecturally guaranteed to be zeroed when
* we enter streaming mode. We do not need to initialize ZA
* since ZA must be disabled at this point and enabling ZA is
* architecturally defined to zero ZA.
*/
if (system_supports_sve() && !test_thread_flag(TIF_SVE))
sve_init_regs();

put_cpu_fpsimd_context();
}

Expand Down
8 changes: 3 additions & 5 deletions arch/arm64/kernel/pi/kaslr_early.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,9 @@ asmlinkage u64 kaslr_early_init(void *fdt)

seed = get_kaslr_seed(fdt);
if (!seed) {
#ifdef CONFIG_ARCH_RANDOM
if (!__early_cpu_has_rndr() ||
!__arm64_rndr((unsigned long *)&seed))
#endif
return 0;
if (!__early_cpu_has_rndr() ||
!__arm64_rndr((unsigned long *)&seed))
return 0;
}

/*
Expand Down
6 changes: 3 additions & 3 deletions arch/arm64/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ static int sve_set_common(struct task_struct *target,
* state and ensure there's storage.
*/
if (target->thread.svcr != old_svcr)
sve_alloc(target);
sve_alloc(target, true);
}

/* Registers: FPSIMD-only case */
Expand Down Expand Up @@ -912,7 +912,7 @@ static int sve_set_common(struct task_struct *target,
goto out;
}

sve_alloc(target);
sve_alloc(target, true);
if (!target->thread.sve_state) {
ret = -ENOMEM;
clear_tsk_thread_flag(target, TIF_SVE);
Expand Down Expand Up @@ -1082,7 +1082,7 @@ static int za_set(struct task_struct *target,

/* Ensure there is some SVE storage for streaming mode */
if (!target->thread.sve_state) {
sve_alloc(target);
sve_alloc(target, false);
if (!target->thread.sve_state) {
clear_thread_flag(TIF_SME);
ret = -ENOMEM;
Expand Down
14 changes: 12 additions & 2 deletions arch/arm64/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ static size_t sigframe_size(struct rt_sigframe_user_layout const *user)
* not taken into account. This limit is not a guarantee and is
* NOT ABI.
*/
#define SIGFRAME_MAXSZ SZ_64K
#define SIGFRAME_MAXSZ SZ_256K

static int __sigframe_alloc(struct rt_sigframe_user_layout *user,
unsigned long *offset, size_t size, bool extend)
Expand Down Expand Up @@ -310,7 +310,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
fpsimd_flush_task_state(current);
/* From now, fpsimd_thread_switch() won't touch thread.sve_state */

sve_alloc(current);
sve_alloc(current, true);
if (!current->thread.sve_state) {
clear_thread_flag(TIF_SVE);
return -ENOMEM;
Expand Down Expand Up @@ -926,6 +926,16 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,

/* Signal handlers are invoked with ZA and streaming mode disabled */
if (system_supports_sme()) {
/*
* If we were in streaming mode the saved register
* state was SVE but we will exit SM and use the
* FPSIMD register state - flush the saved FPSIMD
* register state in case it gets loaded.
*/
if (current->thread.svcr & SVCR_SM_MASK)
memset(&current->thread.uw.fpsimd_state, 0,
sizeof(current->thread.uw.fpsimd_state));

current->thread.svcr &= ~(SVCR_ZA_MASK |
SVCR_SM_MASK);
sme_smstop();
Expand Down
Loading

0 comments on commit e022620

Please sign in to comment.