All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sonia Sharma <sosha@linux.microsoft.com>
To: linux-kernel@vger.kernel.org
Cc: sosha@microsoft.com
Subject: [PATCH] Drivers: hv: Allow single instance of hv_util device
Date: Fri, 20 Dec 2024 14:45:56 -0800	[thread overview]
Message-ID: <1734734756-12551-1-git-send-email-sosha@linux.microsoft.com> (raw)

From: Ubuntu <lisatest@lisa--591-e0-n0.keodsgad4ihuzdtqkyy1i1s3qg.cx.internal.cloudapp.net>

Harden hv_util type device drivers to allow single
instance of the device be configured at given time.

New function vmbus_is_valid_hvutil_offer() is added.
It checks if the new offer is for hv_util device type,
then read the refcount for that device and accept or
reject the offer accordingly.

Signed-off-by: Sonia Sharma <sonia.sharma@linux.microsoft.com>
---
 drivers/hv/channel_mgmt.c | 64 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 3c6011a48dab..1a135cfad81f 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/cpu.h>
 #include <linux/hyperv.h>
+#include <linux/refcount.h>
 #include <asm/mshyperv.h>
 #include <linux/sched/isolation.h>
 
@@ -156,6 +157,8 @@ const struct vmbus_device vmbus_devs[] = {
 };
 EXPORT_SYMBOL_GPL(vmbus_devs);
 
+static refcount_t singleton_vmbus_devs[HV_UNKNOWN + 1];
+
 static const struct {
 	guid_t guid;
 } vmbus_unsupported_devs[] = {
@@ -198,6 +201,25 @@ static bool is_unsupported_vmbus_devs(const guid_t *guid)
 	return false;
 }
 
+static bool is_dev_hv_util(u16 dev_type)
+{
+	switch (dev_type) {
+	case HV_SHUTDOWN:
+		fallthrough;
+	case HV_TS:
+		fallthrough;
+	case HV_HB:
+		fallthrough;
+	case HV_KVP:
+		fallthrough;
+	case HV_BACKUP:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
 static u16 hv_get_dev_type(const struct vmbus_channel *channel)
 {
 	const guid_t *guid = &channel->offermsg.offer.if_type;
@@ -1004,6 +1026,26 @@ find_primary_channel_by_offer(const struct vmbus_channel_offer_channel *offer)
 	return channel;
 }
 
+static u16 vmbus_is_valid_hvutil_offer(const struct vmbus_channel_offer_channel *offer)
+{
+	const guid_t *guid = &offer->offer.if_type;
+	u16 i;
+
+	if (is_hvsock_offer(offer))
+		return HV_UNKNOWN;
+
+	for (i = HV_IDE; i < HV_UNKNOWN; i++) {
+		if (guid_equal(guid, &vmbus_devs[i].guid) && is_dev_hv_util(i)) {
+			if (refcount_read(&singleton_vmbus_devs[i]))
+				return HV_UNKNOWN;
+			refcount_set(&singleton_vmbus_devs[i], 1);
+			return i;
+		}
+	}
+
+	return i;
+}
+
 static bool vmbus_is_valid_offer(const struct vmbus_channel_offer_channel *offer)
 {
 	const guid_t *guid = &offer->offer.if_type;
@@ -1031,6 +1073,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
 	struct vmbus_channel_offer_channel *offer;
 	struct vmbus_channel *oldchannel, *newchannel;
 	size_t offer_sz;
+	u16 dev_type;
 
 	offer = (struct vmbus_channel_offer_channel *)hdr;
 
@@ -1115,11 +1158,29 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
 		return;
 	}
 
+	/*
+	 * If vmbus_is_valid_offer() returns -
+	 *	HV_UNKNOWN - Subsequent offer received for hv_util dev, thus reject offer.
+	 *	HV_SHUTDOWN|HV_TS|HV_KVP|HV_HB|HV-KVP|HV_BACKUP - Increment refcount
+	 *	Others - Continue as is without doing anything.
+	 *
+	 * NOTE - We do not want to increase refcount if we resume from hibernation.
+	 */
+	dev_type = vmbus_is_valid_hvutil_offer(offer);
+	if (dev_type == HV_UNKNOWN) {
+		pr_err_ratelimited("Invalid hv_util offer %d from the host supporting "
+			"isolation\n", offer->child_relid);
+		atomic_dec(&vmbus_connection.offer_in_progress);
+		return;
+	}
+
 	/* Allocate the channel object and save this offer. */
 	newchannel = alloc_channel();
 	if (!newchannel) {
 		vmbus_release_relid(offer->child_relid);
 		atomic_dec(&vmbus_connection.offer_in_progress);
+		if (is_dev_hv_util(dev_type))
+			refcount_dec(&singleton_vmbus_devs[dev_type]);
 		pr_err("Unable to allocate channel object\n");
 		return;
 	}
@@ -1235,7 +1296,6 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 	/*
 	 * At this point, the rescind handling can proceed safely.
 	 */
-
 	if (channel->device_obj) {
 		if (channel->chn_rescind_callback) {
 			channel->chn_rescind_callback(channel);
@@ -1251,6 +1311,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 		 */
 		dev = get_device(&channel->device_obj->device);
 		if (dev) {
+			if (is_dev_hv_util(hv_get_dev_type(channel)))
+				refcount_dec(&singleton_vmbus_devs[hv_get_dev_type(channel)]);
 			vmbus_device_unregister(channel->device_obj);
 			put_device(dev);
 		}
-- 
2.34.1


             reply	other threads:[~2024-12-20 22:46 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-20 22:45 Sonia Sharma [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-12-20 22:51 [PATCH] Drivers: hv: Allow single instance of hv_util device Sonia Sharma

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=1734734756-12551-1-git-send-email-sosha@linux.microsoft.com \
    --to=sosha@linux.microsoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sosha@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.