linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] arm64: Add command-line override for ID_AA64ISAR0_EL1.ATOMIC
@ 2025-09-02  9:28 Neil Armstrong
  2025-09-02  9:57 ` Mark Rutland
  0 siblings, 1 reply; 2+ messages in thread
From: Neil Armstrong @ 2025-09-02  9:28 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon
  Cc: linux-arm-kernel, linux-kernel, Neil Armstrong

Implement overriding AA64ISAR0_EL1 to set the ATOMIC feature bits,
allowing booting with LSE Atomic disabled in case the feature
is badly advertised as implemented or incorrectly masked by
the hypervisor.

Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
 arch/arm64/include/asm/cpufeature.h   | 1 +
 arch/arm64/kernel/cpufeature.c        | 4 +++-
 arch/arm64/kernel/image-vars.h        | 1 +
 arch/arm64/kernel/pi/idreg-override.c | 9 +++++++++
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index bf13d676aae2cc9903c83e9a3c4be0ad4bc86204..74fa9efd6938905a6397c78aeddb03a134d4d8c9 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -963,6 +963,7 @@ extern struct arm64_ftr_override id_aa64pfr0_override;
 extern struct arm64_ftr_override id_aa64pfr1_override;
 extern struct arm64_ftr_override id_aa64zfr0_override;
 extern struct arm64_ftr_override id_aa64smfr0_override;
+extern struct arm64_ftr_override id_aa64isar0_override;
 extern struct arm64_ftr_override id_aa64isar1_override;
 extern struct arm64_ftr_override id_aa64isar2_override;
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index ef269a5a37e12c53e8e825e947b910f6d3efd296..1084475c479b0101e151ff7dfc12c7b79506cbed 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -778,6 +778,7 @@ struct arm64_ftr_override __read_mostly id_aa64pfr0_override;
 struct arm64_ftr_override __read_mostly id_aa64pfr1_override;
 struct arm64_ftr_override __read_mostly id_aa64zfr0_override;
 struct arm64_ftr_override __read_mostly id_aa64smfr0_override;
+struct arm64_ftr_override __read_mostly id_aa64isar0_override;
 struct arm64_ftr_override __read_mostly id_aa64isar1_override;
 struct arm64_ftr_override __read_mostly id_aa64isar2_override;
 
@@ -832,7 +833,8 @@ static const struct __ftr_reg_entry {
 	ARM64_FTR_REG(SYS_ID_AA64DFR1_EL1, ftr_raz),
 
 	/* Op1 = 0, CRn = 0, CRm = 6 */
-	ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
+	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0,
+			       &id_aa64isar0_override),
 	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1,
 			       &id_aa64isar1_override),
 	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2,
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 714b0b5ec5ac4a64037834545b0246eb04fb2bce..10deaa63ce7f801fb96d69fc97ae033bcea73fb1 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -46,6 +46,7 @@ PROVIDE(__pi___memcpy			= __pi_memcpy);
 PROVIDE(__pi___memmove			= __pi_memmove);
 PROVIDE(__pi___memset			= __pi_memset);
 
+PI_EXPORT_SYM(id_aa64isar0_override);
 PI_EXPORT_SYM(id_aa64isar1_override);
 PI_EXPORT_SYM(id_aa64isar2_override);
 PI_EXPORT_SYM(id_aa64mmfr0_override);
diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index bc57b290e5e7bab51a9de90d23fe36e1640e4b6b..326fa7d69b6df044d840164be3b504af6d8e8482 100644
--- a/arch/arm64/kernel/pi/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -160,6 +160,14 @@ static const struct ftr_set_desc pfr1 __prel64_initconst = {
 	},
 };
 
+static const struct ftr_set_desc isar0 __prel64_initconst = {
+	.name		= "id_aa64isar0",
+	.override	= &id_aa64isar0_override,
+	.fields		= {
+		FIELD("atomic", ID_AA64ISAR0_EL1_ATOMIC_SHIFT, NULL),
+		{}
+	},
+};
 static const struct ftr_set_desc isar1 __prel64_initconst = {
 	.name		= "id_aa64isar1",
 	.override	= &id_aa64isar1_override,
@@ -222,6 +230,7 @@ PREL64(const struct ftr_set_desc, reg) regs[] __prel64_initconst = {
 	{ &mmfr2	},
 	{ &pfr0 	},
 	{ &pfr1 	},
+	{ &isar0	},
 	{ &isar1	},
 	{ &isar2	},
 	{ &smfr0	},

---
base-commit: 33bcf93b9a6b028758105680f8b538a31bc563cf
change-id: 20250902-topic-arm64-pi-aa64isar0-atomic-8fdd47558eee

Best regards,
-- 
Neil Armstrong <neil.armstrong@linaro.org>


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] arm64: Add command-line override for ID_AA64ISAR0_EL1.ATOMIC
  2025-09-02  9:28 [PATCH] arm64: Add command-line override for ID_AA64ISAR0_EL1.ATOMIC Neil Armstrong
@ 2025-09-02  9:57 ` Mark Rutland
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Rutland @ 2025-09-02  9:57 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Catalin Marinas, Will Deacon, linux-arm-kernel, linux-kernel

Hi Neil,

On Tue, Sep 02, 2025 at 11:28:45AM +0200, Neil Armstrong wrote:
> Implement overriding AA64ISAR0_EL1 to set the ATOMIC feature bits,
> allowing booting with LSE Atomic disabled in case the feature
> is badly advertised as implemented or incorrectly masked by
> the hypervisor.

