From: Dave.Martin@arm.com (Dave Martin)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 19/22] arm64: capabilities: Handle shared entries
Date: Mon, 12 Feb 2018 17:17:37 +0000 [thread overview]
Message-ID: <20180212171736.GM5862@e103592.cambridge.arm.com> (raw)
In-Reply-To: <20180209175513.17100-39-suzuki.poulose@arm.com>
On Fri, Feb 09, 2018 at 05:55:08PM +0000, Suzuki K Poulose wrote:
> Some capabilities have different criteria for detection and associated
> actions based on the matching criteria, even though they all share the
> same capability bit. So far we have used multiple entries with the same
> capability bit to handle this. This is prone to errors, as the
> cpu_enable is invoked for each entry, irrespective of whether the
> detection rule applies to the CPU or not. And also this complicates
> other helpers, e.g, __this_cpu_has_cap.
>
> This patch adds a wrapper entry to cover all the possible variations
> of a capability by maintaining list of matches + cpu_enable callbacks.
> To avoid complicating the prototypes for the "matches()", we use
> arm64_cpu_capabilities maintain the list and we ignore all the other
> fields except the matches & cpu_enable.
>
> This ensures :
>
> 1) The capabilitiy is set when at least one of the entry detects
> 2) Action is only taken for the entries that "matches".
>
> This avoids explicit checks in the cpu_enable() take some action.
> The only constraint here is that, all the entries should have the
> same "type" (i.e, scope and conflict rules).
>
> If a cpu_enable() method is associated with multiple matches for a
> single capability, care should be taken that either the match criteria
> are mutually exclusive, or that the method is robust against being
> called multiple times.
>
> This also reverts the changes introduced by commit 67948af41f2e6818ed
> ("arm64: capabilities: Handle duplicate entries for a capability").
>
> Cc: Dave Martin <dave.martin@arm.com>
> Cc: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> arch/arm64/include/asm/cpufeature.h | 11 ++++++++
> arch/arm64/kernel/cpu_errata.c | 53 ++++++++++++++++++++++++++++++++-----
> arch/arm64/kernel/cpufeature.c | 10 +++----
> 3 files changed, 61 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 3ab1c3422f14..074537acc08b 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -306,6 +306,17 @@ struct arm64_cpu_capabilities {
> bool sign;
> unsigned long hwcap;
> };
> + /*
> + * A list of "matches/cpu_enable" pair for the same "capability"
> + * of the same "type" as described by the parent. All the
> + * fields, except "matches"/"cpu_enable" are ignored in the list.
Nit: This is not quite true: other fields may be needed, for use by the
matches() method -- for example, if matches == has_cpuid_feature, then
sys_reg, field_pos etc. will be used.
To keep things simple, maybe say "Only matches(), cpu_enable() and
fields relevant to these methods are significant in the list." ?
> + * The cpu_enable is invoked only if the corresponding entry
> + * "matches()". However, if a cpu_enable() method is associated
> + * with multiple matches, care should be taken that either the
> + * match criteria are mutually exclusive, or that the method is
> + * robust against being called multiple times.
> + */
> + const struct arm64_cpu_capabilities *cap_list;
Nit: this is not really a list of capabilities, as noted above.
Can we call it something like "match_list"?
> };
> };
>
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index a602a3049404..902d281ea26f 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -264,6 +264,36 @@ qcom_enable_link_stack_sanitization(const struct arm64_cpu_capabilities *entry)
> .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, \
> CAP_MIDR_RANGE_LIST(midr_list)
>
> +/*
> + * Generic helper for handling capabilties with multiple (match,enable) pairs
> + * of call backs, sharing the same capability bit.
> + * Iterate over each entry to see if at least one matches.
> + */
> +static bool multi_entry_cap_matches(const struct arm64_cpu_capabilities *entry,
> + int scope)
> +{
> + const struct arm64_cpu_capabilities *caps = entry->cap_list;
> +
> + for (; caps->matches; caps++)
> + if (caps->matches(caps, scope))
> + return true;
Nit: add blank line?
> + return false;
> +}
> +
> +/*
> + * Take appropriate action for all matching entries in the shared capability
> + * entry.
> + */
> +static void multi_entry_cap_cpu_enable(const struct arm64_cpu_capabilities *entry)
> +{
> + const struct arm64_cpu_capabilities *caps = entry->cap_list;
> +
> + for (; caps->matches; caps++)
Nit: can we move the initialiser into the for(); so
for (entry->cap_list; caps->matches; [...]
IMHO it's more readable to avoid empty expressions in for() unless
there's a good reason.
> + if (caps->matches(caps, SCOPE_LOCAL_CPU) &&
> + caps->cpu_enable)
> + caps->cpu_enable(caps);
> +}
> +
> #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
>
> /*
> @@ -280,6 +310,18 @@ static const struct midr_range arm64_bp_harden_psci_cpus[] = {
> {},
> };
>
> +static const struct arm64_cpu_capabilities arm64_bp_harden_list[] = {
> + {
> + CAP_MIDR_RANGE_LIST(arm64_bp_harden_psci_cpus),
> + .cpu_enable = enable_smccc_arch_workaround_1,
> + },
> + {
> + CAP_MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
> + .cpu_enable = qcom_enable_link_stack_sanitization,
> + },
> + {},
> +};
> +
> #endif
>
> const struct arm64_cpu_capabilities arm64_errata[] = {
> @@ -416,13 +458,10 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
> #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
> {
> .capability = ARM64_HARDEN_BRANCH_PREDICTOR,
> - ERRATA_MIDR_RANGE_LIST(arm64_bp_harden_psci_cpus),
> - .cpu_enable = enable_smccc_arch_workaround_1,
> - },
> - {
> - .capability = ARM64_HARDEN_BRANCH_PREDICTOR,
> - ERRATA_MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
> - .cpu_enable = qcom_enable_link_stack_sanitization,
> + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
> + .matches = multi_entry_cap_matches,
> + .cpu_enable = multi_entry_cap_cpu_enable,
> + .cap_list = arm64_bp_harden_list,
> },
> {
> .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 9eb9e9570468..d8663822c604 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1225,9 +1225,8 @@ static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array,
> return false;
>
> for (caps = cap_array; caps->matches; caps++)
> - if (caps->capability == cap &&
> - caps->matches(caps, SCOPE_LOCAL_CPU))
> - return true;
> + if (caps->capability == cap)
> + return caps->matches(caps, SCOPE_LOCAL_CPU);
Nit: add blank line?
> return false;
> }
>
> @@ -1313,18 +1312,17 @@ static void __init enable_cpu_capabilities(u16 scope_mask)
> *
> * Returns "false" on conflicts.
> */
> -static bool __verify_local_cpu_caps(const struct arm64_cpu_capabilities *caps_list,
> +static bool __verify_local_cpu_caps(const struct arm64_cpu_capabilities *caps,
> u16 scope_mask)
> {
> bool cpu_has_cap, system_has_cap;
> - const struct arm64_cpu_capabilities *caps = caps_list;
>
> scope_mask &= ARM64_CPUCAP_SCOPE_MASK;
> for (; caps->matches; caps++) {
> if (!(caps->type & scope_mask))
> continue;
>
> - cpu_has_cap = __this_cpu_has_cap(caps_list, caps->capability);
> + cpu_has_cap = caps->matches(caps, SCOPE_LOCAL_CPU);
> system_has_cap = cpus_have_cap(caps->capability);
>
> if (system_has_cap) {
> --
> 2.14.3
>
With fair consideration to the nits above,
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
next prev parent reply other threads:[~2018-02-12 17:17 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-09 17:54 [PATCH v3 00/21] arm64: Rework cpu capabilities handling Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 01/21] arm64: capabilities: Move errata work around check on boot CPU Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 01/22] arm64: capabilities: Update prototype for enable call back Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 02/21] arm64: capabilities: Move errata processing code Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 02/22] arm64: capabilities: Move errata work around check on boot CPU Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 03/22] arm64: capabilities: Move errata processing code Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 03/21] arm64: capabilities: Prepare for fine grained capabilities Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 04/21] arm64: capabilities: Add flags to handle the conflicts on late CPU Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 04/22] arm64: capabilities: Prepare for fine grained capabilities Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 05/22] arm64: capabilities: Add flags to handle the conflicts on late CPU Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 05/21] arm64: capabilities: Unify the verification Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 06/21] arm64: capabilities: Filter the entries based on a given mask Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 06/22] arm64: capabilities: Unify the verification Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 07/22] arm64: capabilities: Filter the entries based on a given mask Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 07/21] arm64: capabilities: Prepare for grouping features and errata work arounds Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 08/22] " Suzuki K Poulose
2018-02-09 18:11 ` Dave Martin
2018-02-09 17:54 ` [PATCH v3 08/21] arm64: capabilities: Split the processing of " Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 09/21] arm64: capabilities: Allow features based on local CPU scope Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 09/22] arm64: capabilities: Split the processing of errata work arounds Suzuki K Poulose
2018-02-09 18:18 ` Dave Martin
2018-03-08 12:24 ` Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 10/22] arm64: capabilities: Allow features based on local CPU scope Suzuki K Poulose
2018-02-09 18:22 ` Dave Martin
2018-03-08 12:14 ` Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 10/21] arm64: capabilities: Group handling of features and errata workarounds Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 11/22] " Suzuki K Poulose
2018-02-09 18:25 ` Dave Martin
2018-02-09 17:54 ` [PATCH v3 11/21] arm64: capabilities: Introduce weak features based on local CPU Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 12/22] " Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 12/21] arm64: capabilities: Restrict KPTI detection to boot-time CPUs Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 13/21] arm64: capabilities: Add support for features enabled early Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 13/22] arm64: capabilities: Restrict KPTI detection to boot-time CPUs Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 14/22] arm64: capabilities: Add support for features enabled early Suzuki K Poulose
2018-02-12 17:17 ` Dave Martin
2018-03-07 17:42 ` Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 14/21] arm64: capabilities: Change scope of VHE to Boot CPU feature Suzuki K Poulose
2018-02-09 17:54 ` [PATCH v3 15/22] " Suzuki K Poulose
2018-02-12 17:17 ` Dave Martin
2018-03-08 12:10 ` Suzuki K Poulose
2018-03-08 13:43 ` Dave Martin
2018-02-09 17:55 ` [PATCH v3 15/21] arm64: capabilities: Clean up midr range helpers Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 16/21] arm64: Add helpers for checking CPU MIDR against a range Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 16/22] arm64: capabilities: Clean up midr range helpers Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 17/22] arm64: Add helpers for checking CPU MIDR against a range Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 17/21] arm64: capabilities: Add support for checks based on a list of MIDRs Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 18/22] " Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 18/21] arm64: capabilities: Handle shared entries Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 19/21] arm64: Add MIDR encoding for Arm Cortex-A55 and Cortex-A35 Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 19/22] arm64: capabilities: Handle shared entries Suzuki K Poulose
2018-02-12 17:17 ` Dave Martin [this message]
2018-03-08 12:16 ` Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 20/22] arm64: Add MIDR encoding for Arm Cortex-A55 and Cortex-A35 Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 20/21] arm64: Delay enabling hardware DBM feature Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 21/21] arm64: Add work around for Arm Cortex-A55 Erratum 1024718 Suzuki K Poulose
2018-02-09 17:55 ` [PATCH v3 21/22] arm64: Delay enabling hardware DBM feature Suzuki K Poulose
2018-02-09 18:58 ` Dave Martin
2018-03-07 17:39 ` Suzuki K Poulose
2018-03-08 13:53 ` Dave Martin
2018-03-08 13:55 ` Mark Rutland
2018-02-09 17:55 ` [PATCH v3 22/22] arm64: Add work around for Arm Cortex-A55 Erratum 1024718 Suzuki K Poulose
2018-02-09 18:04 ` [PATCH v3 00/21] arm64: Rework cpu capabilities handling Suzuki K Poulose
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180212171736.GM5862@e103592.cambridge.arm.com \
--to=dave.martin@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).