From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751917AbbEGJHy (ORCPT ); Thu, 7 May 2015 05:07:54 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:38252 "EHLO socrates.bennee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750889AbbEGJHr (ORCPT ); Thu, 7 May 2015 05:07:47 -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 v3 10/12] KVM: arm64: trap nested debug register access Date: Thu, 7 May 2015 10:07:13 +0100 Message-Id: <1430989647-22501-3-git-send-email-alex.bennee@linaro.org> X-Mailer: git-send-email 2.3.5 In-Reply-To: <1430929407-3487-1-git-send-email-alex.bennee@linaro.org> References: <1430929407-3487-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. - any access to mdscr_el1 is now stored in the mirror location - access to DBG[WB][CV]R continues to go to guest's context There is one register (MDCCINT_EL1) which guest debug doesn't care about so this behaves as before. Signed-off-by: Alex Bennée --- v3 - re-factor for better flow and fall through. - much simpler with debug_ptr (use the guest area as before) - tweak shadow fn to avoid multi-line if diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index a44fb32..7aa3b3a 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -132,7 +132,13 @@ struct kvm_vcpu_arch { * here. */ - /* Guest registers we preserve during guest debugging */ + /* + * Guest registers we preserve during guest debugging. + * + * These shadow registers are updated by the kvm_handle_sys_reg + * trap handler if the guest accesses or updates them while we + * are using guest debug. + */ struct { u32 pstate; u32 mdscr_el1; diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index 1ab63dd..dc8bca8 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -50,8 +50,7 @@ static void restore_guest_debug_regs(struct kvm_vcpu *vcpu) { *vcpu_cpsr(vcpu) |= (vcpu->arch.guest_debug_state.pstate & SPSR_DEBUG_MASK); - vcpu_sys_reg(vcpu, MDSCR_EL1) |= - (vcpu->arch.guest_debug_state.mdscr_el1 & MDSCR_EL1_DEBUG_MASK); + vcpu_sys_reg(vcpu, MDSCR_EL1) = vcpu->arch.guest_debug_state.mdscr_el1; } /** diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c370b40..95f422f 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -196,11 +196,40 @@ 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 + * 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. + * */ + +static bool shadow_debug_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + /* MDSCR_EL1 */ + if (r->reg == MDSCR_EL1) { + u32 *shadow_mdscr_el1 = &vcpu->arch.guest_debug_state.mdscr_el1; + + if (p->is_write) + *shadow_mdscr_el1 = *vcpu_reg(vcpu, p->Rt); + else + *vcpu_reg(vcpu, p->Rt) = *shadow_mdscr_el1; + + return true; + } + + return false; +} + 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 && shadow_debug_reg(vcpu, p, r)) + return true; + if (p->is_write) { vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; -- 2.3.5 From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v3 10/12] KVM: arm64: trap nested debug register access Date: Thu, 7 May 2015 10:07:13 +0100 Message-ID: <1430989647-22501-3-git-send-email-alex.bennee@linaro.org> References: <1430929407-3487-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: <1430929407-3487-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 IGJ1aWxkIG9uIHRvcCBvZiB0aGF0LgoKICAtIGFueSBhY2Nlc3MgdG8gbWRzY3JfZWwxIGlzIG5v dyBzdG9yZWQgaW4gdGhlIG1pcnJvciBsb2NhdGlvbgogIC0gYWNjZXNzIHRvIERCR1tXQl1bQ1Zd UiBjb250aW51ZXMgdG8gZ28gdG8gZ3Vlc3QncyBjb250ZXh0CgpUaGVyZSBpcyBvbmUgcmVnaXN0 ZXIgKE1EQ0NJTlRfRUwxKSB3aGljaCBndWVzdCBkZWJ1ZyBkb2Vzbid0IGNhcmUgYWJvdXQKc28g dGhpcyBiZWhhdmVzIGFzIGJlZm9yZS4KClNpZ25lZC1vZmYtYnk6IEFsZXggQmVubsOpZSA8YWxl eC5iZW5uZWVAbGluYXJvLm9yZz4KCi0tLQp2MwogIC0gcmUtZmFjdG9yIGZvciBiZXR0ZXIgZmxv dyBhbmQgZmFsbCB0aHJvdWdoLgogIC0gbXVjaCBzaW1wbGVyIHdpdGggZGVidWdfcHRyICh1c2Ug dGhlIGd1ZXN0IGFyZWEgYXMgYmVmb3JlKQogIC0gdHdlYWsgc2hhZG93IGZuIHRvIGF2b2lkIG11 bHRpLWxpbmUgaWYKCmRpZmYgLS1naXQgYS9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL2t2bV9ob3N0 LmggYi9hcmNoL2FybTY0L2luY2x1ZGUvYXNtL2t2bV9ob3N0LmgKaW5kZXggYTQ0ZmIzMi4uN2Fh M2IzYSAxMDA2NDQKLS0tIGEvYXJjaC9hcm02NC9pbmNsdWRlL2FzbS9rdm1faG9zdC5oCisrKyBi L2FyY2gvYXJtNjQvaW5jbHVkZS9hc20va3ZtX2hvc3QuaApAQCAtMTMyLDcgKzEzMiwxMyBAQCBz dHJ1Y3Qga3ZtX3ZjcHVfYXJjaCB7CiAJICogaGVyZS4KIAkgKi8KIAotCS8qIEd1ZXN0IHJlZ2lz dGVycyB3ZSBwcmVzZXJ2ZSBkdXJpbmcgZ3Vlc3QgZGVidWdnaW5nICovCisJLyoKKwkgKiBHdWVz dCByZWdpc3RlcnMgd2UgcHJlc2VydmUgZHVyaW5nIGd1ZXN0IGRlYnVnZ2luZy4KKwkgKgorCSAq IFRoZXNlIHNoYWRvdyByZWdpc3RlcnMgYXJlIHVwZGF0ZWQgYnkgdGhlIGt2bV9oYW5kbGVfc3lz X3JlZworCSAqIHRyYXAgaGFuZGxlciBpZiB0aGUgZ3Vlc3QgYWNjZXNzZXMgb3IgdXBkYXRlcyB0 aGVtIHdoaWxlIHdlCisJICogYXJlIHVzaW5nIGd1ZXN0IGRlYnVnLgorCSAqLwogCXN0cnVjdCB7 CiAJCXUzMglwc3RhdGU7CiAJCXUzMgltZHNjcl9lbDE7CmRpZmYgLS1naXQgYS9hcmNoL2FybTY0 L2t2bS9kZWJ1Zy5jIGIvYXJjaC9hcm02NC9rdm0vZGVidWcuYwppbmRleCAxYWI2M2RkLi5kYzhi Y2E4IDEwMDY0NAotLS0gYS9hcmNoL2FybTY0L2t2bS9kZWJ1Zy5jCisrKyBiL2FyY2gvYXJtNjQv a3ZtL2RlYnVnLmMKQEAgLTUwLDggKzUwLDcgQEAgc3RhdGljIHZvaWQgcmVzdG9yZV9ndWVzdF9k ZWJ1Z19yZWdzKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSkKIHsKIAkqdmNwdV9jcHNyKHZjcHUpIHw9 CiAJCSh2Y3B1LT5hcmNoLmd1ZXN0X2RlYnVnX3N0YXRlLnBzdGF0ZSAmIFNQU1JfREVCVUdfTUFT Syk7Ci0JdmNwdV9zeXNfcmVnKHZjcHUsIE1EU0NSX0VMMSkgfD0KLQkJKHZjcHUtPmFyY2guZ3Vl c3RfZGVidWdfc3RhdGUubWRzY3JfZWwxICYgTURTQ1JfRUwxX0RFQlVHX01BU0spOworCXZjcHVf c3lzX3JlZyh2Y3B1LCBNRFNDUl9FTDEpID0gdmNwdS0+YXJjaC5ndWVzdF9kZWJ1Z19zdGF0ZS5t ZHNjcl9lbDE7CiB9CiAKIC8qKgpkaWZmIC0tZ2l0IGEvYXJjaC9hcm02NC9rdm0vc3lzX3JlZ3Mu YyBiL2FyY2gvYXJtNjQva3ZtL3N5c19yZWdzLmMKaW5kZXggYzM3MGI0MC4uOTVmNDIyZiAxMDA2 NDQKLS0tIGEvYXJjaC9hcm02NC9rdm0vc3lzX3JlZ3MuYworKysgYi9hcmNoL2FybTY0L2t2bS9z eXNfcmVncy5jCkBAIC0xOTYsMTEgKzE5Niw0MCBAQCBzdGF0aWMgYm9vbCB0cmFwX2RiZ2F1dGhz dGF0dXNfZWwxKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSwKICAqIC0gSWYgdGhlIGRpcnR5IGJpdCBp cyBzZXQsIHNhdmUgZ3Vlc3QgcmVnaXN0ZXJzLCByZXN0b3JlIGhvc3QKICAqICAgcmVnaXN0ZXJz IGFuZCBjbGVhciB0aGUgZGlydHkgYml0LiBUaGlzIGVuc3VyZSB0aGF0IHRoZSBob3N0IGNhbgog ICogICBub3cgdXNlIHRoZSBkZWJ1ZyByZWdpc3RlcnMuCisgKgorICogV2UgYWxzbyB1c2UgdGhp cyBtZWNoYW5pc20gdG8gc2V0LXVwIHRoZSBkZWJ1ZyByZWdpc3RlcnMgZm9yIGd1ZXN0CisgKiBk ZWJ1Z2dpbmcuIElmIHRoaXMgaXMgdGhlIGNhc2Ugd2Ugd2FudCB0byBlbnN1cmUgdGhlIGd1ZXN0 IHNlZXMKKyAqIHRoZSByaWdodCB2ZXJzaW9ucyBvZiB0aGUgcmVnaXN0ZXJzIC0gZXZlbiBpZiB0 aGV5IGFyZSBub3QgZ29pbmcgdG8KKyAqIGJlIGVmZmVjdGl2ZSB3aGlsZSBndWVzdCBkZWJ1ZyBp cyB1c2luZyBIVyBkZWJ1Zy4KKyAqCiAgKi8KKworc3RhdGljIGJvb2wgc2hhZG93X2RlYnVnX3Jl ZyhzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUsCisJCQkgICAgIGNvbnN0IHN0cnVjdCBzeXNfcmVnX3Bh cmFtcyAqcCwKKwkJCSAgICAgY29uc3Qgc3RydWN0IHN5c19yZWdfZGVzYyAqcikKK3sKKwkvKiBN RFNDUl9FTDEgKi8KKwlpZiAoci0+cmVnID09IE1EU0NSX0VMMSkgeworCQl1MzIgKnNoYWRvd19t ZHNjcl9lbDEgPSAmdmNwdS0+YXJjaC5ndWVzdF9kZWJ1Z19zdGF0ZS5tZHNjcl9lbDE7CisKKwkJ aWYgKHAtPmlzX3dyaXRlKQorCQkJKnNoYWRvd19tZHNjcl9lbDEgPSAqdmNwdV9yZWcodmNwdSwg cC0+UnQpOworCQllbHNlCisJCQkqdmNwdV9yZWcodmNwdSwgcC0+UnQpID0gKnNoYWRvd19tZHNj cl9lbDE7CisKKwkJcmV0dXJuIHRydWU7CisJfQorCisJcmV0dXJuIGZhbHNlOworfQorCiBzdGF0 aWMgYm9vbCB0cmFwX2RlYnVnX3JlZ3Moc3RydWN0IGt2bV92Y3B1ICp2Y3B1LAogCQkJICAgIGNv bnN0IHN0cnVjdCBzeXNfcmVnX3BhcmFtcyAqcCwKIAkJCSAgICBjb25zdCBzdHJ1Y3Qgc3lzX3Jl Z19kZXNjICpyKQogeworCWlmICh2Y3B1LT5ndWVzdF9kZWJ1ZyAmJiBzaGFkb3dfZGVidWdfcmVn KHZjcHUsIHAsIHIpKQorCQlyZXR1cm4gdHJ1ZTsKKwogCWlmIChwLT5pc193cml0ZSkgewogCQl2 Y3B1X3N5c19yZWcodmNwdSwgci0+cmVnKSA9ICp2Y3B1X3JlZyh2Y3B1LCBwLT5SdCk7CiAJCXZj cHUtPmFyY2guZGVidWdfZmxhZ3MgfD0gS1ZNX0FSTTY0X0RFQlVHX0RJUlRZOwotLSAKMi4zLjUK Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmt2bWFybSBt YWlsaW5nIGxpc3QKa3ZtYXJtQGxpc3RzLmNzLmNvbHVtYmlhLmVkdQpodHRwczovL2xpc3RzLmNz LmNvbHVtYmlhLmVkdS9tYWlsbWFuL2xpc3RpbmZvL2t2bWFybQo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: alex.bennee@linaro.org (=?UTF-8?q?Alex=20Benn=C3=A9e?=) Date: Thu, 7 May 2015 10:07:13 +0100 Subject: [PATCH v3 10/12] KVM: arm64: trap nested debug register access In-Reply-To: <1430929407-3487-1-git-send-email-alex.bennee@linaro.org> References: <1430929407-3487-1-git-send-email-alex.bennee@linaro.org> Message-ID: <1430989647-22501-3-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. - any access to mdscr_el1 is now stored in the mirror location - access to DBG[WB][CV]R continues to go to guest's context There is one register (MDCCINT_EL1) which guest debug doesn't care about so this behaves as before. Signed-off-by: Alex Benn?e --- v3 - re-factor for better flow and fall through. - much simpler with debug_ptr (use the guest area as before) - tweak shadow fn to avoid multi-line if diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index a44fb32..7aa3b3a 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -132,7 +132,13 @@ struct kvm_vcpu_arch { * here. */ - /* Guest registers we preserve during guest debugging */ + /* + * Guest registers we preserve during guest debugging. + * + * These shadow registers are updated by the kvm_handle_sys_reg + * trap handler if the guest accesses or updates them while we + * are using guest debug. + */ struct { u32 pstate; u32 mdscr_el1; diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index 1ab63dd..dc8bca8 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -50,8 +50,7 @@ static void restore_guest_debug_regs(struct kvm_vcpu *vcpu) { *vcpu_cpsr(vcpu) |= (vcpu->arch.guest_debug_state.pstate & SPSR_DEBUG_MASK); - vcpu_sys_reg(vcpu, MDSCR_EL1) |= - (vcpu->arch.guest_debug_state.mdscr_el1 & MDSCR_EL1_DEBUG_MASK); + vcpu_sys_reg(vcpu, MDSCR_EL1) = vcpu->arch.guest_debug_state.mdscr_el1; } /** diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c370b40..95f422f 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -196,11 +196,40 @@ 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 + * 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. + * */ + +static bool shadow_debug_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + /* MDSCR_EL1 */ + if (r->reg == MDSCR_EL1) { + u32 *shadow_mdscr_el1 = &vcpu->arch.guest_debug_state.mdscr_el1; + + if (p->is_write) + *shadow_mdscr_el1 = *vcpu_reg(vcpu, p->Rt); + else + *vcpu_reg(vcpu, p->Rt) = *shadow_mdscr_el1; + + return true; + } + + return false; +} + 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 && shadow_debug_reg(vcpu, p, r)) + return true; + if (p->is_write) { vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt); vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY; -- 2.3.5