mshv_vp_create() publishes a VP pointer to pt_vp_array with a plain
store. The ISR reads this array locklessly from interrupt context on
other CPUs. Without memory ordering, a reader may observe the non-NULL
pointer before all VP fields (e.g. vp_register_page, run.vp_suspend_queue)
are fully initialized, leading to use of uninitialized data.

Fix by using smp_store_release() when publishing the VP pointer and
smp_load_acquire() on all lockless ISR read sites. This guarantees that
all VP initialization is visible to readers before the pointer itself.

Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose 
/dev/mshv to VMMs")
Signed-off-by: Stanislav Kinsburskii <[email protected]>
---
 drivers/hv/mshv_root_main.c |    3 ++-
 drivers/hv/mshv_synic.c     |    6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index 2b7d56e108bad..f01bd0877aef1 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -1224,7 +1224,8 @@ 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;
+       /* Ensure VP is fully initialized before visible to lockless ISR 
readers */
+       smp_store_release(&partition->pt_vp_array[args.vp_index], vp);
 
        goto out;
 
diff --git a/drivers/hv/mshv_synic.c b/drivers/hv/mshv_synic.c
index d4d98fa771189..5333b3889a408 100644
--- a/drivers/hv/mshv_synic.c
+++ b/drivers/hv/mshv_synic.c
@@ -244,7 +244,7 @@ handle_bitset_message(const struct 
hv_vp_signal_bitset_scheduler_message *msg)
                                goto unlock_out;
                        }
 
-                       vp = partition->pt_vp_array[vp_index];
+                       vp = 
smp_load_acquire(&partition->pt_vp_array[vp_index]);
                        if (unlikely(!vp)) {
                                pr_debug("failed to find VP %u\n", vp_index);
                                goto unlock_out;
@@ -293,7 +293,7 @@ handle_pair_message(const struct 
hv_vp_signal_pair_scheduler_message *msg)
                        break;
                }
 
-               vp = partition->pt_vp_array[vp_index];
+               vp = smp_load_acquire(&partition->pt_vp_array[vp_index]);
                if (!vp) {
                        pr_debug("failed to find VP %u\n", vp_index);
                        break;
@@ -388,7 +388,7 @@ mshv_intercept_isr(struct hv_message *msg)
                pr_debug("VP index %u out of bounds\n", vp_index);
                goto unlock_out;
        }
-       vp = partition->pt_vp_array[vp_index];
+       vp = smp_load_acquire(&partition->pt_vp_array[vp_index]);
        if (unlikely(!vp)) {
                pr_debug("failed to find VP %u\n", vp_index);
                goto unlock_out;



Reply via email to