From patchwork Thu Apr 1 13:54:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 12178129 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6291EC433ED for ; Thu, 1 Apr 2021 13:57:35 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 C1724610CF for ; Thu, 1 Apr 2021 13:57:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C1724610CF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=6flIf98SExVr5/qp5QI+Qt2Aj07EepyNTffJ9Wzl8qM=; b=IOsBGE9QWL/AcQBRaE+j04cUa Z5foxXGpxKcV7siCnkbAdVNRY6XfOCsjVIClGuT4svS9V2qLuUR7mP7WWhFCVfxtNf9tBT9GkbzKn zUWRYREAsQorMLQEefF5BMuly8qK1kBAGs53vp7Ksjvk7C8RIjHBEk0hf4pZX4WZ7XdjytZo1KEVM Hpt4p5nxsnXJMhdoOp5d73yYS8jNLAEdQBrXlt6JBPyrar/hMG/H97L5f48Lfx6bnE+JX+Fp+B2xQ 0UH/oOy+sydQ6xjggyKihCBGxYhBZR4I9pNVFXmS80W9QOh16Ks36H31Si5laYypASQC7yzslTADF kK++tDtqg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lRxo3-009kOH-Hs; Thu, 01 Apr 2021 13:56:19 +0000 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lRxnz-009kN2-Ey for linux-arm-kernel@lists.infradead.org; Thu, 01 Apr 2021 13:56:17 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617285373; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=93LEfSuuqIW0DBrW+Poi8yq3BZzX4V4otYYlW/jGzRg=; b=WDKVLll/njCdXBeRE87ZVasqTAl17V1i0rFSw2YNOH6tvwEw33UTmeG7AUPK2WpsyTvgKV smmouXA1WLpUwOikH9+NX43UYA0bYO6ZQkZEWMisQqB/6DOTnTbXHKWFfE8lre1akdrOfZ cwqZwts6U6UEV7RPLJtmkrHH3+ZY52A= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-251-lvtRGc1hNvyqH7m-ZYkRWg-1; Thu, 01 Apr 2021 09:56:11 -0400 X-MC-Unique: lvtRGc1hNvyqH7m-ZYkRWg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CB2DDA40C1; Thu, 1 Apr 2021 13:56:06 +0000 (UTC) Received: from localhost.localdomain (unknown [10.35.206.58]) by smtp.corp.redhat.com (Postfix) with ESMTP id 944725D6B1; Thu, 1 Apr 2021 13:55:53 +0000 (UTC) From: Maxim Levitsky To: kvm@vger.kernel.org Cc: x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)), Ingo Molnar , Andrew Morton , Thomas Gleixner , Sean Christopherson , Marc Zyngier , Catalin Marinas , linux-kernel@vger.kernel.org (open list), Julien Thierry , Stefano Garzarella , Borislav Petkov , Suzuki K Poulose , Jonathan Corbet , Jessica Yu , "H. Peter Anvin" , Jan Kiszka , Will Deacon , kvmarm@lists.cs.columbia.edu (open list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)), Paolo Bonzini , Vitaly Kuznetsov , Vasily Gorbik , Joerg Roedel , Claudio Imbrenda , Jim Mattson , Cornelia Huck , David Hildenbrand , Maxim Levitsky , Wanpeng Li , Janosch Frank , Christian Borntraeger , linux-s390@vger.kernel.org (open list:S390), Heiko Carstens , Kieran Bingham , linux-doc@vger.kernel.org (open list:DOCUMENTATION), linux-arm-kernel@lists.infradead.org (moderated list:KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)), James Morse Subject: [PATCH v2 6/9] KVM: x86: implement KVM_GUESTDBG_BLOCKEVENTS Date: Thu, 1 Apr 2021 16:54:48 +0300 Message-Id: <20210401135451.1004564-7-mlevitsk@redhat.com> In-Reply-To: <20210401135451.1004564-1-mlevitsk@redhat.com> References: <20210401135451.1004564-1-mlevitsk@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210401_145615_637394_73FD15B2 X-CRM114-Status: GOOD ( 24.29 ) 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 KVM_GUESTDBG_BLOCKEVENTS is a guest debug feature that will allow KVM to block all interrupts while running. It is mostly intended to be used together with single stepping, to make it more robust, and has the following benefits: * Resuming from a breakpoint is much more reliable: When resuming execution from a breakpoint, with interrupts enabled, more often than not, KVM would inject an interrupt and make the CPU jump immediately to the interrupt handler and eventually return to the breakpoint, only to trigger it again. From the gdb's user point of view it looks like the CPU has never executed a single instruction and in some cases that can even prevent forward progress, for example, when the breakpoint is placed by an automated script (e.g lx-symbols), which does something in response to the breakpoint and then continues the guest automatically. If the script execution takes enough time for another interrupt to arrive, the guest will be stuck on the same breakpoint forever. * Normal single stepping is much more predictable, since it won't land the debugger into an interrupt handler. * Chances of RFLAGS.TF being leaked to the guest are reduced: KVM sets that flag behind the guest's back to single step it, but if the single step lands the vCPU into an interrupt/exception handler the RFLAGS.TF will be leaked to the guest in the form of being pushed to the stack. This doesn't completely eliminate this problem as exceptions can still happen, but at least this eliminates the common case. Signed-off-by: Maxim Levitsky --- Documentation/virt/kvm/api.rst | 1 + arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/x86.c | 4 ++++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 9778b2434c03..a4f2dc84741f 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -3338,6 +3338,7 @@ flags which can include the following: - 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] + - KVM_GUESTDBG_BLOCKIRQ: avoid injecting interrupts/NMI/SMI [x86] For example KVM_GUESTDBG_USE_SW_BP indicates that software breakpoints are enabled in memory so we need to ensure breakpoint exceptions are diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index cc7c82a449d5..8c529ae9dbbe 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -227,7 +227,8 @@ enum x86_intercept_stage; KVM_GUESTDBG_USE_HW_BP | \ KVM_GUESTDBG_USE_SW_BP | \ KVM_GUESTDBG_INJECT_BP | \ - KVM_GUESTDBG_INJECT_DB) + KVM_GUESTDBG_INJECT_DB | \ + KVM_GUESTDBG_BLOCKIRQ) #define PFERR_PRESENT_BIT 0 diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 5a3022c8af82..b0f9945067f7 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -282,6 +282,7 @@ struct kvm_debug_exit_arch { #define KVM_GUESTDBG_USE_HW_BP 0x00020000 #define KVM_GUESTDBG_INJECT_DB 0x00040000 #define KVM_GUESTDBG_INJECT_BP 0x00080000 +#define KVM_GUESTDBG_BLOCKIRQ 0x00100000 /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 956e8e0bd6af..3627ce8fe5bb 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8460,6 +8460,10 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit can_inject = false; } + /* Don't inject interrupts if the user asked to avoid doing so */ + if (vcpu->guest_debug & KVM_GUESTDBG_BLOCKIRQ) + return; + /* * Finally, inject interrupt events. If an event cannot be injected * due to architectural conditions (e.g. IF=0) a window-open exit