From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753499AbbDMIAj (ORCPT ); Mon, 13 Apr 2015 04:00:39 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:48602 "EHLO socrates.bennee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752492AbbDMIAd (ORCPT ); Mon, 13 Apr 2015 04:00:33 -0400 References: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> <1427814488-28467-9-git-send-email-alex.bennee@linaro.org> <20150410122520.GA3227@hawk.usersys.redhat.com> From: Alex =?utf-8?Q?Benn=C3=A9e?= To: Andrew Jones Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org, marc.zyngier@arm.com, peter.maydell@linaro.org, agraf@suse.de, pbonzini@redhat.com, zhichao.huang@linaro.org, jan.kiszka@siemens.com, dahi@linux.vnet.ibm.com, r65777@freescale.com, bp@suse.de, Gleb Natapov , Jonathan Corbet , Russell King , Catalin Marinas , Will Deacon , AKASHI Takahiro , Lorenzo Pieralisi , "open list\:DOCUMENTATION" , open list , "open list\:ABI\/API" Subject: Re: [PATCH v2 08/10] KVM: arm64: guest debug, HW assisted debug support In-reply-to: <20150410122520.GA3227@hawk.usersys.redhat.com> Date: Mon, 13 Apr 2015 09:00:35 +0100 Message-ID: <876190laos.fsf@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 127.0.0.1 X-SA-Exim-Mail-From: alex.bennee@linaro.org X-SA-Exim-Scanned: No (on socrates.bennee.com); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Andrew Jones writes: > On Tue, Mar 31, 2015 at 04:08:06PM +0100, Alex Bennée wrote: >> This adds support for userspace to control the HW debug registers for >> guest debug. We'll only copy the $ARCH defined number across as that is >> all that hyp.S will use anyway. I've moved some helper functions into >> the hw_breakpoint.h header for re-use. >> >> As with single step we need to tweak the guest registers to enable the >> exceptions so we need to save and restore those bits. >> >> Two new capabilities have been added to the KVM_EXTENSION ioctl to allow >> userspace to query the number of hardware break and watch points >> available on the host hardware. >> >> As QEMU tests for watchpoints based on the address and not the PC we >> also need to export the value of far_el2 to userspace. >> >> Signed-off-by: Alex Bennée >> >> --- >> v2 >> - switched to C setup >> - replace host debug registers directly into context >> - minor tweak to api docs >> - setup right register for debug >> - add FAR_EL2 to debug exit structure >> - add support fro trapping debug register access >> >> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt >> index 17d4f9c..ac34093 100644 >> --- a/Documentation/virtual/kvm/api.txt >> +++ b/Documentation/virtual/kvm/api.txt >> @@ -2627,7 +2627,7 @@ The top 16 bits of the control field are architecture specific control >> flags which can include the following: >> >> - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64] >> - - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390] >> + - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64] >> - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86] >> - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86] >> - KVM_GUESTDBG_EXIT_PENDING: trigger an immediate guest exit [s390] >> @@ -2642,6 +2642,10 @@ updated to the correct (supplied) values. >> The second part of the structure is architecture specific and >> typically contains a set of debug registers. >> >> +For arm64 the number of debug registers is implementation defined and >> +can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and >> +KVM_CAP_GUEST_DEBUG_HW_WPS capabilities. >> + >> When debug events exit the main run loop with the reason >> KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run >> structure containing architecture specific debug information. >> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c >> index c1ed8cb..a286026 100644 >> --- a/arch/arm/kvm/arm.c >> +++ b/arch/arm/kvm/arm.c >> @@ -306,6 +306,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) >> >> #define KVM_GUESTDBG_VALID (KVM_GUESTDBG_ENABLE | \ >> KVM_GUESTDBG_USE_SW_BP | \ >> + KVM_GUESTDBG_USE_HW_BP | \ >> KVM_GUESTDBG_SINGLESTEP) >> >> /** >> @@ -328,6 +329,26 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, >> return -EINVAL; >> >> vcpu->guest_debug = dbg->control; >> + >> + /* Hardware assisted Break and Watch points */ >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + int nb = get_num_brps(); >> + int nw = get_num_wrps(); >> + >> + /* Copy across up to IMPDEF debug registers to our >> + * shadow copy in the vcpu structure. The debug code >> + * will then set them up before we re-enter the guest. >> + */ > > Is it necessary to limit the number copied here by anything other than > what the struct supports? Userspace gave us a struct kvm_guest_debug_arch, > so let's save the whole thing. How about just > > vcpu->arch.guest_debug_regs = *dbg; Makes sense for the ioctl. I'll still limit it in the setup/clear function. > >> + memcpy(vcpu->arch.guest_debug_regs.dbg_bcr, >> + dbg->arch.dbg_bcr, sizeof(__u64)*nb); >> + memcpy(vcpu->arch.guest_debug_regs.dbg_bvr, >> + dbg->arch.dbg_bvr, sizeof(__u64)*nb); >> + memcpy(vcpu->arch.guest_debug_regs.dbg_wcr, >> + dbg->arch.dbg_wcr, sizeof(__u64)*nw); >> + memcpy(vcpu->arch.guest_debug_regs.dbg_wvr, >> + dbg->arch.dbg_wvr, sizeof(__u64)*nw); >> + } >> + >> } else { >> /* If not enabled clear all flags */ >> vcpu->guest_debug = 0; >> diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h >> index 52b484b..c450552 100644 >> --- a/arch/arm64/include/asm/hw_breakpoint.h >> +++ b/arch/arm64/include/asm/hw_breakpoint.h >> @@ -130,6 +130,18 @@ static inline void ptrace_hw_copy_thread(struct task_struct *task) >> } >> #endif >> >> +/* Determine number of BRP registers available. */ >> +static inline int get_num_brps(void) >> +{ >> + return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1; >> +} >> + >> +/* Determine number of WRP registers available. */ >> +static inline int get_num_wrps(void) >> +{ >> + return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1; >> +} >> + >> extern struct pmu perf_ops_bp; >> >> #endif /* __KERNEL__ */ >> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h >> index 6a33647..2c359c9 100644 >> --- a/arch/arm64/include/asm/kvm_host.h >> +++ b/arch/arm64/include/asm/kvm_host.h >> @@ -106,8 +106,9 @@ struct kvm_vcpu_arch { >> /* Exception Information */ >> struct kvm_vcpu_fault_info fault; >> >> - /* Debug state */ >> + /* Guest debug state */ >> u64 debug_flags; >> + struct kvm_guest_debug_arch guest_debug_regs; >> >> /* Pointer to host CPU context */ >> kvm_cpu_context_t *host_cpu_context; >> @@ -126,6 +127,7 @@ struct kvm_vcpu_arch { >> u32 pstate_ss_bit; >> u32 mdscr_el1_bits; >> >> + struct kvm_guest_debug_arch debug_regs; >> } debug_saved_regs; >> >> /* Don't run the guest */ >> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h >> index 6ee70a0..73f21e4 100644 >> --- a/arch/arm64/include/uapi/asm/kvm.h >> +++ b/arch/arm64/include/uapi/asm/kvm.h >> @@ -118,6 +118,7 @@ struct kvm_guest_debug_arch { >> struct kvm_debug_exit_arch { >> __u64 pc; >> __u32 hsr; >> + __u64 far; /* used for watchpoints */ >> }; >> >> struct kvm_sync_regs { >> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c >> index 98bbe06..923be44 100644 >> --- a/arch/arm64/kernel/hw_breakpoint.c >> +++ b/arch/arm64/kernel/hw_breakpoint.c >> @@ -49,18 +49,6 @@ static DEFINE_PER_CPU(int, stepping_kernel_bp); >> static int core_num_brps; >> static int core_num_wrps; >> >> -/* Determine number of BRP registers available. */ >> -static int get_num_brps(void) >> -{ >> - return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1; >> -} >> - >> -/* Determine number of WRP registers available. */ >> -static int get_num_wrps(void) >> -{ >> - return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1; >> -} >> - >> int hw_breakpoint_slots(int type) >> { >> /* >> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c >> index b32362c..3b368f3 100644 >> --- a/arch/arm64/kvm/debug.c >> +++ b/arch/arm64/kvm/debug.c >> @@ -50,14 +50,19 @@ >> >> void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) >> { >> + bool trap_debug = false; >> + >> vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | MDCR_EL2_TPMCR); >> vcpu->arch.mdcr_el2 |= (MDCR_EL2_TDRA | MDCR_EL2_TDOSA); >> >> - /* Trap debug register access? */ >> + trace_kvm_arch_setup_debug_reg32("MDCR_EL2", vcpu->arch.mdcr_el2); > > This is 2 patches too early. You don't introduce this tracepoint until > later. > >> + >> + /* >> + * If we are not treating debug registers are dirty we need > ^^ as >> + * to trap if the guest starts accessing them. >> + */ >> if (!vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY) >> - vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; >> - else >> - vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA; >> + trap_debug = true; > > How about just > > bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY); > > at the top instead? > >> >> /* Is Guest debugging in effect? */ >> if (vcpu->guest_debug) { >> @@ -84,10 +89,69 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) >> vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS; >> } >> >> + /* >> + * HW Break/Watch points >> + */ >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + int nb = get_num_brps(); >> + int nw = get_num_wrps(); >> + struct kvm_guest_debug_arch *saved, *host; >> + >> + vcpu_sys_reg(vcpu, MDSCR_EL1) |= >> + (DBG_MDSCR_KDE|DBG_MDSCR_MDE); >> + >> + /* >> + * First we need to make a copy of the guest >> + * debug registers before we wipe them out >> + * with the ones we want to use. >> + */ >> + saved = &vcpu_debug_saved_reg(vcpu, debug_regs); >> + host = &vcpu->arch.guest_debug_regs; > > Again, I don't think we need to be so precise with our copy. We can > always copy extra without problems. It's just what we use that matters. > And how about a couple helpers? > > debug_regs_save_to(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dst) > { > memcpy(dst->dbg_bcr, &vcpu_sys_reg(vcpu, DBGBCR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(dst->dbg_bvr, &vcpu_sys_reg(vcpu, DBGBVR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(dst->dbg_wcr, &vcpu_sys_reg(vcpu, DBGWCR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(dst->dbg_wvr, &vcpu_sys_reg(vcpu, DBGWVR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > } > debug_regs_restore_from(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *src) > { > memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1), src->dbg_bcr, sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1), src->dbg_bvr, sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1), src->dbg_wcr, sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1), src->dbg_wvr, sizeof(u64)*KVM_ARM_NDBG_REGS); > } > >> + >> + /* Save guest values */ >> + memcpy(&saved->dbg_bcr, >> + &vcpu_sys_reg(vcpu, DBGBCR0_EL1), >> + sizeof(__u64)*nb); >> + memcpy(&saved->dbg_bvr, >> + &vcpu_sys_reg(vcpu, DBGBVR0_EL1), >> + sizeof(__u64)*nb); >> + memcpy(&saved->dbg_wcr, >> + &vcpu_sys_reg(vcpu, DBGWCR0_EL1), >> + sizeof(__u64)*nw); >> + memcpy(&saved->dbg_wvr, >> + &vcpu_sys_reg(vcpu, DBGWVR0_EL1), >> + sizeof(__u64)*nw); >> + >> + /* Copy in host values */ >> + memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1), >> + &host->dbg_bcr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1), >> + &host->dbg_bvr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1), >> + &host->dbg_wcr, >> + sizeof(__u64)*nw); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1), >> + &host->dbg_wvr, >> + sizeof(__u64)*nw); >> + >> + /* Make sure hyp.S copies them in/out */ >> + vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; >> + /* Also track guest changes */ >> + trap_debug = true; >> + } >> + >> } else { >> /* Debug operations can go straight to the guest */ >> vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE; >> } >> + >> + /* Trap debug register access? */ >> + if (trap_debug) >> + vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; >> + else >> + vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA; >> } >> >> void kvm_arch_clear_debug(struct kvm_vcpu *vcpu) >> @@ -100,5 +164,31 @@ void kvm_arch_clear_debug(struct kvm_vcpu *vcpu) >> vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~MDSCR_EL1_DEBUG_BITS; >> vcpu_sys_reg(vcpu, MDSCR_EL1) |= >> vcpu_debug_saved_reg(vcpu, mdscr_el1_bits); >> + >> + /* >> + * If we were using HW debug we need to restore the >> + * values the guest had set them up with >> + */ >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + struct kvm_guest_debug_arch *regs; >> + int nb = get_num_brps(); >> + int nw = get_num_wrps(); >> + >> + regs = &vcpu_debug_saved_reg(vcpu, debug_regs); > debug_regs_restore_from(vcpu, regs); >> + >> + /* Restore the saved debug register values */ >> + memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1), >> + ®s->dbg_bcr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1), >> + ®s->dbg_bvr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1), >> + ®s->dbg_wcr, >> + sizeof(__u64)*nw); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1), >> + ®s->dbg_wvr, >> + sizeof(__u64)*nw); >> + } >> } >> } >> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c >> index 16accae..460a1aa 100644 >> --- a/arch/arm64/kvm/handle_exit.c >> +++ b/arch/arm64/kvm/handle_exit.c >> @@ -101,7 +101,11 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run) >> run->debug.arch.hsr = hsr; >> >> switch (hsr >> ESR_ELx_EC_SHIFT) { >> + case ESR_ELx_EC_WATCHPT_LOW: >> + run->debug.arch.far = vcpu->arch.fault.far_el2; >> + /* fall through */ >> case ESR_ELx_EC_SOFTSTP_LOW: >> + case ESR_ELx_EC_BREAKPT_LOW: >> case ESR_ELx_EC_BKPT32: >> case ESR_ELx_EC_BRK64: >> run->debug.arch.pc = *vcpu_pc(vcpu); >> @@ -129,6 +133,8 @@ static exit_handle_fn arm_exit_handlers[] = { >> [ESR_ELx_EC_IABT_LOW] = kvm_handle_guest_abort, >> [ESR_ELx_EC_DABT_LOW] = kvm_handle_guest_abort, >> [ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug, >> + [ESR_ELx_EC_WATCHPT_LOW]= kvm_handle_guest_debug, >> + [ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug, >> [ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug, >> [ESR_ELx_EC_BRK64] = kvm_handle_guest_debug, >> }; >> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c >> index 0b43265..c2732c7 100644 >> --- a/arch/arm64/kvm/reset.c >> +++ b/arch/arm64/kvm/reset.c >> @@ -64,6 +64,12 @@ int kvm_arch_dev_ioctl_check_extension(long ext) >> case KVM_CAP_ARM_EL1_32BIT: >> r = cpu_has_32bit_el1(); >> break; >> + case KVM_CAP_GUEST_DEBUG_HW_BPS: >> + r = get_num_brps(); >> + break; >> + case KVM_CAP_GUEST_DEBUG_HW_WPS: >> + r = get_num_wrps(); >> + break; >> default: >> r = 0; >> } >> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c >> index c370b40..be9b188 100644 >> --- a/arch/arm64/kvm/sys_regs.c >> +++ b/arch/arm64/kvm/sys_regs.c >> @@ -196,16 +196,49 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu, >> * - If the dirty bit is set, save guest registers, restore host >> * registers and clear the dirty bit. This ensure that the host can >> * now use the debug registers. >> + * >> + * We also use this mechanism to set-up the debug registers for guest > setup >> + * debugging. If this is the case we want to ensure the guest sees >> + * the right versions of the registers - even if they are not going to >> + * be effective while guest debug is using HW debug. >> + * > no need for this blank comment line >> */ >> + >> static bool trap_debug_regs(struct kvm_vcpu *vcpu, >> const struct sys_reg_params *p, >> const struct sys_reg_desc *r) >> { >> - if (p->is_write) { >> - vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); >> - vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + struct kvm_guest_debug_arch *saved; >> + __u64 *val; >> + >> + saved = &vcpu_debug_saved_reg(vcpu, debug_regs); > > Here we don't bother enforcing num_brps/wrps, which is fine by me. > >> + >> + if (r->reg >= DBGBCR0_EL1 && r->reg <= DBGBCR15_EL1) >> + val = &saved->dbg_bcr[r->reg - DBGBCR0_EL1]; >> + else if (r->reg >= DBGBVR0_EL1 && r->reg <= DBGBVR15_EL1) >> + val = &saved->dbg_bvr[r->reg - DBGBVR0_EL1]; >> + else if (r->reg >= DBGWCR0_EL1 && r->reg <= DBGWCR15_EL1) >> + val = &saved->dbg_wcr[r->reg - DBGWCR0_EL1]; >> + else if (r->reg >= DBGWVR0_EL1 && r->reg <= DBGWVR15_EL1) >> + val = &saved->dbg_wvr[r->reg - DBGWVR0_EL1]; >> + else { >> + kvm_err("Bad register index %d\n", r->reg); >> + return false; >> + } >> + >> + if (p->is_write) >> + *val = *vcpu_reg(vcpu, p->Rt); >> + else >> + *vcpu_reg(vcpu, p->Rt) = *val; >> + >> } else { >> - *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg); >> + if (p->is_write) { >> + vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); >> + vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; >> + } else { >> + *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg); >> + } >> } >> >> return true; >> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h >> index ce2db14..0e48c0d 100644 >> --- a/include/uapi/linux/kvm.h >> +++ b/include/uapi/linux/kvm.h >> @@ -771,6 +771,8 @@ struct kvm_ppc_smmu_info { >> #define KVM_CAP_PPC_ENABLE_HCALL 104 >> #define KVM_CAP_CHECK_EXTENSION_VM 105 >> #define KVM_CAP_S390_USER_SIGP 106 >> +#define KVM_CAP_GUEST_DEBUG_HW_BPS 107 >> +#define KVM_CAP_GUEST_DEBUG_HW_WPS 108 >> >> #ifdef KVM_CAP_IRQ_ROUTING >> >> -- >> 2.3.4 >> -- Alex Bennée From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex =?utf-8?Q?Benn=C3=A9e?= Subject: Re: [PATCH v2 08/10] KVM: arm64: guest debug, HW assisted debug support Date: Mon, 13 Apr 2015 09:00:35 +0100 Message-ID: <876190laos.fsf@linaro.org> References: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> <1427814488-28467-9-git-send-email-alex.bennee@linaro.org> <20150410122520.GA3227@hawk.usersys.redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-reply-to: <20150410122520.GA3227@hawk.usersys.redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kvmarm-bounces@lists.cs.columbia.edu Sender: kvmarm-bounces@lists.cs.columbia.edu To: Andrew Jones Cc: kvm@vger.kernel.org, "open list:DOCUMENTATION" , jan.kiszka@siemens.com, Will Deacon , kvmarm@lists.cs.columbia.edu, Lorenzo Pieralisi , Russell King , Jonathan Corbet , AKASHI Takahiro , zhichao.huang@linaro.org, Catalin Marinas , bp@suse.de, Gleb Natapov , marc.zyngier@arm.com, r65777@freescale.com, linux-arm-kernel@lists.infradead.org, "open list:ABI/API" , open list , dahi@linux.vnet.ibm.com, pbonzini@redhat.com List-Id: linux-api@vger.kernel.org CkFuZHJldyBKb25lcyA8ZHJqb25lc0ByZWRoYXQuY29tPiB3cml0ZXM6Cgo+IE9uIFR1ZSwgTWFy IDMxLCAyMDE1IGF0IDA0OjA4OjA2UE0gKzAxMDAsIEFsZXggQmVubsOpZSB3cm90ZToKPj4gVGhp cyBhZGRzIHN1cHBvcnQgZm9yIHVzZXJzcGFjZSB0byBjb250cm9sIHRoZSBIVyBkZWJ1ZyByZWdp c3RlcnMgZm9yCj4+IGd1ZXN0IGRlYnVnLiBXZSdsbCBvbmx5IGNvcHkgdGhlICRBUkNIIGRlZmlu ZWQgbnVtYmVyIGFjcm9zcyBhcyB0aGF0IGlzCj4+IGFsbCB0aGF0IGh5cC5TIHdpbGwgdXNlIGFu eXdheS4gSSd2ZSBtb3ZlZCBzb21lIGhlbHBlciBmdW5jdGlvbnMgaW50bwo+PiB0aGUgaHdfYnJl YWtwb2ludC5oIGhlYWRlciBmb3IgcmUtdXNlLgo+PiAKPj4gQXMgd2l0aCBzaW5nbGUgc3RlcCB3 ZSBuZWVkIHRvIHR3ZWFrIHRoZSBndWVzdCByZWdpc3RlcnMgdG8gZW5hYmxlIHRoZQo+PiBleGNl cHRpb25zIHNvIHdlIG5lZWQgdG8gc2F2ZSBhbmQgcmVzdG9yZSB0aG9zZSBiaXRzLgo+PiAKPj4g VHdvIG5ldyBjYXBhYmlsaXRpZXMgaGF2ZSBiZWVuIGFkZGVkIHRvIHRoZSBLVk1fRVhURU5TSU9O IGlvY3RsIHRvIGFsbG93Cj4+IHVzZXJzcGFjZSB0byBxdWVyeSB0aGUgbnVtYmVyIG9mIGhhcmR3 YXJlIGJyZWFrIGFuZCB3YXRjaCBwb2ludHMKPj4gYXZhaWxhYmxlIG9uIHRoZSBob3N0IGhhcmR3 YXJlLgo+PiAKPj4gQXMgUUVNVSB0ZXN0cyBmb3Igd2F0Y2hwb2ludHMgYmFzZWQgb24gdGhlIGFk ZHJlc3MgYW5kIG5vdCB0aGUgUEMgd2UKPj4gYWxzbyBuZWVkIHRvIGV4cG9ydCB0aGUgdmFsdWUg b2YgZmFyX2VsMiB0byB1c2Vyc3BhY2UuCj4+IAo+PiBTaWduZWQtb2ZmLWJ5OiBBbGV4IEJlbm7D qWUgPGFsZXguYmVubmVlQGxpbmFyby5vcmc+Cj4+IAo+PiAtLS0KPj4gdjIKPj4gICAgLSBzd2l0 Y2hlZCB0byBDIHNldHVwCj4+ICAgIC0gcmVwbGFjZSBob3N0IGRlYnVnIHJlZ2lzdGVycyBkaXJl Y3RseSBpbnRvIGNvbnRleHQKPj4gICAgLSBtaW5vciB0d2VhayB0byBhcGkgZG9jcwo+PiAgICAt IHNldHVwIHJpZ2h0IHJlZ2lzdGVyIGZvciBkZWJ1Zwo+PiAgICAtIGFkZCBGQVJfRUwyIHRvIGRl YnVnIGV4aXQgc3RydWN0dXJlCj4+ICAgIC0gYWRkIHN1cHBvcnQgZnJvIHRyYXBwaW5nIGRlYnVn IHJlZ2lzdGVyIGFjY2Vzcwo+PiAKPj4gZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vdmlydHVh bC9rdm0vYXBpLnR4dCBiL0RvY3VtZW50YXRpb24vdmlydHVhbC9rdm0vYXBpLnR4dAo+PiBpbmRl eCAxN2Q0ZjljLi5hYzM0MDkzIDEwMDY0NAo+PiAtLS0gYS9Eb2N1bWVudGF0aW9uL3ZpcnR1YWwv a3ZtL2FwaS50eHQKPj4gKysrIGIvRG9jdW1lbnRhdGlvbi92aXJ0dWFsL2t2bS9hcGkudHh0Cj4+ IEBAIC0yNjI3LDcgKzI2MjcsNyBAQCBUaGUgdG9wIDE2IGJpdHMgb2YgdGhlIGNvbnRyb2wgZmll bGQgYXJlIGFyY2hpdGVjdHVyZSBzcGVjaWZpYyBjb250cm9sCj4+ICBmbGFncyB3aGljaCBjYW4g aW5jbHVkZSB0aGUgZm9sbG93aW5nOgo+PiAgCj4+ICAgIC0gS1ZNX0dVRVNUREJHX1VTRV9TV19C UDogICAgIHVzaW5nIHNvZnR3YXJlIGJyZWFrcG9pbnRzIFt4ODYsIGFybTY0XQo+PiAtICAtIEtW TV9HVUVTVERCR19VU0VfSFdfQlA6ICAgICB1c2luZyBoYXJkd2FyZSBicmVha3BvaW50cyBbeDg2 LCBzMzkwXQo+PiArICAtIEtWTV9HVUVTVERCR19VU0VfSFdfQlA6ICAgICB1c2luZyBoYXJkd2Fy ZSBicmVha3BvaW50cyBbeDg2LCBzMzkwLCBhcm02NF0KPj4gICAgLSBLVk1fR1VFU1REQkdfSU5K RUNUX0RCOiAgICAgaW5qZWN0IERCIHR5cGUgZXhjZXB0aW9uIFt4ODZdCj4+ICAgIC0gS1ZNX0dV RVNUREJHX0lOSkVDVF9CUDogICAgIGluamVjdCBCUCB0eXBlIGV4Y2VwdGlvbiBbeDg2XQo+PiAg ICAtIEtWTV9HVUVTVERCR19FWElUX1BFTkRJTkc6ICB0cmlnZ2VyIGFuIGltbWVkaWF0ZSBndWVz dCBleGl0IFtzMzkwXQo+PiBAQCAtMjY0Miw2ICsyNjQyLDEwIEBAIHVwZGF0ZWQgdG8gdGhlIGNv cnJlY3QgKHN1cHBsaWVkKSB2YWx1ZXMuCj4+ICBUaGUgc2Vjb25kIHBhcnQgb2YgdGhlIHN0cnVj dHVyZSBpcyBhcmNoaXRlY3R1cmUgc3BlY2lmaWMgYW5kCj4+ICB0eXBpY2FsbHkgY29udGFpbnMg YSBzZXQgb2YgZGVidWcgcmVnaXN0ZXJzLgo+PiAgCj4+ICtGb3IgYXJtNjQgdGhlIG51bWJlciBv ZiBkZWJ1ZyByZWdpc3RlcnMgaXMgaW1wbGVtZW50YXRpb24gZGVmaW5lZCBhbmQKPj4gK2NhbiBi ZSBkZXRlcm1pbmVkIGJ5IHF1ZXJ5aW5nIHRoZSBLVk1fQ0FQX0dVRVNUX0RFQlVHX0hXX0JQUyBh bmQKPj4gK0tWTV9DQVBfR1VFU1RfREVCVUdfSFdfV1BTIGNhcGFiaWxpdGllcy4KPj4gKwo+PiAg V2hlbiBkZWJ1ZyBldmVudHMgZXhpdCB0aGUgbWFpbiBydW4gbG9vcCB3aXRoIHRoZSByZWFzb24K Pj4gIEtWTV9FWElUX0RFQlVHIHdpdGggdGhlIGt2bV9kZWJ1Z19leGl0X2FyY2ggcGFydCBvZiB0 aGUga3ZtX3J1bgo+PiAgc3RydWN0dXJlIGNvbnRhaW5pbmcgYXJjaGl0ZWN0dXJlIHNwZWNpZmlj IGRlYnVnIGluZm9ybWF0aW9uLgo+PiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm0va3ZtL2FybS5jIGIv YXJjaC9hcm0va3ZtL2FybS5jCj4+IGluZGV4IGMxZWQ4Y2IuLmEyODYwMjYgMTAwNjQ0Cj4+IC0t LSBhL2FyY2gvYXJtL2t2bS9hcm0uYwo+PiArKysgYi9hcmNoL2FybS9rdm0vYXJtLmMKPj4gQEAg LTMwNiw2ICszMDYsNyBAQCB2b2lkIGt2bV9hcmNoX3ZjcHVfcHV0KHN0cnVjdCBrdm1fdmNwdSAq dmNwdSkKPj4gIAo+PiAgI2RlZmluZSBLVk1fR1VFU1REQkdfVkFMSUQgKEtWTV9HVUVTVERCR19F TkFCTEUgfCAgICBcCj4+ICAJCQkgICAgS1ZNX0dVRVNUREJHX1VTRV9TV19CUCB8IFwKPj4gKwkJ CSAgICBLVk1fR1VFU1REQkdfVVNFX0hXX0JQIHwgXAo+PiAgCQkJICAgIEtWTV9HVUVTVERCR19T SU5HTEVTVEVQKQo+PiAgCj4+ICAvKioKPj4gQEAgLTMyOCw2ICszMjksMjYgQEAgaW50IGt2bV9h cmNoX3ZjcHVfaW9jdGxfc2V0X2d1ZXN0X2RlYnVnKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSwKPj4g IAkJCXJldHVybiAtRUlOVkFMOwo+PiAgCj4+ICAJCXZjcHUtPmd1ZXN0X2RlYnVnID0gZGJnLT5j b250cm9sOwo+PiArCj4+ICsJCS8qIEhhcmR3YXJlIGFzc2lzdGVkIEJyZWFrIGFuZCBXYXRjaCBw b2ludHMgKi8KPj4gKwkJaWYgKHZjcHUtPmd1ZXN0X2RlYnVnICYgS1ZNX0dVRVNUREJHX1VTRV9I V19CUCkgewo+PiArCQkJaW50IG5iID0gZ2V0X251bV9icnBzKCk7Cj4+ICsJCQlpbnQgbncgPSBn ZXRfbnVtX3dycHMoKTsKPj4gKwo+PiArCQkJLyogQ29weSBhY3Jvc3MgdXAgdG8gSU1QREVGIGRl YnVnIHJlZ2lzdGVycyB0byBvdXIKPj4gKwkJCSAqIHNoYWRvdyBjb3B5IGluIHRoZSB2Y3B1IHN0 cnVjdHVyZS4gVGhlIGRlYnVnIGNvZGUKPj4gKwkJCSAqIHdpbGwgdGhlbiBzZXQgdGhlbSB1cCBi ZWZvcmUgd2UgcmUtZW50ZXIgdGhlIGd1ZXN0Lgo+PiArCQkJICovCj4KPiBJcyBpdCBuZWNlc3Nh cnkgdG8gbGltaXQgdGhlIG51bWJlciBjb3BpZWQgaGVyZSBieSBhbnl0aGluZyBvdGhlciB0aGFu Cj4gd2hhdCB0aGUgc3RydWN0IHN1cHBvcnRzPyBVc2Vyc3BhY2UgZ2F2ZSB1cyBhIHN0cnVjdCBr dm1fZ3Vlc3RfZGVidWdfYXJjaCwKPiBzbyBsZXQncyBzYXZlIHRoZSB3aG9sZSB0aGluZy4gSG93 IGFib3V0IGp1c3QKPgo+IHZjcHUtPmFyY2guZ3Vlc3RfZGVidWdfcmVncyA9ICpkYmc7CgpNYWtl cyBzZW5zZSBmb3IgdGhlIGlvY3RsLiBJJ2xsIHN0aWxsIGxpbWl0IGl0IGluIHRoZSBzZXR1cC9j bGVhciBmdW5jdGlvbi4KCj4KPj4gKwkJCW1lbWNweSh2Y3B1LT5hcmNoLmd1ZXN0X2RlYnVnX3Jl Z3MuZGJnX2JjciwKPj4gKwkJCQlkYmctPmFyY2guZGJnX2Jjciwgc2l6ZW9mKF9fdTY0KSpuYik7 Cj4+ICsJCQltZW1jcHkodmNwdS0+YXJjaC5ndWVzdF9kZWJ1Z19yZWdzLmRiZ19idnIsCj4+ICsJ CQkJZGJnLT5hcmNoLmRiZ19idnIsIHNpemVvZihfX3U2NCkqbmIpOwo+PiArCQkJbWVtY3B5KHZj cHUtPmFyY2guZ3Vlc3RfZGVidWdfcmVncy5kYmdfd2NyLAo+PiArCQkJCWRiZy0+YXJjaC5kYmdf d2NyLCBzaXplb2YoX191NjQpKm53KTsKPj4gKwkJCW1lbWNweSh2Y3B1LT5hcmNoLmd1ZXN0X2Rl YnVnX3JlZ3MuZGJnX3d2ciwKPj4gKwkJCQlkYmctPmFyY2guZGJnX3d2ciwgc2l6ZW9mKF9fdTY0 KSpudyk7Cj4+ICsJCX0KPj4gKwo+PiAgCX0gZWxzZSB7Cj4+ICAJCS8qIElmIG5vdCBlbmFibGVk IGNsZWFyIGFsbCBmbGFncyAqLwo+PiAgCQl2Y3B1LT5ndWVzdF9kZWJ1ZyA9IDA7Cj4+IGRpZmYg LS1naXQgYS9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL2h3X2JyZWFrcG9pbnQuaCBiL2FyY2gvYXJt NjQvaW5jbHVkZS9hc20vaHdfYnJlYWtwb2ludC5oCj4+IGluZGV4IDUyYjQ4NGIuLmM0NTA1NTIg MTAwNjQ0Cj4+IC0tLSBhL2FyY2gvYXJtNjQvaW5jbHVkZS9hc20vaHdfYnJlYWtwb2ludC5oCj4+ ICsrKyBiL2FyY2gvYXJtNjQvaW5jbHVkZS9hc20vaHdfYnJlYWtwb2ludC5oCj4+IEBAIC0xMzAs NiArMTMwLDE4IEBAIHN0YXRpYyBpbmxpbmUgdm9pZCBwdHJhY2VfaHdfY29weV90aHJlYWQoc3Ry dWN0IHRhc2tfc3RydWN0ICp0YXNrKQo+PiAgfQo+PiAgI2VuZGlmCj4+ICAKPj4gKy8qIERldGVy bWluZSBudW1iZXIgb2YgQlJQIHJlZ2lzdGVycyBhdmFpbGFibGUuICovCj4+ICtzdGF0aWMgaW5s aW5lIGludCBnZXRfbnVtX2JycHModm9pZCkKPj4gK3sKPj4gKwlyZXR1cm4gKChyZWFkX2NwdWlk KElEX0FBNjRERlIwX0VMMSkgPj4gMTIpICYgMHhmKSArIDE7Cj4+ICt9Cj4+ICsKPj4gKy8qIERl dGVybWluZSBudW1iZXIgb2YgV1JQIHJlZ2lzdGVycyBhdmFpbGFibGUuICovCj4+ICtzdGF0aWMg aW5saW5lIGludCBnZXRfbnVtX3dycHModm9pZCkKPj4gK3sKPj4gKwlyZXR1cm4gKChyZWFkX2Nw dWlkKElEX0FBNjRERlIwX0VMMSkgPj4gMjApICYgMHhmKSArIDE7Cj4+ICt9Cj4+ICsKPj4gIGV4 dGVybiBzdHJ1Y3QgcG11IHBlcmZfb3BzX2JwOwo+PiAgCj4+ICAjZW5kaWYJLyogX19LRVJORUxf XyAqLwo+PiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9rdm1faG9zdC5oIGIv YXJjaC9hcm02NC9pbmNsdWRlL2FzbS9rdm1faG9zdC5oCj4+IGluZGV4IDZhMzM2NDcuLjJjMzU5 YzkgMTAwNjQ0Cj4+IC0tLSBhL2FyY2gvYXJtNjQvaW5jbHVkZS9hc20va3ZtX2hvc3QuaAo+PiAr KysgYi9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL2t2bV9ob3N0LmgKPj4gQEAgLTEwNiw4ICsxMDYs OSBAQCBzdHJ1Y3Qga3ZtX3ZjcHVfYXJjaCB7Cj4+ICAJLyogRXhjZXB0aW9uIEluZm9ybWF0aW9u ICovCj4+ICAJc3RydWN0IGt2bV92Y3B1X2ZhdWx0X2luZm8gZmF1bHQ7Cj4+ICAKPj4gLQkvKiBE ZWJ1ZyBzdGF0ZSAqLwo+PiArCS8qIEd1ZXN0IGRlYnVnIHN0YXRlICovCj4+ICAJdTY0IGRlYnVn X2ZsYWdzOwo+PiArCXN0cnVjdCBrdm1fZ3Vlc3RfZGVidWdfYXJjaCBndWVzdF9kZWJ1Z19yZWdz Owo+PiAgCj4+ICAJLyogUG9pbnRlciB0byBob3N0IENQVSBjb250ZXh0ICovCj4+ICAJa3ZtX2Nw dV9jb250ZXh0X3QgKmhvc3RfY3B1X2NvbnRleHQ7Cj4+IEBAIC0xMjYsNiArMTI3LDcgQEAgc3Ry dWN0IGt2bV92Y3B1X2FyY2ggewo+PiAgCQl1MzIJcHN0YXRlX3NzX2JpdDsKPj4gIAkJdTMyCW1k c2NyX2VsMV9iaXRzOwo+PiAgCj4+ICsJCXN0cnVjdCBrdm1fZ3Vlc3RfZGVidWdfYXJjaCBkZWJ1 Z19yZWdzOwo+PiAgCX0gZGVidWdfc2F2ZWRfcmVnczsKPj4gIAo+PiAgCS8qIERvbid0IHJ1biB0 aGUgZ3Vlc3QgKi8KPj4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQvaW5jbHVkZS91YXBpL2FzbS9r dm0uaCBiL2FyY2gvYXJtNjQvaW5jbHVkZS91YXBpL2FzbS9rdm0uaAo+PiBpbmRleCA2ZWU3MGEw Li43M2YyMWU0IDEwMDY0NAo+PiAtLS0gYS9hcmNoL2FybTY0L2luY2x1ZGUvdWFwaS9hc20va3Zt LmgKPj4gKysrIGIvYXJjaC9hcm02NC9pbmNsdWRlL3VhcGkvYXNtL2t2bS5oCj4+IEBAIC0xMTgs NiArMTE4LDcgQEAgc3RydWN0IGt2bV9ndWVzdF9kZWJ1Z19hcmNoIHsKPj4gIHN0cnVjdCBrdm1f ZGVidWdfZXhpdF9hcmNoIHsKPj4gIAlfX3U2NCBwYzsKPj4gIAlfX3UzMiBoc3I7Cj4+ICsJX191 NjQgZmFyOwkvKiB1c2VkIGZvciB3YXRjaHBvaW50cyAqLwo+PiAgfTsKPj4gIAo+PiAgc3RydWN0 IGt2bV9zeW5jX3JlZ3Mgewo+PiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9rZXJuZWwvaHdfYnJl YWtwb2ludC5jIGIvYXJjaC9hcm02NC9rZXJuZWwvaHdfYnJlYWtwb2ludC5jCj4+IGluZGV4IDk4 YmJlMDYuLjkyM2JlNDQgMTAwNjQ0Cj4+IC0tLSBhL2FyY2gvYXJtNjQva2VybmVsL2h3X2JyZWFr cG9pbnQuYwo+PiArKysgYi9hcmNoL2FybTY0L2tlcm5lbC9od19icmVha3BvaW50LmMKPj4gQEAg LTQ5LDE4ICs0OSw2IEBAIHN0YXRpYyBERUZJTkVfUEVSX0NQVShpbnQsIHN0ZXBwaW5nX2tlcm5l bF9icCk7Cj4+ICBzdGF0aWMgaW50IGNvcmVfbnVtX2JycHM7Cj4+ICBzdGF0aWMgaW50IGNvcmVf bnVtX3dycHM7Cj4+ICAKPj4gLS8qIERldGVybWluZSBudW1iZXIgb2YgQlJQIHJlZ2lzdGVycyBh dmFpbGFibGUuICovCj4+IC1zdGF0aWMgaW50IGdldF9udW1fYnJwcyh2b2lkKQo+PiAtewo+PiAt CXJldHVybiAoKHJlYWRfY3B1aWQoSURfQUE2NERGUjBfRUwxKSA+PiAxMikgJiAweGYpICsgMTsK Pj4gLX0KPj4gLQo+PiAtLyogRGV0ZXJtaW5lIG51bWJlciBvZiBXUlAgcmVnaXN0ZXJzIGF2YWls YWJsZS4gKi8KPj4gLXN0YXRpYyBpbnQgZ2V0X251bV93cnBzKHZvaWQpCj4+IC17Cj4+IC0JcmV0 dXJuICgocmVhZF9jcHVpZChJRF9BQTY0REZSMF9FTDEpID4+IDIwKSAmIDB4ZikgKyAxOwo+PiAt fQo+PiAtCj4+ICBpbnQgaHdfYnJlYWtwb2ludF9zbG90cyhpbnQgdHlwZSkKPj4gIHsKPj4gIAkv Kgo+PiBkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9rdm0vZGVidWcuYyBiL2FyY2gvYXJtNjQva3Zt L2RlYnVnLmMKPj4gaW5kZXggYjMyMzYyYy4uM2IzNjhmMyAxMDA2NDQKPj4gLS0tIGEvYXJjaC9h cm02NC9rdm0vZGVidWcuYwo+PiArKysgYi9hcmNoL2FybTY0L2t2bS9kZWJ1Zy5jCj4+IEBAIC01 MCwxNCArNTAsMTkgQEAKPj4gIAo+PiAgdm9pZCBrdm1fYXJjaF9zZXR1cF9kZWJ1ZyhzdHJ1Y3Qg a3ZtX3ZjcHUgKnZjcHUpCj4+ICB7Cj4+ICsJYm9vbCB0cmFwX2RlYnVnID0gZmFsc2U7Cj4+ICsK Pj4gIAl2Y3B1LT5hcmNoLm1kY3JfZWwyIHw9IChNRENSX0VMMl9UUE0gfCBNRENSX0VMMl9UUE1D Uik7Cj4+ICAJdmNwdS0+YXJjaC5tZGNyX2VsMiB8PSAoTURDUl9FTDJfVERSQSB8IE1EQ1JfRUwy X1RET1NBKTsKPj4gIAo+PiAtCS8qIFRyYXAgZGVidWcgcmVnaXN0ZXIgYWNjZXNzPyAqLwo+PiAr CXRyYWNlX2t2bV9hcmNoX3NldHVwX2RlYnVnX3JlZzMyKCJNRENSX0VMMiIsIHZjcHUtPmFyY2gu bWRjcl9lbDIpOwo+Cj4gVGhpcyBpcyAyIHBhdGNoZXMgdG9vIGVhcmx5LiBZb3UgZG9uJ3QgaW50 cm9kdWNlIHRoaXMgdHJhY2Vwb2ludCB1bnRpbAo+IGxhdGVyLgo+Cj4+ICsKPj4gKwkvKgo+PiAr CSAqIElmIHdlIGFyZSBub3QgdHJlYXRpbmcgZGVidWcgcmVnaXN0ZXJzIGFyZSBkaXJ0eSB3ZSBu ZWVkCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBe XiBhcwo+PiArCSAqIHRvIHRyYXAgaWYgdGhlIGd1ZXN0IHN0YXJ0cyBhY2Nlc3NpbmcgdGhlbS4K Pj4gKwkgKi8KPj4gIAlpZiAoIXZjcHUtPmFyY2guZGVidWdfZmxhZ3MgJiBLVk1fQVJNNjRfREVC VUdfRElSVFkpCj4+IC0JCXZjcHUtPmFyY2gubWRjcl9lbDIgfD0gTURDUl9FTDJfVERBOwo+PiAt CWVsc2UKPj4gLQkJdmNwdS0+YXJjaC5tZGNyX2VsMiAmPSB+TURDUl9FTDJfVERBOwo+PiArCQl0 cmFwX2RlYnVnID0gdHJ1ZTsKPgo+IEhvdyBhYm91dCBqdXN0Cj4KPiBib29sIHRyYXBfZGVidWcg PSAhKHZjcHUtPmFyY2guZGVidWdfZmxhZ3MgJiBLVk1fQVJNNjRfREVCVUdfRElSVFkpOwo+Cj4g YXQgdGhlIHRvcCBpbnN0ZWFkPwo+Cj4+ICAKPj4gIAkvKiBJcyBHdWVzdCBkZWJ1Z2dpbmcgaW4g ZWZmZWN0PyAqLwo+PiAgCWlmICh2Y3B1LT5ndWVzdF9kZWJ1Zykgewo+PiBAQCAtODQsMTAgKzg5 LDY5IEBAIHZvaWQga3ZtX2FyY2hfc2V0dXBfZGVidWcoc3RydWN0IGt2bV92Y3B1ICp2Y3B1KQo+ PiAgCQkJdmNwdV9zeXNfcmVnKHZjcHUsIE1EU0NSX0VMMSkgJj0gfkRCR19NRFNDUl9TUzsKPj4g IAkJfQo+PiAgCj4+ICsJCS8qCj4+ICsJCSAqIEhXIEJyZWFrL1dhdGNoIHBvaW50cwo+PiArCQkg Ki8KPj4gKwkJaWYgKHZjcHUtPmd1ZXN0X2RlYnVnICYgS1ZNX0dVRVNUREJHX1VTRV9IV19CUCkg ewo+PiArCQkJaW50IG5iID0gZ2V0X251bV9icnBzKCk7Cj4+ICsJCQlpbnQgbncgPSBnZXRfbnVt X3dycHMoKTsKPj4gKwkJCXN0cnVjdCBrdm1fZ3Vlc3RfZGVidWdfYXJjaCAqc2F2ZWQsICpob3N0 Owo+PiArCj4+ICsJCQl2Y3B1X3N5c19yZWcodmNwdSwgTURTQ1JfRUwxKSB8PQo+PiArCQkJCShE QkdfTURTQ1JfS0RFfERCR19NRFNDUl9NREUpOwo+PiArCj4+ICsJCQkvKgo+PiArCQkJICogRmly c3Qgd2UgbmVlZCB0byBtYWtlIGEgY29weSBvZiB0aGUgZ3Vlc3QKPj4gKwkJCSAqIGRlYnVnIHJl Z2lzdGVycyBiZWZvcmUgd2Ugd2lwZSB0aGVtIG91dAo+PiArCQkJICogd2l0aCB0aGUgb25lcyB3 ZSB3YW50IHRvIHVzZS4KPj4gKwkJCSAqLwo+PiArCQkJc2F2ZWQgPSAmdmNwdV9kZWJ1Z19zYXZl ZF9yZWcodmNwdSwgZGVidWdfcmVncyk7Cj4+ICsJCQlob3N0ID0gJnZjcHUtPmFyY2guZ3Vlc3Rf ZGVidWdfcmVnczsKPgo+IEFnYWluLCBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gYmUgc28gcHJl Y2lzZSB3aXRoIG91ciBjb3B5LiBXZSBjYW4KPiBhbHdheXMgY29weSBleHRyYSB3aXRob3V0IHBy b2JsZW1zLiBJdCdzIGp1c3Qgd2hhdCB3ZSB1c2UgdGhhdCBtYXR0ZXJzLgo+IEFuZCBob3cgYWJv dXQgYSBjb3VwbGUgaGVscGVycz8KPgo+IGRlYnVnX3JlZ3Nfc2F2ZV90byhzdHJ1Y3Qga3ZtX3Zj cHUgKnZjcHUsIHN0cnVjdCBrdm1fZ3Vlc3RfZGVidWdfYXJjaCAqZHN0KQo+IHsKPiAgIG1lbWNw eShkc3QtPmRiZ19iY3IsICZ2Y3B1X3N5c19yZWcodmNwdSwgREJHQkNSMF9FTDEpLCBzaXplb2Yo dTY0KSpLVk1fQVJNX05EQkdfUkVHUyk7Cj4gICBtZW1jcHkoZHN0LT5kYmdfYnZyLCAmdmNwdV9z eXNfcmVnKHZjcHUsIERCR0JWUjBfRUwxKSwgc2l6ZW9mKHU2NCkqS1ZNX0FSTV9OREJHX1JFR1Mp Owo+ICAgbWVtY3B5KGRzdC0+ZGJnX3djciwgJnZjcHVfc3lzX3JlZyh2Y3B1LCBEQkdXQ1IwX0VM MSksIHNpemVvZih1NjQpKktWTV9BUk1fTkRCR19SRUdTKTsKPiAgIG1lbWNweShkc3QtPmRiZ193 dnIsICZ2Y3B1X3N5c19yZWcodmNwdSwgREJHV1ZSMF9FTDEpLCBzaXplb2YodTY0KSpLVk1fQVJN X05EQkdfUkVHUyk7Cj4gfQo+IGRlYnVnX3JlZ3NfcmVzdG9yZV9mcm9tKHN0cnVjdCBrdm1fdmNw dSAqdmNwdSwgc3RydWN0IGt2bV9ndWVzdF9kZWJ1Z19hcmNoICpzcmMpCj4gewo+ICAgbWVtY3B5 KCZ2Y3B1X3N5c19yZWcodmNwdSwgREJHQkNSMF9FTDEpLCBzcmMtPmRiZ19iY3IsIHNpemVvZih1 NjQpKktWTV9BUk1fTkRCR19SRUdTKTsKPiAgIG1lbWNweSgmdmNwdV9zeXNfcmVnKHZjcHUsIERC R0JWUjBfRUwxKSwgc3JjLT5kYmdfYnZyLCBzaXplb2YodTY0KSpLVk1fQVJNX05EQkdfUkVHUyk7 Cj4gICBtZW1jcHkoJnZjcHVfc3lzX3JlZyh2Y3B1LCBEQkdXQ1IwX0VMMSksIHNyYy0+ZGJnX3dj ciwgc2l6ZW9mKHU2NCkqS1ZNX0FSTV9OREJHX1JFR1MpOwo+ICAgbWVtY3B5KCZ2Y3B1X3N5c19y ZWcodmNwdSwgREJHV1ZSMF9FTDEpLCBzcmMtPmRiZ193dnIsIHNpemVvZih1NjQpKktWTV9BUk1f TkRCR19SRUdTKTsKPiB9Cj4KPj4gKwo+PiArCQkJLyogU2F2ZSBndWVzdCB2YWx1ZXMgKi8KPj4g KwkJCW1lbWNweSgmc2F2ZWQtPmRiZ19iY3IsCj4+ICsJCQkgICAgICAgJnZjcHVfc3lzX3JlZyh2 Y3B1LCBEQkdCQ1IwX0VMMSksCj4+ICsJCQkgICAgICAgc2l6ZW9mKF9fdTY0KSpuYik7Cj4+ICsJ CQltZW1jcHkoJnNhdmVkLT5kYmdfYnZyLAo+PiArCQkJICAgICAgICZ2Y3B1X3N5c19yZWcodmNw dSwgREJHQlZSMF9FTDEpLAo+PiArCQkJICAgICAgIHNpemVvZihfX3U2NCkqbmIpOwo+PiArCQkJ bWVtY3B5KCZzYXZlZC0+ZGJnX3djciwKPj4gKwkJCSAgICAgICAmdmNwdV9zeXNfcmVnKHZjcHUs IERCR1dDUjBfRUwxKSwKPj4gKwkJCSAgICAgICBzaXplb2YoX191NjQpKm53KTsKPj4gKwkJCW1l bWNweSgmc2F2ZWQtPmRiZ193dnIsCj4+ICsJCQkgICAgICAgJnZjcHVfc3lzX3JlZyh2Y3B1LCBE QkdXVlIwX0VMMSksCj4+ICsJCQkgICAgICAgc2l6ZW9mKF9fdTY0KSpudyk7Cj4+ICsKPj4gKwkJ CS8qIENvcHkgaW4gaG9zdCB2YWx1ZXMgKi8KPj4gKwkJCW1lbWNweSgmdmNwdV9zeXNfcmVnKHZj cHUsIERCR0JDUjBfRUwxKSwKPj4gKwkJCSAgICAgICAmaG9zdC0+ZGJnX2JjciwKPj4gKwkJCSAg ICAgICBzaXplb2YoX191NjQpKm5iKTsKPj4gKwkJCW1lbWNweSgmdmNwdV9zeXNfcmVnKHZjcHUs IERCR0JWUjBfRUwxKSwKPj4gKwkJCSAgICAgICAmaG9zdC0+ZGJnX2J2ciwKPj4gKwkJCSAgICAg ICBzaXplb2YoX191NjQpKm5iKTsKPj4gKwkJCW1lbWNweSgmdmNwdV9zeXNfcmVnKHZjcHUsIERC R1dDUjBfRUwxKSwKPj4gKwkJCSAgICAgICAmaG9zdC0+ZGJnX3djciwKPj4gKwkJCSAgICAgICBz aXplb2YoX191NjQpKm53KTsKPj4gKwkJCW1lbWNweSgmdmNwdV9zeXNfcmVnKHZjcHUsIERCR1dW UjBfRUwxKSwKPj4gKwkJCSAgICAgICAmaG9zdC0+ZGJnX3d2ciwKPj4gKwkJCSAgICAgICBzaXpl b2YoX191NjQpKm53KTsKPj4gKwo+PiArCQkJLyogTWFrZSBzdXJlIGh5cC5TIGNvcGllcyB0aGVt IGluL291dCAqLwo+PiArCQkJdmNwdS0+YXJjaC5kZWJ1Z19mbGFncyB8PSBLVk1fQVJNNjRfREVC VUdfRElSVFk7Cj4+ICsJCQkvKiBBbHNvIHRyYWNrIGd1ZXN0IGNoYW5nZXMgKi8KPj4gKwkJCXRy YXBfZGVidWcgPSB0cnVlOwo+PiArCQl9Cj4+ICsKPj4gIAl9IGVsc2Ugewo+PiAgCQkvKiBEZWJ1 ZyBvcGVyYXRpb25zIGNhbiBnbyBzdHJhaWdodCB0byB0aGUgZ3Vlc3QgKi8KPj4gIAkJdmNwdS0+ YXJjaC5tZGNyX2VsMiAmPSB+TURDUl9FTDJfVERFOwo+PiAgCX0KPj4gKwo+PiArCS8qIFRyYXAg ZGVidWcgcmVnaXN0ZXIgYWNjZXNzPyAqLwo+PiArCWlmICh0cmFwX2RlYnVnKQo+PiArCQl2Y3B1 LT5hcmNoLm1kY3JfZWwyIHw9IE1EQ1JfRUwyX1REQTsKPj4gKwllbHNlCj4+ICsJCXZjcHUtPmFy Y2gubWRjcl9lbDIgJj0gfk1EQ1JfRUwyX1REQTsKPj4gIH0KPj4gIAo+PiAgdm9pZCBrdm1fYXJj aF9jbGVhcl9kZWJ1ZyhzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpCj4+IEBAIC0xMDAsNSArMTY0LDMx IEBAIHZvaWQga3ZtX2FyY2hfY2xlYXJfZGVidWcoc3RydWN0IGt2bV92Y3B1ICp2Y3B1KQo+PiAg CQl2Y3B1X3N5c19yZWcodmNwdSwgTURTQ1JfRUwxKSAmPSB+TURTQ1JfRUwxX0RFQlVHX0JJVFM7 Cj4+ICAJCXZjcHVfc3lzX3JlZyh2Y3B1LCBNRFNDUl9FTDEpIHw9Cj4+ICAJCQl2Y3B1X2RlYnVn X3NhdmVkX3JlZyh2Y3B1LCBtZHNjcl9lbDFfYml0cyk7Cj4+ICsKPj4gKwkJLyoKPj4gKwkJICog SWYgd2Ugd2VyZSB1c2luZyBIVyBkZWJ1ZyB3ZSBuZWVkIHRvIHJlc3RvcmUgdGhlCj4+ICsJCSAq IHZhbHVlcyB0aGUgZ3Vlc3QgaGFkIHNldCB0aGVtIHVwIHdpdGgKPj4gKwkJICovCj4+ICsJCWlm ICh2Y3B1LT5ndWVzdF9kZWJ1ZyAmIEtWTV9HVUVTVERCR19VU0VfSFdfQlApIHsKPj4gKwkJCXN0 cnVjdCBrdm1fZ3Vlc3RfZGVidWdfYXJjaCAqcmVnczsKPj4gKwkJCWludCBuYiA9IGdldF9udW1f YnJwcygpOwo+PiArCQkJaW50IG53ID0gZ2V0X251bV93cnBzKCk7Cj4+ICsKPj4gKwkJCXJlZ3Mg PSAmdmNwdV9kZWJ1Z19zYXZlZF9yZWcodmNwdSwgZGVidWdfcmVncyk7Cj4gZGVidWdfcmVnc19y ZXN0b3JlX2Zyb20odmNwdSwgcmVncyk7Cj4+ICsKPj4gKwkJCS8qIFJlc3RvcmUgdGhlIHNhdmVk IGRlYnVnIHJlZ2lzdGVyIHZhbHVlcyAqLwo+PiArCQkJbWVtY3B5KCZ2Y3B1X3N5c19yZWcodmNw dSwgREJHQkNSMF9FTDEpLAo+PiArCQkJICAgICAgICZyZWdzLT5kYmdfYmNyLAo+PiArCQkJICAg ICAgIHNpemVvZihfX3U2NCkqbmIpOwo+PiArCQkJbWVtY3B5KCZ2Y3B1X3N5c19yZWcodmNwdSwg REJHQlZSMF9FTDEpLAo+PiArCQkJICAgICAgICZyZWdzLT5kYmdfYnZyLAo+PiArCQkJICAgICAg IHNpemVvZihfX3U2NCkqbmIpOwo+PiArCQkJbWVtY3B5KCZ2Y3B1X3N5c19yZWcodmNwdSwgREJH V0NSMF9FTDEpLAo+PiArCQkJICAgICAgICZyZWdzLT5kYmdfd2NyLAo+PiArCQkJICAgICAgIHNp emVvZihfX3U2NCkqbncpOwo+PiArCQkJbWVtY3B5KCZ2Y3B1X3N5c19yZWcodmNwdSwgREJHV1ZS MF9FTDEpLAo+PiArCQkJICAgICAgICZyZWdzLT5kYmdfd3ZyLAo+PiArCQkJICAgICAgIHNpemVv ZihfX3U2NCkqbncpOwo+PiArCQl9Cj4+ICAJfQo+PiAgfQo+PiBkaWZmIC0tZ2l0IGEvYXJjaC9h cm02NC9rdm0vaGFuZGxlX2V4aXQuYyBiL2FyY2gvYXJtNjQva3ZtL2hhbmRsZV9leGl0LmMKPj4g aW5kZXggMTZhY2NhZS4uNDYwYTFhYSAxMDA2NDQKPj4gLS0tIGEvYXJjaC9hcm02NC9rdm0vaGFu ZGxlX2V4aXQuYwo+PiArKysgYi9hcmNoL2FybTY0L2t2bS9oYW5kbGVfZXhpdC5jCj4+IEBAIC0x MDEsNyArMTAxLDExIEBAIHN0YXRpYyBpbnQga3ZtX2hhbmRsZV9ndWVzdF9kZWJ1ZyhzdHJ1Y3Qg a3ZtX3ZjcHUgKnZjcHUsIHN0cnVjdCBrdm1fcnVuICpydW4pCj4+ICAJcnVuLT5kZWJ1Zy5hcmNo LmhzciA9IGhzcjsKPj4gIAo+PiAgCXN3aXRjaCAoaHNyID4+IEVTUl9FTHhfRUNfU0hJRlQpIHsK Pj4gKwljYXNlIEVTUl9FTHhfRUNfV0FUQ0hQVF9MT1c6Cj4+ICsJCXJ1bi0+ZGVidWcuYXJjaC5m YXIgPSB2Y3B1LT5hcmNoLmZhdWx0LmZhcl9lbDI7Cj4+ICsJCS8qIGZhbGwgdGhyb3VnaCAqLwo+ PiAgCWNhc2UgRVNSX0VMeF9FQ19TT0ZUU1RQX0xPVzoKPj4gKwljYXNlIEVTUl9FTHhfRUNfQlJF QUtQVF9MT1c6Cj4+ICAJY2FzZSBFU1JfRUx4X0VDX0JLUFQzMjoKPj4gIAljYXNlIEVTUl9FTHhf RUNfQlJLNjQ6Cj4+ICAJCXJ1bi0+ZGVidWcuYXJjaC5wYyA9ICp2Y3B1X3BjKHZjcHUpOwo+PiBA QCAtMTI5LDYgKzEzMyw4IEBAIHN0YXRpYyBleGl0X2hhbmRsZV9mbiBhcm1fZXhpdF9oYW5kbGVy c1tdID0gewo+PiAgCVtFU1JfRUx4X0VDX0lBQlRfTE9XXQk9IGt2bV9oYW5kbGVfZ3Vlc3RfYWJv cnQsCj4+ICAJW0VTUl9FTHhfRUNfREFCVF9MT1ddCT0ga3ZtX2hhbmRsZV9ndWVzdF9hYm9ydCwK Pj4gIAlbRVNSX0VMeF9FQ19TT0ZUU1RQX0xPV109IGt2bV9oYW5kbGVfZ3Vlc3RfZGVidWcsCj4+ ICsJW0VTUl9FTHhfRUNfV0FUQ0hQVF9MT1ddPSBrdm1faGFuZGxlX2d1ZXN0X2RlYnVnLAo+PiAr CVtFU1JfRUx4X0VDX0JSRUFLUFRfTE9XXT0ga3ZtX2hhbmRsZV9ndWVzdF9kZWJ1ZywKPj4gIAlb RVNSX0VMeF9FQ19CS1BUMzJdCT0ga3ZtX2hhbmRsZV9ndWVzdF9kZWJ1ZywKPj4gIAlbRVNSX0VM eF9FQ19CUks2NF0JPSBrdm1faGFuZGxlX2d1ZXN0X2RlYnVnLAo+PiAgfTsKPj4gZGlmZiAtLWdp dCBhL2FyY2gvYXJtNjQva3ZtL3Jlc2V0LmMgYi9hcmNoL2FybTY0L2t2bS9yZXNldC5jCj4+IGlu ZGV4IDBiNDMyNjUuLmMyNzMyYzcgMTAwNjQ0Cj4+IC0tLSBhL2FyY2gvYXJtNjQva3ZtL3Jlc2V0 LmMKPj4gKysrIGIvYXJjaC9hcm02NC9rdm0vcmVzZXQuYwo+PiBAQCAtNjQsNiArNjQsMTIgQEAg aW50IGt2bV9hcmNoX2Rldl9pb2N0bF9jaGVja19leHRlbnNpb24obG9uZyBleHQpCj4+ICAJY2Fz ZSBLVk1fQ0FQX0FSTV9FTDFfMzJCSVQ6Cj4+ICAJCXIgPSBjcHVfaGFzXzMyYml0X2VsMSgpOwo+ PiAgCQlicmVhazsKPj4gKwljYXNlIEtWTV9DQVBfR1VFU1RfREVCVUdfSFdfQlBTOgo+PiArCQly ID0gZ2V0X251bV9icnBzKCk7Cj4+ICsJCWJyZWFrOwo+PiArCWNhc2UgS1ZNX0NBUF9HVUVTVF9E RUJVR19IV19XUFM6Cj4+ICsJCXIgID0gZ2V0X251bV93cnBzKCk7Cj4+ICsJCWJyZWFrOwo+PiAg CWRlZmF1bHQ6Cj4+ICAJCXIgPSAwOwo+PiAgCX0KPj4gZGlmZiAtLWdpdCBhL2FyY2gvYXJtNjQv a3ZtL3N5c19yZWdzLmMgYi9hcmNoL2FybTY0L2t2bS9zeXNfcmVncy5jCj4+IGluZGV4IGMzNzBi NDAuLmJlOWIxODggMTAwNjQ0Cj4+IC0tLSBhL2FyY2gvYXJtNjQva3ZtL3N5c19yZWdzLmMKPj4g KysrIGIvYXJjaC9hcm02NC9rdm0vc3lzX3JlZ3MuYwo+PiBAQCAtMTk2LDE2ICsxOTYsNDkgQEAg c3RhdGljIGJvb2wgdHJhcF9kYmdhdXRoc3RhdHVzX2VsMShzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUs Cj4+ICAgKiAtIElmIHRoZSBkaXJ0eSBiaXQgaXMgc2V0LCBzYXZlIGd1ZXN0IHJlZ2lzdGVycywg cmVzdG9yZSBob3N0Cj4+ICAgKiAgIHJlZ2lzdGVycyBhbmQgY2xlYXIgdGhlIGRpcnR5IGJpdC4g VGhpcyBlbnN1cmUgdGhhdCB0aGUgaG9zdCBjYW4KPj4gICAqICAgbm93IHVzZSB0aGUgZGVidWcg cmVnaXN0ZXJzLgo+PiArICoKPj4gKyAqIFdlIGFsc28gdXNlIHRoaXMgbWVjaGFuaXNtIHRvIHNl dC11cCB0aGUgZGVidWcgcmVnaXN0ZXJzIGZvciBndWVzdAo+IHNldHVwCj4+ICsgKiBkZWJ1Z2dp bmcuIElmIHRoaXMgaXMgdGhlIGNhc2Ugd2Ugd2FudCB0byBlbnN1cmUgdGhlIGd1ZXN0IHNlZXMK Pj4gKyAqIHRoZSByaWdodCB2ZXJzaW9ucyBvZiB0aGUgcmVnaXN0ZXJzIC0gZXZlbiBpZiB0aGV5 IGFyZSBub3QgZ29pbmcgdG8KPj4gKyAqIGJlIGVmZmVjdGl2ZSB3aGlsZSBndWVzdCBkZWJ1ZyBp cyB1c2luZyBIVyBkZWJ1Zy4KPj4gKyAqCj4gbm8gbmVlZCBmb3IgdGhpcyBibGFuayBjb21tZW50 IGxpbmUKPj4gICAqLwo+PiArCj4+ICBzdGF0aWMgYm9vbCB0cmFwX2RlYnVnX3JlZ3Moc3RydWN0 IGt2bV92Y3B1ICp2Y3B1LAo+PiAgCQkJICAgIGNvbnN0IHN0cnVjdCBzeXNfcmVnX3BhcmFtcyAq cCwKPj4gIAkJCSAgICBjb25zdCBzdHJ1Y3Qgc3lzX3JlZ19kZXNjICpyKQo+PiAgewo+PiAtCWlm IChwLT5pc193cml0ZSkgewo+PiAtCQl2Y3B1X3N5c19yZWcodmNwdSwgci0+cmVnKSA9ICp2Y3B1 X3JlZyh2Y3B1LCBwLT5SdCk7Cj4+IC0JCXZjcHUtPmFyY2guZGVidWdfZmxhZ3MgfD0gS1ZNX0FS TTY0X0RFQlVHX0RJUlRZOwo+PiArCWlmICh2Y3B1LT5ndWVzdF9kZWJ1ZyAmIEtWTV9HVUVTVERC R19VU0VfSFdfQlApIHsKPj4gKwkJc3RydWN0IGt2bV9ndWVzdF9kZWJ1Z19hcmNoICpzYXZlZDsK Pj4gKwkJX191NjQgKnZhbDsKPj4gKwo+PiArCQlzYXZlZCA9ICZ2Y3B1X2RlYnVnX3NhdmVkX3Jl Zyh2Y3B1LCBkZWJ1Z19yZWdzKTsKPgo+IEhlcmUgd2UgZG9uJ3QgYm90aGVyIGVuZm9yY2luZyBu dW1fYnJwcy93cnBzLCB3aGljaCBpcyBmaW5lIGJ5IG1lLgo+Cj4+ICsKPj4gKwkJaWYgKHItPnJl ZyA+PSBEQkdCQ1IwX0VMMSAmJiByLT5yZWcgPD0gREJHQkNSMTVfRUwxKQo+PiArCQkJdmFsID0g JnNhdmVkLT5kYmdfYmNyW3ItPnJlZyAtIERCR0JDUjBfRUwxXTsKPj4gKwkJZWxzZSBpZiAoci0+ cmVnID49IERCR0JWUjBfRUwxICYmIHItPnJlZyA8PSBEQkdCVlIxNV9FTDEpCj4+ICsJCQl2YWwg PSAmc2F2ZWQtPmRiZ19idnJbci0+cmVnIC0gREJHQlZSMF9FTDFdOwo+PiArCQllbHNlIGlmIChy LT5yZWcgPj0gREJHV0NSMF9FTDEgJiYgci0+cmVnIDw9IERCR1dDUjE1X0VMMSkKPj4gKwkJCXZh bCA9ICZzYXZlZC0+ZGJnX3djcltyLT5yZWcgLSBEQkdXQ1IwX0VMMV07Cj4+ICsJCWVsc2UgaWYg KHItPnJlZyA+PSBEQkdXVlIwX0VMMSAmJiByLT5yZWcgPD0gREJHV1ZSMTVfRUwxKQo+PiArCQkJ dmFsID0gJnNhdmVkLT5kYmdfd3ZyW3ItPnJlZyAtIERCR1dWUjBfRUwxXTsKPj4gKwkJZWxzZSB7 Cj4+ICsJCQlrdm1fZXJyKCJCYWQgcmVnaXN0ZXIgaW5kZXggJWRcbiIsIHItPnJlZyk7Cj4+ICsJ CQlyZXR1cm4gZmFsc2U7Cj4+ICsJCX0KPj4gKwo+PiArCQlpZiAocC0+aXNfd3JpdGUpCj4+ICsJ CQkqdmFsID0gKnZjcHVfcmVnKHZjcHUsIHAtPlJ0KTsKPj4gKwkJZWxzZQo+PiArCQkJKnZjcHVf cmVnKHZjcHUsIHAtPlJ0KSA9ICp2YWw7Cj4+ICsKPj4gIAl9IGVsc2Ugewo+PiAtCQkqdmNwdV9y ZWcodmNwdSwgcC0+UnQpID0gdmNwdV9zeXNfcmVnKHZjcHUsIHItPnJlZyk7Cj4+ICsJCWlmIChw LT5pc193cml0ZSkgewo+PiArCQkJdmNwdV9zeXNfcmVnKHZjcHUsIHItPnJlZykgPSAqdmNwdV9y ZWcodmNwdSwgcC0+UnQpOwo+PiArCQkJdmNwdS0+YXJjaC5kZWJ1Z19mbGFncyB8PSBLVk1fQVJN NjRfREVCVUdfRElSVFk7Cj4+ICsJCX0gZWxzZSB7Cj4+ICsJCQkqdmNwdV9yZWcodmNwdSwgcC0+ UnQpID0gdmNwdV9zeXNfcmVnKHZjcHUsIHItPnJlZyk7Cj4+ICsJCX0KPj4gIAl9Cj4+ICAKPj4g IAlyZXR1cm4gdHJ1ZTsKPj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvdWFwaS9saW51eC9rdm0uaCBi L2luY2x1ZGUvdWFwaS9saW51eC9rdm0uaAo+PiBpbmRleCBjZTJkYjE0Li4wZTQ4YzBkIDEwMDY0 NAo+PiAtLS0gYS9pbmNsdWRlL3VhcGkvbGludXgva3ZtLmgKPj4gKysrIGIvaW5jbHVkZS91YXBp L2xpbnV4L2t2bS5oCj4+IEBAIC03NzEsNiArNzcxLDggQEAgc3RydWN0IGt2bV9wcGNfc21tdV9p bmZvIHsKPj4gICNkZWZpbmUgS1ZNX0NBUF9QUENfRU5BQkxFX0hDQUxMIDEwNAo+PiAgI2RlZmlu ZSBLVk1fQ0FQX0NIRUNLX0VYVEVOU0lPTl9WTSAxMDUKPj4gICNkZWZpbmUgS1ZNX0NBUF9TMzkw X1VTRVJfU0lHUCAxMDYKPj4gKyNkZWZpbmUgS1ZNX0NBUF9HVUVTVF9ERUJVR19IV19CUFMgMTA3 Cj4+ICsjZGVmaW5lIEtWTV9DQVBfR1VFU1RfREVCVUdfSFdfV1BTIDEwOAo+PiAgCj4+ICAjaWZk ZWYgS1ZNX0NBUF9JUlFfUk9VVElORwo+PiAgCj4+IC0tIAo+PiAyLjMuNAo+PiAKCi0tIApBbGV4 IEJlbm7DqWUKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18K a3ZtYXJtIG1haWxpbmcgbGlzdAprdm1hcm1AbGlzdHMuY3MuY29sdW1iaWEuZWR1Cmh0dHBzOi8v bGlzdHMuY3MuY29sdW1iaWEuZWR1L21haWxtYW4vbGlzdGluZm8va3ZtYXJtCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: alex.bennee@linaro.org (Alex =?utf-8?Q?Benn=C3=A9e?=) Date: Mon, 13 Apr 2015 09:00:35 +0100 Subject: [PATCH v2 08/10] KVM: arm64: guest debug, HW assisted debug support In-Reply-To: <20150410122520.GA3227@hawk.usersys.redhat.com> References: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> <1427814488-28467-9-git-send-email-alex.bennee@linaro.org> <20150410122520.GA3227@hawk.usersys.redhat.com> Message-ID: <876190laos.fsf@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Andrew Jones writes: > On Tue, Mar 31, 2015 at 04:08:06PM +0100, Alex Benn?e wrote: >> This adds support for userspace to control the HW debug registers for >> guest debug. We'll only copy the $ARCH defined number across as that is >> all that hyp.S will use anyway. I've moved some helper functions into >> the hw_breakpoint.h header for re-use. >> >> As with single step we need to tweak the guest registers to enable the >> exceptions so we need to save and restore those bits. >> >> Two new capabilities have been added to the KVM_EXTENSION ioctl to allow >> userspace to query the number of hardware break and watch points >> available on the host hardware. >> >> As QEMU tests for watchpoints based on the address and not the PC we >> also need to export the value of far_el2 to userspace. >> >> Signed-off-by: Alex Benn?e >> >> --- >> v2 >> - switched to C setup >> - replace host debug registers directly into context >> - minor tweak to api docs >> - setup right register for debug >> - add FAR_EL2 to debug exit structure >> - add support fro trapping debug register access >> >> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt >> index 17d4f9c..ac34093 100644 >> --- a/Documentation/virtual/kvm/api.txt >> +++ b/Documentation/virtual/kvm/api.txt >> @@ -2627,7 +2627,7 @@ The top 16 bits of the control field are architecture specific control >> flags which can include the following: >> >> - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64] >> - - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390] >> + - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64] >> - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86] >> - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86] >> - KVM_GUESTDBG_EXIT_PENDING: trigger an immediate guest exit [s390] >> @@ -2642,6 +2642,10 @@ updated to the correct (supplied) values. >> The second part of the structure is architecture specific and >> typically contains a set of debug registers. >> >> +For arm64 the number of debug registers is implementation defined and >> +can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and >> +KVM_CAP_GUEST_DEBUG_HW_WPS capabilities. >> + >> When debug events exit the main run loop with the reason >> KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run >> structure containing architecture specific debug information. >> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c >> index c1ed8cb..a286026 100644 >> --- a/arch/arm/kvm/arm.c >> +++ b/arch/arm/kvm/arm.c >> @@ -306,6 +306,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) >> >> #define KVM_GUESTDBG_VALID (KVM_GUESTDBG_ENABLE | \ >> KVM_GUESTDBG_USE_SW_BP | \ >> + KVM_GUESTDBG_USE_HW_BP | \ >> KVM_GUESTDBG_SINGLESTEP) >> >> /** >> @@ -328,6 +329,26 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, >> return -EINVAL; >> >> vcpu->guest_debug = dbg->control; >> + >> + /* Hardware assisted Break and Watch points */ >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + int nb = get_num_brps(); >> + int nw = get_num_wrps(); >> + >> + /* Copy across up to IMPDEF debug registers to our >> + * shadow copy in the vcpu structure. The debug code >> + * will then set them up before we re-enter the guest. >> + */ > > Is it necessary to limit the number copied here by anything other than > what the struct supports? Userspace gave us a struct kvm_guest_debug_arch, > so let's save the whole thing. How about just > > vcpu->arch.guest_debug_regs = *dbg; Makes sense for the ioctl. I'll still limit it in the setup/clear function. > >> + memcpy(vcpu->arch.guest_debug_regs.dbg_bcr, >> + dbg->arch.dbg_bcr, sizeof(__u64)*nb); >> + memcpy(vcpu->arch.guest_debug_regs.dbg_bvr, >> + dbg->arch.dbg_bvr, sizeof(__u64)*nb); >> + memcpy(vcpu->arch.guest_debug_regs.dbg_wcr, >> + dbg->arch.dbg_wcr, sizeof(__u64)*nw); >> + memcpy(vcpu->arch.guest_debug_regs.dbg_wvr, >> + dbg->arch.dbg_wvr, sizeof(__u64)*nw); >> + } >> + >> } else { >> /* If not enabled clear all flags */ >> vcpu->guest_debug = 0; >> diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h >> index 52b484b..c450552 100644 >> --- a/arch/arm64/include/asm/hw_breakpoint.h >> +++ b/arch/arm64/include/asm/hw_breakpoint.h >> @@ -130,6 +130,18 @@ static inline void ptrace_hw_copy_thread(struct task_struct *task) >> } >> #endif >> >> +/* Determine number of BRP registers available. */ >> +static inline int get_num_brps(void) >> +{ >> + return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1; >> +} >> + >> +/* Determine number of WRP registers available. */ >> +static inline int get_num_wrps(void) >> +{ >> + return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1; >> +} >> + >> extern struct pmu perf_ops_bp; >> >> #endif /* __KERNEL__ */ >> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h >> index 6a33647..2c359c9 100644 >> --- a/arch/arm64/include/asm/kvm_host.h >> +++ b/arch/arm64/include/asm/kvm_host.h >> @@ -106,8 +106,9 @@ struct kvm_vcpu_arch { >> /* Exception Information */ >> struct kvm_vcpu_fault_info fault; >> >> - /* Debug state */ >> + /* Guest debug state */ >> u64 debug_flags; >> + struct kvm_guest_debug_arch guest_debug_regs; >> >> /* Pointer to host CPU context */ >> kvm_cpu_context_t *host_cpu_context; >> @@ -126,6 +127,7 @@ struct kvm_vcpu_arch { >> u32 pstate_ss_bit; >> u32 mdscr_el1_bits; >> >> + struct kvm_guest_debug_arch debug_regs; >> } debug_saved_regs; >> >> /* Don't run the guest */ >> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h >> index 6ee70a0..73f21e4 100644 >> --- a/arch/arm64/include/uapi/asm/kvm.h >> +++ b/arch/arm64/include/uapi/asm/kvm.h >> @@ -118,6 +118,7 @@ struct kvm_guest_debug_arch { >> struct kvm_debug_exit_arch { >> __u64 pc; >> __u32 hsr; >> + __u64 far; /* used for watchpoints */ >> }; >> >> struct kvm_sync_regs { >> diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c >> index 98bbe06..923be44 100644 >> --- a/arch/arm64/kernel/hw_breakpoint.c >> +++ b/arch/arm64/kernel/hw_breakpoint.c >> @@ -49,18 +49,6 @@ static DEFINE_PER_CPU(int, stepping_kernel_bp); >> static int core_num_brps; >> static int core_num_wrps; >> >> -/* Determine number of BRP registers available. */ >> -static int get_num_brps(void) >> -{ >> - return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1; >> -} >> - >> -/* Determine number of WRP registers available. */ >> -static int get_num_wrps(void) >> -{ >> - return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1; >> -} >> - >> int hw_breakpoint_slots(int type) >> { >> /* >> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c >> index b32362c..3b368f3 100644 >> --- a/arch/arm64/kvm/debug.c >> +++ b/arch/arm64/kvm/debug.c >> @@ -50,14 +50,19 @@ >> >> void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) >> { >> + bool trap_debug = false; >> + >> vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | MDCR_EL2_TPMCR); >> vcpu->arch.mdcr_el2 |= (MDCR_EL2_TDRA | MDCR_EL2_TDOSA); >> >> - /* Trap debug register access? */ >> + trace_kvm_arch_setup_debug_reg32("MDCR_EL2", vcpu->arch.mdcr_el2); > > This is 2 patches too early. You don't introduce this tracepoint until > later. > >> + >> + /* >> + * If we are not treating debug registers are dirty we need > ^^ as >> + * to trap if the guest starts accessing them. >> + */ >> if (!vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY) >> - vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; >> - else >> - vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA; >> + trap_debug = true; > > How about just > > bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY); > > at the top instead? > >> >> /* Is Guest debugging in effect? */ >> if (vcpu->guest_debug) { >> @@ -84,10 +89,69 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) >> vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS; >> } >> >> + /* >> + * HW Break/Watch points >> + */ >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + int nb = get_num_brps(); >> + int nw = get_num_wrps(); >> + struct kvm_guest_debug_arch *saved, *host; >> + >> + vcpu_sys_reg(vcpu, MDSCR_EL1) |= >> + (DBG_MDSCR_KDE|DBG_MDSCR_MDE); >> + >> + /* >> + * First we need to make a copy of the guest >> + * debug registers before we wipe them out >> + * with the ones we want to use. >> + */ >> + saved = &vcpu_debug_saved_reg(vcpu, debug_regs); >> + host = &vcpu->arch.guest_debug_regs; > > Again, I don't think we need to be so precise with our copy. We can > always copy extra without problems. It's just what we use that matters. > And how about a couple helpers? > > debug_regs_save_to(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *dst) > { > memcpy(dst->dbg_bcr, &vcpu_sys_reg(vcpu, DBGBCR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(dst->dbg_bvr, &vcpu_sys_reg(vcpu, DBGBVR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(dst->dbg_wcr, &vcpu_sys_reg(vcpu, DBGWCR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(dst->dbg_wvr, &vcpu_sys_reg(vcpu, DBGWVR0_EL1), sizeof(u64)*KVM_ARM_NDBG_REGS); > } > debug_regs_restore_from(struct kvm_vcpu *vcpu, struct kvm_guest_debug_arch *src) > { > memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1), src->dbg_bcr, sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1), src->dbg_bvr, sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1), src->dbg_wcr, sizeof(u64)*KVM_ARM_NDBG_REGS); > memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1), src->dbg_wvr, sizeof(u64)*KVM_ARM_NDBG_REGS); > } > >> + >> + /* Save guest values */ >> + memcpy(&saved->dbg_bcr, >> + &vcpu_sys_reg(vcpu, DBGBCR0_EL1), >> + sizeof(__u64)*nb); >> + memcpy(&saved->dbg_bvr, >> + &vcpu_sys_reg(vcpu, DBGBVR0_EL1), >> + sizeof(__u64)*nb); >> + memcpy(&saved->dbg_wcr, >> + &vcpu_sys_reg(vcpu, DBGWCR0_EL1), >> + sizeof(__u64)*nw); >> + memcpy(&saved->dbg_wvr, >> + &vcpu_sys_reg(vcpu, DBGWVR0_EL1), >> + sizeof(__u64)*nw); >> + >> + /* Copy in host values */ >> + memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1), >> + &host->dbg_bcr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1), >> + &host->dbg_bvr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1), >> + &host->dbg_wcr, >> + sizeof(__u64)*nw); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1), >> + &host->dbg_wvr, >> + sizeof(__u64)*nw); >> + >> + /* Make sure hyp.S copies them in/out */ >> + vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; >> + /* Also track guest changes */ >> + trap_debug = true; >> + } >> + >> } else { >> /* Debug operations can go straight to the guest */ >> vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE; >> } >> + >> + /* Trap debug register access? */ >> + if (trap_debug) >> + vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; >> + else >> + vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA; >> } >> >> void kvm_arch_clear_debug(struct kvm_vcpu *vcpu) >> @@ -100,5 +164,31 @@ void kvm_arch_clear_debug(struct kvm_vcpu *vcpu) >> vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~MDSCR_EL1_DEBUG_BITS; >> vcpu_sys_reg(vcpu, MDSCR_EL1) |= >> vcpu_debug_saved_reg(vcpu, mdscr_el1_bits); >> + >> + /* >> + * If we were using HW debug we need to restore the >> + * values the guest had set them up with >> + */ >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + struct kvm_guest_debug_arch *regs; >> + int nb = get_num_brps(); >> + int nw = get_num_wrps(); >> + >> + regs = &vcpu_debug_saved_reg(vcpu, debug_regs); > debug_regs_restore_from(vcpu, regs); >> + >> + /* Restore the saved debug register values */ >> + memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1), >> + ®s->dbg_bcr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1), >> + ®s->dbg_bvr, >> + sizeof(__u64)*nb); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1), >> + ®s->dbg_wcr, >> + sizeof(__u64)*nw); >> + memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1), >> + ®s->dbg_wvr, >> + sizeof(__u64)*nw); >> + } >> } >> } >> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c >> index 16accae..460a1aa 100644 >> --- a/arch/arm64/kvm/handle_exit.c >> +++ b/arch/arm64/kvm/handle_exit.c >> @@ -101,7 +101,11 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run) >> run->debug.arch.hsr = hsr; >> >> switch (hsr >> ESR_ELx_EC_SHIFT) { >> + case ESR_ELx_EC_WATCHPT_LOW: >> + run->debug.arch.far = vcpu->arch.fault.far_el2; >> + /* fall through */ >> case ESR_ELx_EC_SOFTSTP_LOW: >> + case ESR_ELx_EC_BREAKPT_LOW: >> case ESR_ELx_EC_BKPT32: >> case ESR_ELx_EC_BRK64: >> run->debug.arch.pc = *vcpu_pc(vcpu); >> @@ -129,6 +133,8 @@ static exit_handle_fn arm_exit_handlers[] = { >> [ESR_ELx_EC_IABT_LOW] = kvm_handle_guest_abort, >> [ESR_ELx_EC_DABT_LOW] = kvm_handle_guest_abort, >> [ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug, >> + [ESR_ELx_EC_WATCHPT_LOW]= kvm_handle_guest_debug, >> + [ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug, >> [ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug, >> [ESR_ELx_EC_BRK64] = kvm_handle_guest_debug, >> }; >> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c >> index 0b43265..c2732c7 100644 >> --- a/arch/arm64/kvm/reset.c >> +++ b/arch/arm64/kvm/reset.c >> @@ -64,6 +64,12 @@ int kvm_arch_dev_ioctl_check_extension(long ext) >> case KVM_CAP_ARM_EL1_32BIT: >> r = cpu_has_32bit_el1(); >> break; >> + case KVM_CAP_GUEST_DEBUG_HW_BPS: >> + r = get_num_brps(); >> + break; >> + case KVM_CAP_GUEST_DEBUG_HW_WPS: >> + r = get_num_wrps(); >> + break; >> default: >> r = 0; >> } >> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c >> index c370b40..be9b188 100644 >> --- a/arch/arm64/kvm/sys_regs.c >> +++ b/arch/arm64/kvm/sys_regs.c >> @@ -196,16 +196,49 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu, >> * - If the dirty bit is set, save guest registers, restore host >> * registers and clear the dirty bit. This ensure that the host can >> * now use the debug registers. >> + * >> + * We also use this mechanism to set-up the debug registers for guest > setup >> + * debugging. If this is the case we want to ensure the guest sees >> + * the right versions of the registers - even if they are not going to >> + * be effective while guest debug is using HW debug. >> + * > no need for this blank comment line >> */ >> + >> static bool trap_debug_regs(struct kvm_vcpu *vcpu, >> const struct sys_reg_params *p, >> const struct sys_reg_desc *r) >> { >> - if (p->is_write) { >> - vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); >> - vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) { >> + struct kvm_guest_debug_arch *saved; >> + __u64 *val; >> + >> + saved = &vcpu_debug_saved_reg(vcpu, debug_regs); > > Here we don't bother enforcing num_brps/wrps, which is fine by me. > >> + >> + if (r->reg >= DBGBCR0_EL1 && r->reg <= DBGBCR15_EL1) >> + val = &saved->dbg_bcr[r->reg - DBGBCR0_EL1]; >> + else if (r->reg >= DBGBVR0_EL1 && r->reg <= DBGBVR15_EL1) >> + val = &saved->dbg_bvr[r->reg - DBGBVR0_EL1]; >> + else if (r->reg >= DBGWCR0_EL1 && r->reg <= DBGWCR15_EL1) >> + val = &saved->dbg_wcr[r->reg - DBGWCR0_EL1]; >> + else if (r->reg >= DBGWVR0_EL1 && r->reg <= DBGWVR15_EL1) >> + val = &saved->dbg_wvr[r->reg - DBGWVR0_EL1]; >> + else { >> + kvm_err("Bad register index %d\n", r->reg); >> + return false; >> + } >> + >> + if (p->is_write) >> + *val = *vcpu_reg(vcpu, p->Rt); >> + else >> + *vcpu_reg(vcpu, p->Rt) = *val; >> + >> } else { >> - *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg); >> + if (p->is_write) { >> + vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); >> + vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; >> + } else { >> + *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg); >> + } >> } >> >> return true; >> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h >> index ce2db14..0e48c0d 100644 >> --- a/include/uapi/linux/kvm.h >> +++ b/include/uapi/linux/kvm.h >> @@ -771,6 +771,8 @@ struct kvm_ppc_smmu_info { >> #define KVM_CAP_PPC_ENABLE_HCALL 104 >> #define KVM_CAP_CHECK_EXTENSION_VM 105 >> #define KVM_CAP_S390_USER_SIGP 106 >> +#define KVM_CAP_GUEST_DEBUG_HW_BPS 107 >> +#define KVM_CAP_GUEST_DEBUG_HW_WPS 108 >> >> #ifdef KVM_CAP_IRQ_ROUTING >> >> -- >> 2.3.4 >> -- Alex Benn?e