Skip to content
cpufeature.c 101 KiB
Newer Older
	rc = emulate_sys_reg(sys_reg, &val);
	if (!rc) {
		pt_regs_write_reg(regs, rt, val);
		arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
static int emulate_mrs(struct pt_regs *regs, u32 insn)
{
	u32 sys_reg, rt;

	/*
	 * sys_reg values are defined as used in mrs/msr instruction.
	 * shift the imm value to get the encoding.
	 */
	sys_reg = (u32)aarch64_insn_decode_immediate(AARCH64_INSN_IMM_16, insn) << 5;
	rt = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RT, insn);
	return do_emulate_mrs(regs, sys_reg, rt);
}

static struct undef_hook mrs_hook = {
	.instr_mask = 0xffff0000,
	.instr_val  = 0xd5380000,
	.pstate_mask = PSR_AA32_MODE_MASK,
	.pstate_val = PSR_MODE_EL0t,
	.fn = emulate_mrs,
};

static int __init enable_mrs_emulation(void)
{
	register_undef_hook(&mrs_hook);
	return 0;
}

core_initcall(enable_mrs_emulation);
enum mitigation_state arm64_get_meltdown_state(void)
{
	if (__meltdown_safe)
		return SPECTRE_UNAFFECTED;

	if (arm64_kernel_unmapped_at_el0())
		return SPECTRE_MITIGATED;

	return SPECTRE_VULNERABLE;
}

ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	switch (arm64_get_meltdown_state()) {
	case SPECTRE_UNAFFECTED:
		return sprintf(buf, "Not affected\n");

	case SPECTRE_MITIGATED:
		return sprintf(buf, "Mitigation: PTI\n");

	default:
		return sprintf(buf, "Vulnerable\n");
	}