xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@arm.com>
To: Florian Jakobsmeier <florian.jakobsmeier@googlemail.com>
Cc: xen-devel <xen-devel@lists.xenproject.org>,
	Stefano Stabellini <sstabellini@kernel.org>,
	James Morse <james.morse@arm.com>
Subject: Re: xen/arm: Software Step ARMv8 - PC stuck on instruction
Date: Wed, 2 Aug 2017 14:32:43 +0100	[thread overview]
Message-ID: <51641005-94fc-2b04-ae49-25e84f3cc56f@arm.com> (raw)
In-Reply-To: <CAAH2ineGnh5VzDsVQLUaSN_o+wqBST4R7H18GJpHFqzgbmX9Ww@mail.gmail.com>

Hi Florian,

Sorry for the late answer.

On 26/07/17 14:12, Florian Jakobsmeier wrote:
> Hello,
>
> i was just testing the single step implementation and realized that the
> before mentioned solution is not fully working. I'm still trying to
> enable SS for a VM on Xen.

Would you mind sharing the latest version of your code?

> To test my implementation i wrote a small Kernel Module and started it
> in the DomU. The module only contains a loop which increments a counter
> and prints its value.
> Right after loading the moduleI start the single step mechanism in the
> Dom0 for the VM (again with xen-access).
> As soon as i start the SS the VM will stop working.
>
> In the SS handler i print the "cpu_user_regs->pc" program counter. From
> there i can see, that each instruction address is used twice: (as it
> generates the following outputs)
>
>     (XEN) d1v0 do_trap_software_step PC =  0xffff000008081a80
>     (XEN) d1v0 do_trap_software_step PC =  0xffff000008081a80
>     (XEN) d1v0 do_trap_software_step PC =  0xffff000008082700
>     (XEN) d1v0 do_trap_software_step PC =  0xffff000008082700
>     (XEN) d1v0 do_trap_software_step PC =  0xffff000008082704
>     (XEN) d1v0 do_trap_software_step PC =  0xffff000008082704
>     (XEN) d1v0 do_trap_software_step PC =  0xffff000008082708
>     (XEN) printk: 119614 messages suppressed.
>     (XEN) d1v0 do_trap_software_step PC =  0xffff0000088cbd6c
>     (XEN) printk: 120131 messages suppressed.
>     (XEN) d1v0 do_trap_software_step PC =  0xffff0000088cbd64
>     (XEN) printk: 120255 messages suppressed.
>     (XEN) d1v0 do_trap_software_step PC =  0xffff0000088cbd64

Did you look where the PCs point to? Is it your kernel module?

