Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 621f48e4 authored by Tyler Baicar's avatar Tyler Baicar Committed by Will Deacon
Browse files

arm/arm64: KVM: add guest SEA support



Currently external aborts are unsupported by the guest abort
handling. Add handling for SEAs so that the host kernel reports
SEAs which occur in the guest kernel.

When an SEA occurs in the guest kernel, the guest exits and is
routed to kvm_handle_guest_abort(). Prior to this patch, a print
message of an unsupported FSC would be printed and nothing else
would happen. With this patch, the code gets routed to the APEI
handling of SEAs in the host kernel to report the SEA information.

Signed-off-by: default avatarTyler Baicar <tbaicar@codeaurora.org>
Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Acked-by: default avatarChristoffer Dall <cdall@linaro.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent e9279e83
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -187,6 +187,16 @@
#define FSC_FAULT	(0x04)
#define FSC_ACCESS	(0x08)
#define FSC_PERM	(0x0c)
#define FSC_SEA		(0x10)
#define FSC_SEA_TTW0	(0x14)
#define FSC_SEA_TTW1	(0x15)
#define FSC_SEA_TTW2	(0x16)
#define FSC_SEA_TTW3	(0x17)
#define FSC_SECC	(0x18)
#define FSC_SECC_TTW0	(0x1c)
#define FSC_SECC_TTW1	(0x1d)
#define FSC_SECC_TTW2	(0x1e)
#define FSC_SECC_TTW3	(0x1f)

/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
#define HPFAR_MASK	(~0xf)
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,11 @@ extern void (*arm_pm_idle)(void);

extern unsigned int user_debug;

static inline int handle_guest_sea(phys_addr_t addr, unsigned int esr)
{
	return -1;
}

#endif /* !__ASSEMBLY__ */

#endif /* __ASM_ARM_SYSTEM_MISC_H */
+10 −0
Original line number Diff line number Diff line
@@ -204,6 +204,16 @@
#define FSC_FAULT	ESR_ELx_FSC_FAULT
#define FSC_ACCESS	ESR_ELx_FSC_ACCESS
#define FSC_PERM	ESR_ELx_FSC_PERM
#define FSC_SEA		ESR_ELx_FSC_EXTABT
#define FSC_SEA_TTW0	(0x14)
#define FSC_SEA_TTW1	(0x15)
#define FSC_SEA_TTW2	(0x16)
#define FSC_SEA_TTW3	(0x17)
#define FSC_SECC	(0x18)
#define FSC_SECC_TTW0	(0x1c)
#define FSC_SECC_TTW1	(0x1d)
#define FSC_SECC_TTW2	(0x1e)
#define FSC_SECC_TTW3	(0x1f)

/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
#define HPFAR_MASK	(~UL(0xf))
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
	__show_ratelimited;						\
})

int handle_guest_sea(phys_addr_t addr, unsigned int esr);

#endif	/* __ASSEMBLY__ */

#endif	/* __ASM_SYSTEM_MISC_H */
+20 −2
Original line number Diff line number Diff line
@@ -532,6 +532,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
{
	struct siginfo info;
	const struct fault_info *inf;
	int ret = 0;

	inf = esr_to_fault_info(esr);
	pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
@@ -546,7 +547,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
		if (interrupts_enabled(regs))
			nmi_enter();

		ghes_notify_sea();
		ret = ghes_notify_sea();

		if (interrupts_enabled(regs))
			nmi_exit();
@@ -561,7 +562,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
		info.si_addr  = (void __user *)addr;
	arm64_notify_die("", regs, &info, esr);

	return 0;
	return ret;
}

static const struct fault_info fault_info[] = {
@@ -631,6 +632,23 @@ static const struct fault_info fault_info[] = {
	{ do_bad,		SIGBUS,  0,		"unknown 63"			},
};

/*
 * Handle Synchronous External Aborts that occur in a guest kernel.
 *
 * The return value will be zero if the SEA was successfully handled
 * and non-zero if there was an error processing the error or there was
 * no error to process.
 */
int handle_guest_sea(phys_addr_t addr, unsigned int esr)
{
	int ret = -ENOENT;

	if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
		ret = ghes_notify_sea();

	return ret;
}

/*
 * Dispatch a data abort to the relevant handler.
 */
Loading