From mboxrd@z Thu Jan 1 00:00:00 1970 From: Florian Jakobsmeier Subject: Re: xen/arm: Software Step ARMv8 - PC stuck on instruction Date: Wed, 5 Jul 2017 16:03:00 +0200 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6240017935144386835==" Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dSktT-0000Ll-7l for xen-devel@lists.xenproject.org; Wed, 05 Jul 2017 14:03:03 +0000 Received: by mail-wm0-f49.google.com with SMTP id i127so167948374wma.0 for ; Wed, 05 Jul 2017 07:03:01 -0700 (PDT) In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: Julien Grall Cc: xen-devel , Stefano Stabellini List-Id: xen-devel@lists.xenproject.org --===============6240017935144386835== Content-Type: multipart/alternative; boundary="001a114b2d1042b17e055392757d" --001a114b2d1042b17e055392757d Content-Type: text/plain; charset="UTF-8" 2017-07-04 20:37 GMT+02:00 Julien Grall : > > 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 --001a114b2d1042b17e055392757d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

2017-07-04 20:37 GMT+02:00 = Julien Grall <julien.grall@arm.com>:

On 07/04/2017 01:30 PM, Florian Jakobsmeier wrote:
Hello all,

Hi Florian,


=C2=A0 =C2=A0 =C2=A0 asmlinkage void leave_hypervisor_tail(void)
=C2=A0 =C2=A0 =C2=A0 {
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 /*This methode will be called after the 'g= uest_entry' macro in
=C2=A0 =C2=A0 /arch/arm64/entry.S set guest registers
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 Check single_step_enabled flag in domain struc= t here and set
=C2=A0 =C2=A0 needed registers
=C2=A0 =C2=A0 +
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 */
=C2=A0 =C2=A0 +
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 struct vcpu *v =3D current;
=C2=A0 =C2=A0 +
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 if ( unlikely(v->domain->arch.monit= or.singlestep_enabled ) )
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 {
=C2=A0 =C2=A0 +
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 WRITE_SYSREG(READ_SYSREG(MDCR_EL2)=C2=A0 | HDCR_TDE, MDCR_EL2);
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 WRITE_SYSREG(READ_SYSREG(SPSR_EL2)=C2=A0 | 0x200000, SPSR_EL2 );
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 WRITE_SYSREG(READ_SYSREG(MDSCR_EL1) | 0x1, MDSCR_EL1);
=C2=A0 =C2=A0 +
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!(v->arch.single_step ))<= br> =C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gprintk(XENLOG_ERR= , "Setting vcpu=3D%d for
=C2=A0 =C2=A0 domain=3D%d\n",v->vcpu_id,v->domain->domai= n_id);
=C2=A0 =C2=A0 +
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gprintk(XENLOG_ERR= , "[Set_singlestep] MDSCR_EL1=C2=A0 =C2=A0 =C2=A0 =C2=A0 0x%lx\n"= , READ_SYSREG(MDSCR_EL1));
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gprintk(XENLOG_ERR= , "[Set_singlestep] SPSR_EL2=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x%lx\n&= quot;, READ_SYSREG(SPSR_EL2));
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gprintk(XENLOG_ERR= , "[Set_singlestep] MDCR_EL2=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x%lx\n&= quot;, READ_SYSREG(MDCR_EL2));
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 v->arch.single_= step =3D 1;
=C2=A0 =C2=A0 +
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return;
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }else
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 //gprintk(XENLOG_E= RR, "Register for vcpu=3D%d for
=C2=A0 =C2=A0 domain=3D%d already set\n",v->vcpu_id,v->domain-&g= t;domain_id);
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 +=C2=A0 =C2=A0 }


As mentioned, this function will set the needed registers. "monitor.si= nglestep_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 no= w). "HDCR_TDE" is the same value as "MDCR_EL2_TDE" woul= d 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 exce= ption will be taken to the hypervisor). "MDSCR_EL1 | 0x1" to enab= le 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 (s= ee arch/arm/arm*/entry.S). So the value you wrote in the register is overri= dden 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 |=3D 0x200000;

This solved the problem. Thank you
=C2=A0
Cheers,

--
Julien Grall

Greet= ings
Florian
--001a114b2d1042b17e055392757d-- --===============6240017935144386835== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVs IG1haWxpbmcgbGlzdApYZW4tZGV2ZWxAbGlzdHMueGVuLm9yZwpodHRwczovL2xpc3RzLnhlbi5v cmcveGVuLWRldmVsCg== --===============6240017935144386835==--