static int update_32bit_cpu_features()

in kernel/cpufeature.c [1042:1111]


static int update_32bit_cpu_features(int cpu, struct cpuinfo_32bit *info,
				     struct cpuinfo_32bit *boot)
{
	int taint = 0;
	u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);

	/*
	 * If we don't have AArch32 at EL1, then relax the strictness of
	 * EL1-dependent register fields to avoid spurious sanity check fails.
	 */
	if (!id_aa64pfr0_32bit_el1(pfr0)) {
		relax_cpu_ftr_reg(SYS_ID_ISAR4_EL1, ID_ISAR4_SMC_SHIFT);
		relax_cpu_ftr_reg(SYS_ID_PFR1_EL1, ID_PFR1_VIRT_FRAC_SHIFT);
		relax_cpu_ftr_reg(SYS_ID_PFR1_EL1, ID_PFR1_SEC_FRAC_SHIFT);
		relax_cpu_ftr_reg(SYS_ID_PFR1_EL1, ID_PFR1_VIRTUALIZATION_SHIFT);
		relax_cpu_ftr_reg(SYS_ID_PFR1_EL1, ID_PFR1_SECURITY_SHIFT);
		relax_cpu_ftr_reg(SYS_ID_PFR1_EL1, ID_PFR1_PROGMOD_SHIFT);
	}

	taint |= check_update_ftr_reg(SYS_ID_DFR0_EL1, cpu,
				      info->reg_id_dfr0, boot->reg_id_dfr0);
	taint |= check_update_ftr_reg(SYS_ID_DFR1_EL1, cpu,
				      info->reg_id_dfr1, boot->reg_id_dfr1);
	taint |= check_update_ftr_reg(SYS_ID_ISAR0_EL1, cpu,
				      info->reg_id_isar0, boot->reg_id_isar0);
	taint |= check_update_ftr_reg(SYS_ID_ISAR1_EL1, cpu,
				      info->reg_id_isar1, boot->reg_id_isar1);
	taint |= check_update_ftr_reg(SYS_ID_ISAR2_EL1, cpu,
				      info->reg_id_isar2, boot->reg_id_isar2);
	taint |= check_update_ftr_reg(SYS_ID_ISAR3_EL1, cpu,
				      info->reg_id_isar3, boot->reg_id_isar3);
	taint |= check_update_ftr_reg(SYS_ID_ISAR4_EL1, cpu,
				      info->reg_id_isar4, boot->reg_id_isar4);
	taint |= check_update_ftr_reg(SYS_ID_ISAR5_EL1, cpu,
				      info->reg_id_isar5, boot->reg_id_isar5);
	taint |= check_update_ftr_reg(SYS_ID_ISAR6_EL1, cpu,
				      info->reg_id_isar6, boot->reg_id_isar6);

	/*
	 * Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and
	 * ACTLR formats could differ across CPUs and therefore would have to
	 * be trapped for virtualization anyway.
	 */
	taint |= check_update_ftr_reg(SYS_ID_MMFR0_EL1, cpu,
				      info->reg_id_mmfr0, boot->reg_id_mmfr0);
	taint |= check_update_ftr_reg(SYS_ID_MMFR1_EL1, cpu,
				      info->reg_id_mmfr1, boot->reg_id_mmfr1);
	taint |= check_update_ftr_reg(SYS_ID_MMFR2_EL1, cpu,
				      info->reg_id_mmfr2, boot->reg_id_mmfr2);
	taint |= check_update_ftr_reg(SYS_ID_MMFR3_EL1, cpu,
				      info->reg_id_mmfr3, boot->reg_id_mmfr3);
	taint |= check_update_ftr_reg(SYS_ID_MMFR4_EL1, cpu,
				      info->reg_id_mmfr4, boot->reg_id_mmfr4);
	taint |= check_update_ftr_reg(SYS_ID_MMFR5_EL1, cpu,
				      info->reg_id_mmfr5, boot->reg_id_mmfr5);
	taint |= check_update_ftr_reg(SYS_ID_PFR0_EL1, cpu,
				      info->reg_id_pfr0, boot->reg_id_pfr0);
	taint |= check_update_ftr_reg(SYS_ID_PFR1_EL1, cpu,
				      info->reg_id_pfr1, boot->reg_id_pfr1);
	taint |= check_update_ftr_reg(SYS_ID_PFR2_EL1, cpu,
				      info->reg_id_pfr2, boot->reg_id_pfr2);
	taint |= check_update_ftr_reg(SYS_MVFR0_EL1, cpu,
				      info->reg_mvfr0, boot->reg_mvfr0);
	taint |= check_update_ftr_reg(SYS_MVFR1_EL1, cpu,
				      info->reg_mvfr1, boot->reg_mvfr1);
	taint |= check_update_ftr_reg(SYS_MVFR2_EL1, cpu,
				      info->reg_mvfr2, boot->reg_mvfr2);

	return taint;
}