From nobody Sun Dec 22 03:11:59 2024 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2BA1C21C180 for ; Fri, 20 Dec 2024 22:51:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734735109; cv=none; b=kSxdahB2gFNsmp4umGnT4UKCd3pvi4roW9nxPitgoGbBsaRCzuWr0KfdtzmD4HVYaD5KdA8XWjzGWG1Vww16ZunyHSfbyw3MImkC944grgdHpHsnv+8zr2bc5q6WqAIZa1zFyaYDE4cFDWb5qI3YF8rrtZiJdDTlifuvQZOCg2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734735109; c=relaxed/simple; bh=RaiGn/bIx+gfWbcVAMLx/tuIFOXqPbm9JpaPY2AiNWM=; h=From:To:Cc:Subject:Date:Message-Id; b=BCMjkX7QlBza01Jgo7mmm8ujIpdxnXw2uqQjkI0mBsSRuKquGFnMofQsX5v/kdhGCQhHrg/BirUUmAAYXk9JaLTKO3qaopC9chf40KRUJcblubyKVSfjPDvF5AaHzhfsH0oh3K0kfqUVpm8uV164P74xDuxVBIqvrlpnFjnfkE4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=BXKnIzwb; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="BXKnIzwb" Received: from linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net (linux.microsoft.com [13.77.154.182]) by linux.microsoft.com (Postfix) with ESMTPSA id C75D62042985; Fri, 20 Dec 2024 14:51:47 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C75D62042985 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1734735107; bh=Fjdbo6CfaUmFp1fuerZnht5QwC6ZNLV+cs3c1Hgycww=; h=From:To:Cc:Subject:Date:From; b=BXKnIzwbJz6VY29ni6Xo25jgedHBQWInu53tMVPXNDlMQdc2RYr0O0/e+fEo9fuJa pztFp7CTYQbBiHHOmrIph51qy9L8tn16O6LMjmPWhoZkgBeELz8ouq2XnCSe5TxsjS Jrvgc2XHOlDlMtNdBS2IgRfRhufkSLVyED6T/pmI= From: Sonia Sharma 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:51:40 -0800 Message-Id: <1734735100-13342-1-git-send-email-sosha@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Sonia Sharma 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 --- 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 #include #include +#include #include #include =20 @@ -156,6 +157,8 @@ const struct vmbus_device vmbus_devs[] =3D { }; EXPORT_SYMBOL_GPL(vmbus_devs); =20 +static refcount_t singleton_vmbus_devs[HV_UNKNOWN + 1]; + static const struct { guid_t guid; } vmbus_unsupported_devs[] =3D { @@ -198,6 +201,25 @@ static bool is_unsupported_vmbus_devs(const guid_t *gu= id) return false; } =20 +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 =3D &channel->offermsg.offer.if_type; @@ -1004,6 +1026,26 @@ find_primary_channel_by_offer(const struct vmbus_cha= nnel_offer_channel *offer) return channel; } =20 +static u16 vmbus_is_valid_hvutil_offer(const struct vmbus_channel_offer_ch= annel *offer) +{ + const guid_t *guid =3D &offer->offer.if_type; + u16 i; + + if (is_hvsock_offer(offer)) + return HV_UNKNOWN; + + for (i =3D 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 =3D &offer->offer.if_type; @@ -1031,6 +1073,7 @@ static void vmbus_onoffer(struct vmbus_channel_messag= e_header *hdr) struct vmbus_channel_offer_channel *offer; struct vmbus_channel *oldchannel, *newchannel; size_t offer_sz; + u16 dev_type; =20 offer =3D (struct vmbus_channel_offer_channel *)hdr; =20 @@ -1115,11 +1158,29 @@ static void vmbus_onoffer(struct vmbus_channel_mess= age_header *hdr) return; } =20 + /* + * If vmbus_is_valid_offer() returns - + * HV_UNKNOWN - Subsequent offer received for hv_util dev, thus reject of= fer. + * 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 hibernati= on. + */ + dev_type =3D vmbus_is_valid_hvutil_offer(offer); + if (dev_type =3D=3D 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 =3D 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_channe= l_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_channe= l_message_header *hdr) */ dev =3D 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); } --=20 2.34.1