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,