Unverified Commit 35807891 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11757 arm64/mpam: Check mpam_detect_is_enabled() before accessing MPAM registers

Merge Pull Request from: @ci-robot 
 
PR sync from: Zeng Heng <zengheng4@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/TMDAU2DLVLTJLYVCCV53LPREMIOBOKQQ/ 
Zeng Heng (2):
  Revert "arm64: head.S: Initialise MPAM EL2 registers and disable
    traps"
  arm64/mpam: Check mpam_detect_is_enabled() before accessing MPAM
    registers


--
2.25.1
 
https://gitee.com/src-openeuler/kernel/issues/I9OXPO 
 
Link:https://gitee.com/openeuler/kernel/pulls/11757

 

Reviewed-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Reviewed-by: default avatarZhang Peng <zhangpeng362@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents d25e57f4 ab331ac5
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -858,6 +858,15 @@ static inline bool cpus_support_mpam(void)
		cpus_have_final_cap(ARM64_MPAM);
}

#ifdef CONFIG_ARM64_MPAM
bool mpam_detect_is_enabled(void);
#else
static inline bool mpam_detect_is_enabled(void)
{
	return false;
}
#endif

int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);

+0 −16
Original line number Diff line number Diff line
@@ -209,21 +209,6 @@
	msr	spsr_el2, x0
.endm

.macro __init_el2_mpam
#ifdef CONFIG_ARM64_MPAM
	/* Memory Partioning And Monitoring: disable EL2 traps */
	mrs	x1, id_aa64pfr0_el1
	ubfx	x0, x1, #ID_AA64PFR0_EL1_MPAM_SHIFT, #4
	cbz	x0, .Lskip_mpam_\@		// skip if no MPAM
	msr_s	SYS_MPAM2_EL2, xzr		// use the default partition
						// and disable lower traps
	mrs_s	x0, SYS_MPAMIDR_EL1
	tbz	x0, #17, .Lskip_mpam_\@		// skip if no MPAMHCR reg
	msr_s	SYS_MPAMHCR_EL2, xzr		// clear TRAP_MPAMIDR_EL1 -> EL2
.Lskip_mpam_\@:
#endif /* CONFIG_ARM64_MPAM */
.endm

/**
 * Initialize EL2 registers to sane values. This should be called early on all
 * cores that were booted in EL2. Note that everything gets initialised as
@@ -241,7 +226,6 @@
	__init_el2_stage2
	__init_el2_gicv3
	__init_el2_hstr
	__init_el2_mpam
	__init_el2_nvhe_idregs
	__init_el2_cptr
	__init_el2_fgt
+35 −4
Original line number Diff line number Diff line
@@ -1078,8 +1078,9 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
		vec_init_vq_map(ARM64_VEC_SME);
	}

	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) ||
	    id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1))
	if (mpam_detect_is_enabled() &&
	   (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) ||
	    id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1)))
		init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr);

	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
@@ -1341,8 +1342,9 @@ void update_cpu_features(int cpu,
			vec_update_vq_map(ARM64_VEC_SME);
	}

	if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) ||
	    id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1)) {
	if (mpam_detect_is_enabled() &&
	   (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) ||
	    id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1))) {
		taint |= check_update_ftr_reg(SYS_MPAMIDR_EL1, cpu,
					info->reg_mpamidr, boot->reg_mpamidr);
	}
@@ -2307,6 +2309,19 @@ cpucap_panic_on_conflict(const struct arm64_cpu_capabilities *cap)
	return !!(cap->type & ARM64_CPUCAP_PANIC_ON_CONFLICT);
}

static bool __read_mostly mpam_force_enabled;
bool mpam_detect_is_enabled(void)
{
	return mpam_force_enabled;
}

static int __init mpam_setup(char *str)
{
	mpam_force_enabled = true;
	return 0;
}
early_param("arm64.mpam", mpam_setup);

static bool __maybe_unused
test_has_mpam(const struct arm64_cpu_capabilities *entry, int scope)
{
@@ -2317,6 +2332,12 @@ test_has_mpam(const struct arm64_cpu_capabilities *entry, int scope)
	    !id_aa64pfr1_mpamfrac(pfr1))
		return false;

	if (is_kdump_kernel())
		return false;

	if (!mpam_detect_is_enabled())
		return false;

	/* Check firmware actually enabled MPAM on this cpu. */
	return (read_sysreg_s(SYS_MPAM1_EL1) & MPAM_SYSREG_EN);
}
@@ -2324,6 +2345,16 @@ test_has_mpam(const struct arm64_cpu_capabilities *entry, int scope)
static void __maybe_unused
cpu_enable_mpam(const struct arm64_cpu_capabilities *entry)
{
	u64 idr = read_sanitised_ftr_reg(SYS_MPAMIDR_EL1);

	/*
	 * Initialise MPAM EL2 registers and disable EL2 traps.
	 */
	write_sysreg_s(0, SYS_MPAM2_EL2);

	if (idr & MPAMIDR_HAS_HCR)
		write_sysreg_s(0, SYS_MPAMHCR_EL2);

	/*
	 * Access by the kernel (at EL1) should use the reserved PARTID
	 * which is configured unrestricted. This avoids priority-inversion
+1 −0
Original line number Diff line number Diff line
@@ -461,6 +461,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
		__cpuinfo_store_cpu_32bit(&info->aarch32);

	if (IS_ENABLED(CONFIG_ARM64_MPAM) &&
	    mpam_detect_is_enabled() &&
	   (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) ||
	    id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1)))
		info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
+11 −4
Original line number Diff line number Diff line
@@ -15,13 +15,20 @@ DEFINE_PER_CPU(u64, arm64_mpam_current);

static int __init arm64_mpam_register_cpus(void)
{
	u16 partid_max;
	u64 mpamidr;
	u8 pmg_max;

	if (is_kdump_kernel())
		return 0;

	u64 mpamidr = read_sanitised_ftr_reg(SYS_MPAMIDR_EL1);
	u16 partid_max = FIELD_GET(MPAMIDR_PARTID_MAX, mpamidr);
	u8 pmg_max = FIELD_GET(MPAMIDR_PMG_MAX, mpamidr);
	if (!mpam_cpus_have_feature())
		return 0;

	mpamidr = read_sanitised_ftr_reg(SYS_MPAMIDR_EL1);
	partid_max = FIELD_GET(MPAMIDR_PARTID_MAX, mpamidr);
	pmg_max = FIELD_GET(MPAMIDR_PMG_MAX, mpamidr);

	return mpam_register_requestor(partid_max, pmg_max);
}
arch_initcall(arm64_mpam_register_cpus)
arch_initcall(arm64_mpam_register_cpus);