netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support
@ 2023-11-19 13:57 Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 1/7] net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity Wen Gu
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

The fourth edition of SMCv2 adds the SMC version 2.1 feature updates for
SMC-Dv2 with virtual ISM. Virtual ISM are created and supported mainly by
OS or hypervisor software, comparable to IBM ISM which is based on platform
firmware or hardware.

With the introduction of virtual ISM, SMCv2.1 makes some updates:

- Introduce feature bitmask to indicate supplemental features.
- Reserve a range of CHIDs for virtual ISM.
- Support extended GIDs (128 bits) in CLC handshake.

So this patch set aims to implement these updates in Linux kernel. And it
acts as the first part of the new version of [1].

[1] https://lore.kernel.org/netdev/1695568613-125057-1-git-send-email-guwen@linux.alibaba.com/

Wen Gu (7):
  net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity
  net/smc: support SMCv2.x supplemental features negotiation
  net/smc: introduce virtual ISM device support feature
  net/smc: define a reserved CHID range for virtual ISM devices
  net/smc: compatible with 128-bits extend GID of virtual ISM device
  net/smc: disable SEID on non-s390 archs where virtual ISM may be used
  net/smc: manage system EID in SMC stack instead of ISM driver

 drivers/s390/net/ism.h     |  6 ---
 drivers/s390/net/ism_drv.c | 54 +++++++--------------------
 include/linux/ism.h        |  1 -
 include/net/smc.h          | 16 +++++---
 net/smc/af_smc.c           | 68 ++++++++++++++++++++++++++-------
 net/smc/smc.h              |  7 ++++
 net/smc/smc_clc.c          | 93 ++++++++++++++++++++++++++++++++--------------
 net/smc/smc_clc.h          | 22 +++++++----
 net/smc/smc_core.c         | 30 ++++++++++-----
 net/smc/smc_core.h         |  8 ++--
 net/smc/smc_diag.c         |  7 +++-
 net/smc/smc_ism.c          | 57 ++++++++++++++++++++--------
 net/smc/smc_ism.h          | 31 +++++++++++++++-
 net/smc/smc_pnet.c         |  4 +-
 14 files changed, 269 insertions(+), 135 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH net-next 1/7] net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
@ 2023-11-19 13:57 ` Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 2/7] net/smc: support SMCv2.x supplemental features negotiation Wen Gu
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

Rename some smc_clc_first_contact_ext_v2x type variables to 'fce_v2x'
to distinguish them from smc_clc_first_contact_ext type variables.

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 net/smc/smc_clc.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index 8deb46c..f2f86c2 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -418,15 +418,15 @@ static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
 	return true;
 }
 
-static int smc_clc_fill_fce(struct smc_clc_first_contact_ext_v2x *fce,
+static int smc_clc_fill_fce(struct smc_clc_first_contact_ext_v2x *fce_v2x,
 			    struct smc_init_info *ini)
 {
-	int ret = sizeof(*fce);
+	int ret = sizeof(*fce_v2x);
 
-	memset(fce, 0, sizeof(*fce));
-	fce->fce_v2_base.os_type = SMC_CLC_OS_LINUX;
-	fce->fce_v2_base.release = ini->release_nr;
-	memcpy(fce->fce_v2_base.hostname, smc_hostname, sizeof(smc_hostname));
+	memset(fce_v2x, 0, sizeof(*fce_v2x));
+	fce_v2x->fce_v2_base.os_type = SMC_CLC_OS_LINUX;
+	fce_v2x->fce_v2_base.release = ini->release_nr;
+	memcpy(fce_v2x->fce_v2_base.hostname, smc_hostname, sizeof(smc_hostname));
 	if (ini->is_smcd && ini->release_nr < SMC_RELEASE_1) {
 		ret = sizeof(struct smc_clc_first_contact_ext);
 		goto out;
@@ -434,8 +434,8 @@ static int smc_clc_fill_fce(struct smc_clc_first_contact_ext_v2x *fce,
 
 	if (ini->release_nr >= SMC_RELEASE_1) {
 		if (!ini->is_smcd) {
-			fce->max_conns = ini->max_conns;
-			fce->max_links = ini->max_links;
+			fce_v2x->max_conns = ini->max_conns;
+			fce_v2x->max_links = ini->max_links;
 		}
 	}
 
@@ -1002,8 +1002,8 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
 				       int first_contact, u8 version,
 				       u8 *eid, struct smc_init_info *ini)
 {
+	struct smc_clc_first_contact_ext_v2x fce_v2x;
 	struct smc_connection *conn = &smc->conn;
-	struct smc_clc_first_contact_ext_v2x fce;
 	struct smc_clc_msg_accept_confirm *clc;
 	struct smc_clc_fce_gid_ext gle;
 	struct smc_clc_msg_trail trl;
@@ -1036,7 +1036,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
 				memcpy(clc_v2->d1.eid, eid, SMC_MAX_EID_LEN);
 			len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
 			if (first_contact) {
-				fce_len = smc_clc_fill_fce(&fce, ini);
+				fce_len = smc_clc_fill_fce(&fce_v2x, ini);
 				len += fce_len;
 			}
 			clc_v2->hdr.length = htons(len);
@@ -1082,9 +1082,9 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
 				memcpy(clc_v2->r1.eid, eid, SMC_MAX_EID_LEN);
 			len = SMCR_CLC_ACCEPT_CONFIRM_LEN_V2;
 			if (first_contact) {
-				fce_len = smc_clc_fill_fce(&fce, ini);
+				fce_len = smc_clc_fill_fce(&fce_v2x, ini);
 				len += fce_len;
-				fce.fce_v2_base.v2_direct = !link->lgr->uses_gateway;
+				fce_v2x.fce_v2_base.v2_direct = !link->lgr->uses_gateway;
 				if (clc->hdr.type == SMC_CLC_CONFIRM) {
 					memset(&gle, 0, sizeof(gle));
 					gle.gid_cnt = ini->smcrv2.gidlist.len;
@@ -1111,7 +1111,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
 						SMCR_CLC_ACCEPT_CONFIRM_LEN) -
 				   sizeof(trl);
 	if (version > SMC_V1 && first_contact) {
-		vec[i].iov_base = &fce;
+		vec[i].iov_base = &fce_v2x;
 		vec[i++].iov_len = fce_len;
 		if (!conn->lgr->is_smcd) {
 			if (clc->hdr.type == SMC_CLC_CONFIRM) {
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 2/7] net/smc: support SMCv2.x supplemental features negotiation
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 1/7] net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity Wen Gu
@ 2023-11-19 13:57 ` Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 3/7] net/smc: introduce virtual ISM device support feature Wen Gu
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

This patch adds SMCv2.x supplemental features negotiation. Supported
SMCv2.x supplemental features are represented by feature_mask in FCE
field. The negotiation process is as follows.

 Server                                        Client
            Proposal(features(c-mask bits))
      <-----------------------------------------
            Accept(features(s-mask bits))
      ----------------------------------------->
           Confirm(features(s&c-mask bits))
      <-----------------------------------------

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 net/smc/smc.h      |  4 ++++
 net/smc/smc_clc.c  |  7 +++++++
 net/smc/smc_clc.h  | 14 ++++++++++----
 net/smc/smc_core.h |  1 +
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/net/smc/smc.h b/net/smc/smc.h
index e377980..903b151 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -58,6 +58,10 @@ enum smc_state {		/* possible states of an SMC socket */
 	SMC_PROCESSABORT	= 27,
 };
 
+#define SMC_FEATURE_MASK	0	/* bitmask of
+					 * supported supplemental features
+					 */
+
 struct smc_link_group;
 
 struct smc_wr_rx_hdr {	/* common prefix part of LLC and CDC to demultiplex */
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index f2f86c2..254bdf2 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -437,6 +437,7 @@ static int smc_clc_fill_fce(struct smc_clc_first_contact_ext_v2x *fce_v2x,
 			fce_v2x->max_conns = ini->max_conns;
 			fce_v2x->max_links = ini->max_links;
 		}
+		fce_v2x->feature_mask = htons(ini->feature_mask);
 	}
 
 out:
@@ -906,6 +907,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 		pclc_smcd->v2_ext_offset = htons(v2_ext_offset);
 		plen += sizeof(*v2_ext);
 
+		v2_ext->feature_mask = htons(SMC_FEATURE_MASK);
 		read_lock(&smc_clc_eid_table.lock);
 		v2_ext->hdr.eid_cnt = smc_clc_eid_table.ueid_cnt;
 		plen += smc_clc_eid_table.ueid_cnt * SMC_MAX_EID_LEN;
@@ -1178,6 +1180,7 @@ int smc_clc_srv_v2x_features_validate(struct smc_clc_msg_proposal *pclc,
 
 	ini->max_conns = SMC_CONN_PER_LGR_MAX;
 	ini->max_links = SMC_LINKS_ADD_LNK_MAX;
+	ini->feature_mask = SMC_FEATURE_MASK;
 
 	if ((!(ini->smcd_version & SMC_V2) && !(ini->smcr_version & SMC_V2)) ||
 	    ini->release_nr < SMC_RELEASE_1)
@@ -1219,6 +1222,8 @@ int smc_clc_clnt_v2x_features_validate(struct smc_clc_first_contact_ext *fce,
 			return SMC_CLC_DECL_MAXLINKERR;
 		ini->max_links = fce_v2x->max_links;
 	}
+	/* common supplemental features of server and client */
+	ini->feature_mask = ntohs(fce_v2x->feature_mask) & SMC_FEATURE_MASK;
 
 	return 0;
 }
@@ -1249,6 +1254,8 @@ int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc,
 		if (fce_v2x->max_links != ini->max_links)
 			return SMC_CLC_DECL_MAXLINKERR;
 	}
+	/* common supplemental features returned by client */
+	ini->feature_mask = ntohs(fce_v2x->feature_mask);
 
 	return 0;
 }
diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h
index c5c8e7d..30da76d 100644
--- a/net/smc/smc_clc.h
+++ b/net/smc/smc_clc.h
@@ -138,7 +138,8 @@ struct smc_clc_v2_extension {
 	u8 roce[16];		/* RoCEv2 GID */
 	u8 max_conns;
 	u8 max_links;
-	u8 reserved[14];
+	__be16 feature_mask;
+	u8 reserved[12];
 	u8 user_eids[][SMC_MAX_EID_LEN];
 };
 
@@ -240,9 +241,14 @@ struct smc_clc_first_contact_ext {
 
 struct smc_clc_first_contact_ext_v2x {
 	struct smc_clc_first_contact_ext fce_v2_base;
-	u8 max_conns; /* for SMC-R only */
-	u8 max_links; /* for SMC-R only */
-	u8 reserved3[2];
+	union {
+		struct {
+			u8 max_conns; /* for SMC-R only */
+			u8 max_links; /* for SMC-R only */
+		};
+		u8 reserved3[2];	/* for SMC-D only */
+	};
+	__be16 feature_mask;
 	__be32 vendor_exp_options;
 	u8 reserved4[8];
 } __packed;		/* format defined in
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
index 120027d..9f65678 100644
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -401,6 +401,7 @@ struct smc_init_info {
 	u8			max_links;
 	u8			first_contact_peer;
 	u8			first_contact_local;
+	u16			feature_mask;
 	unsigned short		vlan_id;
 	u32			rc;
 	u8			negotiated_eid[SMC_MAX_EID_LEN];
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 3/7] net/smc: introduce virtual ISM device support feature
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 1/7] net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 2/7] net/smc: support SMCv2.x supplemental features negotiation Wen Gu
@ 2023-11-19 13:57 ` Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 4/7] net/smc: define a reserved CHID range for virtual ISM devices Wen Gu
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

This introduces virtual ISM device support feature to SMCv2.1 as the
first supplemental feature.

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 net/smc/af_smc.c | 2 ++
 net/smc/smc.h    | 9 ++++++---
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index da97f94..f145608 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1516,6 +1516,7 @@ static int __smc_connect(struct smc_sock *smc)
 	ini->smcr_version = SMC_V1 | SMC_V2;
 	ini->smc_type_v1 = SMC_TYPE_B;
 	ini->smc_type_v2 = SMC_TYPE_B;
+	ini->feature_mask = SMC_FEATURE_MASK;
 
 	/* get vlan id from IP device */
 	if (smc_vlan_by_tcpsk(smc->clcsock, ini)) {
@@ -1981,6 +1982,7 @@ static int smc_listen_v2_check(struct smc_sock *new_smc,
 	ini->smc_type_v2 = pclc->hdr.typev2;
 	ini->smcd_version = smcd_indicated(ini->smc_type_v1) ? SMC_V1 : 0;
 	ini->smcr_version = smcr_indicated(ini->smc_type_v1) ? SMC_V1 : 0;
+	ini->feature_mask = SMC_FEATURE_MASK;
 	if (pclc->hdr.version > SMC_V1) {
 		if (smcd_indicated(ini->smc_type_v2))
 			ini->smcd_version |= SMC_V2;
diff --git a/net/smc/smc.h b/net/smc/smc.h
index 903b151..9929d1e 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -58,9 +58,12 @@ enum smc_state {		/* possible states of an SMC socket */
 	SMC_PROCESSABORT	= 27,
 };
 
-#define SMC_FEATURE_MASK	0	/* bitmask of
-					 * supported supplemental features
-					 */
+enum smc_supplemental_features {
+	SMC_SPF_VIRT_ISM_DEV	= 0,
+};
+
+#define SMC_FEATURE_MASK \
+	(BIT(SMC_SPF_VIRT_ISM_DEV))
 
 struct smc_link_group;
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 4/7] net/smc: define a reserved CHID range for virtual ISM devices
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
                   ` (2 preceding siblings ...)
  2023-11-19 13:57 ` [PATCH net-next 3/7] net/smc: introduce virtual ISM device support feature Wen Gu
@ 2023-11-19 13:57 ` Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device Wen Gu
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

According to virtual ISM support feature defined by SMCv2.1, CHIDs in
the range 0xFF00 to 0xFFFF are reserved for use by virtual ISM devices.

And two helpers are introduced to distinguish virtual ISM devices from
the existing platform firmware ISM devices.

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 net/smc/smc_ism.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/net/smc/smc_ism.h b/net/smc/smc_ism.h
index 832b2f4..d1228a6 100644
--- a/net/smc/smc_ism.h
+++ b/net/smc/smc_ism.h
@@ -15,6 +15,8 @@
 
 #include "smc.h"
 
+#define SMC_VIRTUAL_ISM_CHID_MASK	0xFF00
+
 struct smcd_dev_list {	/* List of SMCD devices */
 	struct list_head list;
 	struct mutex mutex;	/* Protects list of devices */
@@ -56,4 +58,22 @@ static inline int smc_ism_write(struct smcd_dev *smcd, u64 dmb_tok,
 	return rc < 0 ? rc : 0;
 }
 
+static inline bool __smc_ism_is_virtual(u16 chid)
+{
+	/* CHIDs in range of 0xFF00 to 0xFFFF are reserved
+	 * for virtual ISM device.
+	 *
+	 * loopback-ism:	0xFFFF
+	 * virtio-ism:		0xFF00 ~ 0xFFFE
+	 */
+	return ((chid & 0xFF00) == 0xFF00);
+}
+
+static inline bool smc_ism_is_virtual(struct smcd_dev *smcd)
+{
+	u16 chid = smcd->ops->get_chid(smcd);
+
+	return __smc_ism_is_virtual(chid);
+}
+
 #endif
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
                   ` (3 preceding siblings ...)
  2023-11-19 13:57 ` [PATCH net-next 4/7] net/smc: define a reserved CHID range for virtual ISM devices Wen Gu
@ 2023-11-19 13:57 ` Wen Gu
  2023-11-20 19:17   ` Jakub Kicinski
  2023-11-22 19:07   ` Simon Horman
  2023-11-19 13:57 ` [PATCH net-next 6/7] net/smc: disable SEID on non-s390 archs where virtual ISM may be used Wen Gu
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

According to virtual ISM support feature defined by SMCv2.1, GIDs of
virtual ISM device are UUIDs defined by RFC4122, which are 128-bits
long. So some adaptation work is required. And note that the GIDs of
existing platform firmware ISM devices still remain 64-bits long.

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 drivers/s390/net/ism_drv.c | 18 +++++++------
 include/net/smc.h          | 15 +++++++----
 net/smc/af_smc.c           | 66 +++++++++++++++++++++++++++++++++++++---------
 net/smc/smc_clc.c          | 46 ++++++++++++++++++++++----------
 net/smc/smc_clc.h          |  8 +++---
 net/smc/smc_core.c         | 30 ++++++++++++++-------
 net/smc/smc_core.h         |  7 ++---
 net/smc/smc_diag.c         |  7 +++--
 net/smc/smc_ism.c          | 17 +++++++-----
 net/smc/smc_ism.h          |  3 ++-
 net/smc/smc_pnet.c         |  4 +--
 11 files changed, 153 insertions(+), 68 deletions(-)

diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index 6df7f37..54b865b 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -774,10 +774,10 @@ static void __exit ism_exit(void)
 /*************************** SMC-D Implementation *****************************/
 
 #if IS_ENABLED(CONFIG_SMC)
-static int smcd_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
-			   u32 vid)
+static int smcd_query_rgid(struct smcd_dev *smcd, struct smcd_gid *rgid,
+			   u32 vid_valid, u32 vid)
 {
-	return ism_query_rgid(smcd->priv, rgid, vid_valid, vid);
+	return ism_query_rgid(smcd->priv, rgid->gid, vid_valid, vid);
 }
 
 static int smcd_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb,
@@ -811,10 +811,10 @@ static int smcd_reset_vlan_required(struct smcd_dev *smcd)
 	return ism_cmd_simple(smcd->priv, ISM_RESET_VLAN);
 }
 
-static int smcd_signal_ieq(struct smcd_dev *smcd, u64 rgid, u32 trigger_irq,
-			   u32 event_code, u64 info)
+static int smcd_signal_ieq(struct smcd_dev *smcd, struct smcd_gid *rgid,
+			   u32 trigger_irq, u32 event_code, u64 info)
 {
-	return ism_signal_ieq(smcd->priv, rgid, trigger_irq, event_code, info);
+	return ism_signal_ieq(smcd->priv, rgid->gid, trigger_irq, event_code, info);
 }
 
 static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
@@ -830,9 +830,11 @@ static int smcd_supports_v2(void)
 		SYSTEM_EID.type[0] != '0';
 }
 
-static u64 smcd_get_local_gid(struct smcd_dev *smcd)
+static void smcd_get_local_gid(struct smcd_dev *smcd,
+			       struct smcd_gid *smcd_gid)
 {
-	return ism_get_local_gid(smcd->priv);
+	smcd_gid->gid = ism_get_local_gid(smcd->priv);
+	smcd_gid->gid_ext = 0;
 }
 
 static u16 smcd_get_chid(struct smcd_dev *smcd)
diff --git a/include/net/smc.h b/include/net/smc.h
index a002552..a0dc1187e 100644
--- a/include/net/smc.h
+++ b/include/net/smc.h
@@ -52,9 +52,14 @@ struct smcd_dmb {
 struct smcd_dev;
 struct ism_client;
 
+struct smcd_gid {
+	u64	gid;
+	u64	gid_ext;
+};
+
 struct smcd_ops {
-	int (*query_remote_gid)(struct smcd_dev *dev, u64 rgid, u32 vid_valid,
-				u32 vid);
+	int (*query_remote_gid)(struct smcd_dev *dev, struct smcd_gid *rgid,
+				u32 vid_valid, u32 vid);
 	int (*register_dmb)(struct smcd_dev *dev, struct smcd_dmb *dmb,
 			    struct ism_client *client);
 	int (*unregister_dmb)(struct smcd_dev *dev, struct smcd_dmb *dmb);
@@ -62,14 +67,14 @@ struct smcd_ops {
 	int (*del_vlan_id)(struct smcd_dev *dev, u64 vlan_id);
 	int (*set_vlan_required)(struct smcd_dev *dev);
 	int (*reset_vlan_required)(struct smcd_dev *dev);
-	int (*signal_event)(struct smcd_dev *dev, u64 rgid, u32 trigger_irq,
-			    u32 event_code, u64 info);
+	int (*signal_event)(struct smcd_dev *dev, struct smcd_gid *rgid,
+			    u32 trigger_irq, u32 event_code, u64 info);
 	int (*move_data)(struct smcd_dev *dev, u64 dmb_tok, unsigned int idx,
 			 bool sf, unsigned int offset, void *data,
 			 unsigned int size);
 	int (*supports_v2)(void);
 	u8* (*get_system_eid)(void);
-	u64 (*get_local_gid)(struct smcd_dev *dev);
+	void (*get_local_gid)(struct smcd_dev *dev, struct smcd_gid *gid);
 	u16 (*get_chid)(struct smcd_dev *dev);
 	struct device* (*get_dev)(struct smcd_dev *dev);
 };
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index f145608..0e55e8b 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -719,7 +719,7 @@ static void smcd_conn_save_peer_info(struct smc_sock *smc,
 	int bufsize = smc_uncompress_bufsize(clc->d0.dmbe_size);
 
 	smc->conn.peer_rmbe_idx = clc->d0.dmbe_idx;
-	smc->conn.peer_token = clc->d0.token;
+	smc->conn.peer_token = ntohll(clc->d0.token);
 	/* msg header takes up space in the buffer */
 	smc->conn.peer_rmbe_size = bufsize - sizeof(struct smcd_cdc_msg);
 	atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size);
@@ -1044,7 +1044,8 @@ static int smc_find_ism_v2_device_clnt(struct smc_sock *smc,
 {
 	int rc = SMC_CLC_DECL_NOSMCDDEV;
 	struct smcd_dev *smcd;
-	int i = 1;
+	int i = 1, entry = 1;
+	bool is_virtual;
 	u16 chid;
 
 	if (smcd_indicated(ini->smc_type_v1))
@@ -1056,14 +1057,23 @@ static int smc_find_ism_v2_device_clnt(struct smc_sock *smc,
 		chid = smc_ism_get_chid(smcd);
 		if (!smc_find_ism_v2_is_unique_chid(chid, ini, i))
 			continue;
+		is_virtual = __smc_ism_is_virtual(chid);
 		if (!smc_pnet_is_pnetid_set(smcd->pnetid) ||
 		    smc_pnet_is_ndev_pnetid(sock_net(&smc->sk), smcd->pnetid)) {
+			if (is_virtual && entry == SMC_MAX_ISM_DEVS)
+				/* only one GID-CHID entry left in CLC Proposal SMC-Dv2
+				 * extension. but a virtual ISM device's GID takes two
+				 * entries. So give up it and try the next potential ISM
+				 * device.
+				 */
+				continue;
 			ini->ism_dev[i] = smcd;
 			ini->ism_chid[i] = chid;
 			ini->is_smcd = true;
 			rc = 0;
 			i++;
-			if (i > SMC_MAX_ISM_DEVS)
+			entry = is_virtual ? entry + 2 : entry + 1;
+			if (entry > SMC_MAX_ISM_DEVS)
 				break;
 		}
 	}
@@ -1410,8 +1420,13 @@ static int smc_connect_ism(struct smc_sock *smc,
 		rc = smc_v2_determine_accepted_chid(aclc_v2, ini);
 		if (rc)
 			return rc;
+
+		if (__smc_ism_is_virtual(ini->ism_chid[ini->ism_selected]))
+			ini->ism_peer_gid[ini->ism_selected].gid_ext =
+						ntohll(aclc_v2->d1.gid_ext);
+		/* for non-virtual ISM devices, peer gid_ext remains 0. */
 	}
-	ini->ism_peer_gid[ini->ism_selected] = aclc->d0.gid;
+	ini->ism_peer_gid[ini->ism_selected].gid = ntohll(aclc->d0.gid);
 
 	/* there is only one lgr role for SMC-D; use server lock */
 	mutex_lock(&smc_server_lgr_pending);
@@ -2104,7 +2119,8 @@ static bool smc_is_already_selected(struct smcd_dev *smcd,
 
 /* check for ISM devices matching proposed ISM devices */
 static void smc_check_ism_v2_match(struct smc_init_info *ini,
-				   u16 proposed_chid, u64 proposed_gid,
+				   u16 proposed_chid,
+				   struct smcd_gid *proposed_gid,
 				   unsigned int *matches)
 {
 	struct smcd_dev *smcd;
@@ -2116,7 +2132,11 @@ static void smc_check_ism_v2_match(struct smc_init_info *ini,
 			continue;
 		if (smc_ism_get_chid(smcd) == proposed_chid &&
 		    !smc_ism_cantalk(proposed_gid, ISM_RESERVED_VLANID, smcd)) {
-			ini->ism_peer_gid[*matches] = proposed_gid;
+			ini->ism_peer_gid[*matches].gid = proposed_gid->gid;
+			if (__smc_ism_is_virtual(proposed_chid))
+				ini->ism_peer_gid[*matches].gid_ext =
+							proposed_gid->gid_ext;
+				/* non-virtual ISM's peer gid_ext remains 0. */
 			ini->ism_dev[*matches] = smcd;
 			(*matches)++;
 			break;
@@ -2138,9 +2158,11 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
 	struct smc_clc_v2_extension *smc_v2_ext;
 	struct smc_clc_msg_smcd *pclc_smcd;
 	unsigned int matches = 0;
+	struct smcd_gid smcd_gid;
 	u8 smcd_version;
 	u8 *eid = NULL;
 	int i, rc;
+	u16 chid;
 
 	if (!(ini->smcd_version & SMC_V2) || !smcd_indicated(ini->smc_type_v2))
 		goto not_found;
@@ -2150,18 +2172,35 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
 	smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext);
 
 	mutex_lock(&smcd_dev_list.mutex);
-	if (pclc_smcd->ism.chid)
+	if (pclc_smcd->ism.chid) {
 		/* check for ISM device matching proposed native ISM device */
+		smcd_gid.gid = ntohll(pclc_smcd->ism.gid);
+		smcd_gid.gid_ext = 0;
 		smc_check_ism_v2_match(ini, ntohs(pclc_smcd->ism.chid),
-				       ntohll(pclc_smcd->ism.gid), &matches);
+				       &smcd_gid, &matches);
+	}
 	for (i = 1; i <= smc_v2_ext->hdr.ism_gid_cnt; i++) {
 		/* check for ISM devices matching proposed non-native ISM
 		 * devices
 		 */
-		smc_check_ism_v2_match(ini,
-				       ntohs(smcd_v2_ext->gidchid[i - 1].chid),
-				       ntohll(smcd_v2_ext->gidchid[i - 1].gid),
-				       &matches);
+		smcd_gid.gid = ntohll(smcd_v2_ext->gidchid[i - 1].gid);
+		smcd_gid.gid_ext = 0;
+		chid = ntohs(smcd_v2_ext->gidchid[i - 1].chid);
+		if (__smc_ism_is_virtual(chid)) {
+			if (i == smc_v2_ext->hdr.ism_gid_cnt ||
+			    chid != ntohs(smcd_v2_ext->gidchid[i].chid))
+				/* a virtual ISM device takes two GID-CHID entries
+				 * and CHID of the second entry repeats that of the
+				 * first entry.
+				 *
+				 * So check if the second GID-CHID entry exists and
+				 * the CHIDs of these two entries are the same.
+				 */
+				continue;
+
+			smcd_gid.gid_ext = ntohll(smcd_v2_ext->gidchid[i++].gid);
+		}
+		smc_check_ism_v2_match(ini, chid, &smcd_gid, &matches);
 	}
 	mutex_unlock(&smcd_dev_list.mutex);
 
@@ -2210,7 +2249,8 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,
 	if (!(ini->smcd_version & SMC_V1) || !smcd_indicated(ini->smc_type_v1))
 		goto not_found;
 	ini->is_smcd = true; /* prepare ISM check */
-	ini->ism_peer_gid[0] = ntohll(pclc_smcd->ism.gid);
+	ini->ism_peer_gid[0].gid = ntohll(pclc_smcd->ism.gid);
+	ini->ism_peer_gid[0].gid_ext = 0;
 	rc = smc_find_ism_device(new_smc, ini);
 	if (rc)
 		goto not_found;
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index 254bdf2..92f1935 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -882,11 +882,13 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 		       ETH_ALEN);
 	}
 	if (smcd_indicated(ini->smc_type_v1)) {
+		struct smcd_gid smcd_gid;
+
 		/* add SMC-D specifics */
 		if (ini->ism_dev[0]) {
 			smcd = ini->ism_dev[0];
-			pclc_smcd->ism.gid =
-				htonll(smcd->ops->get_local_gid(smcd));
+			smcd->ops->get_local_gid(smcd, &smcd_gid);
+			pclc_smcd->ism.gid = htonll(smcd_gid.gid);
 			pclc_smcd->ism.chid =
 				htons(smc_ism_get_chid(ini->ism_dev[0]));
 		}
@@ -919,10 +921,11 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 		read_unlock(&smc_clc_eid_table.lock);
 	}
 	if (smcd_indicated(ini->smc_type_v2)) {
+		struct smcd_gid smcd_gid;
 		u8 *eid = NULL;
+		int entry = 0;
 
 		v2_ext->hdr.flag.seid = smc_clc_eid_table.seid_enabled;
-		v2_ext->hdr.ism_gid_cnt = ini->ism_offered_cnt;
 		v2_ext->hdr.smcd_v2_ext_offset = htons(sizeof(*v2_ext) -
 				offsetofend(struct smc_clnt_opts_area_hdr,
 					    smcd_v2_ext_offset) +
@@ -934,14 +937,24 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 		if (ini->ism_offered_cnt) {
 			for (i = 1; i <= ini->ism_offered_cnt; i++) {
 				smcd = ini->ism_dev[i];
-				gidchids[i - 1].gid =
-					htonll(smcd->ops->get_local_gid(smcd));
-				gidchids[i - 1].chid =
+				smcd->ops->get_local_gid(smcd, &smcd_gid);
+				gidchids[entry].chid =
 					htons(smc_ism_get_chid(ini->ism_dev[i]));
+				gidchids[entry].gid = htonll(smcd_gid.gid);
+				if (__smc_ism_is_virtual(gidchids[entry].chid)) {
+					/* a virtual ISM device takes two entries.
+					 * CHID of the second entry repeats that of the
+					 * first entry.
+					 */
+					gidchids[entry + 1].chid = gidchids[entry].chid;
+					gidchids[entry + 1].gid = htonll(smcd_gid.gid_ext);
+					entry++;
+				}
+				entry++;
 			}
-			plen += ini->ism_offered_cnt *
-				sizeof(struct smc_clc_smcd_gid_chid);
+			plen += entry * sizeof(struct smc_clc_smcd_gid_chid);
 		}
+		v2_ext->hdr.ism_gid_cnt = entry;
 	}
 	if (smcr_indicated(ini->smc_type_v2)) {
 		memcpy(v2_ext->roce, ini->smcrv2.ib_gid_v2, SMC_GID_SIZE);
@@ -977,7 +990,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 			vec[i++].iov_len = sizeof(*smcd_v2_ext);
 			if (ini->ism_offered_cnt) {
 				vec[i].iov_base = gidchids;
-				vec[i++].iov_len = ini->ism_offered_cnt *
+				vec[i++].iov_len = v2_ext->hdr.ism_gid_cnt *
 					sizeof(struct smc_clc_smcd_gid_chid);
 			}
 		}
@@ -1019,23 +1032,28 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
 	if (first_contact)
 		clc->hdr.typev2 |= SMC_FIRST_CONTACT_MASK;
 	if (conn->lgr->is_smcd) {
+		struct smcd_gid smcd_gid;
+		u16 chid;
+
 		/* SMC-D specific settings */
 		memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
 		       sizeof(SMCD_EYECATCHER));
+		conn->lgr->smcd->ops->get_local_gid(conn->lgr->smcd, &smcd_gid);
 		clc->hdr.typev1 = SMC_TYPE_D;
-		clc->d0.gid =
-			conn->lgr->smcd->ops->get_local_gid(conn->lgr->smcd);
-		clc->d0.token = conn->rmb_desc->token;
+		clc->d0.gid = htonll(smcd_gid.gid);
+		clc->d0.token = htonll(conn->rmb_desc->token);
 		clc->d0.dmbe_size = conn->rmbe_size_comp;
 		clc->d0.dmbe_idx = 0;
 		memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
 		if (version == SMC_V1) {
 			clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
 		} else {
-			clc_v2->d1.chid =
-				htons(smc_ism_get_chid(conn->lgr->smcd));
+			chid = smc_ism_get_chid(conn->lgr->smcd);
+			clc_v2->d1.chid = htons(chid);
 			if (eid && eid[0])
 				memcpy(clc_v2->d1.eid, eid, SMC_MAX_EID_LEN);
+			if (__smc_ism_is_virtual(chid))
+				clc_v2->d1.gid_ext = htonll(smcd_gid.gid_ext);
 			len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
 			if (first_contact) {
 				fce_len = smc_clc_fill_fce(&fce_v2x, ini);
diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h
index 30da76d..51d4480 100644
--- a/net/smc/smc_clc.h
+++ b/net/smc/smc_clc.h
@@ -205,8 +205,8 @@ struct smcr_clc_msg_accept_confirm {	/* SMCR accept/confirm */
 } __packed;
 
 struct smcd_clc_msg_accept_confirm_common {	/* SMCD accept/confirm */
-	u64 gid;		/* Sender GID */
-	u64 token;		/* DMB token */
+	__be64 gid;		/* Sender GID */
+	__be64 token;		/* DMB token */
 	u8 dmbe_idx;		/* DMBE index */
 #if defined(__BIG_ENDIAN_BITFIELD)
 	u8 dmbe_size : 4,	/* buf size (compressed) */
@@ -285,8 +285,8 @@ struct smc_clc_msg_accept_confirm_v2 {	/* clc accept / confirm message */
 			struct smcd_clc_msg_accept_confirm_common d0;
 			__be16 chid;
 			u8 eid[SMC_MAX_EID_LEN];
-			u8 reserved5[8];
-		} d1;
+			__be64 gid_ext;
+		} __packed d1;
 	};
 };
 
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index d520ee6..6b33f2a 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -506,6 +506,7 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,
 {
 	char smc_pnet[SMC_MAX_PNETID_LEN + 1];
 	struct smcd_dev *smcd = lgr->smcd;
+	struct smcd_gid smcd_gid;
 	struct nlattr *attrs;
 	void *nlh;
 
@@ -521,11 +522,11 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,
 
 	if (nla_put_u32(skb, SMC_NLA_LGR_D_ID, *((u32 *)&lgr->id)))
 		goto errattr;
+	smcd->ops->get_local_gid(smcd, &smcd_gid);
 	if (nla_put_u64_64bit(skb, SMC_NLA_LGR_D_GID,
-			      smcd->ops->get_local_gid(smcd),
-				  SMC_NLA_LGR_D_PAD))
+			      smcd_gid.gid, SMC_NLA_LGR_D_PAD))
 		goto errattr;
-	if (nla_put_u64_64bit(skb, SMC_NLA_LGR_D_PEER_GID, lgr->peer_gid,
+	if (nla_put_u64_64bit(skb, SMC_NLA_LGR_D_PEER_GID, lgr->peer_gid.gid,
 			      SMC_NLA_LGR_D_PAD))
 		goto errattr;
 	if (nla_put_u8(skb, SMC_NLA_LGR_D_VLAN_ID, lgr->vlan_id))
@@ -876,7 +877,10 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
 		/* SMC-D specific settings */
 		smcd = ini->ism_dev[ini->ism_selected];
 		get_device(smcd->ops->get_dev(smcd));
-		lgr->peer_gid = ini->ism_peer_gid[ini->ism_selected];
+		lgr->peer_gid.gid =
+			ini->ism_peer_gid[ini->ism_selected].gid;
+		lgr->peer_gid.gid_ext =
+			ini->ism_peer_gid[ini->ism_selected].gid_ext;
 		lgr->smcd = ini->ism_dev[ini->ism_selected];
 		lgr_list = &ini->ism_dev[ini->ism_selected]->lgr_list;
 		lgr_lock = &lgr->smcd->lgr_lock;
@@ -1514,7 +1518,8 @@ void smc_lgr_terminate_sched(struct smc_link_group *lgr)
 }
 
 /* Called when peer lgr shutdown (regularly or abnormally) is received */
-void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan)
+void smc_smcd_terminate(struct smcd_dev *dev, struct smcd_gid *peer_gid,
+			unsigned short vlan)
 {
 	struct smc_link_group *lgr, *l;
 	LIST_HEAD(lgr_free_list);
@@ -1522,7 +1527,10 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan)
 	/* run common cleanup function and build free list */
 	spin_lock_bh(&dev->lgr_lock);
 	list_for_each_entry_safe(lgr, l, &dev->lgr_list, list) {
-		if ((!peer_gid || lgr->peer_gid == peer_gid) &&
+		if ((!peer_gid->gid ||
+		     (lgr->peer_gid.gid == peer_gid->gid &&
+		      !smc_ism_is_virtual(dev) ? 1 :
+		      lgr->peer_gid.gid_ext == peer_gid->gid_ext)) &&
 		    (vlan == VLAN_VID_MASK || lgr->vlan_id == vlan)) {
 			if (peer_gid) /* peer triggered termination */
 				lgr->peer_shutdown = 1;
@@ -1859,10 +1867,12 @@ static bool smcr_lgr_match(struct smc_link_group *lgr, u8 smcr_version,
 	return false;
 }
 
-static bool smcd_lgr_match(struct smc_link_group *lgr,
-			   struct smcd_dev *smcismdev, u64 peer_gid)
+static bool smcd_lgr_match(struct smc_link_group *lgr, struct smcd_dev *smcismdev,
+			   struct smcd_gid *peer_gid)
 {
-	return lgr->peer_gid == peer_gid && lgr->smcd == smcismdev;
+	return lgr->peer_gid.gid == peer_gid->gid && lgr->smcd == smcismdev &&
+		smc_ism_is_virtual(smcismdev) ?
+		(lgr->peer_gid.gid_ext == peer_gid->gid_ext) : 1;
 }
 
 /* create a new SMC connection (and a new link group if necessary) */
@@ -1892,7 +1902,7 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
 		write_lock_bh(&lgr->conns_lock);
 		if ((ini->is_smcd ?
 		     smcd_lgr_match(lgr, ini->ism_dev[ini->ism_selected],
-				    ini->ism_peer_gid[ini->ism_selected]) :
+				    &ini->ism_peer_gid[ini->ism_selected]) :
 		     smcr_lgr_match(lgr, ini->smcr_version,
 				    ini->peer_systemid,
 				    ini->peer_gid, ini->peer_mac, role,
diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
index 9f65678..d57eb9b 100644
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -17,6 +17,7 @@
 #include <linux/pci.h>
 #include <rdma/ib_verbs.h>
 #include <net/genetlink.h>
+#include <net/smc.h>
 
 #include "smc.h"
 #include "smc_ib.h"
@@ -355,7 +356,7 @@ struct smc_link_group {
 						/* max links can be added in lgr */
 		};
 		struct { /* SMC-D */
-			u64			peer_gid;
+			struct smcd_gid		peer_gid;
 						/* Peer GID (remote) */
 			struct smcd_dev		*smcd;
 						/* ISM device for VLAN reg. */
@@ -417,7 +418,7 @@ struct smc_init_info {
 	u32			ib_clcqpn;
 	struct smc_init_info_smcrv2 smcrv2;
 	/* SMC-D */
-	u64			ism_peer_gid[SMC_MAX_ISM_DEVS + 1];
+	struct smcd_gid		ism_peer_gid[SMC_MAX_ISM_DEVS + 1];
 	struct smcd_dev		*ism_dev[SMC_MAX_ISM_DEVS + 1];
 	u16			ism_chid[SMC_MAX_ISM_DEVS + 1];
 	u8			ism_offered_cnt; /* # of ISM devices offered */
@@ -545,7 +546,7 @@ static inline void smc_set_pci_values(struct pci_dev *pci_dev,
 void smc_lgr_put(struct smc_link_group *lgr);
 void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport);
 void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport);
-void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid,
+void smc_smcd_terminate(struct smcd_dev *dev, struct smcd_gid *peer_gid,
 			unsigned short vlan);
 void smc_smcd_terminate_all(struct smcd_dev *dev);
 void smc_smcr_terminate_all(struct smc_ib_device *smcibdev);
diff --git a/net/smc/smc_diag.c b/net/smc/smc_diag.c
index 7ff2152..3c68b8c 100644
--- a/net/smc/smc_diag.c
+++ b/net/smc/smc_diag.c
@@ -21,6 +21,7 @@
 
 #include "smc.h"
 #include "smc_core.h"
+#include "smc_ism.h"
 
 struct smc_diag_dump_ctx {
 	int pos[2];
@@ -168,12 +169,14 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
 		struct smc_connection *conn = &smc->conn;
 		struct smcd_diag_dmbinfo dinfo;
 		struct smcd_dev *smcd = conn->lgr->smcd;
+		struct smcd_gid smcd_gid;
 
 		memset(&dinfo, 0, sizeof(dinfo));
 
 		dinfo.linkid = *((u32 *)conn->lgr->id);
-		dinfo.peer_gid = conn->lgr->peer_gid;
-		dinfo.my_gid = smcd->ops->get_local_gid(smcd);
+		dinfo.peer_gid = conn->lgr->peer_gid.gid;
+		smcd->ops->get_local_gid(smcd, &smcd_gid);
+		dinfo.my_gid = smcd_gid.gid;
 		dinfo.token = conn->rmb_desc->token;
 		dinfo.peer_token = conn->peer_token;
 
diff --git a/net/smc/smc_ism.c b/net/smc/smc_ism.c
index fbee249..a33f861 100644
--- a/net/smc/smc_ism.c
+++ b/net/smc/smc_ism.c
@@ -44,7 +44,8 @@ static void smcd_handle_irq(struct ism_dev *ism, unsigned int dmbno,
 #endif
 
 /* Test if an ISM communication is possible - same CPC */
-int smc_ism_cantalk(u64 peer_gid, unsigned short vlan_id, struct smcd_dev *smcd)
+int smc_ism_cantalk(struct smcd_gid *peer_gid, unsigned short vlan_id,
+		    struct smcd_dev *smcd)
 {
 	return smcd->ops->query_remote_gid(smcd, peer_gid, vlan_id ? 1 : 0,
 					   vlan_id);
@@ -208,7 +209,7 @@ int smc_ism_register_dmb(struct smc_link_group *lgr, int dmb_len,
 	dmb.dmb_len = dmb_len;
 	dmb.sba_idx = dmb_desc->sba_idx;
 	dmb.vlan_id = lgr->vlan_id;
-	dmb.rgid = lgr->peer_gid;
+	dmb.rgid = lgr->peer_gid.gid;
 	rc = lgr->smcd->ops->register_dmb(lgr->smcd, &dmb, &smc_ism_client);
 	if (!rc) {
 		dmb_desc->sba_idx = dmb.sba_idx;
@@ -340,18 +341,20 @@ struct smc_ism_event_work {
 
 static void smcd_handle_sw_event(struct smc_ism_event_work *wrk)
 {
+	struct smcd_gid peer_gid = { .gid = wrk->event.tok,
+				     .gid_ext = 0 };
 	union smcd_sw_event_info ev_info;
 
 	ev_info.info = wrk->event.info;
 	switch (wrk->event.code) {
 	case ISM_EVENT_CODE_SHUTDOWN:	/* Peer shut down DMBs */
-		smc_smcd_terminate(wrk->smcd, wrk->event.tok, ev_info.vlan_id);
+		smc_smcd_terminate(wrk->smcd, &peer_gid, ev_info.vlan_id);
 		break;
 	case ISM_EVENT_CODE_TESTLINK:	/* Activity timer */
 		if (ev_info.code == ISM_EVENT_REQUEST) {
 			ev_info.code = ISM_EVENT_RESPONSE;
 			wrk->smcd->ops->signal_event(wrk->smcd,
-						     wrk->event.tok,
+						     &peer_gid,
 						     ISM_EVENT_REQUEST_IR,
 						     ISM_EVENT_CODE_TESTLINK,
 						     ev_info.info);
@@ -365,10 +368,12 @@ static void smc_ism_event_work(struct work_struct *work)
 {
 	struct smc_ism_event_work *wrk =
 		container_of(work, struct smc_ism_event_work, work);
+	struct smcd_gid smcd_gid = { .gid = wrk->event.tok,
+				     .gid_ext = 0 };
 
 	switch (wrk->event.type) {
 	case ISM_EVENT_GID:	/* GID event, token is peer GID */
-		smc_smcd_terminate(wrk->smcd, wrk->event.tok, VLAN_VID_MASK);
+		smc_smcd_terminate(wrk->smcd, &smcd_gid, VLAN_VID_MASK);
 		break;
 	case ISM_EVENT_DMB:
 		break;
@@ -525,7 +530,7 @@ int smc_ism_signal_shutdown(struct smc_link_group *lgr)
 	memcpy(ev_info.uid, lgr->id, SMC_LGR_ID_SIZE);
 	ev_info.vlan_id = lgr->vlan_id;
 	ev_info.code = ISM_EVENT_REQUEST;
-	rc = lgr->smcd->ops->signal_event(lgr->smcd, lgr->peer_gid,
+	rc = lgr->smcd->ops->signal_event(lgr->smcd, &lgr->peer_gid,
 					  ISM_EVENT_REQUEST_IR,
 					  ISM_EVENT_CODE_SHUTDOWN,
 					  ev_info.info);
diff --git a/net/smc/smc_ism.h b/net/smc/smc_ism.h
index d1228a6..0e5e563 100644
--- a/net/smc/smc_ism.h
+++ b/net/smc/smc_ism.h
@@ -32,7 +32,8 @@ struct smc_ism_vlanid {			/* VLAN id set on ISM device */
 
 struct smcd_dev;
 
-int smc_ism_cantalk(u64 peer_gid, unsigned short vlan_id, struct smcd_dev *dev);
+int smc_ism_cantalk(struct smcd_gid *peer_gid, unsigned short vlan_id,
+		    struct smcd_dev *dev);
 void smc_ism_set_conn(struct smc_connection *conn);
 void smc_ism_unset_conn(struct smc_connection *conn);
 int smc_ism_get_vlan(struct smcd_dev *dev, unsigned short vlan_id);
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index 1177540..9f2c58c 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -1103,8 +1103,8 @@ static void smc_pnet_find_ism_by_pnetid(struct net_device *ndev,
 	list_for_each_entry(ismdev, &smcd_dev_list.list, list) {
 		if (smc_pnet_match(ismdev->pnetid, ndev_pnetid) &&
 		    !ismdev->going_away &&
-		    (!ini->ism_peer_gid[0] ||
-		     !smc_ism_cantalk(ini->ism_peer_gid[0], ini->vlan_id,
+		    (!ini->ism_peer_gid[0].gid ||
+		     !smc_ism_cantalk(&ini->ism_peer_gid[0], ini->vlan_id,
 				      ismdev))) {
 			ini->ism_dev[0] = ismdev;
 			break;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 6/7] net/smc: disable SEID on non-s390 archs where virtual ISM may be used
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
                   ` (4 preceding siblings ...)
  2023-11-19 13:57 ` [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device Wen Gu
@ 2023-11-19 13:57 ` Wen Gu
  2023-11-19 13:57 ` [PATCH net-next 7/7] net/smc: manage system EID in SMC stack instead of ISM driver Wen Gu
  2023-11-24 13:11 ` [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wenjia Zhang
  7 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

The system EID (SEID) is an internal EID used by SMC-D to represent the
s390 physical machine that OS is executing on. On s390 architecture, it
predefined by fixed string and part of cpuid and is enabled regardless
of whether underlay device is virtual ISM or platform firmware ISM.

However on non-s390 architectures where SMC-D can be used with virtual
ISM devices, there is no similar information to identify physical
machines, especially in virtualization scenarios. So in such cases, SEID
is forcibly disabled and the user-defined UEID will be used to represent
the communicable space.

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 net/smc/smc_clc.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index 92f1935..2226c66 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -155,10 +155,12 @@ static int smc_clc_ueid_remove(char *ueid)
 			rc = 0;
 		}
 	}
+#if IS_ENABLED(CONFIG_S390)
 	if (!rc && !smc_clc_eid_table.ueid_cnt) {
 		smc_clc_eid_table.seid_enabled = 1;
 		rc = -EAGAIN;	/* indicate success and enabling of seid */
 	}
+#endif
 	write_unlock(&smc_clc_eid_table.lock);
 	return rc;
 }
@@ -273,22 +275,30 @@ int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb)
 
 int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info)
 {
+#if IS_ENABLED(CONFIG_S390)
 	write_lock(&smc_clc_eid_table.lock);
 	smc_clc_eid_table.seid_enabled = 1;
 	write_unlock(&smc_clc_eid_table.lock);
 	return 0;
+#else
+	return -EOPNOTSUPP;
+#endif
 }
 
 int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info)
 {
 	int rc = 0;
 
+#if IS_ENABLED(CONFIG_S390)
 	write_lock(&smc_clc_eid_table.lock);
 	if (!smc_clc_eid_table.ueid_cnt)
 		rc = -ENOENT;
 	else
 		smc_clc_eid_table.seid_enabled = 0;
 	write_unlock(&smc_clc_eid_table.lock);
+#else
+	rc = -EOPNOTSUPP;
+#endif
 	return rc;
 }
 