Can you say a bit more about where you intend to use this?

We had a similar request in the past:

  https://lore.kernel.org/linux-arm-kernel/20230710055955.36551-1-quic_aiquny@quicinc.com/

... but IIRC in that case the CPU was just mis-configured (to emit
atomic transactions to interconnect when the interconnect did not
support those), and since there are no traps for LSE atomics, hiding
them isn't a complete workaround.

Any more detail on this would be helpful.

Mark.

> 
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
>  arch/arm64/include/asm/cpufeature.h   | 1 +
>  arch/arm64/kernel/cpufeature.c        | 4 +++-
>  arch/arm64/kernel/image-vars.h        | 1 +
>  arch/arm64/kernel/pi/idreg-override.c | 9 +++++++++
>  4 files changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index bf13d676aae2cc9903c83e9a3c4be0ad4bc86204..74fa9efd6938905a6397c78aeddb03a134d4d8c9 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -963,6 +963,7 @@ extern struct arm64_ftr_override id_aa64pfr0_override;
>  extern struct arm64_ftr_override id_aa64pfr1_override;
>  extern struct arm64_ftr_override id_aa64zfr0_override;
>  extern struct arm64_ftr_override id_aa64smfr0_override;
> +extern struct arm64_ftr_override id_aa64isar0_override;
>  extern struct arm64_ftr_override id_aa64isar1_override;
>  extern struct arm64_ftr_override id_aa64isar2_override;
>  
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index ef269a5a37e12c53e8e825e947b910f6d3efd296..1084475c479b0101e151ff7dfc12c7b79506cbed 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -778,6 +778,7 @@ struct arm64_ftr_override __read_mostly id_aa64pfr0_override;
>  struct arm64_ftr_override __read_mostly id_aa64pfr1_override;
>  struct arm64_ftr_override __read_mostly id_aa64zfr0_override;
>  struct arm64_ftr_override __read_mostly id_aa64smfr0_override;
> +struct arm64_ftr_override __read_mostly id_aa64isar0_override;
>  struct arm64_ftr_override __read_mostly id_aa64isar1_override;
>  struct arm64_ftr_override __read_mostly id_aa64isar2_override;
>  
> @@ -832,7 +833,8 @@ static const struct __ftr_reg_entry {
>  	ARM64_FTR_REG(SYS_ID_AA64DFR1_EL1, ftr_raz),
>  
>  	/* Op1 = 0, CRn = 0, CRm = 6 */
> -	ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
> +	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0,
> +			       &id_aa64isar0_override),
>  	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1,
>  			       &id_aa64isar1_override),
>  	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2,
> diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
> index 714b0b5ec5ac4a64037834545b0246eb04fb2bce..10deaa63ce7f801fb96d69fc97ae033bcea73fb1 100644
> --- a/arch/arm64/kernel/image-vars.h
> +++ b/arch/arm64/kernel/image-vars.h
> @@ -46,6 +46,7 @@ PROVIDE(__pi___memcpy			= __pi_memcpy);
>  PROVIDE(__pi___memmove			= __pi_memmove);
>  PROVIDE(__pi___memset			= __pi_memset);
>  
> +PI_EXPORT_SYM(id_aa64isar0_override);
>  PI_EXPORT_SYM(id_aa64isar1_override);
>  PI_EXPORT_SYM(id_aa64isar2_override);
>  PI_EXPORT_SYM(id_aa64mmfr0_override);
> diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
> index bc57b290e5e7bab51a9de90d23fe36e1640e4b6b..326fa7d69b6df044d840164be3b504af6d8e8482 100644
> --- a/arch/arm64/kernel/pi/idreg-override.c
> +++ b/arch/arm64/kernel/pi/idreg-override.c
> @@ -160,6 +160,14 @@ static const struct ftr_set_desc pfr1 __prel64_initconst = {
>  	},
>  };
>  
> +static const struct ftr_set_desc isar0 __prel64_initconst = {
> +	.name		= "id_aa64isar0",
> +	.override	= &id_aa64isar0_override,
> +	.fields		= {
> +		FIELD("atomic", ID_AA64ISAR0_EL1_ATOMIC_SHIFT, NULL),
> +		{}
> +	},
> +};
>  static const struct ftr_set_desc isar1 __prel64_initconst = {
>  	.name		= "id_aa64isar1",
>  	.override	= &id_aa64isar1_override,
> @@ -222,6 +230,7 @@ PREL64(const struct ftr_set_desc, reg) regs[] __prel64_initconst = {
>  	{ &mmfr2	},
>  	{ &pfr0 	},
>  	{ &pfr1 	},
> +	{ &isar0	},
>  	{ &isar1	},
>  	{ &isar2	},
>  	{ &smfr0	},
> 
> ---
> base-commit: 33bcf93b9a6b028758105680f8b538a31bc563cf
> change-id: 20250902-topic-arm64-pi-aa64isar0-atomic-8fdd47558eee
> 
> Best regards,
> -- 
> Neil Armstrong <neil.armstrong@linaro.org>
> 
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-09-02  9:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-02  9:28 [PATCH] arm64: Add command-line override for ID_AA64ISAR0_EL1.ATOMIC Neil Armstrong
2025-09-02  9:57 ` Mark Rutland

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).