diff mbox series

[v2,1/3] arm64: cpufeature: Extract capped fields

Message ID 20191210120146.2942-2-andrew.murray@arm.com (mailing list archive)
State New, archived
Headers show
Series arm64: perf: Add support for ARMv8.5-PMU 64-bit counters | expand

Commit Message

Andrew Murray Dec. 10, 2019, 12:01 p.m. UTC
When emulating ID registers there is often a need to cap the version
bits of a feature such that the guest will not use features that do
not yet exist.

Let's add a helper that extracts a field and caps the version to a
given value.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/include/asm/cpufeature.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Comments

Suzuki K Poulose Dec. 11, 2019, 3:20 p.m. UTC | #1
Hi Andrew,

On 10/12/2019 12:01, Andrew Murray wrote:
> When emulating ID registers there is often a need to cap the version
> bits of a feature such that the guest will not use features that do
> not yet exist.
> 
> Let's add a helper that extracts a field and caps the version to a
> given value.
> 
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
>   arch/arm64/include/asm/cpufeature.h | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 4261d55e8506..19f051ec1610 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -447,6 +447,21 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
>   	return cpuid_feature_extract_unsigned_field_width(features, field, 4);
>   }
>   
> +static inline u64 __attribute_const__
> +cpuid_feature_cap_signed_field_width(u64 features, int field, int width,
> +				     s64 cap)
> +{
> +	s64 val = cpuid_feature_extract_signed_field_width(features, field,
> +							   width);
> +
> +	if (val > cap) {
> +		features &= ~GENMASK_ULL(field + width - 1, field);
> +		features |= cap << field;

Please could we make sure that the "cap" is masked to "width" bits. 
Otherwise looks good to me.

Suzuki
diff mbox series

Patch

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 4261d55e8506..19f051ec1610 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -447,6 +447,21 @@  cpuid_feature_extract_unsigned_field(u64 features, int field)
 	return cpuid_feature_extract_unsigned_field_width(features, field, 4);
 }
 
+static inline u64 __attribute_const__
+cpuid_feature_cap_signed_field_width(u64 features, int field, int width,
+				     s64 cap)
+{
+	s64 val = cpuid_feature_extract_signed_field_width(features, field,
+							   width);
+
+	if (val > cap) {
+		features &= ~GENMASK_ULL(field + width - 1, field);
+		features |= cap << field;
+	}
+
+	return features;
+}
+
 static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
 {
 	return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);