|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RFC PATCH V1 01/12] hvm/ioreq: Make x86's IOREQ feature common
On Mon, 10 Aug 2020, Oleksandr wrote:
> On 08.08.20 01:19, Oleksandr wrote:
> > On 08.08.20 00:50, Stefano Stabellini wrote:
> > > On Fri, 7 Aug 2020, Oleksandr wrote:
> > > > On 06.08.20 03:37, Stefano Stabellini wrote:
> > > >
> > > > Hi Stefano
> > > >
> > > > Trying to simulate IO_RETRY handling mechanism (according to model
> > > > below) I
> > > > continuously get IO_RETRY from try_fwd_ioserv() ...
> > > >
> > > > > OK, thanks for the details. My interpretation seems to be correct.
> > > > >
> > > > > In which case, it looks like xen/arch/arm/io.c:try_fwd_ioserv should
> > > > > return IO_RETRY. Then, xen/arch/arm/traps.c:do_trap_stage2_abort_guest
> > > > > also needs to handle try_handle_mmio returning IO_RETRY the first
> > > > > around, and IO_HANDLED when after QEMU does its job.
> > > > >
> > > > > What should do_trap_stage2_abort_guest do on IO_RETRY? Simply return
> > > > > early and let the scheduler do its job? Something like:
> > > > >
> > > > > enum io_state state = try_handle_mmio(regs, hsr, gpa);
> > > > >
> > > > > switch ( state )
> > > > > {
> > > > > case IO_ABORT:
> > > > > goto inject_abt;
> > > > > case IO_HANDLED:
> > > > > advance_pc(regs, hsr);
> > > > > return;
> > > > > case IO_RETRY:
> > > > > /* finish later */
> > > > > return;
> > > > > case IO_UNHANDLED:
> > > > > /* IO unhandled, try another way to handle it. */
> > > > > break;
> > > > > default:
> > > > > ASSERT_UNREACHABLE();
> > > > > }
> > > > >
> > > > > Then, xen/arch/arm/ioreq.c:handle_mmio() gets called by
> > > > > handle_hvm_io_completion() after QEMU completes the emulation. Today,
> > > > > handle_mmio just sets the user register with the read value.
> > > > >
> > > > > But it would be better if it called again the original function
> > > > > do_trap_stage2_abort_guest to actually retry the original operation.
> > > > > This time do_trap_stage2_abort_guest calls try_handle_mmio() and gets
> > > > > IO_HANDLED instead of IO_RETRY,
> > > > I may miss some important point, but I failed to see why try_handle_mmio
> > > > (try_fwd_ioserv) will return IO_HANDLED instead of IO_RETRY at this
> > > > stage.
> > > > Or current try_fwd_ioserv() logic needs rework?
> > > I think you should check the ioreq->state in try_fwd_ioserv(), if the
> > > result is ready, then ioreq->state should be STATE_IORESP_READY, and you
> > > can return IO_HANDLED.
> >
>
> I optimized test patch a bit (now it looks much simpler). I didn't face any
> issues during a quick test.
Both patches get much closer to following the proper state machine,
great! I think this patch is certainly a good improvement. I think the
other patch you sent earlier, slightly larger, is even better. It makes
the following additional changes that would be good to have:
- try_fwd_ioserv returns IO_HANDLED on state == STATE_IORESP_READY
- handle_mmio simply calls do_trap_stage2_abort_guest
I would also remove "handle_mmio_finish" and do the guest register
setting as well as setting vio->io_req.state to STATE_IOREQ_NONE
directly in try_fwd_ioserv.
> ---
> xen/arch/arm/io.c | 4 ----
> xen/arch/arm/ioreq.c | 7 ++++++-
> xen/arch/arm/traps.c | 4 +++-
> 3 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c
> index 436f669..3063577 100644
> --- a/xen/arch/arm/io.c
> +++ b/xen/arch/arm/io.c
> @@ -156,10 +156,6 @@ static enum io_state try_fwd_ioserv(struct cpu_user_regs
> *regs,
> else
> vio->io_completion = HVMIO_mmio_completion;
>
> - /* XXX: Decide what to do */
> - if ( rc 7== IO_RETRY )
> - rc = IO_HANDLED;
> -
> return rc;
> }
> #endif
> diff --git a/xen/arch/arm/ioreq.c b/xen/arch/arm/ioreq.c
> index 8f60c41..e5235c6 100644
> --- a/xen/arch/arm/ioreq.c
> +++ b/xen/arch/arm/ioreq.c
> @@ -33,6 +33,8 @@
> #include <public/hvm/dm_op.h>
> #include <public/hvm/ioreq.h>
>
> +#include <asm/traps.h>
> +
> bool handle_mmio(void)
> {
> struct vcpu *v = current;
> @@ -52,7 +54,7 @@ bool handle_mmio(void)
>
> /* XXX: Do we need to take care of write here ? */
> if ( dabt.write )
> - return true;
> + goto done;
>
> /*
> * Sign extend if required.
> @@ -72,6 +74,9 @@ bool handle_mmio(void)
>
> set_user_reg(regs, dabt.reg, r);
>
> +done:
> + advance_pc(regs, hsr);
> +
> return true;
> }
>
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index ea472d1..974c744 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -1965,11 +1965,13 @@ static void do_trap_stage2_abort_guest(struct
> cpu_user_regs *regs,
> case IO_HANDLED:
> advance_pc(regs, hsr);
> return;
> + case IO_RETRY:
> + /* finish later */
> + return;
> case IO_UNHANDLED:
> /* IO unhandled, try another way to handle it. */
> break;
> default:
> - /* XXX: Handle IO_RETRY */
> ASSERT_UNREACHABLE();
> }
> }
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |