RE: [PATCH 3/8] KVM: PPC: booke: Added debug handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> >>>>>>>> -----Original Message-----
> >>>>>>>> From: Alexander Graf [mailto:agraf@xxxxxxx]
> >>>>>>>> Sent: Friday, January 25, 2013 5:13 PM
> >>>>>>>> To: Bhushan Bharat-R65777
> >>>>>>>> Cc: kvm-ppc@xxxxxxxxxxxxxxx; kvm@xxxxxxxxxxxxxxx; Bhushan
> >>>>>>>> Bharat-R65777
> >>>>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> >>>>>>>>
> >>>>>>>>> From: Bharat Bhushan <Bharat.Bhushan@xxxxxxxxxxxxx>
> >>>>>>>>>
> >>>>>>>>> Installed debug handler will be used for guest debug support
> >>>>>>>>> and debug facility emulation features (patches for these
> >>>>>>>>> features will follow this patch).
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Liu Yu <yu.liu@xxxxxxxxxxxxx>
> >>>>>>>>> [bharat.bhushan@xxxxxxxxxxxxx: Substantial changes]
> >>>>>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@xxxxxxxxxxxxx>
> >>>>>>>>> ---
> >>>>>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
> >>>>>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
> >>>>>>>>> arch/powerpc/kvm/booke_interrupts.S |   49
> >> ++++++++++++++++++++++++++++++-
> >>>> --
> >>>>>> --
> >>>>>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> b/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> index 8a72d59..f4ba881 100644
> >>>>>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
> >>>>>>>>> 	u32 tlbcfg[4];
> >>>>>>>>> 	u32 mmucfg;
> >>>>>>>>> 	u32 epr;
> >>>>>>>>> +	u32 crit_save;
> >>>>>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
> >>>>>>>>> 	gpa_t paddr_accessed;
> >>>>>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> b/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> index 46f6afd..02048f3 100644
> >>>>>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> @@ -562,6 +562,7 @@ int main(void)
> >>>>>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> >>>>>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu,
> >> arch.fault_dear));
> >>>>>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu,
> >>>>>>>>> arch.fault_esr));
> >>>>>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu,
> >>>>>>>>> +arch.crit_save));
> >>>>>>>>> #endif /* CONFIG_PPC_BOOK3S */ #endif /* CONFIG_KVM */
> >>>>>>>>>
> >>>>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> index eae8483..dd9c5d4 100644
> >>>>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> @@ -52,12 +52,7 @@
> >>>>>>>>>                    (1<<BOOKE_INTERRUPT_PROGRAM) | \
> >>>>>>>>>                    (1<<BOOKE_INTERRUPT_DTLB_MISS))
> >>>>>>>>>
> >>>>>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> -	/* Get pointer to vcpu and record exit number. */
> >>>>>>>>> -	mtspr	\scratch , r4
> >>>>>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
> >>>>>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
> >>>>>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
> >>>>>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
> >>>>>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> 	bctr
> >>>>>>>>> .endm
> >>>>>>>>>
> >>>>>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> +	/* Get pointer to vcpu and record exit number. */
> >>>>>>>>> +	mtspr	\scratch , r4
> >>>>>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>>>>>> +
> >>>>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> +	mtspr   \scratch, r4
> >>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
> >>>>>>>>> +	mfcr	r3
> >>>>>>>>> +	mfspr	r4, SPRN_CSRR1
> >>>>>>>>> +	andi.	r4, r4, MSR_PR
> >>>>>>>>> +	bne	1f
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> +	/* debug interrupt happened in enter/exit path */
> >>>>>>>>> +	mfspr   r4, SPRN_CSRR1
> >>>>>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
> >>>>>>>>> +	mtspr   SPRN_CSRR1, r4
> >>>>>>>>> +	lis	r4, 0xffff
> >>>>>>>>> +	ori	r4, r4, 0xffff
> >>>>>>>>> +	mtspr	SPRN_DBSR, r4
> >>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	mtcr	r3
> >>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>>>> +	mfspr   r4, \scratch
> >>>>>>>>> +	rfci
> >>>>>>>>
> >>>>>>>> What is this part doing? Try to ignore the debug exit?
> >>>>>>>
> >>>>>>> As BOOKE doesn't have hardware support for virtualization,
> >>>>>>> hardware never know
> >>>>>> current pc is in guest or in host.
> >>>>>>> So when enable hardware single step for guest, it cannot be
> >>>>>>> disabled at the
> >>>>>> time guest exit. Thus, we'll see that an single step interrupt
> >>>>>> happens at the beginning of guest exit path.
> >>>>>>>
> >>>>>>> With the above code we recognize this kind of single step
> >>>>>>> interrupt disable
> >>>>>> single step and rfci.
> >>>>>>>
> >>>>>>>> Why would we have MSR_DE
> >>>>>>>> enabled in the first place when we can't handle it?
> >>>>>>>
> >>>>>>> When QEMU is using hardware debug resource then we always set
> >>>>>>> MSR_DE during
> >>>>>> guest is running.
> >>>>>>
> >>>>>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE
> >>>>>> wasn't set, you wouldn't get a single step exit.
> >>>>>
> >>>>> We always set MSR_DE in hw MSR when qemu using the debug resource.
> >>>>
> >>>> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't
> >>>> be set anymore, because we're in an interrupt handler, no? Or is
> >>>> MSR_DE kept alive on interrupts?
> >>>>
> >>>>>
> >>>>>> During the exit code path, you could then swap DBSR back to what
> >>>>>> the host expects (which means no single step). Only after that
> >>>>>> enable MSR_DE again.
> >>>>>
> >>>>> We do not support deferred debug interrupt, so we do save restore dbsr.
> >>>>>
> >>>>>>
> >>>>>>>
> >>>>>>>>
> >>>>>>>>> +1:	/* debug interrupt happened in guest */
> >>>>>>>>> +	mtcr	r3
> >>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
> >>>>>>>>
> >>>>>>>> I don't think you need the __KVM_HANDLER split. This should be
> >>>>>>>> quite easily refactorable into a simple DBG prolog.
> >>>>>>>
> >>>>>>> Can you please elaborate how you are envisioning this?
> >>>>>>
> >>>>>> With this patch, you have
> >>>>>>
> >>>>>> KVM_HANLDER:
> >>>>>>
> >>>>>> <code>
> >>>>>> __KVM_HANDLER
> >>>>>>
> >>>>>> KVM_DBG_HANDLER:
> >>>>>>
> >>>>>> <code>
> >>>>>> __KVM_HANDLER
> >>>>>>
> >>>>>> Right?
> >>>>>>
> >>>>>> In KVM_HANDLER, you get:
> >>>>>>
> >>>>>>> .macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>> _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> 	/* Get pointer to vcpu and record exit number. */
> >>>>>>> 	mtspr	\scratch , r4
> >>>>>>> 	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>> 	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>>>
> >>>>>>
> >>>>>> while KVM_DBG_HANDLER is:
> >>>>>>
> >>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> <debug specific handling>
> >>>>>>> +1:	/* debug interrupt happened in guest */
> >>>>>>> +	mtcr	r3
> >>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>>>
> >>>>>>
> >>>>>> So if you write this as
> >>>>>>
> >>>>>> KVM_DBG_HANDLER:
> >>>>>> 	<debug specific handling>
> >>>>>> 	1:
> >>>>>> 	mtcr		r3
> >>>>>> 	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>> 	lwz		r4, THREAD_KVM_VCPU(r4)
> >>>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> >>>>>> 	lwz		r4, \scratch
> >>>>>> 	<KVM_HANDLER>
> >>>>>>
> >>>>>> then you get code that is slower :) but it should be easier to
> >>>>>> read, since the interface between the individual pieces is always the
> same.
> >>>>>> Debug shouldn't be a fast path anyway, right?
> >>>>>
> >>>>> Frankly speaking I do not see much difference :).
> >>>>>
> >>>>> If we have to do as you mentioned then I think we can just do
> >>>>>
> >>>>> KVM_DBG_HANDLER:
> >>>>> 	<debug specific handling>
> >>>>> 	1:
> >>>>> 	mtcr		r3
> >>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> >>>>> 	lwz		r4, \scratch
> >>>>> 	<KVM_HANDLER>
> >>>>
> >>>> Whatever it takes to keep the oddball (debug) an oddball and keep
> >>>> the normal case easy :).
> >>>
> >>> I think there will be another problem as  the
> >>> kvmppc_handler_\ivor_nr will not
> >> be the starting address which is required as per our ivor/ivpr usages
> >> for booke architecture.
> >>>
> >>> I am thinking of keeping as is :).
> >>
> >> How about we take a hybrid approach? You write the code as I
> >> described above, but call __KVM_HANDLER at the end. The normal KVM_HANDLER
> would look like:
> >>
> >> KVM_HANDLER:
> >> 	kvmppc_handler_\ivor_nr:
> >> 	__KVM_HANDLER ...
> >>
> >> That way the code should still be more understandable :)
> >>
> >
> > With my current Patch it is defined as:
> >
> > .macro KVM_HANDLER ivor_nr scratch srr0
> > _GLOBAL(kvmppc_handler_\ivor_nr)
> >        /* Get pointer to vcpu and record exit number. */
> >        mtspr   \scratch , r4
> >        mfspr   r4, SPRN_SPRG_THREAD
> >        lwz     r4, THREAD_KVM_VCPU(r4)
> 
> Move these into __KVM_HANDLER (aka: keep the code in there the same as
> KVM_HANDLER today)
> 
> >        __KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >
> > .macro KVM_DBG_HANDLER ivor_nr scratch srr0
> > _GLOBAL(kvmppc_handler_\ivor_nr)
> >
> > <<<<<<Debug related handling>>>>>
> >
> > 1:      /* debug interrupt happened in guest */
> >        mtcr    r3
> >        mfspr   r4, SPRN_SPRG_THREAD
> >        lwz     r4, THREAD_KVM_VCPU(r4)
> >        lwz     r3, VCPU_CRIT_SAVE(r4)
> 
> Restore the state here as if a non-debug interrupt occurred. __KVM_HANDLER will
> fetch r4 itself from SPRG_THREAD.
> 
> I'm basically advocating to not optimize the debug case at all. Instead, I would
> prefer to have the exception ABI be identical to the fallback case ABI. That way
> we don't have to worry about 4 code paths, but only about 3, keeping the
> complexity of the code low.
> 
> 
> Alex
> 
> >        __KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >

Do you mean something like this ?

.macro __KVM_HANDLER
+        /* Get pointer to vcpu and record exit number. */
+        mtspr   \scratch , r4
+        mfspr   r4, SPRN_SPRG_THREAD
+        lwz     r4, THREAD_KVM_VCPU(r4)
 << Existing code >>


.macro KVM_HANDLER ivor_nr scratch srr0
_GLOBAL(kvmppc_handler_\ivor_nr)
	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm




.macro KVM_DBG_HANDLER ivor_nr scratch srr0
_GLOBAL(kvmppc_handler_\ivor_nr)
<<<<<<Debug related handling>>>>>
1:      /* debug interrupt happened in guest */
        mtcr    r3
        mfspr   r4, SPRN_SPRG_THREAD
        lwz     r4, THREAD_KVM_VCPU(r4)
        lwz     r3, VCPU_CRIT_SAVE(r4)
	 lwz		r4, \scratch 
        __KVM_HANDLER \ivor_nr \scratch \srr0 .endm


Thanks
-Bharat

> > So the kvmppc_handler_\ivor_nr is defined and should always be at the start of
> exception handling?
> >
> > So if KVM_DBG_HANDLER need to call KVM_HANDLER then there will be issue of 2
> definition for DBG interrupt.
> >
> > I am sorry but I did not understood how you want this to define. Can you
> please describe ?
> >
> > Thanks
> > -Bharat
> >
> >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body
> of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at
> http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux