mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
xen/arm: traps: Introduce a helper to read the hypersivor fault register
While ARM32 has 2 distinct registers for the hypervisor fault register (one for prefetch abort, the other for data abort), AArch64 has only one. Currently, the logic is open-code but a follow-up patch will require to read it too. So move the logic in a separate helper and use it instead of open-coding it. Signed-off-by: Julien Grall <julien.grall@arm.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
1 parent
d7216b07e8
commit
c8a8923e15
1 file changed
+25
-10
+25
-10
@@ -1931,6 +1931,28 @@ done:
|
||||
if (first) unmap_domain_page(first);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the value of the hypervisor fault address register.
|
||||
*
|
||||
* On ARM32, the register will be different depending whether the
|
||||
* fault is a prefetch abort or data abort.
|
||||
*/
|
||||
static inline vaddr_t get_hfar(bool is_data)
|
||||
{
|
||||
vaddr_t gva;
|
||||
|
||||
#ifdef CONFIG_ARM_32
|
||||
if ( is_data )
|
||||
gva = READ_CP32(HDFAR);
|
||||
else
|
||||
gva = READ_CP32(HIFAR);
|
||||
#else
|
||||
gva = READ_SYSREG(FAR_EL2);
|
||||
#endif
|
||||
|
||||
return gva;
|
||||
}
|
||||
|
||||
static inline paddr_t get_faulting_ipa(vaddr_t gva)
|
||||
{
|
||||
register_t hpfar = READ_SYSREG(HPFAR_EL2);
|
||||
@@ -1966,11 +1988,7 @@ static void do_trap_instr_abort_guest(struct cpu_user_regs *regs,
|
||||
paddr_t gpa;
|
||||
mfn_t mfn;
|
||||
|
||||
#ifdef CONFIG_ARM_32
|
||||
gva = READ_CP32(HIFAR);
|
||||
#else
|
||||
gva = READ_SYSREG64(FAR_EL2);
|
||||
#endif
|
||||
gva = get_hfar(false /* is_data */);
|
||||
|
||||
/*
|
||||
* If this bit has been set, it means that this instruction abort is caused
|
||||
@@ -2112,11 +2130,8 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs,
|
||||
return __do_trap_serror(regs, true);
|
||||
|
||||
info.dabt = dabt;
|
||||
#ifdef CONFIG_ARM_32
|
||||
info.gva = READ_CP32(HDFAR);
|
||||
#else
|
||||
info.gva = READ_SYSREG64(FAR_EL2);
|
||||
#endif
|
||||
|
||||
info.gva = get_hfar(true /* is_data */);
|
||||
|
||||
if ( hpfar_is_valid(dabt.s1ptw, fsc) )
|
||||
info.gpa = get_faulting_ipa(info.gva);
|
||||
|
||||