[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 1/3] xen/arm: io: Distinguish unhandled IO from aborted one
On Tue, 30 Jan 2018, Julien Grall wrote: > Hi Stefano, > > On 30/01/18 18:14, Stefano Stabellini wrote: > > On Tue, 30 Jan 2018, Julien Grall wrote: > > > Currently, Xen is considering that an IO could either be handled or > > > unhandled. When unhandled, the stage-2 abort function will try another > > > way to resolve the abort. > > > > > > However, the MMIO emulation may return unhandled when the address > > > belongs to an emulated range but was not correct. In that case, Xen > > > should avodi to try another way and directly inject a guest data abort. > > ^ avoid > > > > > > > Introduce a tri-state return to distinguish the following state: > > > * IO_ABORT: The IO was handled but resulted to an abort > > ^ in an abort > > > > > > > * IO_HANDLED: The IO was handled > > > * IO_UNHANDLED: The IO was unhandled > > > > > > For now, it is considered that an IO belonging to an emulated range > > > could either be handled or inject an abort. This could be revisit in the > > > future if overlapped region exist (or we want to try another way to > > > resolve the abort). > > > > > > Signed-off-by: Julien Grall <julien.grall@xxxxxxx> > > > --- > > > xen/arch/arm/io.c | 24 ++++++++++++++---------- > > > xen/arch/arm/traps.c | 34 +++++++++++++++++++++++----------- > > > xen/include/asm-arm/mmio.h | 9 ++++++++- > > > 3 files changed, 45 insertions(+), 22 deletions(-) > > > > > > diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c > > > index c748d8f5bf..a74ec21b86 100644 > > > --- a/xen/arch/arm/io.c > > > +++ b/xen/arch/arm/io.c > > > @@ -23,8 +23,9 @@ > > > #include <asm/current.h> > > > #include <asm/mmio.h> > > > -static int handle_read(const struct mmio_handler *handler, struct vcpu > > > *v, > > > - mmio_info_t *info) > > > +static enum io_state handle_read(const struct mmio_handler *handler, > > > + struct vcpu *v, > > > + mmio_info_t *info) > > > { > > > const struct hsr_dabt dabt = info->dabt; > > > struct cpu_user_regs *regs = guest_cpu_user_regs(); > > > @@ -37,7 +38,7 @@ static int handle_read(const struct mmio_handler > > > *handler, struct vcpu *v, > > > uint8_t size = (1 << dabt.size) * 8; > > > if ( !handler->ops->read(v, info, &r, handler->priv) ) > > > - return 0; > > > + return IO_ABORT; > > > /* > > > * Sign extend if required. > > > @@ -57,17 +58,20 @@ static int handle_read(const struct mmio_handler > > > *handler, struct vcpu *v, > > > set_user_reg(regs, dabt.reg, r); > > > - return 1; > > > + return IO_HANDLED; > > > } > > > -static int handle_write(const struct mmio_handler *handler, struct vcpu > > > *v, > > > - mmio_info_t *info) > > > +static enum io_state handle_write(const struct mmio_handler *handler, > > > + struct vcpu *v, > > > + mmio_info_t *info) > > > { > > > const struct hsr_dabt dabt = info->dabt; > > > struct cpu_user_regs *regs = guest_cpu_user_regs(); > > > + int ret; > > > - return handler->ops->write(v, info, get_user_reg(regs, dabt.reg), > > > - handler->priv); > > > + ret = handler->ops->write(v, info, get_user_reg(regs, dabt.reg), > > > + handler->priv); > > > + return ( ret ) ? IO_HANDLED : IO_ABORT; > > > } > > > /* This function assumes that mmio regions are not overlapped */ > > > @@ -100,14 +104,14 @@ static const struct mmio_handler > > > *find_mmio_handler(struct domain *d, > > > return handler; > > > } > > > -int handle_mmio(mmio_info_t *info) > > > +enum io_state handle_mmio(mmio_info_t *info) > > > { > > > struct vcpu *v = current; > > > const struct mmio_handler *handler = NULL; > > > handler = find_mmio_handler(v->domain, info->gpa); > > > if ( !handler ) > > > - return 0; > > > + return IO_UNHANDLED; > > > if ( info->dabt.write ) > > > return handle_write(handler, v, info); > > > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c > > > index c8534d6cff..843adf4959 100644 > > > --- a/xen/arch/arm/traps.c > > > +++ b/xen/arch/arm/traps.c > > > @@ -1864,10 +1864,10 @@ static inline bool hpfar_is_valid(bool s1ptw, > > > uint8_t fsc) > > > return s1ptw || (fsc == FSC_FLT_TRANS && > > > !check_workaround_834220()); > > > } > > > -static bool try_handle_mmio(struct cpu_user_regs *regs, > > > - const union hsr hsr, > > > - paddr_t gpa) > > > -{ > > > +static enum io_state try_handle_mmio(struct cpu_user_regs *regs, > > > + const union hsr hsr, > > > + paddr_t gpa) > > > + { > > > const struct hsr_dabt dabt = hsr.dabt; > > > mmio_info_t info = { > > > .gpa = gpa, > > > @@ -1879,11 +1879,11 @@ static bool try_handle_mmio(struct cpu_user_regs > > > *regs, > > > /* stage-1 page table should never live in an emulated MMIO region > > > */ > > > if ( dabt.s1ptw ) > > > - return false; > > > + return IO_UNHANDLED; > > > /* All the instructions used on emulated MMIO region should be > > > valid */ > > > if ( !dabt.valid ) > > > - return false; > > > + return IO_UNHANDLED; > > > /* > > > * Erratum 766422: Thumb store translation fault to Hypervisor may > > > @@ -1896,11 +1896,11 @@ static bool try_handle_mmio(struct cpu_user_regs > > > *regs, > > > if ( rc ) > > > { > > > gprintk(XENLOG_DEBUG, "Unable to decode instruction\n"); > > > - return false; > > > + return IO_ABORT; > > > } > > > } > > > > Why do the first two error checks result in IO_UNHANDLED, while the > > third result in IO_ABORT? Specifically in relation to pagetable walk > > failures due to someone else changing stage-2 entry simultaneously (see > > comment toward the end of do_trap_stage2_abort_guest)? > > Good question. Somehow I considered the first two as part of looking up the > proper handler and not the device itself. > > But I guess that at this stage we know that IO was targeting an emulated > region. So we can return IO_ABORT. That is what I thought as well > On a side note, it looks like the check dabt.s1ptw is unnecessary because a > stage 2 abort on stage 1 translation table lookup will not return a valid > instruction syndrome (see B3-1433 in DDI 0406C.c and D10-2460 in DDI 0487C.a). in that case, go ahead and remove it as part of this patch, mention it in the commit message _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |