Linux-HyperV List
 help / color / mirror / Atom feed
From: Wei Liu <wei.liu@kernel.org>
To: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, longli@microsoft.com,
	linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 10/18] mshv: portid_table: Make mshv_portid_lookup() RCU-aware by contract
Date: Wed, 22 Jul 2026 16:46:37 -0700	[thread overview]
Message-ID: <20260722234637.GH2020652@liuwe-devbox-debian-v2.local> (raw)
In-Reply-To: <177816863447.21765.7284842709694944084.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>

On Thu, May 07, 2026 at 03:43:54PM +0000, Stanislav Kinsburskii wrote:
> mshv_portid_lookup() previously took rcu_read_lock() internally, ran
> idr_find(), released the read lock, and copied the struct contents
> into a caller-supplied buffer.  This had two problems.
> 
> 1. The struct copy ran outside the read section, racing with
>    mshv_portid_free() which does idr_remove + synchronize_rcu + kfree.
>    A copy that started just before synchronize_rcu() observed the read
>    section as already drained and was free to read freed memory while
>    the writer was kfree()'ing the entry.
> 
> 2. The only consumer, mshv_doorbell_isr(), then dispatched a callback
>    using fields of the snapshot — entirely outside any RCU read
>    section.  The callback's data argument and any field it touches
>    were therefore safe only because mshv_isr() runs from
>    sysvec_hyperv_callback, a non-threaded system vector that
>    synchronize_rcu() implicitly waits for via the hardirq quiescent-
>    state coupling.  That protection is real today but undocumented and
>    fragile: a future move of mshv_isr() to a threaded context, or a
>    future caller that registers a doorbell with a shorter-lived data
>    pointer, would silently expose a use-after-free.
> 
> Make the contract explicit instead of implicit.  mshv_portid_lookup()
> now returns a pointer to the table entry and requires the caller to
> hold rcu_read_lock for the entire lifetime of that pointer.  The
> contract is annotated with __must_hold(RCU) so sparse flags any
> direct caller that forgets it.  The sole caller, mshv_doorbell_isr(),
> takes rcu_read_lock around the whole drain loop, so the lookup, the
> field reads, and the doorbell_cb dispatch all run inside one
> read-side critical section.  synchronize_rcu() in mshv_portid_free()
> now genuinely waits for any in-flight callback before kfree() runs,
> without relying on hardirq context for correctness.
> 
> This also drops the by-value struct copy: entries are publish-once
> (populated before idr_alloc) and free-once (after synchronize_rcu),
> so a pointer dereferenced inside the read section gives a stable
> view of the contents without copying.
> 
> Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs")
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> ---
>  drivers/hv/mshv_portid_table.c |   22 +++++++---------------
>  drivers/hv/mshv_root.h         |    2 +-
>  drivers/hv/mshv_synic.c        |   15 +++++++++------
>  3 files changed, 17 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/hv/mshv_portid_table.c b/drivers/hv/mshv_portid_table.c
> index c349af1f0aaac..4cdf8e9575390 100644
> --- a/drivers/hv/mshv_portid_table.c
> +++ b/drivers/hv/mshv_portid_table.c
> @@ -64,20 +64,12 @@ mshv_portid_free(int port_id)
>  	kfree(info);
>  }
>  
> -int
> -mshv_portid_lookup(int port_id, struct port_table_info *info)
> +/*
> + * Caller must hold rcu_read_lock for the entire lifetime of the
> + * returned pointer.  Returns NULL if @port_id is not in the table.
> + */
> +struct port_table_info *mshv_portid_lookup(int port_id)
> +	__must_hold(RCU)
>  {
> -	struct port_table_info *_info;
> -	int ret = -ENOENT;
> -
> -	rcu_read_lock();
> -	_info = idr_find(&port_table_idr, port_id);
> -	rcu_read_unlock();
> -
> -	if (_info) {
> -		*info = *_info;
> -		ret = 0;
> -	}
> -
> -	return ret;
> +	return idr_find(&port_table_idr, port_id);
>  }

This is now a one line function. We can drop this function completely.

Wei

  parent reply	other threads:[~2026-07-22 23:46 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-07 15:42 [PATCH v4 00/18] mshv: Bug fixes across the mshv_root module Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 01/18] mshv: Fix IRQ leak and type hazards in hv_call_modify_spa_host_access Stanislav Kinsburskii
2026-05-11  3:46   ` Anirudh Rayabharam
2026-05-19 20:07   ` Michael Kelley
2026-05-07 15:43 ` [PATCH v4 02/18] mshv: Fix mshv_prepare_pinned_region error path for unencrypted partitions Stanislav Kinsburskii
2026-05-11 13:48   ` Anirudh Rayabharam
2026-05-11 15:06     ` Stanislav Kinsburskii
2026-05-13 11:15       ` Anirudh Rayabharam
2026-05-13 17:31         ` Stanislav Kinsburskii
2026-05-11 15:12     ` Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 03/18] mshv: Fix race in mshv_irqfd_deassign Stanislav Kinsburskii
2026-05-11 13:57   ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 04/18] mshv: Add NULL check for vp in mshv_try_assert_irq_fast Stanislav Kinsburskii
2026-05-11  3:24   ` Anirudh Rayabharam
2026-05-19 20:08   ` Michael Kelley
2026-05-07 15:43 ` [PATCH v4 05/18] mshv: irqfd: Reject routing updates that invalidate resampler binding Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 06/18] mshv: Fix broken seqcount read protection Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 07/18] mshv: Consolidate irqfd interrupt injection paths Stanislav Kinsburskii
2026-05-07 15:43 ` [PATCH v4 08/18] mshv: Fix level-triggered check on uninitialized data Stanislav Kinsburskii
2026-05-13 12:14   ` Anirudh Rayabharam
2026-05-13 17:38     ` Stanislav Kinsburskii
2026-05-14  5:49       ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 09/18] mshv: Fix duplicate GSI detection for GSI 0 Stanislav Kinsburskii
2026-05-13 11:36   ` Anirudh Rayabharam
2026-05-07 15:43 ` [PATCH v4 10/18] mshv: portid_table: Make mshv_portid_lookup() RCU-aware by contract Stanislav Kinsburskii
2026-05-13 11:20   ` Anirudh Rayabharam
2026-07-22 23:46   ` Wei Liu [this message]
2026-05-07 15:43 ` [PATCH v4 11/18] mshv: Fix sleeping under spinlock in mshv_portid_alloc Stanislav Kinsburskii
2026-05-11  3:33   ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 12/18] mshv: Use kfree_rcu in mshv_portid_free Stanislav Kinsburskii
2026-05-13 11:22   ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 13/18] mshv: Add missing vp_index bounds check in intercept ISR Stanislav Kinsburskii
2026-05-13  5:32   ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 14/18] mshv: Order pt_vp_array publish against irqfd assertion path Stanislav Kinsburskii
2026-05-13  9:57   ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 15/18] mshv: Defer mshv_vp free to an RCU grace period Stanislav Kinsburskii
2026-05-13 10:11   ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 16/18] mshv: Validate scheduler message bounds from hypervisor Stanislav Kinsburskii
2026-05-13 11:12   ` Anirudh Rayabharam
2026-05-13 17:39     ` Stanislav Kinsburskii
2026-05-14  5:49       ` Anirudh Rayabharam
2026-05-14 15:17         ` Stanislav Kinsburskii
2026-05-19 20:21   ` Michael Kelley
2026-05-07 15:44 ` [PATCH v4 17/18] mshv: Publish VP to pt_vp_array before installing the file descriptor Stanislav Kinsburskii
2026-05-11 14:26   ` Anirudh Rayabharam
2026-05-11 15:29     ` Stanislav Kinsburskii
2026-05-12 12:46       ` Anirudh Rayabharam
2026-05-07 15:44 ` [PATCH v4 18/18] mshv: Fix missing error code on VP allocation failure Stanislav Kinsburskii
2026-05-11  3:35   ` Anirudh Rayabharam

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=20260722234637.GH2020652@liuwe-devbox-debian-v2.local \
    --to=wei.liu@kernel.org \
    --cc=decui@microsoft.com \
    --cc=haiyangz@microsoft.com \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longli@microsoft.com \
    --cc=skinsburskii@linux.microsoft.com \
    /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