@@ -1295,7 +1305,11 @@ void __init smc_clc_init(void)
 	INIT_LIST_HEAD(&smc_clc_eid_table.list);
 	rwlock_init(&smc_clc_eid_table.lock);
 	smc_clc_eid_table.ueid_cnt = 0;
+#if IS_ENABLED(CONFIG_S390)
 	smc_clc_eid_table.seid_enabled = 1;
+#else
+	smc_clc_eid_table.seid_enabled = 0;
+#endif
 }
 
 void smc_clc_exit(void)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 7/7] net/smc: manage system EID in SMC stack instead of ISM driver
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
                   ` (5 preceding siblings ...)
  2023-11-19 13:57 ` [PATCH net-next 6/7] net/smc: disable SEID on non-s390 archs where virtual ISM may be used Wen Gu
@ 2023-11-19 13:57 ` Wen Gu
  2023-11-24 13:11 ` [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wenjia Zhang
  7 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-19 13:57 UTC (permalink / raw)
  To: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, guwen, raspl, schnelle,
	linux-s390, netdev, linux-kernel

The System EID (SEID) is an internal EID that is used by the SMCv2
software stack that has a predefined and constant value representing
the s390 physical machine that the OS is executing on. So it should
be managed by SMC stack instead of ISM driver and be consistent for
all ISMv2 device (including virtual ISM devices) on s390 architecture.

Suggested-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
---
 drivers/s390/net/ism.h     |  6 ------
 drivers/s390/net/ism_drv.c | 36 ++++--------------------------------
 include/linux/ism.h        |  1 -
 include/net/smc.h          |  1 -
 net/smc/smc_ism.c          | 40 ++++++++++++++++++++++++++++++----------
 net/smc/smc_ism.h          |  8 ++++++++
 6 files changed, 42 insertions(+), 50 deletions(-)

diff --git a/drivers/s390/net/ism.h b/drivers/s390/net/ism.h
index 70c5bbd..49ccbd68 100644
--- a/drivers/s390/net/ism.h
+++ b/drivers/s390/net/ism.h
@@ -192,12 +192,6 @@ struct ism_sba {
 #define ISM_CREATE_REQ(dmb, idx, sf, offset)		\
 	((dmb) | (idx) << 24 | (sf) << 23 | (offset))
 
-struct ism_systemeid {
-	u8	seid_string[24];
-	u8	serial_number[4];
-	u8	type[4];
-};
-
 static inline void __ism_read_cmd(struct ism_dev *ism, void *data,
 				  unsigned long offset, unsigned long len)
 {
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index 54b865b..4e5ff5d 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -37,6 +37,7 @@
 						/* a list for fast mapping  */
 static u8 max_client;
 static DEFINE_MUTEX(clients_lock);
+static bool ism_v2_capable;
 struct ism_dev_list {
 	struct list_head list;
 	struct mutex mutex; /* protects ism device list */
@@ -477,32 +478,6 @@ int ism_move(struct ism_dev *ism, u64 dmb_tok, unsigned int idx, bool sf,
 }
 EXPORT_SYMBOL_GPL(ism_move);
 
-static struct ism_systemeid SYSTEM_EID = {
-	.seid_string = "IBM-SYSZ-ISMSEID00000000",
-	.serial_number = "0000",
-	.type = "0000",
-};
-
-static void ism_create_system_eid(void)
-{
-	struct cpuid id;
-	u16 ident_tail;
-	char tmp[5];
-
-	get_cpu_id(&id);
-	ident_tail = (u16)(id.ident & ISM_IDENT_MASK);
-	snprintf(tmp, 5, "%04X", ident_tail);
-	memcpy(&SYSTEM_EID.serial_number, tmp, 4);
-	snprintf(tmp, 5, "%04X", id.machine);
-	memcpy(&SYSTEM_EID.type, tmp, 4);
-}
-
-u8 *ism_get_seid(void)
-{
-	return SYSTEM_EID.seid_string;
-}
-EXPORT_SYMBOL_GPL(ism_get_seid);
-
 static u16 ism_get_chid(struct ism_dev *ism)
 {
 	if (!ism || !ism->pdev)
@@ -607,7 +582,7 @@ static int ism_dev_init(struct ism_dev *ism)
 
 	if (!ism_add_vlan_id(ism, ISM_RESERVED_VLANID))
 		/* hardware is V2 capable */
-		ism_create_system_eid();
+		ism_v2_capable = true;
 
 	mutex_lock(&ism_dev_list.mutex);
 	mutex_lock(&clients_lock);
@@ -712,8 +687,7 @@ static void ism_dev_exit(struct ism_dev *ism)
 	}
 	mutex_unlock(&clients_lock);
 
-	if (SYSTEM_EID.serial_number[0] != '0' ||
-	    SYSTEM_EID.type[0] != '0')
+	if (ism_v2_capable)
 		ism_del_vlan_id(ism, ISM_RESERVED_VLANID);
 	unregister_ieq(ism);
 	unregister_sba(ism);
@@ -826,8 +800,7 @@ static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
 
 static int smcd_supports_v2(void)
 {
-	return SYSTEM_EID.serial_number[0] != '0' ||
-		SYSTEM_EID.type[0] != '0';
+	return ism_v2_capable;
 }
 
 static void smcd_get_local_gid(struct smcd_dev *smcd,
@@ -860,7 +833,6 @@ static inline struct device *smcd_get_dev(struct smcd_dev *dev)
 	.signal_event = smcd_signal_ieq,
 	.move_data = smcd_move,
 	.supports_v2 = smcd_supports_v2,
-	.get_system_eid = ism_get_seid,
 	.get_local_gid = smcd_get_local_gid,
 	.get_chid = smcd_get_chid,
 	.get_dev = smcd_get_dev,
diff --git a/include/linux/ism.h b/include/linux/ism.h
index 9a4c204..5428edd 100644
--- a/include/linux/ism.h
+++ b/include/linux/ism.h
@@ -86,7 +86,6 @@ int  ism_register_dmb(struct ism_dev *dev, struct ism_dmb *dmb,
 int  ism_unregister_dmb(struct ism_dev *dev, struct ism_dmb *dmb);
 int  ism_move(struct ism_dev *dev, u64 dmb_tok, unsigned int idx, bool sf,
 	      unsigned int offset, void *data, unsigned int size);
-u8  *ism_get_seid(void);
 
 const struct smcd_ops *ism_get_smcd_ops(void);
 
diff --git a/include/net/smc.h b/include/net/smc.h
index a0dc1187e..c9dcb30 100644
--- a/include/net/smc.h
+++ b/include/net/smc.h
@@ -73,7 +73,6 @@ struct smcd_ops {
 			 bool sf, unsigned int offset, void *data,
 			 unsigned int size);
 	int (*supports_v2)(void);
-	u8* (*get_system_eid)(void);
 	void (*get_local_gid)(struct smcd_dev *dev, struct smcd_gid *gid);
 	u16 (*get_chid)(struct smcd_dev *dev);
 	struct device* (*get_dev)(struct smcd_dev *dev);
diff --git a/net/smc/smc_ism.c b/net/smc/smc_ism.c
index a33f861..d463d05 100644
--- a/net/smc/smc_ism.c
+++ b/net/smc/smc_ism.c
@@ -43,6 +43,27 @@ static void smcd_handle_irq(struct ism_dev *ism, unsigned int dmbno,
 };
 #endif
 
+static void smc_ism_create_system_eid(void)
+{
+	struct smc_ism_seid *seid =
+		(struct smc_ism_seid *)smc_ism_v2_system_eid;
+#if IS_ENABLED(CONFIG_S390)
+	struct cpuid id;
+	u16 ident_tail;
+	char tmp[5];
+
+	memcpy(seid->seid_string, "IBM-SYSZ-ISMSEID00000000", 24);
+	get_cpu_id(&id);
+	ident_tail = (u16)(id.ident & SMC_ISM_IDENT_MASK);
+	snprintf(tmp, 5, "%04X", ident_tail);
+	memcpy(seid->serial_number, tmp, 4);
+	snprintf(tmp, 5, "%04X", id.machine);
+	memcpy(seid->type, tmp, 4);
+#else
+	memset(seid, 0, SMC_MAX_EID_LEN);
+#endif
+}
+
 /* Test if an ISM communication is possible - same CPC */
 int smc_ism_cantalk(struct smcd_gid *peer_gid, unsigned short vlan_id,
 		    struct smcd_dev *smcd)
@@ -70,6 +91,11 @@ bool smc_ism_is_v2_capable(void)
 	return smc_ism_v2_capable;
 }
 
+void smc_ism_set_v2_capable(void)
+{
+	smc_ism_v2_capable = true;
+}
+
 /* Set a connection using this DMBE. */
 void smc_ism_set_conn(struct smc_connection *conn)
 {
@@ -431,14 +457,8 @@ static void smcd_register_dev(struct ism_dev *ism)
 
 	mutex_lock(&smcd_dev_list.mutex);
 	if (list_empty(&smcd_dev_list.list)) {
-		u8 *system_eid = NULL;
-
-		system_eid = smcd->ops->get_system_eid();
-		if (smcd->ops->supports_v2()) {
-			smc_ism_v2_capable = true;
-			memcpy(smc_ism_v2_system_eid, system_eid,
-			       SMC_MAX_EID_LEN);
-		}
+		if (smcd->ops->supports_v2())
+			smc_ism_set_v2_capable();
 	}
 	/* sort list: devices without pnetid before devices with pnetid */
 	if (smcd->pnetid[0])
@@ -542,10 +562,10 @@ int smc_ism_init(void)
 {
 	int rc = 0;
 
-#if IS_ENABLED(CONFIG_ISM)
 	smc_ism_v2_capable = false;
-	memset(smc_ism_v2_system_eid, 0, SMC_MAX_EID_LEN);
+	smc_ism_create_system_eid();
 
+#if IS_ENABLED(CONFIG_ISM)
 	rc = ism_register_client(&smc_ism_client);
 #endif
 	return rc;
diff --git a/net/smc/smc_ism.h b/net/smc/smc_ism.h
index 0e5e563..6903cd5 100644
--- a/net/smc/smc_ism.h
+++ b/net/smc/smc_ism.h
@@ -16,6 +16,7 @@
 #include "smc.h"
 
 #define SMC_VIRTUAL_ISM_CHID_MASK	0xFF00
+#define SMC_ISM_IDENT_MASK		0x00FFFF
 
 struct smcd_dev_list {	/* List of SMCD devices */
 	struct list_head list;
@@ -30,6 +31,12 @@ struct smc_ism_vlanid {			/* VLAN id set on ISM device */
 	refcount_t refcnt;		/* Reference count */
 };
 
+struct smc_ism_seid {
+	u8 seid_string[24];
+	u8 serial_number[4];
+	u8 type[4];
+};
+
 struct smcd_dev;
 
 int smc_ism_cantalk(struct smcd_gid *peer_gid, unsigned short vlan_id,
@@ -45,6 +52,7 @@ int smc_ism_register_dmb(struct smc_link_group *lgr, int buf_size,
 void smc_ism_get_system_eid(u8 **eid);
 u16 smc_ism_get_chid(struct smcd_dev *dev);
 bool smc_ism_is_v2_capable(void);
+void smc_ism_set_v2_capable(void);
 int smc_ism_init(void);
 void smc_ism_exit(void);
 int smcd_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device
  2023-11-19 13:57 ` [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device Wen Gu
@ 2023-11-20 19:17   ` Jakub Kicinski
  2023-11-23 13:16     ` Wen Gu
  2023-11-22 19:07   ` Simon Horman
  1 sibling, 1 reply; 15+ messages in thread
From: Jakub Kicinski @ 2023-11-20 19:17 UTC (permalink / raw)
  To: Wen Gu
  Cc: wintera, wenjia, hca, gor, agordeev, davem, edumazet, pabeni,
	kgraul, jaka, borntraeger, svens, alibuda, tonylu, raspl,
	schnelle, linux-s390, netdev, linux-kernel

On Sun, 19 Nov 2023 21:57:55 +0800 Wen Gu wrote:
> According to virtual ISM support feature defined by SMCv2.1, GIDs of
> virtual ISM device are UUIDs defined by RFC4122, which are 128-bits
> long. So some adaptation work is required. And note that the GIDs of
> existing platform firmware ISM devices still remain 64-bits long.

sparse (C=1 build) complains:

net/smc/smc_clc.c:944:73: warning: incorrect type in argument 1 (different base types)
net/smc/smc_clc.c:944:73:    expected unsigned short [usertype] chid
net/smc/smc_clc.c:944:73:    got restricted __be16 [usertype] chid
-- 
pw-bot: cr

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device
  2023-11-19 13:57 ` [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device Wen Gu
  2023-11-20 19:17   ` Jakub Kicinski
@ 2023-11-22 19:07   ` Simon Horman
  2023-11-23 13:39     ` Wen Gu
  1 sibling, 1 reply; 15+ messages in thread
From: Simon Horman @ 2023-11-22 19:07 UTC (permalink / raw)
  To: Wen Gu
  Cc: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka, borntraeger, svens, alibuda, tonylu, raspl,
	schnelle, linux-s390, netdev, linux-kernel

On Sun, Nov 19, 2023 at 09:57:55PM +0800, Wen Gu wrote:
> According to virtual ISM support feature defined by SMCv2.1, GIDs of
> virtual ISM device are UUIDs defined by RFC4122, which are 128-bits
> long. So some adaptation work is required. And note that the GIDs of
> existing platform firmware ISM devices still remain 64-bits long.
> 
> Signed-off-by: Wen Gu <guwen@linux.alibaba.com>

...

> diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c

...

> @@ -1522,7 +1527,10 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan)
>  	/* run common cleanup function and build free list */
>  	spin_lock_bh(&dev->lgr_lock);
>  	list_for_each_entry_safe(lgr, l, &dev->lgr_list, list) {
> -		if ((!peer_gid || lgr->peer_gid == peer_gid) &&
> +		if ((!peer_gid->gid ||

Hi Wen Gu,

Previously this condition assumed that peer could be NULL,
and that is still the case in the next condition, a few lines down.
But with this patch peer is unconditionally dereferenced here.

As flagged by Smatch.

> +		     (lgr->peer_gid.gid == peer_gid->gid &&
> +		      !smc_ism_is_virtual(dev) ? 1 :
> +		      lgr->peer_gid.gid_ext == peer_gid->gid_ext)) &&
>  		    (vlan == VLAN_VID_MASK || lgr->vlan_id == vlan)) {
>  			if (peer_gid) /* peer triggered termination */
>  				lgr->peer_shutdown = 1;

...

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device
  2023-11-20 19:17   ` Jakub Kicinski
@ 2023-11-23 13:16     ` Wen Gu
  0 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-23 13:16 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: wintera, wenjia, hca, gor, agordeev, davem, edumazet, pabeni,
	kgraul, jaka, borntraeger, svens, alibuda, tonylu, raspl,
	schnelle, linux-s390, netdev, linux-kernel



On 2023/11/21 03:17, Jakub Kicinski wrote:
> On Sun, 19 Nov 2023 21:57:55 +0800 Wen Gu wrote:
>> According to virtual ISM support feature defined by SMCv2.1, GIDs of
>> virtual ISM device are UUIDs defined by RFC4122, which are 128-bits
>> long. So some adaptation work is required. And note that the GIDs of
>> existing platform firmware ISM devices still remain 64-bits long.
> 
> sparse (C=1 build) complains:
> 
> net/smc/smc_clc.c:944:73: warning: incorrect type in argument 1 (different base types)
> net/smc/smc_clc.c:944:73:    expected unsigned short [usertype] chid
> net/smc/smc_clc.c:944:73:    got restricted __be16 [usertype] chid

It will be fixed in the next version. Thank you very much!

Thanks,
Wen Gu

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device
  2023-11-22 19:07   ` Simon Horman
@ 2023-11-23 13:39     ` Wen Gu
  0 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-23 13:39 UTC (permalink / raw)
  To: Simon Horman
  Cc: wintera, wenjia, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka, borntraeger, svens, alibuda, tonylu, raspl,
	schnelle, linux-s390, netdev, linux-kernel



On 2023/11/23 03:07, Simon Horman wrote:

> On Sun, Nov 19, 2023 at 09:57:55PM +0800, Wen Gu wrote:
>> According to virtual ISM support feature defined by SMCv2.1, GIDs of
>> virtual ISM device are UUIDs defined by RFC4122, which are 128-bits
>> long. So some adaptation work is required. And note that the GIDs of
>> existing platform firmware ISM devices still remain 64-bits long.
>>
>> Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
> 
> ...
> 
>> diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
> 
> ...
> 
>> @@ -1522,7 +1527,10 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan)
>>   	/* run common cleanup function and build free list */
>>   	spin_lock_bh(&dev->lgr_lock);
>>   	list_for_each_entry_safe(lgr, l, &dev->lgr_list, list) {
>> -		if ((!peer_gid || lgr->peer_gid == peer_gid) &&
>> +		if ((!peer_gid->gid ||
> 
> Hi Wen Gu,
> 
> Previously this condition assumed that peer could be NULL,
> and that is still the case in the next condition, a few lines down.
> But with this patch peer is unconditionally dereferenced here.
> 
> As flagged by Smatch.
> 

Hi Simon,

Good catch!

Previously the peer_gid is an u64 type variable and it will be checked if it is 0.

With this patch, peer_gid is an struct smcd_gid type pointer and the function that
calls smc_smcd_terminate will make sure it is not NULL. So it is safe here.

But there is indeed a problem here, see below.

>> +		     (lgr->peer_gid.gid == peer_gid->gid &&
>> +		      !smc_ism_is_virtual(dev) ? 1 :
>> +		      lgr->peer_gid.gid_ext == peer_gid->gid_ext)) &&
>>   		    (vlan == VLAN_VID_MASK || lgr->vlan_id == vlan)) {
>>   			if (peer_gid) /* peer triggered termination */

This if condition should be 'if (peer_gid->gid)'

I will fix this in the next version. Thank you very much.

Regards,
Wen Gu

>>   				lgr->peer_shutdown = 1;
> 
> ...

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support
  2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
                   ` (6 preceding siblings ...)
  2023-11-19 13:57 ` [PATCH net-next 7/7] net/smc: manage system EID in SMC stack instead of ISM driver Wen Gu
@ 2023-11-24 13:11 ` Wenjia Zhang
  2023-11-24 13:34   ` Wen Gu
  7 siblings, 1 reply; 15+ messages in thread
From: Wenjia Zhang @ 2023-11-24 13:11 UTC (permalink / raw)
  To: Wen Gu, wintera, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, raspl, schnelle, linux-s390,
	netdev, linux-kernel



On 19.11.23 14:57, Wen Gu wrote:
> The fourth edition of SMCv2 adds the SMC version 2.1 feature updates for
> SMC-Dv2 with virtual ISM. Virtual ISM are created and supported mainly by
> OS or hypervisor software, comparable to IBM ISM which is based on platform
> firmware or hardware.
> 
> With the introduction of virtual ISM, SMCv2.1 makes some updates:
> 
> - Introduce feature bitmask to indicate supplemental features.
> - Reserve a range of CHIDs for virtual ISM.
> - Support extended GIDs (128 bits) in CLC handshake.
> 
> So this patch set aims to implement these updates in Linux kernel. And it
> acts as the first part of the new version of [1].
> 
> [1] https://lore.kernel.org/netdev/1695568613-125057-1-git-send-email-guwen@linux.alibaba.com/
> 
> Wen Gu (7):
>    net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity
>    net/smc: support SMCv2.x supplemental features negotiation
>    net/smc: introduce virtual ISM device support feature
>    net/smc: define a reserved CHID range for virtual ISM devices
>    net/smc: compatible with 128-bits extend GID of virtual ISM device
>    net/smc: disable SEID on non-s390 archs where virtual ISM may be used
>    net/smc: manage system EID in SMC stack instead of ISM driver
> 
>   drivers/s390/net/ism.h     |  6 ---
>   drivers/s390/net/ism_drv.c | 54 +++++++--------------------
>   include/linux/ism.h        |  1 -
>   include/net/smc.h          | 16 +++++---
>   net/smc/af_smc.c           | 68 ++++++++++++++++++++++++++-------
>   net/smc/smc.h              |  7 ++++
>   net/smc/smc_clc.c          | 93 ++++++++++++++++++++++++++++++++--------------
>   net/smc/smc_clc.h          | 22 +++++++----
>   net/smc/smc_core.c         | 30 ++++++++++-----
>   net/smc/smc_core.h         |  8 ++--
>   net/smc/smc_diag.c         |  7 +++-
>   net/smc/smc_ism.c          | 57 ++++++++++++++++++++--------
>   net/smc/smc_ism.h          | 31 +++++++++++++++-
>   net/smc/smc_pnet.c         |  4 +-
>   14 files changed, 269 insertions(+), 135 deletions(-)
> 

Hi Wen Gu,

Just FYI, the review is still on going and some tests on our plateform 
still need to do. I'll give you my comments as soon as the testing is 
done. I think it would be at the beginning of next week.

Thanks,
Wenjia

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support
  2023-11-24 13:11 ` [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wenjia Zhang
@ 2023-11-24 13:34   ` Wen Gu
  2023-11-24 13:37     ` Wen Gu
  0 siblings, 1 reply; 15+ messages in thread
From: Wen Gu @ 2023-11-24 13:34 UTC (permalink / raw)
  To: Wenjia Zhang, wintera, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, raspl, schnelle, linux-s390,
	netdev, linux-kernel



On 2023/11/24 21:11, Wenjia Zhang wrote:
> 
> 
> On 19.11.23 14:57, Wen Gu wrote:
>> The fourth edition of SMCv2 adds the SMC version 2.1 feature updates for
>> SMC-Dv2 with virtual ISM. Virtual ISM are created and supported mainly by
>> OS or hypervisor software, comparable to IBM ISM which is based on platform
>> firmware or hardware.
>>
>> With the introduction of virtual ISM, SMCv2.1 makes some updates:
>>
>> - Introduce feature bitmask to indicate supplemental features.
>> - Reserve a range of CHIDs for virtual ISM.
>> - Support extended GIDs (128 bits) in CLC handshake.
>>
>> So this patch set aims to implement these updates in Linux kernel. And it
>> acts as the first part of the new version of [1].
>>
>> [1] https://lore.kernel.org/netdev/1695568613-125057-1-git-send-email-guwen@linux.alibaba.com/
>>
>> Wen Gu (7):
>>    net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity
>>    net/smc: support SMCv2.x supplemental features negotiation
>>    net/smc: introduce virtual ISM device support feature
>>    net/smc: define a reserved CHID range for virtual ISM devices
>>    net/smc: compatible with 128-bits extend GID of virtual ISM device
>>    net/smc: disable SEID on non-s390 archs where virtual ISM may be used
>>    net/smc: manage system EID in SMC stack instead of ISM driver
>>
>>   drivers/s390/net/ism.h     |  6 ---
>>   drivers/s390/net/ism_drv.c | 54 +++++++--------------------
>>   include/linux/ism.h        |  1 -
>>   include/net/smc.h          | 16 +++++---
>>   net/smc/af_smc.c           | 68 ++++++++++++++++++++++++++-------
>>   net/smc/smc.h              |  7 ++++
>>   net/smc/smc_clc.c          | 93 ++++++++++++++++++++++++++++++++--------------
>>   net/smc/smc_clc.h          | 22 +++++++----
>>   net/smc/smc_core.c         | 30 ++++++++++-----
>>   net/smc/smc_core.h         |  8 ++--
>>   net/smc/smc_diag.c         |  7 +++-
>>   net/smc/smc_ism.c          | 57 ++++++++++++++++++++--------
>>   net/smc/smc_ism.h          | 31 +++++++++++++++-
>>   net/smc/smc_pnet.c         |  4 +-
>>   14 files changed, 269 insertions(+), 135 deletions(-)
>>
> 
> Hi Wen Gu,
> 
> Just FYI, the review is still on going and some tests on our plateform still need to do. I'll give you my comments as 
> soon as the testing is done. I think it would be at the beginning of next week.
> 
> Thanks,
> Wenjia

Hi Wenjian,

Thank you very much. I appreciate that you help to test them on your platform since I can only test
them with loopback-ism.

And I am going to send a new version which is rebased to the latest net-next and fix two existing
comments. If the current tests have not started yet, could you please test based on my upcoming v2 ?

Thanks and regards,
Wen Gu

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support
  2023-11-24 13:34   ` Wen Gu
@ 2023-11-24 13:37     ` Wen Gu
  0 siblings, 0 replies; 15+ messages in thread
From: Wen Gu @ 2023-11-24 13:37 UTC (permalink / raw)
  To: Wenjia Zhang, wintera, hca, gor, agordeev, davem, edumazet, kuba,
	pabeni, kgraul, jaka
  Cc: borntraeger, svens, alibuda, tonylu, raspl, schnelle, linux-s390,
	netdev, linux-kernel



On 2023/11/24 21:34, Wen Gu wrote:
> 
> 
> On 2023/11/24 21:11, Wenjia Zhang wrote:
>>
>>
>> On 19.11.23 14:57, Wen Gu wrote:
>>> The fourth edition of SMCv2 adds the SMC version 2.1 feature updates for
>>> SMC-Dv2 with virtual ISM. Virtual ISM are created and supported mainly by
>>> OS or hypervisor software, comparable to IBM ISM which is based on platform
>>> firmware or hardware.
>>>
>>> With the introduction of virtual ISM, SMCv2.1 makes some updates:
>>>
>>> - Introduce feature bitmask to indicate supplemental features.
>>> - Reserve a range of CHIDs for virtual ISM.
>>> - Support extended GIDs (128 bits) in CLC handshake.
>>>
>>> So this patch set aims to implement these updates in Linux kernel. And it
>>> acts as the first part of the new version of [1].
>>>
>>> [1] https://lore.kernel.org/netdev/1695568613-125057-1-git-send-email-guwen@linux.alibaba.com/
>>>
>>> Wen Gu (7):
>>>    net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity
>>>    net/smc: support SMCv2.x supplemental features negotiation
>>>    net/smc: introduce virtual ISM device support feature
>>>    net/smc: define a reserved CHID range for virtual ISM devices
>>>    net/smc: compatible with 128-bits extend GID of virtual ISM device
>>>    net/smc: disable SEID on non-s390 archs where virtual ISM may be used
>>>    net/smc: manage system EID in SMC stack instead of ISM driver
>>>
>>>   drivers/s390/net/ism.h     |  6 ---
>>>   drivers/s390/net/ism_drv.c | 54 +++++++--------------------
>>>   include/linux/ism.h        |  1 -
>>>   include/net/smc.h          | 16 +++++---
>>>   net/smc/af_smc.c           | 68 ++++++++++++++++++++++++++-------
>>>   net/smc/smc.h              |  7 ++++
>>>   net/smc/smc_clc.c          | 93 ++++++++++++++++++++++++++++++++--------------
>>>   net/smc/smc_clc.h          | 22 +++++++----
>>>   net/smc/smc_core.c         | 30 ++++++++++-----
>>>   net/smc/smc_core.h         |  8 ++--
>>>   net/smc/smc_diag.c         |  7 +++-
>>>   net/smc/smc_ism.c          | 57 ++++++++++++++++++++--------
>>>   net/smc/smc_ism.h          | 31 +++++++++++++++-
>>>   net/smc/smc_pnet.c         |  4 +-
>>>   14 files changed, 269 insertions(+), 135 deletions(-)
>>>
>>
>> Hi Wen Gu,
>>
>> Just FYI, the review is still on going and some tests on our plateform still need to do. I'll give you my comments as 
>> soon as the testing is done. I think it would be at the beginning of next week.
>>
>> Thanks,
>> Wenjia
> 
> Hi Wenjian,
Wenjia.

Sorry for the typo.

> 
> Thank you very much. I appreciate that you help to test them on your platform since I can only test
> them with loopback-ism.
> 
> And I am going to send a new version which is rebased to the latest net-next and fix two existing
> comments. If the current tests have not started yet, could you please test based on my upcoming v2 ?
> 
> Thanks and regards,
> Wen Gu

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-11-24 13:38 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-19 13:57 [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wen Gu
2023-11-19 13:57 ` [PATCH net-next 1/7] net/smc: Rename some variable 'fce' to 'fce_v2x' for clarity Wen Gu
2023-11-19 13:57 ` [PATCH net-next 2/7] net/smc: support SMCv2.x supplemental features negotiation Wen Gu
2023-11-19 13:57 ` [PATCH net-next 3/7] net/smc: introduce virtual ISM device support feature Wen Gu
2023-11-19 13:57 ` [PATCH net-next 4/7] net/smc: define a reserved CHID range for virtual ISM devices Wen Gu
2023-11-19 13:57 ` [PATCH net-next 5/7] net/smc: compatible with 128-bits extend GID of virtual ISM device Wen Gu
2023-11-20 19:17   ` Jakub Kicinski
2023-11-23 13:16     ` Wen Gu
2023-11-22 19:07   ` Simon Horman
2023-11-23 13:39     ` Wen Gu
2023-11-19 13:57 ` [PATCH net-next 6/7] net/smc: disable SEID on non-s390 archs where virtual ISM may be used Wen Gu
2023-11-19 13:57 ` [PATCH net-next 7/7] net/smc: manage system EID in SMC stack instead of ISM driver Wen Gu
2023-11-24 13:11 ` [PATCH net-next 0/7] net/smc: implement SMCv2.1 virtual ISM device support Wenjia Zhang
2023-11-24 13:34   ` Wen Gu
2023-11-24 13:37     ` Wen Gu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).