From: Chao Gao <chao.gao@intel.com>
To: xen-devel@lists.xen.org
Cc: Kevin Tian <kevin.tian@intel.com>, Feng Wu <feng.wu@intel.com>,
Jun Nakajima <jun.nakajima@intel.com>,
George Dunlap <George.Dunlap@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Dario Faggioli <dario.faggioli@citrix.com>,
Jan Beulich <jbeulich@suse.com>, Chao Gao <chao.gao@intel.com>
Subject: [PATCH v9 3/8] VMX: Properly handle pi when all the assigned devices are removed
Date: Mon, 27 Feb 2017 09:45:44 +0800 [thread overview]
Message-ID: <1488159949-15011-4-git-send-email-chao.gao@intel.com> (raw)
In-Reply-To: <1488159949-15011-1-git-send-email-chao.gao@intel.com>
From: Feng Wu <feng.wu@intel.com>
This patch handles some corner cases when the last assigned device
is removed from the domain. In this case we should carefully handle
pi descriptor and the per-cpu blocking list, to make sure:
- all the PI descriptor are in the right state when next time a
devices is assigned to the domain again.
- No remaining vcpus of the domain in the per-cpu blocking list.
Here we call vmx_pi_unblock_vcpu() to remove the vCPU from the blocking list
if it is on the list. However, this could happen when vmx_vcpu_block() is
being called, hence we might incorrectly add the vCPU to the blocking list
while the last devcie is detached from the domain. Consider that the situation
can only occur when detaching the last device from the domain and it is not
a frequent operation, so we use domain_pause before that, which is considered
as an clean and maintainable solution for the situation.
Signed-off-by: Feng Wu <feng.wu@intel.com>
Signed-off-by: Chao Gao <chao.gao@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v9:
- Based on [v8 2/7]. Add a assertion before domain pause.
v7:
- Prevent the domain from pausing itself.
v6:
- Comments changes
- Rename vmx_pi_list_remove() to vmx_pi_unblock_vcpu()
v5:
- Remove a no-op wrapper
v4:
- Rename some functions:
vmx_pi_remove_vcpu_from_blocking_list() -> vmx_pi_list_remove()
vmx_pi_blocking_cleanup() -> vmx_pi_list_cleanup()
- Remove the check in vmx_pi_list_cleanup()
- Comments adjustment
xen/arch/x86/hvm/vmx/vmx.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 5fa16dd..a7a70e7 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -155,14 +155,12 @@ static void vmx_pi_switch_to(struct vcpu *v)
pi_clear_sn(pi_desc);
}
-static void vmx_pi_do_resume(struct vcpu *v)
+static void vmx_pi_unblock_vcpu(struct vcpu *v)
{
unsigned long flags;
spinlock_t *pi_blocking_list_lock;
struct pi_desc *pi_desc = &v->arch.hvm_vmx.pi_desc;
- ASSERT(!test_bit(_VPF_blocked, &v->pause_flags));
-
/*
* Set 'NV' field back to posted_intr_vector, so the
* Posted-Interrupts can be delivered to the vCPU when
@@ -170,12 +168,12 @@ static void vmx_pi_do_resume(struct vcpu *v)
*/
write_atomic(&pi_desc->nv, posted_intr_vector);
- /* The vCPU is not on any blocking list. */
pi_blocking_list_lock = v->arch.hvm_vmx.pi_blocking.lock;
/* Prevent the compiler from eliminating the local variable.*/
smp_rmb();
+ /* The vCPU is not on any blocking list. */
if ( pi_blocking_list_lock == NULL )
return;
@@ -195,6 +193,13 @@ static void vmx_pi_do_resume(struct vcpu *v)
spin_unlock_irqrestore(pi_blocking_list_lock, flags);
}
+static void vmx_pi_do_resume(struct vcpu *v)
+{
+ ASSERT(!test_bit(_VPF_blocked, &v->pause_flags));
+
+ vmx_pi_unblock_vcpu(v);
+}
+
/*
* To handle posted interrupts correctly, we need to set the following
* state:
@@ -255,12 +260,23 @@ void vmx_pi_hooks_assign(struct domain *d)
/* This function is called when pcidevs_lock is held */
void vmx_pi_hooks_deassign(struct domain *d)
{
+ struct vcpu *v;
+
if ( !iommu_intpost || !has_hvm_container_domain(d) )
return;
ASSERT(d->arch.hvm_domain.pi_ops.vcpu_block);
/*
+ * Pausing the domain can make sure the vCPUs are not
+ * running and hence not calling the hooks simultaneously
+ * when deassigning the PI hooks and removing the vCPU
+ * from the blocking list.
+ */
+ ASSERT(current->domain != d);
+ domain_pause(d);
+
+ /*
* Note that we don't set 'd->arch.hvm_domain.pi_ops.switch_to' to NULL
* here. If we deassign the hooks while the vCPU is runnable in the
* runqueue with 'SN' set, all the future notification event will be
@@ -270,6 +286,11 @@ void vmx_pi_hooks_deassign(struct domain *d)
d->arch.hvm_domain.pi_ops.vcpu_block = NULL;
d->arch.hvm_domain.pi_ops.switch_from = NULL;
d->arch.hvm_domain.pi_ops.do_resume = NULL;
+
+ for_each_vcpu ( d, v )
+ vmx_pi_unblock_vcpu(v);
+
+ domain_unpause(d);
}
static int vmx_domain_initialise(struct domain *d)
--
1.8.3.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-02-27 1:45 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-27 1:45 [PATCH v9 0/8] VMX: Properly handle pi descriptor and per-cpu Chao Gao
2017-02-27 1:45 ` [PATCH v9 1/8] VMX: Permanently assign PI hook vmx_pi_switch_to() Chao Gao
2017-02-28 16:43 ` Jan Beulich
2017-03-01 0:01 ` Chao Gao
2017-03-01 7:41 ` Jan Beulich
2017-03-03 8:29 ` Tian, Kevin
2017-03-03 10:49 ` Jan Beulich
2017-03-03 11:54 ` Tian, Kevin
2017-02-27 1:45 ` [PATCH v9 2/8] xen/passthrough: Reject self-(de)assignment of devices Chao Gao
2017-02-28 16:46 ` Jan Beulich
2017-02-27 1:45 ` Chao Gao [this message]
2017-03-03 11:51 ` [PATCH v9 3/8] VMX: Properly handle pi when all the assigned devices are removed Tian, Kevin
2017-02-27 1:45 ` [PATCH v9 4/8] VMX: Make sure PI is in proper state before install the hooks Chao Gao
2017-02-27 1:45 ` [PATCH v9 5/8] VT-d: Introduce a new function update_irte_for_msi_common Chao Gao
2017-03-02 8:58 ` Jan Beulich
2017-03-02 7:14 ` Chao Gao
2017-03-02 14:32 ` Jan Beulich
2017-02-27 1:45 ` [PATCH v9 6/8] VT-d: Some cleanups Chao Gao
2017-02-27 1:45 ` [PATCH v9 7/8] VMX: Fixup PI descriptor when cpu is offline Chao Gao
2017-02-27 1:45 ` [PATCH v9 8/8] VT-d: Add copy_irte_{to, from}_irt for updating irte Chao Gao
2017-03-02 9:03 ` Jan Beulich
2017-03-15 10:38 ` Tian, Kevin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1488159949-15011-4-git-send-email-chao.gao@intel.com \
--to=chao.gao@intel.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=dario.faggioli@citrix.com \
--cc=feng.wu@intel.com \
--cc=jbeulich@suse.com \
--cc=jun.nakajima@intel.com \
--cc=kevin.tian@intel.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).