>
>
> The single step handler "do_trap_software_step" is called from (file is
> /arch/arm/arm64/entry.S): hyp_traps_vector
> (VBAR_EL2)->guest_sync->do_trap_guest_sync->do_trap_software_step
>
> The ARM ARM (D2-1956 - ARM DDI 0487B.a ID033117) states that, in order
> to enables software step:
>
>     A debugger enables MDSCR_EL1.SS = 1
>
>     Executes an ERET
>
>
>     The PE executes the instruction to be single-stepped
>
>     Takes a software step exception on the next instruction
>
>
>
> As mentioned I set the needed registers (including MDSCR_EL1) every time
> when the "leave_hypervisor_tail" function is called. This function will
> called from within the "exit" macro in "/arch/arm/arm64/entry.S" which
> is called after every exception return. Including the "guest_sync"
> exception.
>
> Right after the "leave_hypervisor_tail" the ERET instruction will also
> be called within the "return_from_trap" macro.
>
> Because of the prints in the single step handler I can assure that the
> software step exceptions are executed and correctly routed to the
> hypervisor.
> Yet I can't figure out why the PC got the same value twice and why the
> VM will stop working.
>
> My guess is that by setting the needed SS registers ever time when we
> leave the guest, the configuration won't allow the guest to execute the
> "to be single stepped instruction"
> Before executing the (first) instruction the VM will generate the SS
> exception (as desired). In the hypervisor we will set the SS registers
> again, which could hinder the VM to execute the instruction (which we
> want because we already generated an SS exception for this instruction)
> and instead generate a second SS exception for it. This will lead to the
> second PC print in the single step handler
>
> But I'm not able to find any proof for this.
>
> If I'm using the software step exception for only one instruction and
> disable it right after it (from within xen-access with an VM_EVENT) the
> VM will work without problems.
>
> Any help to find the missing step in order to enable VM single stepping
> would be appreciated
>
> Greetings Florian
>
>
> 2017-07-05 16:03 GMT+02:00 Florian Jakobsmeier
> <florian.jakobsmeier@googlemail.com
> <mailto:florian.jakobsmeier@googlemail.com>>:
>
>
>     2017-07-04 20:37 GMT+02:00 Julien Grall <julien.grall@arm.com
>     <mailto:julien.grall@arm.com>>:
>
>
>         On 07/04/2017 01:30 PM, Florian Jakobsmeier wrote:
>
>             Hello all,
>
>
>         Hi Florian,
>
>
>                   asmlinkage void leave_hypervisor_tail(void)
>                   {
>                 +    /*This methode will be called after the
>             'guest_entry' macro in
>                 /arch/arm64/entry.S set guest registers
>                 +    Check single_step_enabled flag in domain struct
>             here and set
>                 needed registers
>                 +
>                 +    */
>                 +
>                 +    struct vcpu *v = current;
>                 +
>                 +    if (
>             unlikely(v->domain->arch.monitor.singlestep_enabled ) )
>                 +    {
>                 +
>                 +        WRITE_SYSREG(READ_SYSREG(MDCR_EL2)  | HDCR_TDE,
>             MDCR_EL2);
>                 +        WRITE_SYSREG(READ_SYSREG(SPSR_EL2)  | 0x200000,
>             SPSR_EL2 );
>                 +        WRITE_SYSREG(READ_SYSREG(MDSCR_EL1) | 0x1,
>             MDSCR_EL1);
>                 +
>                 +        if (!(v->arch.single_step ))
>                 +        {
>                 +            gprintk(XENLOG_ERR, "Setting vcpu=%d for
>                 domain=%d\n",v->vcpu_id,v->domain->domain_id);
>                 +
>                 +            gprintk(XENLOG_ERR, "[Set_singlestep]
>             MDSCR_EL1        0x%lx\n", READ_SYSREG(MDSCR_EL1));
>                 +            gprintk(XENLOG_ERR, "[Set_singlestep]
>             SPSR_EL2         0x%lx\n", READ_SYSREG(SPSR_EL2));
>                 +            gprintk(XENLOG_ERR, "[Set_singlestep]
>             MDCR_EL2         0x%lx\n", READ_SYSREG(MDCR_EL2));
>                 +            v->arch.single_step = 1;
>                 +
>                 +            return;
>                 +        }else
>                 +        {
>                 +            //gprintk(XENLOG_ERR, "Register for vcpu=%d for
>                 domain=%d already set\n",v->vcpu_id,v->domain->domain_id);
>                 +        }
>                 +    }
>
>
>             As mentioned, this function will set the needed registers.
>             "monitor.singlestep_enabled" is the domain SS flag which is
>             used to determine if the registers should be set.
>             "arch.single_step" is the vcpu flag to check if the register
>             were already set once (not really in use as for now).
>             "HDCR_TDE" is the same value as "MDCR_EL2_TDE" would be, but
>             this one is not implemented yet, thats why I'm using
>             HDCR_TDE. "SPSR_EL2 | 0x200000" sets the SS bit for EL2
>             (because our exception will be taken to the hypervisor).
>             "MDSCR_EL1 | 0x1" to enable the SS bit.
>             Because I'm checking the domain in this function, every vcpu
>             that will be used, will be set with the values above. By
>             this I can assure that each vcpu will trigger these exceptions.
>
>
>         SPSR_EL2 is saved/restored on entry and exit of a trap to the
>         hypervisor (see arch/arm/arm*/entry.S). So the value you wrote
>         in the register is overridden afterwards.
>
>         If you want to set the SS bit, you need to do in the save
>         registered cpsr. You can access using:
>
>         guest_cpu_user_regs()->cpsr |= 0x200000;
>
>     This solved the problem. Thank you
>
>
>         Cheers,
>
>         --
>         Julien Grall
>
>
>     Greetings
>     Florian
>
>

Cheers,

-- 
Julien Grall

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

  reply	other threads:[~2017-08-02 13:32 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-04 12:30 xen/arm: Software Step ARMv8 - PC stuck on instruction Florian Jakobsmeier
2017-07-04 18:37 ` Julien Grall
2017-07-05 14:03   ` Florian Jakobsmeier
2017-07-26 13:12     ` Florian Jakobsmeier
2017-08-02 13:32       ` Julien Grall [this message]
2017-08-03  9:49         ` James Morse
2017-08-03 10:16         ` Florian Jakobsmeier
2017-08-03 10:46           ` James Morse
2017-08-03 11:08             ` Julien Grall
2017-08-03 12:29               ` Florian Jakobsmeier
2017-08-03 13:02                 ` James Morse
2017-08-03 16:00                   ` Florian Jakobsmeier
2017-08-07 17:05                     ` James Morse

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=51641005-94fc-2b04-ae49-25e84f3cc56f@arm.com \
    --to=julien.grall@arm.com \
    --cc=florian.jakobsmeier@googlemail.com \
    --cc=james.morse@arm.com \
    --cc=sstabellini@kernel.org \
    --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).