Commit 86f01602 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
 "A simple fix to a definition in the CXL PMU driver, a couple of
  patches to restore SME control registers on the resume path (since
  Arm's fast model now clears them) and a revert for our jump label asm
  constraints after Geert noticed they broke the build with GCC 5.5.

  There was then the ensuing discussion about raising the minimum GCC
  (and corresponding binutils) versions at [1], but for now we'll keep
  things working as they were until that goes ahead.

   - Revert fix to jump label asm constraints, as it regresses the build
     with some GCC 5.5 toolchains.

   - Restore SME control registers when resuming from suspend

   - Fix incorrect filter definition in CXL PMU driver"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64/sme: Restore SMCR_EL1.EZT0 on exit from suspend
  arm64/sme: Restore SME registers on exit from suspend
  Revert "arm64: jump_label: use constraints "Si" instead of "i""
  perf: CXL: fix CPMU filter value mask length
parents 5efa18e8 d7b77a0d
...@@ -386,6 +386,7 @@ extern void sme_alloc(struct task_struct *task, bool flush); ...@@ -386,6 +386,7 @@ extern void sme_alloc(struct task_struct *task, bool flush);
extern unsigned int sme_get_vl(void); extern unsigned int sme_get_vl(void);
extern int sme_set_current_vl(unsigned long arg); extern int sme_set_current_vl(unsigned long arg);
extern int sme_get_current_vl(void); extern int sme_get_current_vl(void);
extern void sme_suspend_exit(void);
/* /*
* Return how many bytes of memory are required to store the full SME * Return how many bytes of memory are required to store the full SME
...@@ -421,6 +422,7 @@ static inline int sme_max_vl(void) { return 0; } ...@@ -421,6 +422,7 @@ static inline int sme_max_vl(void) { return 0; }
static inline int sme_max_virtualisable_vl(void) { return 0; } static inline int sme_max_virtualisable_vl(void) { return 0; }
static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; } static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
static inline int sme_get_current_vl(void) { return -EINVAL; } static inline int sme_get_current_vl(void) { return -EINVAL; }
static inline void sme_suspend_exit(void) { }
static inline size_t sme_state_size(struct task_struct const *task) static inline size_t sme_state_size(struct task_struct const *task)
{ {
......
...@@ -15,10 +15,6 @@ ...@@ -15,10 +15,6 @@
#define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE #define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE
/*
* Prefer the constraint "S" to support PIC with GCC. Clang before 19 does not
* support "S" on a symbol with a constant offset, so we use "i" as a fallback.
*/
static __always_inline bool arch_static_branch(struct static_key * const key, static __always_inline bool arch_static_branch(struct static_key * const key,
const bool branch) const bool branch)
{ {
...@@ -27,9 +23,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key, ...@@ -27,9 +23,9 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
" .pushsection __jump_table, \"aw\" \n\t" " .pushsection __jump_table, \"aw\" \n\t"
" .align 3 \n\t" " .align 3 \n\t"
" .long 1b - ., %l[l_yes] - . \n\t" " .long 1b - ., %l[l_yes] - . \n\t"
" .quad (%[key] - .) + %[bit0] \n\t" " .quad %c0 - . \n\t"
" .popsection \n\t" " .popsection \n\t"
: : [key]"Si"(key), [bit0]"i"(branch) : : l_yes); : : "i"(&((char *)key)[branch]) : : l_yes);
return false; return false;
l_yes: l_yes:
...@@ -44,9 +40,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke ...@@ -44,9 +40,9 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
" .pushsection __jump_table, \"aw\" \n\t" " .pushsection __jump_table, \"aw\" \n\t"
" .align 3 \n\t" " .align 3 \n\t"
" .long 1b - ., %l[l_yes] - . \n\t" " .long 1b - ., %l[l_yes] - . \n\t"
" .quad (%[key] - .) + %[bit0] \n\t" " .quad %c0 - . \n\t"
" .popsection \n\t" " .popsection \n\t"
: : [key]"Si"(key), [bit0]"i"(branch) : : l_yes); : : "i"(&((char *)key)[branch]) : : l_yes);
return false; return false;
l_yes: l_yes:
......
...@@ -1311,6 +1311,22 @@ void __init sme_setup(void) ...@@ -1311,6 +1311,22 @@ void __init sme_setup(void)
get_sme_default_vl()); get_sme_default_vl());
} }
void sme_suspend_exit(void)
{
u64 smcr = 0;
if (!system_supports_sme())
return;
if (system_supports_fa64())
smcr |= SMCR_ELx_FA64;
if (system_supports_sme2())
smcr |= SMCR_ELx_EZT0;
write_sysreg_s(smcr, SYS_SMCR_EL1);
write_sysreg_s(0, SYS_SMPRI_EL1);
}
#endif /* CONFIG_ARM64_SME */ #endif /* CONFIG_ARM64_SME */
static void sve_init_regs(void) static void sve_init_regs(void)
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <asm/daifflags.h> #include <asm/daifflags.h>
#include <asm/debug-monitors.h> #include <asm/debug-monitors.h>
#include <asm/exec.h> #include <asm/exec.h>
#include <asm/fpsimd.h>
#include <asm/mte.h> #include <asm/mte.h>
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
...@@ -80,6 +81,8 @@ void notrace __cpu_suspend_exit(void) ...@@ -80,6 +81,8 @@ void notrace __cpu_suspend_exit(void)
*/ */
spectre_v4_enable_mitigation(NULL); spectre_v4_enable_mitigation(NULL);
sme_suspend_exit();
/* Restore additional feature-specific configuration */ /* Restore additional feature-specific configuration */
ptrauth_suspend_exit(); ptrauth_suspend_exit();
} }
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
#define CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK GENMASK_ULL(63, 59) #define CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK GENMASK_ULL(63, 59)
#define CXL_PMU_FILTER_CFG_REG(n, f) (0x400 + 4 * ((f) + (n) * 8)) #define CXL_PMU_FILTER_CFG_REG(n, f) (0x400 + 4 * ((f) + (n) * 8))
#define CXL_PMU_FILTER_CFG_VALUE_MSK GENMASK(15, 0) #define CXL_PMU_FILTER_CFG_VALUE_MSK GENMASK(31, 0)
#define CXL_PMU_COUNTER_REG(n) (0xc00 + 8 * (n)) #define CXL_PMU_COUNTER_REG(n) (0xc00 + 8 * (n))
...@@ -314,9 +314,9 @@ static bool cxl_pmu_config1_get_edge(struct perf_event *event) ...@@ -314,9 +314,9 @@ static bool cxl_pmu_config1_get_edge(struct perf_event *event)
} }
/* /*
* CPMU specification allows for 8 filters, each with a 16 bit value... * CPMU specification allows for 8 filters, each with a 32 bit value...
* So we need to find 8x16bits to store it in. * So we need to find 8x32bits to store it in.
* As the value used for disable is 0xffff, a separate enable switch * As the value used for disable is 0xffff_ffff, a separate enable switch
* is needed. * is needed.
*/ */
...@@ -642,7 +642,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags) ...@@ -642,7 +642,7 @@ static void cxl_pmu_event_start(struct perf_event *event, int flags)
if (cxl_pmu_config1_hdm_filter_en(event)) if (cxl_pmu_config1_hdm_filter_en(event))
cfg = cxl_pmu_config2_get_hdm_decoder(event); cfg = cxl_pmu_config2_get_hdm_decoder(event);
else else
cfg = GENMASK(15, 0); /* No filtering if 0xFFFF_FFFF */ cfg = GENMASK(31, 0); /* No filtering if 0xFFFF_FFFF */
writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0)); writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0));
} }
......
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