From nobody Sun Dec 22 02:51:08 2024 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 45AA41A3BAD for ; Fri, 20 Dec 2024 22:46:08 +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=1734734772; cv=none; b=Bq3xSt7lkR5EV81BopvNSai9rpI6bL/loam9R4oLt4/CajzyMMUKvzF6/7girYxcyRa7mjPXgLxPpVa2lnhLQCgbb/7Pe7fRaI03zujLJWp0ojcokU3VnKKr6l8Jy0oJ3xu/EL78julijnPfi1byqHRvpwa2phKIEw/ytY0kyuE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734734772; c=relaxed/simple; bh=DWjINuPfmdN/zN+7B5g/Qondl4WMNeWw2r0hSXhaYVk=; h=From:To:Cc:Subject:Date:Message-Id; b=h9U/94+bvRLTjZ5uwN5juNLNDqLscdnSHnc6v/TiSSZFUO7iYvN7zafadqhF7o8DzyNUrMuhCULLnbxcvKwwp3vvlTPetvFUs3JjWkE3ughRAxDyhP1RES5e8wPENJRd+Xqcv+QqmlhzZP5J2YpayvWgjB8bi8KpPDKC45Gp1nI= 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=Lte+0I/G; 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="Lte+0I/G" Received: from linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net (linux.microsoft.com [13.77.154.182]) by linux.microsoft.com (Postfix) with ESMTPSA id 3BFC72042984; Fri, 20 Dec 2024 14:46:02 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 3BFC72042984 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1734734762; bh=h1VY9tqLC0N6Inu1LXIEzSuWL8nhLvGjrZ+P7JJj738=; h=From:To:Cc:Subject:Date:From; b=Lte+0I/GsSloZjlnFgQ2YhtYe1tRuvdheJyE3PIGvviq+Rwjb2Y/8NTqFaSPNTpqK y9PQX9BNCzCechJIZPz0t1qImJw0h03sYpGD0WP5grd9QzXPi48Vvpg+dcwNlHAmaT KZb9K348eL5Wz5IA5FYcwBORwwj2momk2RFBsRVM= 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:45:56 -0800 Message-Id: <1734734756-12551-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: Ubuntu 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