xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Tamas K Lengyel <tamas@tklengyel.com>
To: Julien Grall <julien.grall@arm.com>
Cc: Wei Liu <wei.liu2@citrix.com>, Keir Fraser <keir@xen.org>,
	Razvan Cojocaru <rcojocaru@bitdefender.com>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	Jan Beulich <jbeulich@suse.com>,
	Xen-devel <xen-devel@lists.xenproject.org>
Subject: Re: [PATCH v2 2/5] vm_event: Implement ARM SMC events
Date: Tue, 3 May 2016 12:48:02 -0600	[thread overview]
Message-ID: <CABfawhmbe_oLhUPiQ-eCoGPN6N2g56P=vfs-vULxrsXp63sBDA@mail.gmail.com> (raw)
In-Reply-To: <57288C27.6060600@arm.com>


[-- Attachment #1.1: Type: text/plain, Size: 14130 bytes --]

On Tue, May 3, 2016 at 5:31 AM, Julien Grall <julien.grall@arm.com> wrote:

> Hi Tamas,
>
>
> On 29/04/16 19:07, Tamas K Lengyel wrote:
>
>> The ARM SMC instructions are already configured to trap to Xen by
>> default. In
>> this patch we allow a user-space process in a privileged domain to receive
>> notification of when such event happens through the vm_event subsystem by
>> introducing the PRIVILEGED_CALL type.
>>
>> Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
>> ---
>> Cc: Razvan Cojocaru <rcojocaru@bitdefender.com>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> Cc: Julien Grall <julien.grall@arm.com>
>> Cc: Keir Fraser <keir@xen.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>
>> v2: introduce VM_EVENT_REASON_PRIVELEGED_CALL
>>      aarch64 support
>> ---
>>   MAINTAINERS                         |   6 +-
>>   tools/libxc/include/xenctrl.h       |   2 +
>>   tools/libxc/xc_monitor.c            |  26 +++++++-
>>   tools/tests/xen-access/xen-access.c |  31 ++++++++-
>>   xen/arch/arm/Makefile               |   2 +
>>   xen/arch/arm/monitor.c              |  80 +++++++++++++++++++++++
>>   xen/arch/arm/traps.c                |  20 +++++-
>>   xen/arch/arm/vm_event.c             | 127
>> ++++++++++++++++++++++++++++++++++++
>>   xen/arch/x86/hvm/event.c            |   2 +
>>   xen/common/vm_event.c               |   1 -
>>   xen/include/asm-arm/domain.h        |   5 ++
>>   xen/include/asm-arm/monitor.h       |  20 ++----
>>   xen/include/asm-arm/vm_event.h      |  16 ++---
>>   xen/include/public/domctl.h         |   1 +
>>   xen/include/public/vm_event.h       |  27 ++++++++
>>   15 files changed, 333 insertions(+), 33 deletions(-)
>>   create mode 100644 xen/arch/arm/monitor.c
>>   create mode 100644 xen/arch/arm/vm_event.c
>>
>
> This patch is doing lots of things:
>         - Add support for monitoring
>         - Add support for vm_event
>         - Monitor SMC
>         - Move common code to arch specific code
>
> As far as I can tell, all are distinct from each other. Can you please
> split this patch in smaller ones?
>

While I can split off some parts into separate patches, like
getting/setting ARM registers through VM events and the tools patches, the
other components are pretty tightly coupled and don't actually make sense
to split them. For example, enabling a monitor domctl for an event without
the VM event components doesn't make much sense. Vice verse for the
vm_event parts without being able to enable them.


>
> [...]
>
> diff --git a/xen/arch/arm/monitor.c b/xen/arch/arm/monitor.c
>> new file mode 100644
>> index 0000000..e845f28
>> --- /dev/null
>> +++ b/xen/arch/arm/monitor.c
>>
>
> [...]
>
> +int monitor_smc(const struct cpu_user_regs *regs) {
>>
>
> The { should be on a separate line.


Ack.


>
>
> +    struct vcpu *curr = current;
>> +    vm_event_request_t req = { 0 };
>> +
>> +    if ( !curr->domain->arch.monitor.privileged_call_enabled )
>> +        return 0;
>> +
>> +    req.reason = VM_EVENT_REASON_PRIVILEGED_CALL;
>> +    req.vcpu_id = curr->vcpu_id;
>> +
>> +    vm_event_fill_regs(&req, regs, curr->domain);
>> +
>> +    return vm_event_monitor_traps(curr, 1, &req);
>> +}
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
>> index 9abfc3c..9c8d395 100644
>> --- a/xen/arch/arm/traps.c
>> +++ b/xen/arch/arm/traps.c
>> @@ -41,6 +41,7 @@
>>   #include <asm/mmio.h>
>>   #include <asm/cpufeature.h>
>>   #include <asm/flushtlb.h>
>> +#include <asm/monitor.h>
>>
>>   #include "decode.h"
>>   #include "vtimer.h"
>> @@ -2491,6 +2492,21 @@ bad_data_abort:
>>       inject_dabt_exception(regs, info.gva, hsr.len);
>>   }
>>
>> +static void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr)
>> +{
>> +    int rc = 0;
>>
>
> Newline here.
>

Ack.


>
> +    if ( current->domain->arch.monitor.privileged_call_enabled )
>> +    {
>> +        rc = monitor_smc(regs);
>> +    }
>>
>
> The bracket are not necessary.
>

Ack.


>
> +
>> +    if ( rc != 1 )
>>
>
> I think the code would be clearer if you introduce a define for "1".
>

Maybe not a define but calling the variable "handled" as we do on x86 would
be more descriptive.


>
> +    {
>> +        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
>>
>
> This check cannot work for AArch64 guest.


For HSR_EC_SMC32 there is already
GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr)); and for HSR_EC_SMC64 there is
GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr)); before calling do_trap_smc. So
are you saying that check is wrong for AArch64 as it is right now in
unstable? Also, is there any reason those checks are opposite of each other?


