summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/hv/mshv_eventfd.c9
-rw-r--r--drivers/hv/mshv_root_main.c8
2 files changed, 15 insertions, 2 deletions
diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c
index 047e5bd43238..06aef99c8298 100644
--- a/drivers/hv/mshv_eventfd.c
+++ b/drivers/hv/mshv_eventfd.c
@@ -169,7 +169,14 @@ static int mshv_try_assert_irq_fast(struct mshv_irqfd *irqfd)
return -EOPNOTSUPP;
#endif
- vp = partition->pt_vp_array[irq->lapic_apic_id];
+ /*
+ * Pairs with smp_store_release() in mshv_partition_ioctl_create_vp().
+ * MSHV_IRQFD does not require the target lapic_apic_id to refer to an
+ * existing VP, so this read can race a concurrent VP creation; the
+ * acquire ensures that a non-NULL pointer implies the VP's
+ * initialising stores are visible.
+ */
+ vp = smp_load_acquire(&partition->pt_vp_array[irq->lapic_apic_id]);
if (!vp->vp_register_page)
return -EOPNOTSUPP;
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index 644f9b10cbba..8a15448e2ace 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -1157,7 +1157,13 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition,
/* already exclusive with the partition mutex for all ioctls */
partition->pt_vp_count++;
- partition->pt_vp_array[args.vp_index] = vp;
+ /*
+ * Pairs with smp_load_acquire() in mshv_try_assert_irq_fast(), which
+ * can run concurrently from an irqfd waker without holding pt_mutex.
+ * The release ensures the VP's initialising stores are visible to any
+ * reader that observes a non-NULL pointer in pt_vp_array.
+ */
+ smp_store_release(&partition->pt_vp_array[args.vp_index], vp);
goto out;