From patchwork Tue Nov 2 09:46:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Upton X-Patchwork-Id: 12598269 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81454C433FE for ; Tue, 2 Nov 2021 09:49:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5693F60C4B for ; Tue, 2 Nov 2021 09:49:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 5693F60C4B Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=d5j24qad7PVmqA1bWlWQgMdtUwRjlpeHDiq3Q62Kzuo=; b=IrQeMGL+jtAUkr3nZynw0vQrgO ZOL3z1tN80Otr53dUIsKBO3CCMd0o7i20rivPJ9cVbCxF5ritn+BXw8xSpMlKOPR9Nbb1F3qWHyK8 /IImPnsYIqC2NDJFxiRKVUDmoXsudXroOniKvuUO3J2UIvE8cLGPVRmkQJ0VrUTPpXZpjF6CdVFQe WWRR2xVJKhi+tCStkQlBmAvasC7PSOMViJzsQw0+tTaJmHqdXX5b5m9YedXlRqERsFTeIBE5aun95 rxNZlyfXQK1YnrP5PaAi/aQqqPnESeNmQwW2nwr4bM35zyzTNwWve9dJ4t7yGfAaLAjoaw2Bqc3no 424YIWKQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhqOW-00195D-1X; Tue, 02 Nov 2021 09:47:52 +0000 Received: from mail-io1-xd4a.google.com ([2607:f8b0:4864:20::d4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhqNl-0018ng-2B for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 09:47:06 +0000 Received: by mail-io1-xd4a.google.com with SMTP id j19-20020a0566022cd300b005e1816be9abso6929766iow.8 for ; Tue, 02 Nov 2021 02:47:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=uurkhpIbGOm6d0Vndzx4M8suePh/mfJb26pfAeTQQ2Q=; b=hfG5wU8dCHVF7dzzRdCErkdSpbwwJpZuXaQLMBh7ivg7UkdR7Q2EXzLbnT41pop135 XCHRgVpXBLovwNMqy9DIRMmWmVsZ28tIM6cX3gNxKkrPynPaKlZhQ+8khbqNpw+EoGno 9oGJnKnGefLQm0tEsiIyE3j3FutcPJhp1HNLgqHfFbcSrz1R0C1IWb9eW4kQmZzvK/C0 PltELiax0LrjH9/UNYt+8l1Bs+UIeitFUh56258VomoZ8MR78MzMdJftxtD5GCXcXdhT cEH0Ki7u6Q2zMBKCNJchGI/GIhfrFO+/bowakv7b8AkGnKTiY1XXeU4m796IUaMR/Zcl cYdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=uurkhpIbGOm6d0Vndzx4M8suePh/mfJb26pfAeTQQ2Q=; b=XtQ/staHtBC8JciSxnDZS+3Qx0Lho3P5kZ0cRQ0uYzGHjXHWB+rSRtWM4j5vcVGc8y /n3HOCik4ipGAq0hmEK/mqemrZH49EsOWqJeXkuysnSZpWDK9VJKkFm3aDQ4NCuWYhzF LDeeiYxymy+Jug4vq/hRaFts3C9PCGcD8tVurxK1TQeHYhLEglZ9A0d4TLvsUU1H+71j /Ewacv8X4oUk+xGXapuWSadN9bsW6ed9UsLwFbIJ7tGOLYtsFDnbLL2SqXnv3SSx4u9M /FncplzwNM8DR6eu4ABmURKtp03CbJ4xQUZLEKR94l6owi1qkZAuyBP6IyCUGotfJvKO g1Tg== X-Gm-Message-State: AOAM533sT+ORo3rUJvrj5oGVp0zb0wU9Ok0t/6MAY3/7HXn7nndD4kQy G8RXLB79HJGji8ntgg/FY16e1rpuE6I= X-Google-Smtp-Source: ABdhPJzdE2f0jbKc/HrPBSVM0QUl30mxLU3ZJlUaX+L3AkUnjf0ehb/ooOshHnhNm9o1UfgzNO0sexgE6jQ= X-Received: from oupton.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:404]) (user=oupton job=sendgmr) by 2002:a05:6e02:174d:: with SMTP id y13mr24331087ill.251.1635846423807; Tue, 02 Nov 2021 02:47:03 -0700 (PDT) Date: Tue, 2 Nov 2021 09:46:49 +0000 In-Reply-To: <20211102094651.2071532-1-oupton@google.com> Message-Id: <20211102094651.2071532-5-oupton@google.com> Mime-Version: 1.0 References: <20211102094651.2071532-1-oupton@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [PATCH v2 4/6] KVM: arm64: Emulate the OS Lock From: Oliver Upton To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, Marc Zyngier , James Morse , Alexandru Elisei , Suzuki K Poulose , linux-arm-kernel@lists.infradead.org, Andrew Jones , Peter Shier , Ricardo Koller , Reiji Watanabe , Oliver Upton X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_024705_133733_5AFF4636 X-CRM114-Status: GOOD ( 21.11 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The OS lock blocks all debug exceptions at every EL. To date, KVM has not implemented the OS lock for its guests, despite the fact that it is mandatory per the architecture. Simple context switching between the guest and host is not appropriate, as its effects are not constrained to the guest context. Emulate the OS Lock by clearing MDE and SS in MDSCR_EL1, thereby blocking all but software breakpoint instructions. To handle breakpoint instructions, trap debug exceptions to EL2 and skip the instruction. Signed-off-by: Oliver Upton --- arch/arm64/include/asm/kvm_host.h | 4 ++++ arch/arm64/kvm/debug.c | 20 +++++++++++++++----- arch/arm64/kvm/handle_exit.c | 8 ++++++++ arch/arm64/kvm/sys_regs.c | 6 +++--- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index c98f65c4a1f7..f13b8b79b06d 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -724,6 +724,10 @@ void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu); void kvm_arm_setup_debug(struct kvm_vcpu *vcpu); void kvm_arm_clear_debug(struct kvm_vcpu *vcpu); void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu); + +#define kvm_vcpu_os_lock_enabled(vcpu) \ + (__vcpu_sys_reg(vcpu, OSLSR_EL1) & SYS_OSLSR_OSLK) + int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index db9361338b2a..5690a9c99c89 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -95,8 +95,11 @@ static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu) MDCR_EL2_TDRA | MDCR_EL2_TDOSA); - /* Is the VM being debugged by userspace? */ - if (vcpu->guest_debug) + /* + * Check if the VM is being debugged by userspace or the guest has + * enabled the OS lock. + */ + if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) /* Route all software debug exceptions to EL2 */ vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; @@ -160,8 +163,11 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) kvm_arm_setup_mdcr_el2(vcpu); - /* Is Guest debugging in effect? */ - if (vcpu->guest_debug) { + /* + * Check if the guest is being debugged or if the guest has enabled the + * OS lock. + */ + if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) { /* Save guest debug state */ save_guest_debug_regs(vcpu); @@ -223,6 +229,10 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), &vcpu->arch.debug_ptr->dbg_wcr[0], &vcpu->arch.debug_ptr->dbg_wvr[0]); + } else if (kvm_vcpu_os_lock_enabled(vcpu)) { + mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); + mdscr &= ~DBG_MDSCR_MDE; + vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); } } @@ -244,7 +254,7 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) { trace_kvm_arm_clear_debug(vcpu->guest_debug); - if (vcpu->guest_debug) { + if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) { restore_guest_debug_regs(vcpu); /* diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 275a27368a04..a7136888434d 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -119,6 +119,14 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu->run; u32 esr = kvm_vcpu_get_esr(vcpu); + u8 esr_ec = ESR_ELx_EC(esr); + + if (!vcpu->guest_debug) { + WARN_ONCE(esr_ec != ESR_ELx_EC_BRK64 || esr_ec != ESR_ELx_EC_BKPT32, + "Unexpected debug exception\n"); + kvm_incr_pc(vcpu); + return 1; + } run->exit_reason = KVM_EXIT_DEBUG; run->debug.arch.hsr = esr; diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index acd8aa2e5a44..d336e4c66870 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1446,9 +1446,9 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu, * Debug handling: We do trap most, if not all debug related system * registers. The implementation is good enough to ensure that a guest * can use these with minimal performance degradation. The drawback is - * that we don't implement any of the external debug, none of the - * OSlock protocol. This should be revisited if we ever encounter a - * more demanding guest... + * that we don't implement any of the external debug architecture. + * This should be revisited if we ever encounter a more demanding + * guest... */ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_DC_ISW), access_dcsw },