}
static bool try_handle_mmio(struct cpu_user_regs *regs,
- mmio_info_t *info)
+ const union hsr hsr,
+ paddr_t gpa)
{
- const struct hsr_dabt dabt = info->dabt;
+ const struct hsr_dabt dabt = hsr.dabt;
+ mmio_info_t info = {
+ .gpa = gpa,
+ .dabt = dabt
+ };
int rc;
/* stage-1 page table should never live in an emulated MMIO region */
if ( check_workaround_766422() && (regs->cpsr & PSR_THUMB) &&
dabt.write )
{
- rc = decode_instruction(regs, &info->dabt);
+ rc = decode_instruction(regs, &info.dabt);
if ( rc )
{
gprintk(XENLOG_DEBUG, "Unable to decode instruction\n");
}
}
- return !!handle_mmio(info);
+ return !!handle_mmio(&info);
}
/*
const struct hsr_dabt dabt = hsr.dabt;
int rc;
vaddr_t gva;
- mmio_info_t info;
+ paddr_t gpa;
uint8_t fsc = hsr.dabt.dfsc & ~FSC_LL_MASK;
mfn_t mfn;
if ( dabt.eat )
return __do_trap_serror(regs, true);
- info.dabt = dabt;
-
gva = get_hfar(true /* is_data */);
if ( hpfar_is_valid(dabt.s1ptw, fsc) )
- info.gpa = get_faulting_ipa(gva);
+ gpa = get_faulting_ipa(gva);
else
{
- rc = gva_to_ipa(gva, &info.gpa, GV2M_READ);
+ rc = gva_to_ipa(gva, &gpa, GV2M_READ);
/*
* We may not be able to translate because someone is
* playing with the Stage-2 page table of the domain.
.kind = dabt.s1ptw ? npfec_kind_in_gpt : npfec_kind_with_gla
};
- p2m_mem_access_check(info.gpa, gva, npfec);
+ p2m_mem_access_check(gpa, gva, npfec);
/*
* The only way to get here right now is because of mem_access,
* thus reinjecting the exception to the guest is never required.
* Attempt first to emulate the MMIO as the data abort will
* likely happen in an emulated region.
*/
- if ( try_handle_mmio(regs, &info) )
+ if ( try_handle_mmio(regs, hsr, gpa) )
{
advance_pc(regs, hsr);
return;
* with the Stage-2 page table. Walk the Stage-2 PT to check
* if the entry exists. If it's the case, return to the guest
*/
- mfn = gfn_to_mfn(current->domain, gaddr_to_gfn(info.gpa));
+ mfn = gfn_to_mfn(current->domain, gaddr_to_gfn(gpa));
if ( !mfn_eq(mfn, INVALID_MFN) )
return;
- if ( try_map_mmio(gaddr_to_gfn(info.gpa)) )
+ if ( try_map_mmio(gaddr_to_gfn(gpa)) )
return;
break;
}
gdprintk(XENLOG_DEBUG, "HSR=0x%x pc=%#"PRIregister" gva=%#"PRIvaddr
- " gpa=%#"PRIpaddr"\n", hsr.bits, regs->pc, gva, info.gpa);
+ " gpa=%#"PRIpaddr"\n", hsr.bits, regs->pc, gva, gpa);
inject_dabt_exception(regs, gva, hsr.len);
}