From patchwork Tue Jan 5 23:55:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ioanna Alifieraki X-Patchwork-Id: 1422751 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 4D9Trf3FK3z9sVs; Wed, 6 Jan 2021 10:55:14 +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 1kwwAR-0007au-DR; Tue, 05 Jan 2021 23:55:11 +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 1kwwAO-0007ZD-Nx for kernel-team@lists.ubuntu.com; Tue, 05 Jan 2021 23:55:08 +0000 Received: from mail-ed1-f71.google.com ([209.85.208.71]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kwwAO-0003Wg-Fa for kernel-team@lists.ubuntu.com; Tue, 05 Jan 2021 23:55:08 +0000 Received: by mail-ed1-f71.google.com with SMTP id dh21so997347edb.6 for ; Tue, 05 Jan 2021 15:55:08 -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=xGi6lnICXhnk6S6kpjLCbP19yrrKxvK9f3zsSy+wdTI=; b=LS1ELvcbg4gfu65gmNApa2n6kULRvVKyycAt+pk/C1FzMxd9GuBwCqO5ykF2ArJPim MxrYpukNUQSpNYCLn92fnTT2z21qe95yVKEUzotXed9luAJPj5s4Mgex0lhGHhsf0Nat /POtJWHEFNRq57VoGcXVluVIJmQdhTddOPIQfNs76jJnIT2lWlKEFP3qtVH4MEpbO1IL BXXvI49yqMuz60jUyl+dybNmQafnlnxIcaW6giAf38+xvv4fejiviIkyhcVjims4XlPI 9aFeXJ+w+Fn+P9svYi6DkBsCkXDN49+UgQWhnziMzGhSSD7Prplk6zScLMLUmuVJGNug EvFQ== X-Gm-Message-State: AOAM532bQNOL40xh50BZt5oq4GYITDmtIZCiTettdpnU8r38UeCyCCDl jCtx/cLVV0ke2N235oifpj50nXvqpgZPTpj+nrp9IdixNNmF0qdLlLWpSoyYIRZmajoNHqHeuz0 m97JOp6UMl3HbKGFj8z4yNKIt0gHja0L34UgoECB9Tw== X-Received: by 2002:a50:ac86:: with SMTP id x6mr2104686edc.197.1609890907993; Tue, 05 Jan 2021 15:55:07 -0800 (PST) X-Google-Smtp-Source: ABdhPJxOHwT3Rf/ba2ZFVPDk3oce9J3ywhZMQzyXM+Qrq6mKFdwxX7TorQX4omJrza+HC88UYP3xRA== X-Received: by 2002:a50:ac86:: with SMTP id x6mr2104677edc.197.1609890907785; Tue, 05 Jan 2021 15:55:07 -0800 (PST) Received: from localhost ([2001:67c:1560:8007::aac:c2e0]) by smtp.gmail.com with ESMTPSA id 35sm284915ede.0.2021.01.05.15.55.06 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 05 Jan 2021 15:55:07 -0800 (PST) From: Ioanna Alifieraki To: kernel-team@lists.ubuntu.com, ioanna-maria.alifieraki@canonical.com Subject: [SRU][XENIAL][PATCH v2 3/3] KVM: VMX: simplify and fix vmx_vcpu_pi_load Date: Tue, 5 Jan 2021 23:55:00 +0000 Message-Id: <20210105235500.20681-4-ioanna-maria.alifieraki@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210105235500.20681-1-ioanna-maria.alifieraki@canonical.com> References: <20210105235500.20681-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 e40ca7f5f346..421703d5ed02 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 (cmpxchg64(&pi_desc->control, old.control,