Commit 358dd4a9 authored by Marc Zyngier's avatar Marc Zyngier Committed by Catalin Marinas
Browse files

arm64: Add command-line override for ID_AA64MMFR0_EL1.ECV



It appears that relatively popular hardware out there implements
the CNTPOFF_EL2 variant of FEAT_ECV, advertises it via ID_AA64MMFR0_EL1,
but cannot be bothered to set SCR_EL3.ECVEn to 1.

You would probably think that "this is fine, EL3 will take the
trap on access to CNTPOFF_EL2 and flip the ECVEn bit", as that's
what a semi-decent firmware implementation would do.

But no. None of that. This particular implementation takes the trap,
considers its purpose in life, decides that it has none, and *RESETS*
the system.

Yes, x1e001de, I'm talking about you.

In order to allow this machine to be promoted slightly above the
level of a glorified door-stop, add a new "id_aa64mmfr0.ecv" override.
allowing the kernel to pretend this option was never there.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20241021181434.1052974-1-maz@kernel.org


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 0f612c6e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -38,6 +38,15 @@ struct ftr_set_desc {

#define FIELD(n, s, f)	{ .name = n, .shift = s, .width = 4, .filter = f }

static const struct ftr_set_desc mmfr0 __prel64_initconst = {
	.name		= "id_aa64mmfr0",
	.override	= &id_aa64mmfr0_override,
	.fields		= {
		FIELD("ecv", ID_AA64MMFR0_EL1_ECV_SHIFT, NULL),
		{}
	},
};

static bool __init mmfr1_vh_filter(u64 val)
{
	/*
@@ -196,6 +205,7 @@ static const struct ftr_set_desc sw_features __prel64_initconst = {

static const
PREL64(const struct ftr_set_desc, reg) regs[] __prel64_initconst = {
	{ &mmfr0	},
	{ &mmfr1	},
	{ &mmfr2	},
	{ &pfr0 	},