From: Alexander Graf <agraf@suse.de>
To: Bhushan Bharat-R65777 <R65777@freescale.com>
Cc: "kvm-ppc@vger.kernel.org" <kvm-ppc@vger.kernel.org>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
Wood Scott-B07421 <B07421@freescale.com>
Subject: Re: [PATCH 4/4 v2] KVM: PPC: Add userspace debug stub support
Date: Tue, 02 Apr 2013 17:41:26 +0200 [thread overview]
Message-ID: <515AFC26.5040705@suse.de> (raw)
In-Reply-To: <6A3DF150A5B70D4F9B66A25E3F7C888D06FBBF38@039-SN2MPN1-013.039d.mgd.msft.net>
On 04/02/2013 04:09 PM, Bhushan Bharat-R65777 wrote:
>
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Tuesday, April 02, 2013 1:57 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Wood Scott-B07421
>> Subject: Re: [PATCH 4/4 v2] KVM: PPC: Add userspace debug stub support
>>
>>
>> On 29.03.2013, at 07:04, Bhushan Bharat-R65777 wrote:
>>
>>>
>>>> -----Original Message-----
>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>> Sent: Thursday, March 28, 2013 10:06 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Wood Scott-B07421;
>>>> Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 4/4 v2] KVM: PPC: Add userspace debug stub
>>>> support
>>>>
>>>>
>>>> On 21.03.2013, at 07:25, Bharat Bhushan wrote:
>>>>
>>>>> From: Bharat Bhushan<bharat.bhushan@freescale.com>
>>>>>
>>>>> This patch adds the debug stub support on booke/bookehv.
>>>>> Now QEMU debug stub can use hw breakpoint, watchpoint and software
>>>>> breakpoint to debug guest.
>>>>>
>>>>> Debug registers are saved/restored on vcpu_put()/vcpu_get().
>>>>> Also the debug registers are saved restored only if guest is using
>>>>> debug resources.
>>>>>
>>>>> Signed-off-by: Bharat Bhushan<bharat.bhushan@freescale.com>
>>>>> ---
>>>>> v2:
>>>>> - save/restore in vcpu_get()/vcpu_put()
>>>>> - some more minor cleanup based on review comments.
>>>>>
>>>>> arch/powerpc/include/asm/kvm_host.h | 10 ++
>>>>> arch/powerpc/include/uapi/asm/kvm.h | 22 +++-
>>>>> arch/powerpc/kvm/booke.c | 252 ++++++++++++++++++++++++++++++++-
>> --
>>>>> arch/powerpc/kvm/e500_emulate.c | 10 ++
>>>>> 4 files changed, 272 insertions(+), 22 deletions(-)
>>>>>
>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>>>> b/arch/powerpc/include/asm/kvm_host.h
>>>>> index f4ba881..8571952 100644
>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>>>> @@ -504,7 +504,17 @@ struct kvm_vcpu_arch {
>>>>> u32 mmucfg;
>>>>> u32 epr;
>>>>> u32 crit_save;
>>>>> + /* guest debug registers*/
>>>>> struct kvmppc_booke_debug_reg dbg_reg;
>>>>> + /* shadow debug registers */
>>>>> + struct kvmppc_booke_debug_reg shadow_dbg_reg;
>>>>> + /* host debug registers*/
>>>>> + struct kvmppc_booke_debug_reg host_dbg_reg;
>>>>> + /*
>>>>> + * Flag indicating that debug registers are used by guest
>>>>> + * and requires save restore.
>>>>> + */
>>>>> + bool debug_save_restore;
>>>>> #endif
>>>>> gpa_t paddr_accessed;
>>>>> gva_t vaddr_accessed;
>>>>> diff --git a/arch/powerpc/include/uapi/asm/kvm.h
>>>>> b/arch/powerpc/include/uapi/asm/kvm.h
>>>>> index 15f9a00..d7ce449 100644
>>>>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>>>>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>>>>> @@ -25,6 +25,7 @@
>>>>> /* Select powerpc specific features in<linux/kvm.h> */ #define
>>>>> __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT
>>>>> +#define __KVM_HAVE_GUEST_DEBUG
>>>>>
>>>>> struct kvm_regs {
>>>>> __u64 pc;
>>>>> @@ -267,7 +268,24 @@ struct kvm_fpu {
>>>>> __u64 fpr[32];
>>>>> };
>>>>>
>>>>> +/*
>>>>> + * Defines for h/w breakpoint, watchpoint (read, write or both) and
>>>>> + * software breakpoint.
>>>>> + * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status"
>>>>> + * for KVM_DEBUG_EXIT.
>>>>> + */
>>>>> +#define KVMPPC_DEBUG_NONE 0x0
>>>>> +#define KVMPPC_DEBUG_BREAKPOINT (1UL<< 1)
>>>>> +#define KVMPPC_DEBUG_WATCH_WRITE (1UL<< 2)
>>>>> +#define KVMPPC_DEBUG_WATCH_READ (1UL<< 3)
>>>>> struct kvm_debug_exit_arch {
>>>>> + __u64 address;
>>>>> + /*
>>>>> + * exiting to userspace because of h/w breakpoint, watchpoint
>>>>> + * (read, write or both) and software breakpoint.
>>>>> + */
>>>>> + __u32 status;
>>>>> + __u32 reserved;
>>>>> };
>>>>>
>>>>> /* for KVM_SET_GUEST_DEBUG */
>>>>> @@ -279,10 +297,6 @@ struct kvm_guest_debug_arch {
>>>>> * Type denotes h/w breakpoint, read watchpoint, write
>>>>> * watchpoint or watchpoint (both read and write).
>>>>> */
>>>>> -#define KVMPPC_DEBUG_NOTYPE 0x0
>>>>> -#define KVMPPC_DEBUG_BREAKPOINT (1UL<< 1)
>>>>> -#define KVMPPC_DEBUG_WATCH_WRITE (1UL<< 2)
>>>>> -#define KVMPPC_DEBUG_WATCH_READ (1UL<< 3)
>>>>> __u32 type;
>>>>> __u32 reserved;
>>>>> } bp[16];
>>>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>>>>> index
>>>>> 1de93a8..bf20056 100644
>>>>> --- a/arch/powerpc/kvm/booke.c
>>>>> +++ b/arch/powerpc/kvm/booke.c
>>>>> @@ -133,6 +133,30 @@ static void kvmppc_vcpu_sync_fpu(struct
>>>>> kvm_vcpu
>>>>> *vcpu) #endif }
>>>>>
>>>>> +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) {
>>>>> + /* Synchronize guest's desire to get debug interrupts into shadow
>>>>> +MSR */ #ifndef CONFIG_KVM_BOOKE_HV
>>>>> + vcpu->arch.shadow_msr&= ~MSR_DE;
>>>>> + vcpu->arch.shadow_msr |= vcpu->arch.shared->msr& MSR_DE; #endif
>>>>> +
>>>>> + /* Force enable debug interrupts when user space wants to debug */
>>>>> + if (vcpu->guest_debug) {
>>>>> +#ifdef CONFIG_KVM_BOOKE_HV
>>>>> + /*
>>>>> + * Since there is no shadow MSR, sync MSR_DE into the guest
>>>>> + * visible MSR. Do not allow guest to change MSR[DE].
>>>>> + */
>>>>> + vcpu->arch.shared->msr |= MSR_DE;
>>>>> + mtspr(SPRN_MSRP, mfspr(SPRN_MSRP) | MSRP_DEP);
>>>> This mtspr should really just be a bit or in shadow_mspr when
>>>> guest_debug gets enabled. It should automatically get synchronized as
>>>> soon as the next
>>>> vpcu_load() happens.
>>> I think this is not required here as shadow_dbsr already have MSRP_DEP set.
>>>
>>> Will setup shadow_msrp when setting guest_debug and clear shadow_msrp when
>> guest_debug is cleared.
>>> But that will also not be sufficient as it not sure when vcpu_load()
>>> will be called after the shadow_msrp is changed. So
>>>
>>> When guest_debug is set in debug_ioctl()
>>> /* Set MSRP_DEP in shadow_msrp so that guest cannot change MSR.DE. As
>>> shadow_msrp is loaded on vcpu_load(), and it is not guaranteed that
>>> vcpu_load() will be called just after debug_ioctl(), so also set
>>> MSRP_DEP in SPRN_MSRP. */
>> debug_ioctl is an ioctl. So while that ioctl is on, the vcpu is not running.
>> After that ioctl user space calls another VCPU_RUN ioctl which invokes
>> vcpu_load.
> That's good. I was not aware of vcpu_load() is being called before ioctl handling in KVM :)
>
>>> - shadow_msrp | MSRP_DEP;
>>> - change SPRN_MSRP.MSRP_DEP as you do not know when vcpu_load() will be
>> called?
>>>
>>> When guest_debug is cleared in debug_ioctl()
>>> /* Clear MSRP_DEP in shadow_msrp so that guest can change MSR.DE. As
>>> shadow_msrp is loaded on vcpu_load(), and it is not guaranteed that
>>> vcpu_load() will be called just after debug_ioctl(), so also clear
>>> MSRP_DEP in SPRN_MSRP. */
>> Same thing here again.
>>
>>> - shadow_msrp | MSRP_DEP;
>>> - change SPRN_MSRP.MSRP_DEP as you do not know when vcpu_load() will be
>> called?
>>>> Also, what happens when user space disables guest_debug?
>>>>
>>>>> +#else
>>>>> + vcpu->arch.shadow_msr |= MSR_DE;
>>>>> + vcpu->arch.shared->msr&= ~MSR_DE; #endif
>>>>> + }
>>>>> +}
>>>>> +
>>>>> /*
>>>>> * Helper function for "full" MSR writes. No need to call this if
>>>>> only
>>>>> * EE/CE/ME/DE/RI are changing.
>>>>> @@ -150,6 +174,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
>>>>> kvmppc_mmu_msr_notify(vcpu, old_msr);
>>>>> kvmppc_vcpu_sync_spe(vcpu);
>>>>> kvmppc_vcpu_sync_fpu(vcpu);
>>>>> + kvmppc_vcpu_sync_debug(vcpu);
>>>>> }
>>>>>
>>>>> static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, @@
>>>>> -736,6 +761,9 @@ static int emulation_exit(struct kvm_run *run,
>>>>> struct
>>>> kvm_vcpu *vcpu)
>>>>> run->exit_reason = KVM_EXIT_DCR;
>>>>> return RESUME_HOST;
>>>>>
>>>>> + case EMULATE_EXIT_USER:
>>>>> + return RESUME_HOST;
>>>> This should get folded into the previous patch or be a separate one.
>>> ok
>>>
>>>>> +
>>>>> case EMULATE_FAIL:
>>>>> printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
>>>>> __func__, vcpu->arch.pc, vcpu->arch.last_inst); @@ -751,6
>>>>> +779,30 @@ static int emulation_exit(struct kvm_run *run, struct
>>>>> +kvm_vcpu
>>>> *vcpu)
>>>>> }
>>>>> }
>>>>>
>>>>> +static int kvmppc_handle_debug(struct kvm_run *run, struct kvm_vcpu
>>>>> +*vcpu) {
>>>>> + u32 dbsr = mfspr(SPRN_DBSR);
>>>>> + mtspr(SPRN_DBSR, dbsr);
>>>> This definitely deserves a comment :).
>>> Ok.
>>>
>>>> Also, are we non-preemptible here?
>>> This is called from kvmppc_handle_exit and interrupts are enabled, so I think
>> this can be preempted.
>>> But I do not think there is any issue as we clear DBSR in vpu_put().
>> Ok, make clear_dbsr a function then that you call from both places. That way
>> it's more obvious.
> Ok
>
>>>>> +
>>>>> + run->debug.arch.status = 0;
>>>>> + run->debug.arch.address = vcpu->arch.pc;
>>>>> +
>>>>> + if (dbsr& (DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4)) {
>>>>> + run->debug.arch.status |= KVMPPC_DEBUG_BREAKPOINT;
>>>>> + } else {
>>>>> + if (dbsr& (DBSR_DAC1W | DBSR_DAC2W))
>>>>> + run->debug.arch.status |= KVMPPC_DEBUG_WATCH_WRITE;
>>>>> + else if (dbsr& (DBSR_DAC1R | DBSR_DAC2R))
>>>>> + run->debug.arch.status |= KVMPPC_DEBUG_WATCH_READ;
>>>>> + if (dbsr& (DBSR_DAC1R | DBSR_DAC1W))
>>>>> + run->debug.arch.address = vcpu->arch.shadow_dbg_reg.dac[0];
>>>>> + else if (dbsr& (DBSR_DAC2R | DBSR_DAC2W))
>>>>> + run->debug.arch.address = vcpu->arch.shadow_dbg_reg.dac[1];
>>>>> + }
>>>>> +
>>>>> + return RESUME_HOST;
>>>> Shouldn't this check for guest_debug and only go to user space if it
>>>> asked for debugging? Can't you just leave it at the old code for
>> !guest_debug?
>>> Will add, I thought that it is redundant as of now as debug interrupt in guest
>> can come only when user space is debugging guest.
>>
>> The problem is that user space might not expect a guest debug exit.
> Ok
>
>>> clear DBSR
>>> if (!guest_debug)
>>> return RESUME_GUEST;
>> Can't you just do exactly what was done before when !guest_debug? We usually try
>> to change semantics one step at a time.
> What you mean by "done before" ? do you mean the removed code in "case BOOKE_INTERRUPT_DEBUG" code in kvmppc_handle_exit() ? If yes then that code was meaningless and not correct.
Then change it in a separate patch. One patch, one change. Otherwise
bisectability suffers.
> Right thing should be clear the pending exception and resume the guest. when no one is in state to handle the exception. May be we can have WARN_ON_ONCE()
>
>>>>> +}
>>>>> +
>>>>> static void kvmppc_fill_pt_regs(struct pt_regs *regs) {
>>>>> ulong r1, ip, msr, lr;
>>>>> @@ -1110,18 +1162,10 @@ int kvmppc_handle_exit(struct kvm_run *run,
>>>>> struct
>>>> kvm_vcpu *vcpu,
>>>>> }
>>>>>
>>>>> case BOOKE_INTERRUPT_DEBUG: {
>>>>> - u32 dbsr;
>>>>> -
>>>>> - vcpu->arch.pc = mfspr(SPRN_CSRR0);
>>>>> -
>>>>> - /* clear IAC events in DBSR register */
>>>>> - dbsr = mfspr(SPRN_DBSR);
>>>>> - dbsr&= DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4;
>>>>> - mtspr(SPRN_DBSR, dbsr);
>>>>> -
>>>>> - run->exit_reason = KVM_EXIT_DEBUG;
>>>>> + r = kvmppc_handle_debug(run, vcpu);
>>>>> + if (r == RESUME_HOST)
>>>>> + run->exit_reason = KVM_EXIT_DEBUG;
>>>>> kvmppc_account_exit(vcpu, DEBUG_EXITS);
>>>>> - r = RESUME_HOST;
>>>>> break;
>>>>> }
>>>>>
>>>>> @@ -1172,7 +1216,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
>>>>> kvmppc_set_msr(vcpu, 0);
>>>>>
>>>>> #ifndef CONFIG_KVM_BOOKE_HV
>>>>> - vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;
>>>>> + vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS;
>>>>> vcpu->arch.shadow_pid = 1;
>>>>> vcpu->arch.shared->msr = 0;
>>>>> #endif
>>>>> @@ -1527,12 +1571,6 @@ int kvm_vcpu_ioctl_set_one_reg(struct
>>>>> kvm_vcpu *vcpu,
>>>> struct kvm_one_reg *reg)
>>>>> return r;
>>>>> }
>>>>>
>>>>> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
>>>>> - struct kvm_guest_debug *dbg)
>>>>> -{
>>>>> - return -EINVAL;
>>>>> -}
>>>>> -
>>>>> int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct
>>>>> kvm_fpu
>>>>> *fpu) {
>>>>> return -ENOTSUPP;
>>>>> @@ -1638,16 +1676,194 @@ void kvmppc_decrementer_func(unsigned long data)
>>>>> kvmppc_set_tsr_bits(vcpu, TSR_DIS); }
>>>>>
>>>>> +static void kvmppc_booke_vcpu_put_debug_regs(struct kvm_vcpu *vcpu) {
>>>>> + if (!vcpu->arch.debug_save_restore)
>>>>> + return;
>>>>> +
>>>>> + /* Restore Host Context. Disable all debug events First */
>>>>> + mtspr(SPRN_DBCR0, 0x0);
>>>>> + /* Disable pending debug event by Clearing DBSR */
>>>>> + mtspr(SPRN_DBSR, mfspr(SPRN_DBSR));
>>>>> +
>>>>> + mtspr(SPRN_DBCR1, vcpu->arch.host_dbg_reg.dbcr1);
>>>>> + mtspr(SPRN_DBCR2, vcpu->arch.host_dbg_reg.dbcr2); #ifdef
>>>>> +CONFIG_KVM_E500MC
>>>>> + mtspr(SPRN_DBCR4, vcpu->arch.host_dbg_reg.dbcr4); #endif
>>>>> + mtspr(SPRN_IAC1, vcpu->arch.host_dbg_reg.iac[0]);
>>>>> + mtspr(SPRN_IAC2, vcpu->arch.host_dbg_reg.iac[1]); #if
>>>>> +CONFIG_PPC_ADV_DEBUG_IACS> 2
>>>>> + mtspr(SPRN_IAC3, vcpu->arch.host_dbg_reg.iac[2]);
>>>>> + mtspr(SPRN_IAC4, vcpu->arch.host_dbg_reg.iac[3]); #endif
>>>>> + mtspr(SPRN_DAC1, vcpu->arch.host_dbg_reg.dac[0]);
>>>>> + mtspr(SPRN_DAC2, vcpu->arch.host_dbg_reg.dac[1]);
>>>>> +
>>>>> + /* Enable debug events after all other debug registers restored */
>>>>> + mtspr(SPRN_DBCR0, vcpu->arch.host_dbg_reg.dbcr0);
>>>> How does the normal debug register switching code work in Linux?
>>>> Can't we just reuse that? Or rely on it to restore working state when
>>>> another process gets scheduled in?
>>> Good point, I can see debug registers loading in function __switch_to()-
>>> switch_booke_debug_regs() in file arch/powerpc/kernel/process.c.
>>> So as long as assume that host will not use debug resources we can rely on
>> this restore. But I am not sure that this is a fare assumption. As Scott earlier
>> mentioned someone can use debug resource for kernel debugging also.
>>
>> Someone in the kernel can also use floating point registers. But then it's his
>> responsibility to clean up the mess he leaves behind.
> I am neither convinced by what you said and nor even have much reason to oppose :)
>
> Scott,
> I remember you mentioned that host can use debug resources, you comment on this ?
>
>>>>> +
>>>>> + /* Host debug register are restored */
>>>>> + vcpu->arch.debug_save_restore = false; }
>>>>> +
>>>>> +static void kvmppc_booke_vcpu_load_debug_regs(struct kvm_vcpu
>>>>> +*vcpu) {
>>>>> + /*
>>>>> + * Check whether guest still need debug resource, if not then there
>>>>> + * is no need to resotre guest context.
>>>> restore
>>>>
>>>>> + */
>>>>> + if (!vcpu->arch.shadow_dbg_reg.dbcr0)
>>>>> + return;
>>>> Are we guaranteed that debugging is disabled here?
>>> Ah, I should be clearing the hw DBCR0 and DBSR.
>>>
>>>> We don't want to get debug
>>>> exceptions that were meant for some other process.
>>>>
>>>>> +
>>>>> + /*
>>>>> + * Save Host debug register only after restore. If host debug
>>>>> + * registers are saved and not restored then do not save again.
>>>>> + */
>>>>> + if (!vcpu->arch.debug_save_restore) {
>>>>> + /* Save Host context */
>>>>> + vcpu->arch.host_dbg_reg.dbcr0 = mfspr(SPRN_DBCR0);
>>>>> + vcpu->arch.host_dbg_reg.dbcr1 = mfspr(SPRN_DBCR1);
>>>>> + vcpu->arch.host_dbg_reg.dbcr2 = mfspr(SPRN_DBCR2); #ifdef
>>>>> +CONFIG_KVM_E500MC
>>>>> + vcpu->arch.host_dbg_reg.dbcr4 = mfspr(SPRN_DBCR4); #endif
>>>>> + vcpu->arch.host_dbg_reg.iac[0] = mfspr(SPRN_IAC1);
>>>>> + vcpu->arch.host_dbg_reg.iac[1] = mfspr(SPRN_IAC2); #if
>>>>> +CONFIG_PPC_ADV_DEBUG_IACS> 2
>>>>> + vcpu->arch.host_dbg_reg.iac[2] = mfspr(SPRN_IAC3);
>>>>> + vcpu->arch.host_dbg_reg.iac[3] = mfspr(SPRN_IAC4); #endif
>>>>> + vcpu->arch.host_dbg_reg.dac[0] = mfspr(SPRN_DAC1);
>>>>> + vcpu->arch.host_dbg_reg.dac[1] = mfspr(SPRN_DAC2);
>>>>> + vcpu->arch.debug_save_restore = true;
>>>>> + }
>>>>> +
>>>>> + /* Restore Guest Context. Disable all debug events First */
>>>>> + mtspr(SPRN_DBCR0, 0x0);
>>>>> + /* Clear h/w DBSR */
>>>>> + mtspr(SPRN_DBSR, mfspr(SPRN_DBSR));
>>>>> +
>>>>> + 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); #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); }
>>>>> +
>>>>> +int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
>>>>> + struct kvm_guest_debug *dbg)
>>>>> +{
>>>>> + struct kvmppc_booke_debug_reg *dbg_reg;
>>>>> + int n, b = 0, w = 0;
>>>>> + const u32 bp_code[] = {
>>>>> + DBCR0_IAC1 | DBCR0_IDM,
>>>>> + DBCR0_IAC2 | DBCR0_IDM,
>>>>> + DBCR0_IAC3 | DBCR0_IDM,
>>>>> + DBCR0_IAC4 | DBCR0_IDM
>>>>> + };
>>>>> + const u32 wp_code[] = {
>>>>> + DBCR0_DAC1W | DBCR0_IDM,
>>>>> + DBCR0_DAC2W | DBCR0_IDM,
>>>>> + DBCR0_DAC1R | DBCR0_IDM,
>>>>> + DBCR0_DAC2R | DBCR0_IDM
>>>>> + };
>>>>> +
>>>>> + if (!(dbg->control& KVM_GUESTDBG_ENABLE)) {
>>>>> + /* Clear All debug events */
>>>>> + vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
>>>>> + vcpu->guest_debug = 0;
>>>> Ah, this is where we disable guest_debug. This needs to enable
>>>> guest_debug for the guest again, so you need to remove the DE bit from
>> shadow_msrp here.
>>>>> + return 0;
>>>>> + }
>>>>> +
>>>>> + vcpu->guest_debug = dbg->control;
>>>>> + vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
>>>>> + /* Set DBCR0_EDM in guest visible DBCR0 register. */
>>>>> + vcpu->arch.dbg_reg.dbcr0 = DBCR0_EDM;
>>>>> +
>>>>> + if (vcpu->guest_debug& KVM_GUESTDBG_SINGLESTEP)
>>>>> + vcpu->arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC;
>>>>> +
>>>>> + if (!(vcpu->guest_debug& KVM_GUESTDBG_USE_HW_BP)) {
>>>>> + /* Code below handles only HW breakpoints */
>>>>> + kvmppc_booke_vcpu_load_debug_regs(vcpu);
>>>>> + return 0;
>>>>> + }
>>>>> +
>>>>> + dbg_reg =&(vcpu->arch.shadow_dbg_reg);
>>>>> +
>>>>> + /*
>>>>> + * On BOOKE (e500v2); Set DBCR1 and DBCR2 to allow debug events
>>>>> + * to occur when MSR.PR is set.
>>>>> + * On BOOKE-HV (e500mc+); MSR.PR = 0 when guest is running. So we
>>>>> + * should clear DBCR1 and DBCR2.
>>>>> + */
>>>>> +#ifdef CONFIG_KVM_BOOKE_HV
>>>>> + dbg_reg->dbcr1 = 0;
>>>>> + dbg_reg->dbcr2 = 0;
>>>> Does that mean we can't debug guest user space?
>>> Yes
>> This is wrong.
> Really, So far I am assuming qemu debug stub is not mean for debugging guest application.
Ok, let me rephrase: This is confusing. You do trap in PR mode on
e500v2. IIRC x86 also traps in kernel and user space. I don't see why
e500 hv should be different.
Alex
next prev parent reply other threads:[~2013-04-02 15:41 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-21 6:24 [PATCH 0/4 v2] KVM :PPC: Userspace Debug support Bharat Bhushan
2013-03-21 6:24 ` [PATCH 1/4 v2] Added ONE_REG interface for debug instruction Bharat Bhushan
2013-03-29 1:55 ` Alexander Graf
2013-03-21 6:24 ` [PATCH 2/4 v2] KVM: PPC: debug stub interface parameter defined Bharat Bhushan
2013-03-29 1:55 ` Alexander Graf
2013-03-29 3:08 ` Bhushan Bharat-R65777
2013-04-02 8:27 ` Alexander Graf
2013-03-21 6:25 ` [PATCH 3/4 v2] Rename EMULATE_DO_PAPR to EMULATE_EXIT_USER Bharat Bhushan
2013-03-28 14:05 ` Alexander Graf
2013-03-21 6:25 ` [PATCH 4/4 v2] KVM: PPC: Add userspace debug stub support Bharat Bhushan
2013-03-28 16:36 ` Alexander Graf
2013-03-29 6:04 ` Bhushan Bharat-R65777
2013-04-02 8:27 ` Alexander Graf
2013-04-02 14:09 ` Bhushan Bharat-R65777
2013-04-02 15:41 ` Alexander Graf [this message]
2013-04-03 17:14 ` Bhushan Bharat-R65777
2013-04-03 17:35 ` Alexander Graf
2013-04-03 17:47 ` Bhushan Bharat-R65777
2013-04-03 17:56 ` Alexander Graf
2013-04-03 18:00 ` Bhushan Bharat-R65777
2013-04-02 18:00 ` Scott Wood
2013-04-03 10:03 ` Bhushan Bharat-R65777
2013-04-03 10:28 ` Alexander Graf
2013-04-03 13:50 ` Bhushan Bharat-R65777
2013-04-03 14:09 ` Alexander Graf
2013-04-03 15:18 ` Bhushan Bharat-R65777
2013-04-03 16:26 ` Alexander Graf
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=515AFC26.5040705@suse.de \
--to=agraf@suse.de \
--cc=B07421@freescale.com \
--cc=R65777@freescale.com \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.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