From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932111AbbCaPJI (ORCPT ); Tue, 31 Mar 2015 11:09:08 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:48121 "EHLO socrates.bennee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754581AbbCaPI7 (ORCPT ); Tue, 31 Mar 2015 11:08:59 -0400 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: 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, drjones@redhat.com, pbonzini@redhat.com, zhichao.huang@linaro.org Cc: jan.kiszka@siemens.com, dahi@linux.vnet.ibm.com, r65777@freescale.com, bp@suse.de, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Gleb Natapov , Catalin Marinas , Will Deacon , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v2 09/10] KVM: arm64: trap nested debug register access Date: Tue, 31 Mar 2015 16:08:07 +0100 Message-Id: <1427814488-28467-10-git-send-email-alex.bennee@linaro.org> X-Mailer: git-send-email 2.3.4 In-Reply-To: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> References: <1427814488-28467-1-git-send-email-alex.bennee@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 When we are using the hardware registers for guest debug we need to deal with the guests access to them. There is already a mechanism for dealing with these accesses so we build on top of that. - mdscr_el1_bits is renamed as we save the whole register - any access to mdscr_el1 is now stored in the mirror location - if we are using HW assisted debug we do the same with DBG[WB][CV]R There is one register (MDCCINT_EL1) which guest debug doesn't care about so this behaves as before. Signed-off-by: Alex Bennée diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 2c359c9..3d32d45 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -122,10 +122,13 @@ struct kvm_vcpu_arch { * here. */ - /* Registers pre any guest debug manipulations */ + /* Registers before any guest debug manipulations. These + * shadow registers are updated by the kvm_handle_sys_reg + * trap handler if the guest accesses or updates them + */ struct { u32 pstate_ss_bit; - u32 mdscr_el1_bits; + u32 mdscr_el1; struct kvm_guest_debug_arch debug_regs; } debug_saved_regs; diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index 3b368f3..638c111 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -55,8 +55,6 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | MDCR_EL2_TPMCR); vcpu->arch.mdcr_el2 |= (MDCR_EL2_TDRA | MDCR_EL2_TDOSA); - trace_kvm_arch_setup_debug_reg32("MDCR_EL2", vcpu->arch.mdcr_el2); - /* * If we are not treating debug registers are dirty we need * to trap if the guest starts accessing them. @@ -71,8 +69,10 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) /* Save pstate/mdscr */ vcpu_debug_saved_reg(vcpu, pstate_ss_bit) = *vcpu_cpsr(vcpu) & DBG_SPSR_SS; - vcpu_debug_saved_reg(vcpu, mdscr_el1_bits) = - vcpu_sys_reg(vcpu, MDSCR_EL1) & MDSCR_EL1_DEBUG_BITS; + + vcpu_debug_saved_reg(vcpu, mdscr_el1) = + vcpu_sys_reg(vcpu, MDSCR_EL1); + /* * Single Step (ARM ARM D2.12.3 The software step state * machine) @@ -161,9 +161,8 @@ void kvm_arch_clear_debug(struct kvm_vcpu *vcpu) *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; *vcpu_cpsr(vcpu) |= vcpu_debug_saved_reg(vcpu, pstate_ss_bit); - vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~MDSCR_EL1_DEBUG_BITS; - vcpu_sys_reg(vcpu, MDSCR_EL1) |= - vcpu_debug_saved_reg(vcpu, mdscr_el1_bits); + vcpu_sys_reg(vcpu, MDSCR_EL1) = + vcpu_debug_saved_reg(vcpu, mdscr_el1); /* * If we were using HW debug we need to restore the diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index be9b188..d43d7d1 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -208,39 +208,61 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu, const struct sys_reg_params *p, const struct sys_reg_desc *r) { - 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); - - 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 (vcpu->guest_debug) { + + /* MDSCR_EL1 */ + if (r->reg == MDSCR_EL1) { + if (p->is_write) + vcpu_debug_saved_reg(vcpu, mdscr_el1) = + *vcpu_reg(vcpu, p->Rt); + else + *vcpu_reg(vcpu, p->Rt) = + vcpu_debug_saved_reg(vcpu, mdscr_el1); + + return true; } - if (p->is_write) - *val = *vcpu_reg(vcpu, p->Rt); - else - *vcpu_reg(vcpu, p->Rt) = *val; + /* MDCCINT_EL1 */ + if (r->reg == MDCCINT_EL1) + goto old; + + /* We only shadow DBG* if guest being debugged */ + 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); + + 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; + } - } else { - 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); + if (p->is_write) + *val = *vcpu_reg(vcpu, p->Rt); + else + *vcpu_reg(vcpu, p->Rt) = *val; + + return true; } } +old: + 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; } -- 2.3.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v2 09/10] KVM: arm64: trap nested debug register access Date: Tue, 31 Mar 2015 16:08:07 +0100 Message-ID: <1427814488-28467-10-git-send-email-alex.bennee@linaro.org> References: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Cc: Catalin Marinas , Gleb Natapov , jan.kiszka@siemens.com, Will Deacon , open list , dahi@linux.vnet.ibm.com, r65777@freescale.com, bp@suse.de To: 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, drjones@redhat.com, pbonzini@redhat.com, zhichao.huang@linaro.org Return-path: In-Reply-To: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> 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 List-Id: kvm.vger.kernel.org V2hlbiB3ZSBhcmUgdXNpbmcgdGhlIGhhcmR3YXJlIHJlZ2lzdGVycyBmb3IgZ3Vlc3QgZGVidWcg d2UgbmVlZCB0byBkZWFsCndpdGggdGhlIGd1ZXN0cyBhY2Nlc3MgdG8gdGhlbS4gVGhlcmUgaXMg YWxyZWFkeSBhIG1lY2hhbmlzbSBmb3IgZGVhbGluZwp3aXRoIHRoZXNlIGFjY2Vzc2VzIHNvIHdl IGJ1aWxkIG9uIHRvcCBvZiB0aGF0LgoKICAtIG1kc2NyX2VsMV9iaXRzIGlzIHJlbmFtZWQgYXMg d2Ugc2F2ZSB0aGUgd2hvbGUgcmVnaXN0ZXIKICAtIGFueSBhY2Nlc3MgdG8gbWRzY3JfZWwxIGlz IG5vdyBzdG9yZWQgaW4gdGhlIG1pcnJvciBsb2NhdGlvbgogIC0gaWYgd2UgYXJlIHVzaW5nIEhX IGFzc2lzdGVkIGRlYnVnIHdlIGRvIHRoZSBzYW1lIHdpdGggREJHW1dCXVtDVl1SCgpUaGVyZSBp cyBvbmUgcmVnaXN0ZXIgKE1EQ0NJTlRfRUwxKSB3aGljaCBndWVzdCBkZWJ1ZyBkb2Vzbid0IGNh cmUgYWJvdXQKc28gdGhpcyBiZWhhdmVzIGFzIGJlZm9yZS4KClNpZ25lZC1vZmYtYnk6IEFsZXgg QmVubsOpZSA8YWxleC5iZW5uZWVAbGluYXJvLm9yZz4KCmRpZmYgLS1naXQgYS9hcmNoL2FybTY0 L2luY2x1ZGUvYXNtL2t2bV9ob3N0LmggYi9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL2t2bV9ob3N0 LmgKaW5kZXggMmMzNTljOS4uM2QzMmQ0NSAxMDA2NDQKLS0tIGEvYXJjaC9hcm02NC9pbmNsdWRl L2FzbS9rdm1faG9zdC5oCisrKyBiL2FyY2gvYXJtNjQvaW5jbHVkZS9hc20va3ZtX2hvc3QuaApA QCAtMTIyLDEwICsxMjIsMTMgQEAgc3RydWN0IGt2bV92Y3B1X2FyY2ggewogCSAqIGhlcmUuCiAJ ICovCiAKLQkvKiBSZWdpc3RlcnMgcHJlIGFueSBndWVzdCBkZWJ1ZyBtYW5pcHVsYXRpb25zICov CisJLyogUmVnaXN0ZXJzIGJlZm9yZSBhbnkgZ3Vlc3QgZGVidWcgbWFuaXB1bGF0aW9ucy4gVGhl c2UKKwkgKiBzaGFkb3cgcmVnaXN0ZXJzIGFyZSB1cGRhdGVkIGJ5IHRoZSBrdm1faGFuZGxlX3N5 c19yZWcKKwkgKiB0cmFwIGhhbmRsZXIgaWYgdGhlIGd1ZXN0IGFjY2Vzc2VzIG9yIHVwZGF0ZXMg dGhlbQorCSAqLwogCXN0cnVjdCB7CiAJCXUzMglwc3RhdGVfc3NfYml0OwotCQl1MzIJbWRzY3Jf ZWwxX2JpdHM7CisJCXUzMgltZHNjcl9lbDE7CiAKIAkJc3RydWN0IGt2bV9ndWVzdF9kZWJ1Z19h cmNoIGRlYnVnX3JlZ3M7CiAJfSBkZWJ1Z19zYXZlZF9yZWdzOwpkaWZmIC0tZ2l0IGEvYXJjaC9h cm02NC9rdm0vZGVidWcuYyBiL2FyY2gvYXJtNjQva3ZtL2RlYnVnLmMKaW5kZXggM2IzNjhmMy4u NjM4YzExMSAxMDA2NDQKLS0tIGEvYXJjaC9hcm02NC9rdm0vZGVidWcuYworKysgYi9hcmNoL2Fy bTY0L2t2bS9kZWJ1Zy5jCkBAIC01NSw4ICs1NSw2IEBAIHZvaWQga3ZtX2FyY2hfc2V0dXBfZGVi dWcoc3RydWN0IGt2bV92Y3B1ICp2Y3B1KQogCXZjcHUtPmFyY2gubWRjcl9lbDIgfD0gKE1EQ1Jf RUwyX1RQTSB8IE1EQ1JfRUwyX1RQTUNSKTsKIAl2Y3B1LT5hcmNoLm1kY3JfZWwyIHw9IChNRENS X0VMMl9URFJBIHwgTURDUl9FTDJfVERPU0EpOwogCi0JdHJhY2Vfa3ZtX2FyY2hfc2V0dXBfZGVi dWdfcmVnMzIoIk1EQ1JfRUwyIiwgdmNwdS0+YXJjaC5tZGNyX2VsMik7Ci0KIAkvKgogCSAqIElm IHdlIGFyZSBub3QgdHJlYXRpbmcgZGVidWcgcmVnaXN0ZXJzIGFyZSBkaXJ0eSB3ZSBuZWVkCiAJ ICogdG8gdHJhcCBpZiB0aGUgZ3Vlc3Qgc3RhcnRzIGFjY2Vzc2luZyB0aGVtLgpAQCAtNzEsOCAr NjksMTAgQEAgdm9pZCBrdm1fYXJjaF9zZXR1cF9kZWJ1ZyhzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUp CiAJCS8qIFNhdmUgcHN0YXRlL21kc2NyICovCiAJCXZjcHVfZGVidWdfc2F2ZWRfcmVnKHZjcHUs IHBzdGF0ZV9zc19iaXQpID0KIAkJCSp2Y3B1X2Nwc3IodmNwdSkgJiBEQkdfU1BTUl9TUzsKLQkJ dmNwdV9kZWJ1Z19zYXZlZF9yZWcodmNwdSwgbWRzY3JfZWwxX2JpdHMpID0KLQkJCXZjcHVfc3lz X3JlZyh2Y3B1LCBNRFNDUl9FTDEpICYgTURTQ1JfRUwxX0RFQlVHX0JJVFM7CisKKwkJdmNwdV9k ZWJ1Z19zYXZlZF9yZWcodmNwdSwgbWRzY3JfZWwxKSA9CisJCQl2Y3B1X3N5c19yZWcodmNwdSwg TURTQ1JfRUwxKTsKKwogCQkvKgogCQkgKiBTaW5nbGUgU3RlcCAoQVJNIEFSTSBEMi4xMi4zIFRo ZSBzb2Z0d2FyZSBzdGVwIHN0YXRlCiAJCSAqIG1hY2hpbmUpCkBAIC0xNjEsOSArMTYxLDggQEAg dm9pZCBrdm1fYXJjaF9jbGVhcl9kZWJ1ZyhzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpCiAJCSp2Y3B1 X2Nwc3IodmNwdSkgJj0gfkRCR19TUFNSX1NTOwogCQkqdmNwdV9jcHNyKHZjcHUpIHw9IHZjcHVf ZGVidWdfc2F2ZWRfcmVnKHZjcHUsIHBzdGF0ZV9zc19iaXQpOwogCi0JCXZjcHVfc3lzX3JlZyh2 Y3B1LCBNRFNDUl9FTDEpICY9IH5NRFNDUl9FTDFfREVCVUdfQklUUzsKLQkJdmNwdV9zeXNfcmVn KHZjcHUsIE1EU0NSX0VMMSkgfD0KLQkJCXZjcHVfZGVidWdfc2F2ZWRfcmVnKHZjcHUsIG1kc2Ny X2VsMV9iaXRzKTsKKwkJdmNwdV9zeXNfcmVnKHZjcHUsIE1EU0NSX0VMMSkgPQorCQkJdmNwdV9k ZWJ1Z19zYXZlZF9yZWcodmNwdSwgbWRzY3JfZWwxKTsKIAogCQkvKgogCQkgKiBJZiB3ZSB3ZXJl IHVzaW5nIEhXIGRlYnVnIHdlIG5lZWQgdG8gcmVzdG9yZSB0aGUKZGlmZiAtLWdpdCBhL2FyY2gv YXJtNjQva3ZtL3N5c19yZWdzLmMgYi9hcmNoL2FybTY0L2t2bS9zeXNfcmVncy5jCmluZGV4IGJl OWIxODguLmQ0M2Q3ZDEgMTAwNjQ0Ci0tLSBhL2FyY2gvYXJtNjQva3ZtL3N5c19yZWdzLmMKKysr IGIvYXJjaC9hcm02NC9rdm0vc3lzX3JlZ3MuYwpAQCAtMjA4LDM5ICsyMDgsNjEgQEAgc3RhdGlj IGJvb2wgdHJhcF9kZWJ1Z19yZWdzKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSwKIAkJCSAgICBjb25z dCBzdHJ1Y3Qgc3lzX3JlZ19wYXJhbXMgKnAsCiAJCQkgICAgY29uc3Qgc3RydWN0IHN5c19yZWdf ZGVzYyAqcikKIHsKLQlpZiAodmNwdS0+Z3Vlc3RfZGVidWcgJiBLVk1fR1VFU1REQkdfVVNFX0hX X0JQKSB7Ci0JCXN0cnVjdCBrdm1fZ3Vlc3RfZGVidWdfYXJjaCAqc2F2ZWQ7Ci0JCV9fdTY0ICp2 YWw7Ci0KLQkJc2F2ZWQgPSAmdmNwdV9kZWJ1Z19zYXZlZF9yZWcodmNwdSwgZGVidWdfcmVncyk7 Ci0KLQkJaWYgKHItPnJlZyA+PSBEQkdCQ1IwX0VMMSAmJiByLT5yZWcgPD0gREJHQkNSMTVfRUwx KQotCQkJdmFsID0gJnNhdmVkLT5kYmdfYmNyW3ItPnJlZyAtIERCR0JDUjBfRUwxXTsKLQkJZWxz ZSBpZiAoci0+cmVnID49IERCR0JWUjBfRUwxICYmIHItPnJlZyA8PSBEQkdCVlIxNV9FTDEpCi0J CQl2YWwgPSAmc2F2ZWQtPmRiZ19idnJbci0+cmVnIC0gREJHQlZSMF9FTDFdOwotCQllbHNlIGlm IChyLT5yZWcgPj0gREJHV0NSMF9FTDEgJiYgci0+cmVnIDw9IERCR1dDUjE1X0VMMSkKLQkJCXZh bCA9ICZzYXZlZC0+ZGJnX3djcltyLT5yZWcgLSBEQkdXQ1IwX0VMMV07Ci0JCWVsc2UgaWYgKHIt PnJlZyA+PSBEQkdXVlIwX0VMMSAmJiByLT5yZWcgPD0gREJHV1ZSMTVfRUwxKQotCQkJdmFsID0g JnNhdmVkLT5kYmdfd3ZyW3ItPnJlZyAtIERCR1dWUjBfRUwxXTsKLQkJZWxzZSB7Ci0JCQlrdm1f ZXJyKCJCYWQgcmVnaXN0ZXIgaW5kZXggJWRcbiIsIHItPnJlZyk7Ci0JCQlyZXR1cm4gZmFsc2U7 CisJaWYgKHZjcHUtPmd1ZXN0X2RlYnVnKSB7CisKKwkJLyogTURTQ1JfRUwxICovCisJCWlmIChy LT5yZWcgPT0gTURTQ1JfRUwxKSB7CisJCQlpZiAocC0+aXNfd3JpdGUpCisJCQkJdmNwdV9kZWJ1 Z19zYXZlZF9yZWcodmNwdSwgbWRzY3JfZWwxKSA9CisJCQkJCSp2Y3B1X3JlZyh2Y3B1LCBwLT5S dCk7CisJCQllbHNlCisJCQkJKnZjcHVfcmVnKHZjcHUsIHAtPlJ0KSA9CisJCQkJCXZjcHVfZGVi dWdfc2F2ZWRfcmVnKHZjcHUsIG1kc2NyX2VsMSk7CisKKwkJCXJldHVybiB0cnVlOwogCQl9CiAK LQkJaWYgKHAtPmlzX3dyaXRlKQotCQkJKnZhbCA9ICp2Y3B1X3JlZyh2Y3B1LCBwLT5SdCk7Ci0J CWVsc2UKLQkJCSp2Y3B1X3JlZyh2Y3B1LCBwLT5SdCkgPSAqdmFsOworCQkvKiBNRENDSU5UX0VM MSAqLworCQlpZiAoci0+cmVnID09IE1EQ0NJTlRfRUwxKQorCQkJZ290byBvbGQ7CisKKwkJLyog V2Ugb25seSBzaGFkb3cgREJHKiBpZiBndWVzdCBiZWluZyBkZWJ1Z2dlZCAqLworCQlpZiAodmNw dS0+Z3Vlc3RfZGVidWcgJiBLVk1fR1VFU1REQkdfVVNFX0hXX0JQKSB7CisJCQlzdHJ1Y3Qga3Zt X2d1ZXN0X2RlYnVnX2FyY2ggKnNhdmVkOworCQkJX191NjQgKnZhbDsKKworCQkJc2F2ZWQgPSAm dmNwdV9kZWJ1Z19zYXZlZF9yZWcodmNwdSwgZGVidWdfcmVncyk7CisKKwkJCWlmIChyLT5yZWcg Pj0gREJHQkNSMF9FTDEgJiYgci0+cmVnIDw9IERCR0JDUjE1X0VMMSkKKwkJCQl2YWwgPSAmc2F2 ZWQtPmRiZ19iY3Jbci0+cmVnIC0gREJHQkNSMF9FTDFdOworCQkJZWxzZSBpZiAoci0+cmVnID49 IERCR0JWUjBfRUwxICYmIHItPnJlZyA8PSBEQkdCVlIxNV9FTDEpCisJCQkJdmFsID0gJnNhdmVk LT5kYmdfYnZyW3ItPnJlZyAtIERCR0JWUjBfRUwxXTsKKwkJCWVsc2UgaWYgKHItPnJlZyA+PSBE QkdXQ1IwX0VMMSAmJiByLT5yZWcgPD0gREJHV0NSMTVfRUwxKQorCQkJCXZhbCA9ICZzYXZlZC0+ ZGJnX3djcltyLT5yZWcgLSBEQkdXQ1IwX0VMMV07CisJCQllbHNlIGlmIChyLT5yZWcgPj0gREJH V1ZSMF9FTDEgJiYgci0+cmVnIDw9IERCR1dWUjE1X0VMMSkKKwkJCQl2YWwgPSAmc2F2ZWQtPmRi Z193dnJbci0+cmVnIC0gREJHV1ZSMF9FTDFdOworCQkJZWxzZSB7CisJCQkJa3ZtX2VycigiQmFk IHJlZ2lzdGVyIGluZGV4ICVkXG4iLCByLT5yZWcpOworCQkJCXJldHVybiBmYWxzZTsKKwkJCX0K IAotCX0gZWxzZSB7Ci0JCWlmIChwLT5pc193cml0ZSkgewotCQkJdmNwdV9zeXNfcmVnKHZjcHUs IHItPnJlZykgPSAqdmNwdV9yZWcodmNwdSwgcC0+UnQpOwotCQkJdmNwdS0+YXJjaC5kZWJ1Z19m bGFncyB8PSBLVk1fQVJNNjRfREVCVUdfRElSVFk7Ci0JCX0gZWxzZSB7Ci0JCQkqdmNwdV9yZWco dmNwdSwgcC0+UnQpID0gdmNwdV9zeXNfcmVnKHZjcHUsIHItPnJlZyk7CisJCQlpZiAocC0+aXNf d3JpdGUpCisJCQkJKnZhbCA9ICp2Y3B1X3JlZyh2Y3B1LCBwLT5SdCk7CisJCQllbHNlCisJCQkJ KnZjcHVfcmVnKHZjcHUsIHAtPlJ0KSA9ICp2YWw7CisKKwkJCXJldHVybiB0cnVlOwogCQl9CiAJ fQogCitvbGQ6CisJaWYgKHAtPmlzX3dyaXRlKSB7CisJCXZjcHVfc3lzX3JlZyh2Y3B1LCByLT5y ZWcpID0gKnZjcHVfcmVnKHZjcHUsIHAtPlJ0KTsKKwkJdmNwdS0+YXJjaC5kZWJ1Z19mbGFncyB8 PSBLVk1fQVJNNjRfREVCVUdfRElSVFk7CisJfSBlbHNlIHsKKwkJKnZjcHVfcmVnKHZjcHUsIHAt PlJ0KSA9IHZjcHVfc3lzX3JlZyh2Y3B1LCByLT5yZWcpOworCX0KKwogCXJldHVybiB0cnVlOwog fQogCi0tIAoyLjMuNAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX18Ka3ZtYXJtIG1haWxpbmcgbGlzdAprdm1hcm1AbGlzdHMuY3MuY29sdW1iaWEuZWR1Cmh0 dHBzOi8vbGlzdHMuY3MuY29sdW1iaWEuZWR1L21haWxtYW4vbGlzdGluZm8va3ZtYXJtCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: alex.bennee@linaro.org (=?UTF-8?q?Alex=20Benn=C3=A9e?=) Date: Tue, 31 Mar 2015 16:08:07 +0100 Subject: [PATCH v2 09/10] KVM: arm64: trap nested debug register access In-Reply-To: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> References: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> Message-ID: <1427814488-28467-10-git-send-email-alex.bennee@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org When we are using the hardware registers for guest debug we need to deal with the guests access to them. There is already a mechanism for dealing with these accesses so we build on top of that. - mdscr_el1_bits is renamed as we save the whole register - any access to mdscr_el1 is now stored in the mirror location - if we are using HW assisted debug we do the same with DBG[WB][CV]R There is one register (MDCCINT_EL1) which guest debug doesn't care about so this behaves as before. Signed-off-by: Alex Benn?e diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 2c359c9..3d32d45 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -122,10 +122,13 @@ struct kvm_vcpu_arch { * here. */ - /* Registers pre any guest debug manipulations */ + /* Registers before any guest debug manipulations. These + * shadow registers are updated by the kvm_handle_sys_reg + * trap handler if the guest accesses or updates them + */ struct { u32 pstate_ss_bit; - u32 mdscr_el1_bits; + u32 mdscr_el1; struct kvm_guest_debug_arch debug_regs; } debug_saved_regs; diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index 3b368f3..638c111 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -55,8 +55,6 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | MDCR_EL2_TPMCR); vcpu->arch.mdcr_el2 |= (MDCR_EL2_TDRA | MDCR_EL2_TDOSA); - trace_kvm_arch_setup_debug_reg32("MDCR_EL2", vcpu->arch.mdcr_el2); - /* * If we are not treating debug registers are dirty we need * to trap if the guest starts accessing them. @@ -71,8 +69,10 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) /* Save pstate/mdscr */ vcpu_debug_saved_reg(vcpu, pstate_ss_bit) = *vcpu_cpsr(vcpu) & DBG_SPSR_SS; - vcpu_debug_saved_reg(vcpu, mdscr_el1_bits) = - vcpu_sys_reg(vcpu, MDSCR_EL1) & MDSCR_EL1_DEBUG_BITS; + + vcpu_debug_saved_reg(vcpu, mdscr_el1) = + vcpu_sys_reg(vcpu, MDSCR_EL1); + /* * Single Step (ARM ARM D2.12.3 The software step state * machine) @@ -161,9 +161,8 @@ void kvm_arch_clear_debug(struct kvm_vcpu *vcpu) *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; *vcpu_cpsr(vcpu) |= vcpu_debug_saved_reg(vcpu, pstate_ss_bit); - vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~MDSCR_EL1_DEBUG_BITS; - vcpu_sys_reg(vcpu, MDSCR_EL1) |= - vcpu_debug_saved_reg(vcpu, mdscr_el1_bits); + vcpu_sys_reg(vcpu, MDSCR_EL1) = + vcpu_debug_saved_reg(vcpu, mdscr_el1); /* * If we were using HW debug we need to restore the diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index be9b188..d43d7d1 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -208,39 +208,61 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu, const struct sys_reg_params *p, const struct sys_reg_desc *r) { - 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); - - 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 (vcpu->guest_debug) { + + /* MDSCR_EL1 */ + if (r->reg == MDSCR_EL1) { + if (p->is_write) + vcpu_debug_saved_reg(vcpu, mdscr_el1) = + *vcpu_reg(vcpu, p->Rt); + else + *vcpu_reg(vcpu, p->Rt) = + vcpu_debug_saved_reg(vcpu, mdscr_el1); + + return true; } - if (p->is_write) - *val = *vcpu_reg(vcpu, p->Rt); - else - *vcpu_reg(vcpu, p->Rt) = *val; + /* MDCCINT_EL1 */ + if (r->reg == MDCCINT_EL1) + goto old; + + /* We only shadow DBG* if guest being debugged */ + 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); + + 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; + } - } else { - 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); + if (p->is_write) + *val = *vcpu_reg(vcpu, p->Rt); + else + *vcpu_reg(vcpu, p->Rt) = *val; + + return true; } } +old: + 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; } -- 2.3.4