From patchwork Wed Dec 16 19:41:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ioanna Alifieraki X-Patchwork-Id: 1417376 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cx59X5S6xz9sTg; Thu, 17 Dec 2020 06:41:52 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1kpcgH-00010p-Oy; Wed, 16 Dec 2020 19:41:49 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kpcgF-00010I-Ca for kernel-team@lists.ubuntu.com; Wed, 16 Dec 2020 19:41:47 +0000 Received: from mail-wm1-f69.google.com ([209.85.128.69]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kpcgF-00031d-35 for kernel-team@lists.ubuntu.com; Wed, 16 Dec 2020 19:41:47 +0000 Received: by mail-wm1-f69.google.com with SMTP id r1so2053645wmn.8 for ; Wed, 16 Dec 2020 11:41:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9DUC4p4njO4AIpQm2mHznoe4yYD/jGMdS6uiK1y8gpo=; b=CMhU+uJ5AUY70LNm8WwRJ+iH0WASl5YWxThg2NMmZ8HOaYyt6sDrvo3RhFtTAv4grb oDAJ0louUxuOCaLt4MY6+oBfoS89uR++N3bUHPjq7JjEu3KAKhflOtlNuBN44wrdbeN2 KTfO0gii4VSpv0U2fq/SvPf3PgEeFs/eGuS9jRW47DshStiOHBfpyiNU90lNyOMVZUWM /vyRxmd7ixGVGei66QzIPRuYidQJnbC/FFHAvN5Tgv2lUQUd8jlog44sAiJCv0hwnCPT K/KgeYfTbSLYR9eyRQ3haDNvbl98CaEJ9r8QEkOWfY5A8wOmttj9YpD5nu9FDUkWOVEs DL4Q== X-Gm-Message-State: AOAM5300HYKUo+5hgD7uvB+gkv5ThHYfJhDryDNPyKYdnxhX0T0qVGI2 alMBzWsTBZjIFGaMoEhBUKrPeHfrJ4uUv+Fsmartgk9/AaDdzxaHwCK7M325qdldf/y8CoKqbpb PsvGwhk2Hjz7nKD3Wc/nGnpaFKwA3WcyCoPkKRJgjzQ== X-Received: by 2002:a5d:6a83:: with SMTP id s3mr40667889wru.334.1608147706611; Wed, 16 Dec 2020 11:41:46 -0800 (PST) X-Google-Smtp-Source: ABdhPJz8fKaknXwvoLLD+1PKM2SwBhC5JA0a+5Jb4E0ZORN64fteLcVrmFDdZO4FY7DS7yP4+NERHg== X-Received: by 2002:a5d:6a83:: with SMTP id s3mr40667872wru.334.1608147706349; Wed, 16 Dec 2020 11:41:46 -0800 (PST) Received: from localhost ([2001:67c:1560:8007::aac:c2e0]) by smtp.gmail.com with ESMTPSA id k10sm4092778wrq.38.2020.12.16.11.41.45 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 16 Dec 2020 11:41:45 -0800 (PST) From: Ioanna Alifieraki To: kernel-team@lists.ubuntu.com Subject: [SRU][Xenial][PATCH 1/3] KVM: VMX: extract __pi_post_block Date: Wed, 16 Dec 2020 19:41:43 +0000 Message-Id: <20201216194145.24239-2-ioanna-maria.alifieraki@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201216194145.24239-1-ioanna-maria.alifieraki@canonical.com> References: <20201216194145.24239-1-ioanna-maria.alifieraki@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Paolo Bonzini BugLink: https://bugs.launchpad.net/bugs/1908428 Simple code movement patch, preparing for the next one. Cc: Huangweidong Cc: Gonglei Cc: wangxin Cc: Radim Krčmář Tested-by: Longpeng (Mike) Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini (backported from commit cd39e1176d320157831ce030b4c869bd2d5eb142) [hunk 2 : Original commit changes pi_post_block function. This function is not present in 4.4 kernel, see upstream commit bc22512bb24c(kvm: vmx: rename vmx_pre/post_block to pi_pre/post_block). Make relevant changes in vmx_post_block function.] Signed-off-by: Ioanna Alifieraki --- arch/x86/kvm/vmx.c | 71 +++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 46d1293baa04..472d089f0bd2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -11145,6 +11145,43 @@ static void vmx_enable_log_dirty_pt_masked(struct kvm *kvm, kvm_mmu_clear_dirty_pt_masked(kvm, memslot, offset, mask); } +static void __pi_post_block(struct kvm_vcpu *vcpu) +{ + struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); + struct pi_desc old, new; + unsigned int dest; + unsigned long flags; + + do { + old.control = new.control = pi_desc->control; + + dest = cpu_physical_id(vcpu->cpu); + + if (x2apic_enabled()) + new.ndst = dest; + else + new.ndst = (dest << 8) & 0xFF00; + + /* Allow posting non-urgent interrupts */ + new.sn = 0; + + /* set 'NV' to 'notification vector' */ + new.nv = POSTED_INTR_VECTOR; + } while (cmpxchg(&pi_desc->control, old.control, + new.control) != old.control); + + if(vcpu->pre_pcpu != -1) { + spin_lock_irqsave( + &per_cpu(blocked_vcpu_on_cpu_lock, + vcpu->pre_pcpu), flags); + list_del(&vcpu->blocked_vcpu_list); + spin_unlock_irqrestore( + &per_cpu(blocked_vcpu_on_cpu_lock, + vcpu->pre_pcpu), flags); + vcpu->pre_pcpu = -1; + } +} + /* * This routine does the following things for vCPU which is going * to be blocked if VT-d PI is enabled. @@ -11226,43 +11263,11 @@ static int vmx_pre_block(struct kvm_vcpu *vcpu) static void vmx_post_block(struct kvm_vcpu *vcpu) { - struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); - struct pi_desc old, new; - unsigned int dest; - unsigned long flags; - if (!kvm_arch_has_assigned_device(vcpu->kvm) || !irq_remapping_cap(IRQ_POSTING_CAP)) return; - do { - old.control = new.control = pi_desc->control; - - dest = cpu_physical_id(vcpu->cpu); - - if (x2apic_enabled()) - new.ndst = dest; - else - new.ndst = (dest << 8) & 0xFF00; - - /* Allow posting non-urgent interrupts */ - new.sn = 0; - - /* set 'NV' to 'notification vector' */ - new.nv = POSTED_INTR_VECTOR; - } while (cmpxchg64(&pi_desc->control, old.control, - new.control) != old.control); - - if(vcpu->pre_pcpu != -1) { - spin_lock_irqsave( - &per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); - list_del(&vcpu->blocked_vcpu_list); - spin_unlock_irqrestore( - &per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); - vcpu->pre_pcpu = -1; - } + __pi_post_block(vcpu); } /* From patchwork Wed Dec 16 19:41:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ioanna Alifieraki X-Patchwork-Id: 1417377 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cx59Z1Z4Bz9sVj; Thu, 17 Dec 2020 06:41:53 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1kpcgI-00011H-V0; Wed, 16 Dec 2020 19:41:50 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kpcgH-00010f-CI for kernel-team@lists.ubuntu.com; Wed, 16 Dec 2020 19:41:49 +0000 Received: from mail-wr1-f71.google.com ([209.85.221.71]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kpcgH-00031l-49 for kernel-team@lists.ubuntu.com; Wed, 16 Dec 2020 19:41:49 +0000 Received: by mail-wr1-f71.google.com with SMTP id w8so9895143wrv.18 for ; Wed, 16 Dec 2020 11:41:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sR+nw5PNGkroaYeF2Gj/W6i93vUO4jHEPFQ3vcU9lBs=; b=eFrT6SQRi5JJEtEPyHZrvwyWg9H/CTCOfyWQ8TdS1sVVePAeZmgJcVPX5U7SJEtHxP kRuU3QhxbZBIC23sERwoW4LbPx+bVnfE/s4nGhEzwiY7XkVgFk8rMR7fAOQN+LSkzddA BTNktcHi1FQ2wsKF6ZFAN8Ar+u8OR+W8yS7qRhcdZkEtyD8v/+/GeWKTwgKt5wB+kfZY 5CjdQCUiwWqgytSAa+xfRkGnFiJlBKLAtK8ZukiMrvw+TlrP0lz7Q+VpbgSDLoCBLnyB 5SVVwL0n2e2F3YoLNyPwNhkMFUmD1l8f28ySfFsIiP8mTUxXXhiFmPEaMNNr0iyMPiWh GoCQ== X-Gm-Message-State: AOAM530nA6HWM6poQ74KPtob3p7RhFoeUsYTALityLOMR/JaYqElvEhj Krvqzzw3P+O0LnMI/0f25HjqDXZQ4v1KjXH1WV81WQLYZBVXwoFsuFkwXa9Z2QaP28yGK58keW1 AduBIpjsCXiuRJQXF70z5ss7nkh+e4C5sn2WxD/Shmg== X-Received: by 2002:a5d:4ad0:: with SMTP id y16mr14218945wrs.424.1608147708627; Wed, 16 Dec 2020 11:41:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJyCGLe9yJXRLdWLXUyrewC+YbuOpeLe2fWpe6yNqhSLl5u6ALsVwDzOF21MgwLeO0LNu25aeQ== X-Received: by 2002:a5d:4ad0:: with SMTP id y16mr14218929wrs.424.1608147708350; Wed, 16 Dec 2020 11:41:48 -0800 (PST) Received: from localhost ([2001:67c:1560:8007::aac:c2e0]) by smtp.gmail.com with ESMTPSA id b7sm4276291wrv.47.2020.12.16.11.41.47 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 16 Dec 2020 11:41:47 -0800 (PST) From: Ioanna Alifieraki To: kernel-team@lists.ubuntu.com Subject: [SRU][Xenial][PATCH 2/3] KVM: VMX: avoid double list add with VT-d posted interrupts Date: Wed, 16 Dec 2020 19:41:44 +0000 Message-Id: <20201216194145.24239-3-ioanna-maria.alifieraki@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201216194145.24239-1-ioanna-maria.alifieraki@canonical.com> References: <20201216194145.24239-1-ioanna-maria.alifieraki@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Paolo Bonzini BugLink: https://bugs.launchpad.net/bugs/1908428 In some cases, for example involving hot-unplug of assigned devices, pi_post_block can forget to remove the vCPU from the blocked_vcpu_list. When this happens, the next call to pi_pre_block corrupts the list. Fix this in two ways. First, check vcpu->pre_pcpu in pi_pre_block and WARN instead of adding the element twice in the list. Second, always do the list removal in pi_post_block if vcpu->pre_pcpu is set (not -1). The new code keeps interrupts disabled for the whole duration of pi_pre_block/pi_post_block. This is not strictly necessary, but easier to follow. For the same reason, PI.ON is checked only after the cmpxchg, and to handle it we just call the post-block code. This removes duplication of the list removal code. Cc: Huangweidong Cc: Gonglei Cc: wangxin Cc: Radim Krčmář Tested-by: Longpeng (Mike) Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini (backported from commit 8b306e2f3c41939ea528e6174c88cfbfff893ce1) [hunk 4 and 5 : Original commit changes pi_pre_block function. This function is not present in 4.4 kernel, see upstream commit bc22512bb24c(kvm: vmx: rename vmx_pre/post_block to pi_pre/post_block). Make relevant changes in vmx_pre_block function.] Signed-off-by: Ioanna Alifieraki --- arch/x86/kvm/vmx.c | 65 +++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 472d089f0bd2..19589b1107b2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -11150,10 +11150,11 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); struct pi_desc old, new; unsigned int dest; - unsigned long flags; do { old.control = new.control = pi_desc->control; + WARN(old.nv != POSTED_INTR_WAKEUP_VECTOR, + "Wakeup handler not enabled while the VCPU is blocked\n"); dest = cpu_physical_id(vcpu->cpu); @@ -11170,14 +11171,10 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) } while (cmpxchg(&pi_desc->control, old.control, new.control) != old.control); - if(vcpu->pre_pcpu != -1) { - spin_lock_irqsave( - &per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); + if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); list_del(&vcpu->blocked_vcpu_list); - spin_unlock_irqrestore( - &per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); vcpu->pre_pcpu = -1; } } @@ -11197,7 +11194,6 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) */ static int vmx_pre_block(struct kvm_vcpu *vcpu) { - unsigned long flags; unsigned int dest; struct pi_desc old, new; struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); @@ -11206,34 +11202,20 @@ static int vmx_pre_block(struct kvm_vcpu *vcpu) !irq_remapping_cap(IRQ_POSTING_CAP)) return 0; - vcpu->pre_pcpu = vcpu->cpu; - spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); - list_add_tail(&vcpu->blocked_vcpu_list, - &per_cpu(blocked_vcpu_on_cpu, - vcpu->pre_pcpu)); - spin_unlock_irqrestore(&per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); + WARN_ON(irqs_disabled()); + local_irq_disable(); + if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { + vcpu->pre_pcpu = vcpu->cpu; + spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + list_add_tail(&vcpu->blocked_vcpu_list, + &per_cpu(blocked_vcpu_on_cpu, + vcpu->pre_pcpu)); + spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); + } do { old.control = new.control = pi_desc->control; - /* - * We should not block the vCPU if - * an interrupt is posted for it. - */ - if (pi_test_on(pi_desc) == 1) { - spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); - list_del(&vcpu->blocked_vcpu_list); - spin_unlock_irqrestore( - &per_cpu(blocked_vcpu_on_cpu_lock, - vcpu->pre_pcpu), flags); - vcpu->pre_pcpu = -1; - - return 1; - } - WARN((pi_desc->sn == 1), "Warning: SN field of posted-interrupts " "is set before blocking\n"); @@ -11255,19 +11237,26 @@ static int vmx_pre_block(struct kvm_vcpu *vcpu) /* set 'NV' to 'wakeup vector' */ new.nv = POSTED_INTR_WAKEUP_VECTOR; - } while (cmpxchg64(&pi_desc->control, old.control, - new.control) != old.control); + } while (cmpxchg(&pi_desc->control, old.control, + new.control) != old.control); - return 0; + /* We should not block the vCPU if an interrupt is posted for it. */ + if (pi_test_on(pi_desc) == 1) + __pi_post_block(vcpu); + + local_irq_enable(); + return (vcpu->pre_pcpu == -1); } static void vmx_post_block(struct kvm_vcpu *vcpu) { - if (!kvm_arch_has_assigned_device(vcpu->kvm) || - !irq_remapping_cap(IRQ_POSTING_CAP)) + if (vcpu->pre_pcpu == -1) return; + WARN_ON(irqs_disabled()); + local_irq_disable(); __pi_post_block(vcpu); + local_irq_enable(); } /* From patchwork Wed Dec 16 19:41:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ioanna Alifieraki X-Patchwork-Id: 1417378 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cx59f0nfZz9sT5; Thu, 17 Dec 2020 06:41:58 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1kpcgN-00013Z-B9; Wed, 16 Dec 2020 19:41:55 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kpcgJ-00011m-Es for kernel-team@lists.ubuntu.com; Wed, 16 Dec 2020 19:41:51 +0000 Received: from mail-wm1-f72.google.com ([209.85.128.72]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kpcgJ-00031w-6Q for kernel-team@lists.ubuntu.com; Wed, 16 Dec 2020 19:41:51 +0000 Received: by mail-wm1-f72.google.com with SMTP id r1so2053732wmn.8 for ; Wed, 16 Dec 2020 11:41:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ha0h4x0sruSk3ecpHKyEwUGkxnJKbvoiv1HgWARhFV0=; b=n6+jXVkkxx2mNT26wACMUowlHpdF4DYEg8v6+zXja6fFsRB7JjS5J0tbb/4dE2ZJBi 4ycMBtcbNa5N++c87X/V3G3AXmXY0txsw5nV/QxLhP57crVLqXWfu1Ja2Y1C6h76Zsk/ UNzLndpzid/ZAhNyI0d555GTJl8R5ypr5g/MmOTBHJ7B0sSqgD1IOxv6Ith6Kpgv+0RD 3vJu+2+/P+6iIZ2yuumnqeCb+IQK6e8VpUT9xfGItwWXqB7NUe7Z8G6JtvLEW1n23MEf oBx34xPACLjt0d8TC0UsVylhkteQP6BaCjb2cao9COLq4w2SdIPRhADbQe4yAMQU28qA 5szQ== X-Gm-Message-State: AOAM532sxCaipbi+HJ6jYzPzu0dpaBkdEzHehrIT7gdwmHEfLtjZ+TAB FMN/kjjhYoptJU7Dy6hystpYFGcb3oE8RsRGEE8yNuT1FRdoSuTrEjEmATleCooFiUYanRxam1O 0OgCqHVnouFe7/BzEgjocOUoxAvp3YvoDbeu/bTVonQ== X-Received: by 2002:a5d:6a05:: with SMTP id m5mr8525754wru.96.1608147710725; Wed, 16 Dec 2020 11:41:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJyJOwj4dTFGo37Teb5WTmUaMQRVOdaRuuMv6bBJWRk6rNOhvXjffpAyXx7Xm8Kv6Hm4V2U/qQ== X-Received: by 2002:a5d:6a05:: with SMTP id m5mr8525740wru.96.1608147710454; Wed, 16 Dec 2020 11:41:50 -0800 (PST) Received: from localhost ([2001:67c:1560:8007::aac:c2e0]) by smtp.gmail.com with ESMTPSA id q73sm4500202wme.44.2020.12.16.11.41.49 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 16 Dec 2020 11:41:50 -0800 (PST) From: Ioanna Alifieraki To: kernel-team@lists.ubuntu.com Subject: [SRU][Xenial][PATCH 3/3] KVM: VMX: simplify and fix vmx_vcpu_pi_load Date: Wed, 16 Dec 2020 19:41:45 +0000 Message-Id: <20201216194145.24239-4-ioanna-maria.alifieraki@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201216194145.24239-1-ioanna-maria.alifieraki@canonical.com> References: <20201216194145.24239-1-ioanna-maria.alifieraki@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Paolo Bonzini BugLink: https://bugs.launchpad.net/bugs/1908428 The simplify part: do not touch pi_desc.nv, we can set it when the VCPU is first created. Likewise, pi_desc.sn is only handled by vmx_vcpu_pi_load, do not touch it in __pi_post_block. The fix part: do not check kvm_arch_has_assigned_device, instead check the SN bit to figure out whether vmx_vcpu_pi_put ran before. This matches what the previous patch did in pi_post_block. Cc: Huangweidong Cc: Gonglei Cc: wangxin Cc: Radim Krčmář Tested-by: Longpeng (Mike) Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini (backported from commit 31afb2ea2b10a7d17ce3db4cdb0a12b63b2fe08a) [hunk 1 : resolve conflict on if-clause removed.] Signed-off-by: Ioanna Alifieraki --- arch/x86/kvm/vmx.c | 67 ++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 19589b1107b2..9acd1106ed6d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2235,42 +2235,41 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) struct pi_desc old, new; unsigned int dest; - if (!kvm_arch_has_assigned_device(vcpu->kvm) || - !irq_remapping_cap(IRQ_POSTING_CAP)) + /* + * In case of hot-plug or hot-unplug, we may have to undo + * vmx_vcpu_pi_put even if there is no assigned device. And we + * always keep PI.NDST up to date for simplicity: it makes the + * code easier, and CPU migration is not a fast path. + */ + if (!pi_test_sn(pi_desc) && vcpu->cpu == cpu) + return; + + /* + * First handle the simple case where no cmpxchg is necessary; just + * allow posting non-urgent interrupts. + * + * If the 'nv' field is POSTED_INTR_WAKEUP_VECTOR, do not change + * PI.NDST: pi_post_block will do it for us and the wakeup_handler + * expects the VCPU to be on the blocked_vcpu_list that matches + * PI.NDST. + */ + if (pi_desc->nv == POSTED_INTR_WAKEUP_VECTOR || + vcpu->cpu == cpu) { + pi_clear_sn(pi_desc); return; + } + /* The full case. */ do { old.control = new.control = pi_desc->control; - /* - * If 'nv' field is POSTED_INTR_WAKEUP_VECTOR, there - * are two possible cases: - * 1. After running 'pre_block', context switch - * happened. For this case, 'sn' was set in - * vmx_vcpu_put(), so we need to clear it here. - * 2. After running 'pre_block', we were blocked, - * and woken up by some other guy. For this case, - * we don't need to do anything, 'pi_post_block' - * will do everything for us. However, we cannot - * check whether it is case #1 or case #2 here - * (maybe, not needed), so we also clear sn here, - * I think it is not a big deal. - */ - if (pi_desc->nv != POSTED_INTR_WAKEUP_VECTOR) { - if (vcpu->cpu != cpu) { - dest = cpu_physical_id(cpu); - - if (x2apic_enabled()) - new.ndst = dest; - else - new.ndst = (dest << 8) & 0xFF00; - } + dest = cpu_physical_id(cpu); - /* set 'NV' to 'notification vector' */ - new.nv = POSTED_INTR_VECTOR; - } + if (x2apic_enabled()) + new.ndst = dest; + else + new.ndst = (dest << 8) & 0xFF00; - /* Allow posting non-urgent interrupts */ new.sn = 0; } while (cmpxchg64(&pi_desc->control, old.control, new.control) != old.control); @@ -9283,6 +9282,13 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) vmx->nested.current_vmptr = -1ull; vmx->nested.current_vmcs12 = NULL; + /* + * Enforce invariant: pi_desc.nv is always either POSTED_INTR_VECTOR + * or POSTED_INTR_WAKEUP_VECTOR. + */ + vmx->pi_desc.nv = POSTED_INTR_VECTOR; + vmx->pi_desc.sn = 1; + return &vmx->vcpu; free_vmcs: @@ -11163,9 +11169,6 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) else new.ndst = (dest << 8) & 0xFF00; - /* Allow posting non-urgent interrupts */ - new.sn = 0; - /* set 'NV' to 'notification vector' */ new.nv = POSTED_INTR_VECTOR; } while (cmpxchg(&pi_desc->control, old.control,