xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@arm.com>
To: Stefano Stabellini <sstabellini@kernel.org>
Cc: andrew.cooper3@citrix.com, andre.przywara@linaro.org,
	xen-devel@lists.xen.org
Subject: Re: [PATCH 1/3] xen/arm: io: Distinguish unhandled IO from aborted one
Date: Tue, 30 Jan 2018 18:31:53 +0000	[thread overview]
Message-ID: <d0b17da6-0e9a-f9aa-92fb-673231fcec87@arm.com> (raw)
In-Reply-To: <alpine.DEB.2.10.1801301002570.11958@sstabellini-ThinkPad-X260>

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@arm.com>
>> ---
>>   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.

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).

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2018-01-30 18:31 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-30 16:14 [PATCH 0/3] xen/arm: Inject an exception to the guest rather than crashing it Julien Grall
2018-01-30 16:14 ` [PATCH 1/3] xen/arm: io: Distinguish unhandled IO from aborted one Julien Grall
2018-01-30 18:14   ` Stefano Stabellini
2018-01-30 18:31     ` Julien Grall [this message]
2018-01-30 19:09       ` Stefano Stabellini
2018-01-31 12:17         ` Julien Grall
2018-02-01  0:39           ` Stefano Stabellini
2018-01-30 16:14 ` [PATCH 2/3] xen/arm: Don't crash domain on bad MMIO emulation Julien Grall
2018-01-30 18:18   ` Stefano Stabellini
2018-01-30 16:14 ` [PATCH 3/3] xen/arm: Don't crash the domain on invalid HVC immediate Julien Grall
2018-01-30 18:24   ` Stefano Stabellini
2018-01-30 18:26     ` Julien Grall
2018-01-30 16:38 ` [PATCH 0/3] xen/arm: Inject an exception to the guest rather than crashing it Andrew Cooper
2018-01-30 17:00   ` Julien Grall
2018-01-30 18:29     ` Andrew Cooper
2018-01-30 18:46       ` Julien Grall
2018-01-30 19:09         ` Andrew Cooper
2018-01-30 19:21         ` Stefano Stabellini
2018-01-30 19:23           ` Andrew Cooper
2018-01-31 11:53           ` Julien Grall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d0b17da6-0e9a-f9aa-92fb-673231fcec87@arm.com \
    --to=julien.grall@arm.com \
    --cc=andre.przywara@linaro.org \
    --cc=andrew.cooper3@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).