> >>> +static void kvmppc_booke_vcpu_load_debug_regs(struct kvm_vcpu
> >>> +*vcpu) {
> >>> + if (!vcpu->arch.debug_active)
> >>> +         return;
> >>> +
> >>> + /* Disable all debug events and clead pending debug events */
> >>> + mtspr(SPRN_DBCR0, 0x0);
> >>> + kvmppc_clear_dbsr();
> >>> +
> >>> + /*
> >>> +  * Check whether guest still need debug resource, if not then there
> >>> +  * is no need to restore guest context.
> >>> +  */
> >>> + if (!vcpu->arch.shadow_dbg_reg.dbcr0)
> >>> +         return;
> >>> +
> >>> + /* Load Guest Context */
> >>> + mtspr(SPRN_DBCR1, vcpu->arch.shadow_dbg_reg.dbcr1);
> >>> + mtspr(SPRN_DBCR2, vcpu->arch.shadow_dbg_reg.dbcr2); #ifdef
> >>> +CONFIG_KVM_E500MC
> >>> + mtspr(SPRN_DBCR4, vcpu->arch.shadow_dbg_reg.dbcr4);
> >>
> >> You need to make sure DBCR4 is 0 when you leave things back to normal
> >> user space. Otherwise guest debug can interfere with host debug.
> >
> >
> > ok
> >
> >>
> >>> +#endif
> >>> + mtspr(SPRN_IAC1, vcpu->arch.shadow_dbg_reg.iac[0]);
> >>> + mtspr(SPRN_IAC2, vcpu->arch.shadow_dbg_reg.iac[1]);
> >>> +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> >>> + mtspr(SPRN_IAC3, vcpu->arch.shadow_dbg_reg.iac[2]);
> >>> + mtspr(SPRN_IAC4, vcpu->arch.shadow_dbg_reg.iac[3]);
> >>> +#endif
> >>> + mtspr(SPRN_DAC1, vcpu->arch.shadow_dbg_reg.dac[0]);
> >>> + mtspr(SPRN_DAC2, vcpu->arch.shadow_dbg_reg.dac[1]);
> >>> +
> >>> + /* Enable debug events after other debug registers restored */
> >>> + mtspr(SPRN_DBCR0, vcpu->arch.shadow_dbg_reg.dbcr0); }
> >>
> >> All of the code above looks suspiciously similar to
> >> prime_debug_regs();. Can't we somehow reuse that?
> >
> > I think we can if
> > - Save thread->debug_regs in local data structure
> 
> Yes, it can even be on the stack.
> 
> > - Load vcpu->arch->debug_regs in thread->debug_regs
> > - Call prime_debug_regs();
> > - Restore thread->debug_regs from local save values in first step
> 
> On heavyweight exit, based on the values on stack, yes.

This is how I think we can save/restore debug context. Please correct if I am 
missing something.

1) When QEMU is running

-> thread->debug_reg == QEMU debug register context.
-> Kernel will handle switching the debug register on context switch.
-> no vcpu_load() called

2) QEMU makes ioctls (except RUN) 
 -> This will call vcpu_load()
 -> should not change context.
 -> Some ioctls can change vcpu debug register, context saved in 
vcpu->debug_regs

3) QEMU Makes RUN ioctl
 -> Save thread->debug_reg on STACK
 -> Store thread->debug_reg == vcpu->debug_reg
 -> load thread->debug_reg 
 -> RUN VCPU ( So thread points to vcpu context )

4) Context switch happens When VCPU running
 -> makes vcpu_load() should not load any context
 -> kernel loads the vcpu context as thread->debug_regs points to vcpu context.

5) On heavyweight_exit
 -> Load the context saved on stack in thread->debug_reg

Thanks
-Bharat



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

Reply via email to