lkml.org 
[lkml]   [2018]   [Nov]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.18 069/350] arm64: cpufeature: ctr: Fix cpu capability check for late CPUs
    Date
    4.18-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Suzuki K Poulose <suzuki.poulose@arm.com>

    [ Upstream commit 8ab66cbe63aeaf9e5970fb4aaef1c660fca59321 ]

    The matches() routine for a capability must honor the "scope"
    passed to it and return the proper results.
    i.e, when passed with SCOPE_LOCAL_CPU, it should check the
    status of the capability on the current CPU. This is used by
    verify_local_cpu_capabilities() on a late secondary CPU to make
    sure that it's compliant with the established system features.
    However, ARM64_HAS_CACHE_{IDC/DIC} always checks the system wide
    registers and this could mean that a late secondary CPU could return
    "true" (since the CPU hasn't updated the system wide registers yet)
    and thus lead the system in an inconsistent state, where
    the system assumes it has IDC/DIC feature, while the new CPU
    doesn't.

    Fixes: commit 6ae4b6e0578886eb36 ("arm64: Add support for new control bits CTR_EL0.DIC and CTR_EL0.IDC")
    Cc: Philip Elcan <pelcan@codeaurora.org>
    Cc: Shanker Donthineni <shankerd@codeaurora.org>
    Cc: Mark Rutland <mark.rutland@arm.com>
    Cc: Will Deacon <will.deacon@arm.com>
    Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
    Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/arm64/kernel/cpufeature.c | 22 ++++++++++++++++++----
    1 file changed, 18 insertions(+), 4 deletions(-)

    --- a/arch/arm64/kernel/cpufeature.c
    +++ b/arch/arm64/kernel/cpufeature.c
    @@ -847,15 +847,29 @@ static bool has_no_fpsimd(const struct a
    }

    static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
    - int __unused)
    + int scope)
    {
    - return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_IDC_SHIFT);
    + u64 ctr;
    +
    + if (scope == SCOPE_SYSTEM)
    + ctr = arm64_ftr_reg_ctrel0.sys_val;
    + else
    + ctr = read_cpuid_cachetype();
    +
    + return ctr & BIT(CTR_IDC_SHIFT);
    }

    static bool has_cache_dic(const struct arm64_cpu_capabilities *entry,
    - int __unused)
    + int scope)
    {
    - return read_sanitised_ftr_reg(SYS_CTR_EL0) & BIT(CTR_DIC_SHIFT);
    + u64 ctr;
    +
    + if (scope == SCOPE_SYSTEM)
    + ctr = arm64_ftr_reg_ctrel0.sys_val;
    + else
    + ctr = read_cpuid_cachetype();
    +
    + return ctr & BIT(CTR_DIC_SHIFT);
    }

    #ifdef CONFIG_UNMAP_KERNEL_AT_EL0

    \
     
     \ /
      Last update: 2018-11-12 00:40    [W:2.271 / U:0.156 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site