return;
}
+ /*
+ * When the data abort is caused due to cache maintenance, Xen should check
+ * if the address belongs to an emulated MMIO region or not. The behavior
+ * will differ accordingly.
+ */
+ if ( info->dabt.cache )
+ {
+ info->dabt_instr.state = INSTR_CACHE;
+ return;
+ }
+
/*
* Armv8 processor does not provide a valid syndrome for decoding some
* instructions. So in order to process these instructions, Xen must
ASSERT(info->dabt.ec == HSR_EC_DATA_ABORT_LOWER_EL);
- if ( !info->dabt.valid )
+ if ( !(info->dabt.valid || (info->dabt_instr.state == INSTR_CACHE)) )
{
ASSERT_UNREACHABLE();
return IO_ABORT;
return rc;
}
+ /*
+ * When the data abort is caused due to cache maintenance and the address
+ * belongs to an emulated region, Xen should ignore this instruction.
+ */
+ if ( info->dabt_instr.state == INSTR_CACHE )
+ return IO_HANDLED;
+
/*
* At this point, we know that the instruction is either valid or has been
* decoded successfully. Thus, Xen should be allowed to execute the
struct vcpu *v, mmio_info_t *info)
{
struct vcpu_io *vio = &v->io;
- struct instr_details instr = info->dabt_instr;
+ const struct instr_details instr = info->dabt_instr;
struct hsr_dabt dabt = info->dabt;
ioreq_t p = {
.type = IOREQ_TYPE_COPY,
.addr = info->gpa,
- .size = 1 << info->dabt.size,
.count = 1,
.dir = !info->dabt.write,
/*
* memory access. So for now, we can safely always set to 0.
*/
.df = 0,
- .data = get_user_reg(regs, info->dabt.reg),
.state = STATE_IOREQ_READY,
};
struct ioreq_server *s = NULL;
return IO_ABORT;
}
+ if ( instr.state == INSTR_CACHE )
+ p.size = dcache_line_bytes;
+ else
+ p.size = 1U << info->dabt.size;
+
s = ioreq_server_select(v->domain, &p);
if ( !s )
return IO_UNHANDLED;
+ /*
+ * When the data abort is caused due to cache maintenance and the address
+ * belongs to an emulated region, Xen should ignore this instruction.
+ */
+ if ( instr.state == INSTR_CACHE )
+ return IO_HANDLED;
+
ASSERT(dabt.valid);
+ p.data = get_user_reg(regs, info->dabt.reg);
vio->req = p;
vio->info.dabt_instr = instr;