From patchwork Thu Jul 7 20:17:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Feiner X-Patchwork-Id: 9219605 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 6935160467 for ; Thu, 7 Jul 2016 20:19:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 56FE82851E for ; Thu, 7 Jul 2016 20:19:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 48A9F28521; Thu, 7 Jul 2016 20:19:05 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham 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 CE4952851E for ; Thu, 7 Jul 2016 20:19:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751595AbcGGURz (ORCPT ); Thu, 7 Jul 2016 16:17:55 -0400 Received: from mail-pf0-f175.google.com ([209.85.192.175]:34189 "EHLO mail-pf0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751233AbcGGURx (ORCPT ); Thu, 7 Jul 2016 16:17:53 -0400 Received: by mail-pf0-f175.google.com with SMTP id h14so8943222pfe.1 for ; Thu, 07 Jul 2016 13:17:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=+xDTGX80F+AYBYJZmQ3xFHsas5TUy/3DVS/XvqVMvjo=; b=K8bp4GlPBR+mIlVpRaz19gEjog7i/OcVu337rSukWYaapDcnHmG80XJsTB+AKQX5Xv an/GFqeyIP8A+boDXgI5jB9ClvAFbCpKcHLW779hf1c2DcNGmZxB/04fZ4pN2iXjUGEd Ii8O2UwZ8wSK0iB9a7p/ohexRRSoG6KJG+X1kakNU6vT0jvYoIAS3HuyEwhYf80vabhp BkHMdMgR3O3aadd5V592FCdIXHgz/5M0D2VGoCb5lB3F3YHzFyPddr8K9tV8JzvH0yde /tayABzZV2wn/Zb2oOTgOjKTeRevsxIz/aNTEtATmdEzwWsrQ2oEvAaPyHdO86MgMN0Q +GvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=+xDTGX80F+AYBYJZmQ3xFHsas5TUy/3DVS/XvqVMvjo=; b=iuRxvCoqm74RF/9S3WwHhWkLewWcDvYp/cmlqPyAl+zWLcK1lUOpbZJgcIlTBtZ12c /Z0CQgo2gg0knD1wxrxTmteYzuyD3EZZaNrkr0DmOkXtZCcVSQK1YdAz/0VnQSgfPd5l DXpDsDWYr28F2jOyDAJUSaVd264WrGFn0bpgRMEVofcSwbWFC4/tp8TKQbHQv4TmNZUy n58rtvn8h+vGvrV9nrEEk0qw18enGVQiniDjeoV7cZToBrQ4+6w+mEjXNWe0OfjQ31yA ubXf/bU4AL29FjGXBVgyVaUijgEid1JBez1YqM/zg1Gl02NoUID8+yUdyWo6CCGsBJr3 p05Q== X-Gm-Message-State: ALyK8tKhRM+NBhhHq8PLlZtqLA1iYvw5z/HU1FupqgVvsvvti1e7MqYVgVXJHIYiwH7QzjAg X-Received: by 10.98.50.1 with SMTP id y1mr3443084pfy.120.1467922645206; Thu, 07 Jul 2016 13:17:25 -0700 (PDT) Received: from localhost ([2620:0:1009:11:8488:fd7c:5461:e570]) by smtp.gmail.com with ESMTPSA id c68sm1667610pfk.11.2016.07.07.13.17.24 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Thu, 07 Jul 2016 13:17:24 -0700 (PDT) From: Peter Feiner To: kai.huang@linux.intel.com, guangrong.xiao@linux.intel.com, pbonzini@redhat.com Cc: dmatlack@google.com, jmattson@google.com, kvm@vger.kernel.org, Peter Feiner Subject: [PATCH] kvm: ensure VMCS is current while enabling PML Date: Thu, 7 Jul 2016 13:17:14 -0700 Message-Id: <5409fdb558e5cc0b5967bbdb831ea28a28107cc5.1467922428.git.pfeiner@google.com> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Between loading the new VMCS and enabling PML, the CPU was unpinned. If the vCPU thread were migrated to another CPU in the interim (e.g., due to preemption or sleeping alloc_page), then the VMWRITEs to enable PML would target the wrong VMCS -- or no VMCS at all: [ 2087.266950] vmwrite error: reg 200e value 3fe1d52000 (err -506126336) [ 2087.267062] vmwrite error: reg 812 value 1ff (err 511) [ 2087.267125] vmwrite error: reg 401e value 12229c00 (err 304258048) This patch ensures that the VMCS remains current while enabling PML by doing the VMWRITEs while the CPU is pinned. Allocation of the PML buffer is hoisted out of the critical section. Signed-off-by: Peter Feiner --- arch/x86/kvm/vmx.c | 50 ++++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 64a79f2..6d3a8d7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4876,6 +4876,7 @@ static void ept_set_mmio_spte_mask(void) } #define VMX_XSS_EXIT_BITMAP 0 + /* * Sets up the vmcs for emulated real mode. */ @@ -4979,6 +4980,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) if (vmx_xsaves_supported()) vmcs_write64(XSS_EXIT_BITMAP, VMX_XSS_EXIT_BITMAP); + if (enable_pml) { + ASSERT(vmx->pml_pg); + vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg)); + vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1); + } + return 0; } @@ -7937,22 +7944,6 @@ static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2) *info2 = vmcs_read32(VM_EXIT_INTR_INFO); } -static int vmx_create_pml_buffer(struct vcpu_vmx *vmx) -{ - struct page *pml_pg; - - pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (!pml_pg) - return -ENOMEM; - - vmx->pml_pg = pml_pg; - - vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg)); - vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1); - - return 0; -} - static void vmx_destroy_pml_buffer(struct vcpu_vmx *vmx) { if (vmx->pml_pg) { @@ -8881,6 +8872,19 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) vmx->vpid = allocate_vpid(); + /* + * If PML is turned on, failure on enabling PML just results in failure + * of creating the vcpu, therefore we can simplify PML logic (by + * avoiding dealing with cases, such as enabling PML partially on vcpus + * for the guest, etc. + */ + if (enable_pml) { + vmx->pml_pg = alloc_page(GFP_KERNEL | __GFP_ZERO); + err = -ENOMEM; + if (!vmx->pml_pg) + goto free_vcpu; + } + err = kvm_vcpu_init(&vmx->vcpu, kvm, id); if (err) goto free_vcpu; @@ -8936,18 +8940,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) vmx->nested.current_vmptr = -1ull; vmx->nested.current_vmcs12 = NULL; - /* - * If PML is turned on, failure on enabling PML just results in failure - * of creating the vcpu, therefore we can simplify PML logic (by - * avoiding dealing with cases, such as enabling PML partially on vcpus - * for the guest, etc. - */ - if (enable_pml) { - err = vmx_create_pml_buffer(vmx); - if (err) - goto free_vmcs; - } - return &vmx->vcpu; free_vmcs: @@ -8958,6 +8950,8 @@ free_msrs: uninit_vcpu: kvm_vcpu_uninit(&vmx->vcpu); free_vcpu: + if (vmx->pml_pg) + __free_page(vmx->pml_pg); free_vpid(vmx->vpid); kmem_cache_free(kvm_vcpu_cache, vmx); return ERR_PTR(err);