>
>
> +        inject_undef_exception(regs, hsr);
>> +    }
>> +}
>> +
>>   static void enter_hypervisor_head(struct cpu_user_regs *regs)
>>   {
>>       if ( guest_mode(regs) )
>> @@ -2566,7 +2582,7 @@ asmlinkage void do_trap_hypervisor(struct
>> cpu_user_regs *regs)
>>            */
>>           GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
>>           perfc_incr(trap_smc32);
>> -        inject_undef32_exception(regs);
>> +        do_trap_smc(regs, hsr);
>>           break;
>>       case HSR_EC_HVC32:
>>           GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
>> @@ -2599,7 +2615,7 @@ asmlinkage void do_trap_hypervisor(struct
>> cpu_user_regs *regs)
>>            */
>>           GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr));
>>           perfc_incr(trap_smc64);
>> -        inject_undef64_exception(regs, hsr.len);
>> +        do_trap_smc(regs, hsr);
>>           break;
>>       case HSR_EC_SYSREG:
>>           GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr));
>> diff --git a/xen/arch/arm/vm_event.c b/xen/arch/arm/vm_event.c
>> new file mode 100644
>> index 0000000..3369a96
>> --- /dev/null
>> +++ b/xen/arch/arm/vm_event.c
>> @@ -0,0 +1,127 @@
>> +/*
>> + * arch/arm/vm_event.c
>> + *
>> + * Architecture-specific vm_event handling routines
>> + *
>> + * Copyright (c) 2016 Tamas K Lengyel (tamas@tklengyel.com)
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public
>> + * License v2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public
>> + * License along with this program; If not, see <
>> http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <xen/sched.h>
>> +#include <asm/vm_event.h>
>> +
>> +void vm_event_fill_regs(vm_event_request_t *req,
>> +                        const struct cpu_user_regs *regs,
>> +                        struct domain *d)
>> +{
>> +    if ( is_32bit_domain(d) )
>> +    {
>> +        req->data.regs.arm.x0 = regs->r0;
>> +        req->data.regs.arm.x1 = regs->r1;
>> +        req->data.regs.arm.x2 = regs->r2;
>> +        req->data.regs.arm.x3 = regs->r3;
>> +        req->data.regs.arm.x4 = regs->r4;
>> +        req->data.regs.arm.x5 = regs->r5;
>> +        req->data.regs.arm.x6 = regs->r6;
>> +        req->data.regs.arm.x7 = regs->r7;
>> +        req->data.regs.arm.x8 = regs->r8;
>> +        req->data.regs.arm.x9 = regs->r9;
>> +        req->data.regs.arm.x10 = regs->r10;
>> +        req->data.regs.arm.pc = regs->pc32;
>> +        req->data.regs.arm.sp_el0 = regs->sp_usr;
>> +        req->data.regs.arm.sp_el1 = regs->sp_svc;
>> +    }
>> +#ifdef CONFIG_ARM_64
>>
> Why
>
>> +    else
>> +    {
>> +        req->data.regs.arm.x0 = regs->x0;
>> +        req->data.regs.arm.x1 = regs->x1;
>> +        req->data.regs.arm.x2 = regs->x2;
>> +        req->data.regs.arm.x3 = regs->x3;
>> +        req->data.regs.arm.x4 = regs->x4;
>> +        req->data.regs.arm.x5 = regs->x5;
>> +        req->data.regs.arm.x6 = regs->x6;
>> +        req->data.regs.arm.x7 = regs->x7;
>> +        req->data.regs.arm.x8 = regs->x8;
>> +        req->data.regs.arm.x9 = regs->x9;
>> +        req->data.regs.arm.x10 = regs->x10;
>>
>
> AArch64 provides 31 generate-purpose registers. Although, x29 and x30 are
> respectively used for fp and lr.


For vm_event it's not necessary to get all registers, rather it's just a
handful of selection that may be especially "useful" for introspection.
It's also important not to fill up the vm_event monitor ring with huge
request/response structs so even on x86 we only have a subset of the
registers. As right now there are no applications for aarch64, it's only a
guess of what registers would be "useful" and may be adjusted in future
versions as we start to have applications using this.


>
>
> +        req->data.regs.arm.pc = regs->pc;
>> +        req->data.regs.arm.sp_el0 = regs->sp_el0;
>> +        req->data.regs.arm.sp_el1 = regs->sp_el1;
>> +    }
>> +#endif
>> +    req->data.regs.arm.fp = regs->fp;
>> +    req->data.regs.arm.lr = regs->lr;
>> +    req->data.regs.arm.cpsr = regs->cpsr;
>> +    req->data.regs.arm.spsr_el1 = regs->spsr_svc;
>> +    req->data.regs.arm.ttbr0 = READ_SYSREG64(TTBR0_EL1);
>> +    req->data.regs.arm.ttbr1 = READ_SYSREG64(TTBR1_EL1);
>> +}
>> +
>> +void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp)
>> +{
>> +    struct cpu_user_regs *regs = &v->arch.cpu_info->guest_cpu_user_regs;
>> +
>> +    if ( is_32bit_domain(v->domain) )
>> +    {
>> +        regs->r0 = rsp->data.regs.arm.x0;
>> +        regs->r1 = rsp->data.regs.arm.x1;
>> +        regs->r2 = rsp->data.regs.arm.x2;
>> +        regs->r3 = rsp->data.regs.arm.x3;
>> +        regs->r4 = rsp->data.regs.arm.x4;
>> +        regs->r5 = rsp->data.regs.arm.x5;
>> +        regs->r6 = rsp->data.regs.arm.x6;
>> +        regs->r7 = rsp->data.regs.arm.x7;
>> +        regs->r8 = rsp->data.regs.arm.x8;
>> +        regs->r9 = rsp->data.regs.arm.x9;
>> +        regs->r10 = rsp->data.regs.arm.x10;
>> +        regs->pc32 = rsp->data.regs.arm.pc;
>> +        regs->sp_usr = rsp->data.regs.arm.sp_el0;
>> +        regs->sp_svc = rsp->data.regs.arm.sp_el1;
>> +    }
>> +#ifdef CONFIG_ARM_64
>> +    else
>> +    {
>> +        regs->x0 = rsp->data.regs.arm.x0;
>> +        regs->x1 = rsp->data.regs.arm.x1;
>> +        regs->x2 = rsp->data.regs.arm.x2;
>> +        regs->x3 = rsp->data.regs.arm.x3;
>> +        regs->x4 = rsp->data.regs.arm.x4;
>> +        regs->x5 = rsp->data.regs.arm.x5;
>> +        regs->x6 = rsp->data.regs.arm.x6;
>> +        regs->x7 = rsp->data.regs.arm.x7;
>> +        regs->x8 = rsp->data.regs.arm.x8;
>> +        regs->x9 = rsp->data.regs.arm.x9;
>> +        regs->x10 = rsp->data.regs.arm.x10;
>> +        regs->pc = rsp->data.regs.arm.pc;
>> +        regs->sp_el0 = rsp->data.regs.arm.sp_el0;
>> +        regs->sp_el1 = rsp->data.regs.arm.sp_el1;
>> +    }
>> +#endif
>> +
>> +    regs->fp = rsp->data.regs.arm.fp;
>> +    regs->lr = rsp->data.regs.arm.lr;
>> +    regs->cpsr = rsp->data.regs.arm.cpsr;
>> +    v->arch.ttbr0 = rsp->data.regs.arm.ttbr0;
>> +    v->arch.ttbr1 = rsp->data.regs.arm.ttbr1;
>> +}
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>>
>
> [...]
>
>
> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
>> index 2457698..35adce2 100644
>> --- a/xen/include/public/domctl.h
>> +++ b/xen/include/public/domctl.h
>> @@ -1080,6 +1080,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cmt_op_t);
>>   #define XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP            2
>>   #define XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT   3
>>   #define XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST         4
>> +#define XEN_DOMCTL_MONITOR_EVENT_PRIVILEGED_CALL       5
>>
>>   struct xen_domctl_monitor_op {
>>       uint32_t op; /* XEN_DOMCTL_MONITOR_OP_* */
>> diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h
>> index 9270d52..f039207 100644
>> --- a/xen/include/public/vm_event.h
>> +++ b/xen/include/public/vm_event.h
>> @@ -119,6 +119,8 @@
>>   #define VM_EVENT_REASON_SINGLESTEP              7
>>   /* An event has been requested via HVMOP_guest_request_vm_event. */
>>   #define VM_EVENT_REASON_GUEST_REQUEST           8
>> +/* Privileged call executed (e.g. SMC) */
>> +#define VM_EVENT_REASON_PRIVILEGED_CALL         9
>>
>>   /* Supported values for the vm_event_write_ctrlreg index. */
>>   #define VM_EVENT_X86_CR0    0
>> @@ -166,6 +168,30 @@ struct vm_event_regs_x86 {
>>       uint32_t _pad;
>>   };
>>
>> +struct vm_event_regs_arm {
>> +    /*       Aarch64       Aarch32 */
>> +    uint64_t x0;       /*  r0_usr  */
>> +    uint64_t x1;       /*  r1_usr  */
>> +    uint64_t x2;       /*  r2_usr  */
>> +    uint64_t x3;       /*  r3_usr  */
>> +    uint64_t x4;       /*  r4_usr  */
>> +    uint64_t x5;       /*  r5_usr  */
>> +    uint64_t x6;       /*  r6_usr  */
>> +    uint64_t x7;       /*  r7_usr  */
>> +    uint64_t x8;       /*  r8_usr  */
>> +    uint64_t x9;       /*  r9_usr  */
>> +    uint64_t x10;      /*  r10_usr */
>>
>
> I would introduce an union to let the choice to the userspace to deal only
> with AArch32 registers. See vcpu_guest_core_regs.
>

Sure.


>
> +    uint64_t lr;       /*  lr_usr  */
>> +    uint64_t sp_el0;   /*  sp_usr  */
>> +    uint64_t sp_el1;   /*  sp_svc  */
>> +    uint32_t spsr_el1; /*  spsr_svc */
>> +    uint64_t fp;
>> +    uint64_t pc;
>> +    uint32_t cpsr;
>> +    uint64_t ttbr0;
>> +    uint64_t ttbr1;
>> +};
>> +
>>   /*
>>    * mem_access flag definitions
>>    *
>> @@ -254,6 +280,7 @@ typedef struct vm_event_st {
>>       union {
>>           union {
>>               struct vm_event_regs_x86 x86;
>> +            struct vm_event_regs_arm arm;
>>           } regs;
>>
>>           struct vm_event_emul_read_data emul_read_data;
>>
>>
> Regards,
>
> --
> Julien Grall
>

Thanks,
Tamas

[-- Attachment #1.2: Type: text/html, Size: 20932 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

  reply	other threads:[~2016-05-03 18:48 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-29 18:07 [PATCH v2 1/5] monitor: Rename vm_event_monitor_get_capabilities Tamas K Lengyel
2016-04-29 18:07 ` [PATCH v2 2/5] vm_event: Implement ARM SMC events Tamas K Lengyel
2016-04-29 20:07   ` Razvan Cojocaru
2016-04-29 20:12     ` Tamas K Lengyel
2016-04-29 20:27       ` Tamas K Lengyel
2016-04-29 20:32         ` Razvan Cojocaru
2016-05-02 10:35   ` Wei Liu
2016-05-03 11:31   ` Julien Grall
2016-05-03 18:48     ` Tamas K Lengyel [this message]
2016-05-04 10:31       ` Julien Grall
     [not found]         ` <CABfawhmwVQyYeGYMxKTb1zMUkyOSutMwm4bkTxoeNaFTmGuyXA@mail.gmail.com>
     [not found]           ` <CABfawhmVUyqcuoxitKrXxcg93yLY4e8H7S1A_GEFbX3+Vb-hrA@mail.gmail.com>
2016-05-04 12:42             ` Tamas K Lengyel
2016-05-04 13:26               ` Julien Grall
2016-05-04 13:30                 ` Razvan Cojocaru
2016-05-04 14:03                   ` Julien Grall
2016-05-04 14:08                     ` Tamas K Lengyel
2016-04-29 18:07 ` [PATCH v2 3/5] x86/hvm: Rename hvm/event to hvm/monitor Tamas K Lengyel
2016-05-04  1:13   ` Tian, Kevin
2016-04-29 18:07 ` [PATCH v2 4/5] x86/hvm: Add debug exception vm_events Tamas K Lengyel
2016-05-02 13:12   ` Jan Beulich
2016-05-02 15:35     ` Tamas K Lengyel
2016-05-02 15:40       ` Jan Beulich
2016-05-02 15:45         ` Tamas K Lengyel
2016-04-29 18:07 ` [PATCH v2 5/5] MAINTAINERS: Update monitor/vm_event covered code Tamas K Lengyel
2016-05-02 13:00   ` Jan Beulich
2016-05-03  8:18   ` Jan Beulich
2016-05-03  8:20     ` Razvan Cojocaru
2016-05-03  8:26       ` Jan Beulich
2016-05-03  9:09     ` Wei Liu

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='CABfawhmbe_oLhUPiQ-eCoGPN6N2g56P=vfs-vULxrsXp63sBDA@mail.gmail.com' \
    --to=tamas@tklengyel.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=julien.grall@arm.com \
    --cc=keir@xen.org \
    --cc=rcojocaru@bitdefender.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.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).