From patchwork Thu Sep 14 10:47:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Wanpeng Li X-Patchwork-Id: 9952783 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3EAC2602C9 for ; Thu, 14 Sep 2017 10:48:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2B78128E94 for ; Thu, 14 Sep 2017 10:48:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1F9A028E9F; Thu, 14 Sep 2017 10:48:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B675E28E94 for ; Thu, 14 Sep 2017 10:48:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752118AbdINKrx (ORCPT ); Thu, 14 Sep 2017 06:47:53 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:35812 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751833AbdINKrv (ORCPT ); Thu, 14 Sep 2017 06:47:51 -0400 Received: by mail-pf0-f193.google.com with SMTP id i23so1343681pfi.2; Thu, 14 Sep 2017 03:47:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=WCWRk84Rx9CZhxUhcM6EQQOJU/RYLYbhrmgNlFi6/X4=; b=XpUGxRs8C5efbs8t2T1tjp4y5zrftA+b2Lnx3j7s3wlI47R7TJQCQNqPZOPY0RGbR3 5ybMvqY18L1CQLH/k+lK0pyBcwwJpkP50RlG9K87o/1riXVdczaXVsmFEEPJnJTxrT/W cie0gWX1D7LLvvGnNUCG65HrbdS1iV8ADSCkd70VAn8ZDK0HxI2wxwWMee6yNuLkc270 oW+RWyMUfspLWzXmcAJfGhewcBfqBYB+h1FAKfUlS7uhB9CQFP5fnQKawyBnLqv0NevI rfa9ev4ZBAZht8EpGS2A5CGi2FlFt5yQAYeTXx2d1jmYOLFT+3OymMLfdJcrZtRCp5BQ FADw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=WCWRk84Rx9CZhxUhcM6EQQOJU/RYLYbhrmgNlFi6/X4=; b=aCdLfZITG1P+eiElLbtMEzqQyUE0d9ni8VxFTggbkq8BLWcdJBQkV8wT1D7gS/iwAP p/A3SvWmJW78giVtLrr3bzDzjNypGBl2Q4DUGnSR3566DVodZNGekThhxXA7X4SEN4rU azCu3bYGALKJzLsLKOk4hT3/pTtGa4TpplB4HzsVWFeVEaxzXJ7rIjmHiK9Mb1S3Hp4S wjUEtO1b+e2m0RLG0xkz8UnQ+4fPwZNRnk2sAWI1JclUPY2c6wArN6ugr4uzX6C4ZTOt 1Vms8c63pV+oboboeB115JE0T6Qc//QId6KLu8pL/f4ddBo2ivCn9p60dkG/antSNtxY W2yg== X-Gm-Message-State: AHPjjUi0+NGR4XEs0rzwI1oMc0D7zh+JLfJBBahu1QycttIc03EVVOfR kEuVhDJpbHxTkUln X-Google-Smtp-Source: AOwi7QCj8EJn/CmwuoC1+paC84CMebKJ5NjaOoaAvV/xjpvi3Hj+7uBUfGmnCFHZeffJSbdKniD+Qg== X-Received: by 10.159.246.5 with SMTP id b5mr1988866pls.109.1505386070867; Thu, 14 Sep 2017 03:47:50 -0700 (PDT) Received: from localhost ([203.205.141.123]) by smtp.gmail.com with ESMTPSA id u73sm19851551pfi.58.2017.09.14.03.47.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Sep 2017 03:47:50 -0700 (PDT) From: Wanpeng Li X-Google-Original-From: Wanpeng Li To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Wanpeng Li Subject: [PATCH] KVM: async_pf: Fix #DF due to inject "Page not Present" and "Page Ready" exceptions simultaneously Date: Thu, 14 Sep 2017 03:47:47 -0700 Message-Id: <1505386067-125995-1-git-send-email-wanpeng.li@hotmail.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wanpeng Li qemu-system-x86-8600 [004] d..1 7205.687530: kvm_entry: vcpu 2 qemu-system-x86-8600 [004] .... 7205.687532: kvm_exit: reason EXCEPTION_NMI rip 0xffffffffa921297d info ffffeb2c0e44e018 80000b0e qemu-system-x86-8600 [004] .... 7205.687532: kvm_page_fault: address ffffeb2c0e44e018 error_code 0 qemu-system-x86-8600 [004] .... 7205.687620: kvm_try_async_get_page: gva = 0xffffeb2c0e44e018, gfn = 0x427e4e qemu-system-x86-8600 [004] .N.. 7205.687628: kvm_async_pf_not_present: token 0x8b002 gva 0xffffeb2c0e44e018 kworker/4:2-7814 [004] .... 7205.687655: kvm_async_pf_completed: gva 0xffffeb2c0e44e018 address 0x7fcc30c4e000 qemu-system-x86-8600 [004] .... 7205.687703: kvm_async_pf_ready: token 0x8b002 gva 0xffffeb2c0e44e018 qemu-system-x86-8600 [004] d..1 7205.687711: kvm_entry: vcpu 2 After running some memory intensive workload in guest, I catch the kworker which completes the GUP too quickly, and queues an "Page Ready" #PF exception after the "Page not Present" exception before the next vmentry as the above trace which will result in #DF injected to guest. This patch fixes it by clearing the queue for "Page not Present" if "Page Ready" occurs before the next vmentry since the GUP has already got the required page and shadow page table has already been fixed by "Page Ready" handler. Cc: Paolo Bonzini Cc: Radim Krčmář Signed-off-by: Wanpeng Li --- arch/x86/kvm/x86.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6069af8..16c14c9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8619,6 +8619,13 @@ static int apf_put_user(struct kvm_vcpu *vcpu, u32 val) sizeof(val)); } +static int apf_get_user(struct kvm_vcpu *vcpu, u32 *val) +{ + + return kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apf.data, val, + sizeof(u32)); +} + void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) { @@ -8646,6 +8653,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) { struct x86_exception fault; + u32 val; if (work->wakeup_all) work->arch.token = ~0; /* broadcast wakeup */ @@ -8653,15 +8661,26 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, kvm_del_async_pf_gfn(vcpu, work->arch.gfn); trace_kvm_async_pf_ready(work->arch.token, work->gva); - if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) && - !apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) { - fault.vector = PF_VECTOR; - fault.error_code_valid = true; - fault.error_code = 0; - fault.nested_page_fault = false; - fault.address = work->arch.token; - fault.async_page_fault = true; - kvm_inject_page_fault(vcpu, &fault); + if (vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) { + if (!apf_get_user(vcpu, &val)) { + if (val == KVM_PV_REASON_PAGE_NOT_PRESENT && + vcpu->arch.exception.pending && + vcpu->arch.exception.nr == PF_VECTOR && + !apf_put_user(vcpu, 0)) { + vcpu->arch.exception.pending = false; + vcpu->arch.exception.nr = 0; + vcpu->arch.exception.has_error_code = false; + vcpu->arch.exception.error_code = 0; + } else if (!apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) { + fault.vector = PF_VECTOR; + fault.error_code_valid = true; + fault.error_code = 0; + fault.nested_page_fault = false; + fault.address = work->arch.token; + fault.async_page_fault = true; + kvm_inject_page_fault(vcpu, &fault); + } + } } vcpu->arch.apf.halted = false; vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;