All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 net 0/2] fix shared vcap_props reference
@ 2022-04-29 23:30 Colin Foster
  2022-04-29 23:30 ` [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member Colin Foster
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Colin Foster @ 2022-04-29 23:30 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: Paolo Abeni, Jakub Kicinski, Eric Dumazet, David S. Miller,
	Florian Fainelli, Vivien Didelot, Andrew Lunn, UNGLinuxDriver,
	Alexandre Belloni, Claudiu Manoil, Vladimir Oltean

Felix vcap_props get statically allocated at the file scope, while the
felix / ocelot instances get dynamically allocated at initialization. If
there's more than one instance, each instance will be writing over the
same vcap_props memory region, which would lead to corruption.

I don't have any hardware to confidently test the vcap portions of
Ocelot / Felix, so any testers would be appreciated.

Also, I believe the memcpy of a structure array should be
architecture-portable, but I'm not 100% confident there, so that might
be an area of extra scrutiny.


Colin Foster (2):
  net: ethernet: ocelot: rename vcap_props to clearly be an ocelot
    member
  net: mscc: ocelot: fix possible memory conflict for vcap_props

 drivers/net/dsa/ocelot/felix.c             |  3 +-
 drivers/net/dsa/ocelot/felix.h             |  2 +-
 drivers/net/dsa/ocelot/felix_vsc9959.c     |  2 +-
 drivers/net/dsa/ocelot/seville_vsc9953.c   |  2 +-
 drivers/net/ethernet/mscc/ocelot_flower.c  |  4 +-
 drivers/net/ethernet/mscc/ocelot_vcap.c    | 54 +++++++++++-----------
 drivers/net/ethernet/mscc/ocelot_vsc7514.c |  5 +-
 include/soc/mscc/ocelot.h                  | 34 +++++++++++++-
 include/soc/mscc/ocelot_vcap.h             | 32 -------------
 9 files changed, 71 insertions(+), 67 deletions(-)

-- 
2.25.1


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

* [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member
  2022-04-29 23:30 [PATCH v1 net 0/2] fix shared vcap_props reference Colin Foster
@ 2022-04-29 23:30 ` Colin Foster
  2022-04-30  2:07   ` Jakub Kicinski
  2022-04-29 23:30 ` [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props Colin Foster
  2022-05-01 10:52 ` [PATCH v1 net 0/2] fix shared vcap_props reference Vladimir Oltean
  2 siblings, 1 reply; 13+ messages in thread
From: Colin Foster @ 2022-04-29 23:30 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: Paolo Abeni, Jakub Kicinski, Eric Dumazet, David S. Miller,
	Florian Fainelli, Vivien Didelot, Andrew Lunn, UNGLinuxDriver,
	Alexandre Belloni, Claudiu Manoil, Vladimir Oltean

The vcap_props structure is part of the ocelot driver. It is in the process
of being exported to a wider scope, so renaming it to match other structure
definitions in the include/soc/mscc/ocelot.h makes sense.

I'm splitting the rename operation into this separate commit, since it
should make the actual bug fix (next commit) easier to review.

Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
---
 drivers/net/dsa/ocelot/felix.h             |  2 +-
 drivers/net/dsa/ocelot/felix_vsc9959.c     |  2 +-
 drivers/net/dsa/ocelot/seville_vsc9953.c   |  2 +-
 drivers/net/ethernet/mscc/ocelot_flower.c  |  4 +-
 drivers/net/ethernet/mscc/ocelot_vcap.c    | 54 +++++++++++-----------
 drivers/net/ethernet/mscc/ocelot_vsc7514.c |  2 +-
 include/soc/mscc/ocelot.h                  |  2 +-
 include/soc/mscc/ocelot_vcap.h             |  2 +-
 8 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index f083b06fdfe9..d6cf5e5a48c5 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -27,7 +27,7 @@ struct felix_info {
 	unsigned int			num_stats;
 	int				num_ports;
 	int				num_tx_queues;
-	struct vcap_props		*vcap;
+	struct ocelot_vcap_props	*vcap;
 	u16				vcap_pol_base;
 	u16				vcap_pol_max;
 	u16				vcap_pol_base2;
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 52a8566071ed..a60dbedc1b1c 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -845,7 +845,7 @@ static struct vcap_field vsc9959_vcap_is2_actions[] = {
 	[VCAP_IS2_ACT_HIT_CNT]			= { 44, 32},
 };
 
-static struct vcap_props vsc9959_vcap_props[] = {
+static struct ocelot_vcap_props vsc9959_vcap_props[] = {
 	[VCAP_ES0] = {
 		.action_type_width = 0,
 		.action_table = {
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index 68ef8f111bbe..2fda65fb21a3 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -829,7 +829,7 @@ static struct vcap_field vsc9953_vcap_is2_actions[] = {
 	[VCAP_IS2_ACT_HIT_CNT]			= { 50, 32},
 };
 
-static struct vcap_props vsc9953_vcap_props[] = {
+static struct ocelot_vcap_props vsc9953_vcap_props[] = {
 	[VCAP_ES0] = {
 		.action_type_width = 0,
 		.action_table = {
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index 03b5e59d033e..59b040ad1fee 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -504,8 +504,8 @@ static int ocelot_flower_parse_indev(struct ocelot *ocelot, int port,
 				     struct flow_cls_offload *f,
 				     struct ocelot_vcap_filter *filter)
 {
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
-	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
 	int key_length = vcap->keys[VCAP_ES0_IGR_PORT].length;
 	struct netlink_ext_ack *extack = f->common.extack;
 	struct net_device *dev, *indev;
@@ -786,7 +786,7 @@ static struct ocelot_vcap_filter
 	if (ingress) {
 		filter->ingress_port_mask = BIT(port);
 	} else {
-		const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
+		const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
 		int key_length = vcap->keys[VCAP_ES0_EGR_PORT].length;
 
 		filter->egress_port.value = port;
diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c
index c8701ac955a8..816c8144e18e 100644
--- a/drivers/net/ethernet/mscc/ocelot_vcap.c
+++ b/drivers/net/ethernet/mscc/ocelot_vcap.c
@@ -47,13 +47,14 @@ struct vcap_data {
 };
 
 static u32 vcap_read_update_ctrl(struct ocelot *ocelot,
-				 const struct vcap_props *vcap)
+				 const struct ocelot_vcap_props *vcap)
 {
 	return ocelot_target_read(ocelot, vcap->target, VCAP_CORE_UPDATE_CTRL);
 }
 
-static void vcap_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
-		     u16 ix, int cmd, int sel)
+static void vcap_cmd(struct ocelot *ocelot,
+		     const struct ocelot_vcap_props *vcap, u16 ix, int cmd,
+		     int sel)
 {
 	u32 value = (VCAP_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
 		     VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
@@ -79,14 +80,15 @@ static void vcap_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
 }
 
 /* Convert from 0-based row to VCAP entry row and run command */
-static void vcap_row_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
-			 u32 row, int cmd, int sel)
+static void vcap_row_cmd(struct ocelot *ocelot,
+			 const struct ocelot_vcap_props *vcap, u32 row, int cmd,
+			 int sel)
 {
 	vcap_cmd(ocelot, vcap, vcap->entry_count - row - 1, cmd, sel);
 }
 
 static void vcap_entry2cache(struct ocelot *ocelot,
-			     const struct vcap_props *vcap,
+			     const struct ocelot_vcap_props *vcap,
 			     struct vcap_data *data)
 {
 	u32 entry_words, i;
@@ -103,7 +105,7 @@ static void vcap_entry2cache(struct ocelot *ocelot,
 }
 
 static void vcap_cache2entry(struct ocelot *ocelot,
-			     const struct vcap_props *vcap,
+			     const struct ocelot_vcap_props *vcap,
 			     struct vcap_data *data)
 {
 	u32 entry_words, i;
@@ -121,7 +123,7 @@ static void vcap_cache2entry(struct ocelot *ocelot,
 }
 
 static void vcap_action2cache(struct ocelot *ocelot,
-			      const struct vcap_props *vcap,
+			      const struct ocelot_vcap_props *vcap,
 			      struct vcap_data *data)
 {
 	u32 action_words, mask;
@@ -146,7 +148,7 @@ static void vcap_action2cache(struct ocelot *ocelot,
 }
 
 static void vcap_cache2action(struct ocelot *ocelot,
-			      const struct vcap_props *vcap,
+			      const struct ocelot_vcap_props *vcap,
 			      struct vcap_data *data)
 {
 	u32 action_words;
@@ -170,7 +172,7 @@ static void vcap_cache2action(struct ocelot *ocelot,
 }
 
 /* Calculate offsets for entry */
-static void vcap_data_offset_get(const struct vcap_props *vcap,
+static void vcap_data_offset_get(const struct ocelot_vcap_props *vcap,
 				 struct vcap_data *data, int ix)
 {
 	int num_subwords_per_entry, num_subwords_per_action;
@@ -251,8 +253,8 @@ static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width,
 	vcap_data_set(data->mask, offset + data->key_offset, width, mask);
 }
 
-static void vcap_key_set(const struct vcap_props *vcap, struct vcap_data *data,
-			 int field, u32 value, u32 mask)
+static void vcap_key_set(const struct ocelot_vcap_props *vcap,
+			 struct vcap_data *data, int field, u32 value, u32 mask)
 {
 	u32 offset = vcap->keys[field].offset;
 	u32 length = vcap->keys[field].length;
@@ -260,7 +262,7 @@ static void vcap_key_set(const struct vcap_props *vcap, struct vcap_data *data,
 	vcap_key_field_set(data, offset, length, value, mask);
 }
 
-static void vcap_key_bytes_set(const struct vcap_props *vcap,
+static void vcap_key_bytes_set(const struct ocelot_vcap_props *vcap,
 			       struct vcap_data *data, int field,
 			       u8 *val, u8 *msk)
 {
@@ -291,7 +293,7 @@ static void vcap_key_bytes_set(const struct vcap_props *vcap,
 	}
 }
 
-static void vcap_key_l4_port_set(const struct vcap_props *vcap,
+static void vcap_key_l4_port_set(const struct ocelot_vcap_props *vcap,
 				 struct vcap_data *data, int field,
 				 struct ocelot_vcap_udp_tcp *port)
 {
@@ -303,7 +305,7 @@ static void vcap_key_l4_port_set(const struct vcap_props *vcap,
 	vcap_key_field_set(data, offset, length, port->value, port->mask);
 }
 
-static void vcap_key_bit_set(const struct vcap_props *vcap,
+static void vcap_key_bit_set(const struct ocelot_vcap_props *vcap,
 			     struct vcap_data *data, int field,
 			     enum ocelot_vcap_bit val)
 {
@@ -317,7 +319,7 @@ static void vcap_key_bit_set(const struct vcap_props *vcap,
 	vcap_key_field_set(data, offset, length, value, msk);
 }
 
-static void vcap_action_set(const struct vcap_props *vcap,
+static void vcap_action_set(const struct ocelot_vcap_props *vcap,
 			    struct vcap_data *data, int field, u32 value)
 {
 	int offset = vcap->actions[field].offset;
@@ -330,7 +332,7 @@ static void vcap_action_set(const struct vcap_props *vcap,
 static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
 			   struct ocelot_vcap_filter *filter)
 {
-	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
 	struct ocelot_vcap_action *a = &filter->action;
 
 	vcap_action_set(vcap, data, VCAP_IS2_ACT_MASK_MODE, a->mask_mode);
@@ -345,7 +347,7 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
 static void is2_entry_set(struct ocelot *ocelot, int ix,
 			  struct ocelot_vcap_filter *filter)
 {
-	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
 	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
 	u32 val, msk, type, type_mask = 0xf, i, count;
 	struct ocelot_vcap_u64 payload;
@@ -647,7 +649,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 static void is1_action_set(struct ocelot *ocelot, struct vcap_data *data,
 			   const struct ocelot_vcap_filter *filter)
 {
-	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
 	const struct ocelot_vcap_action *a = &filter->action;
 
 	vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_REPLACE_ENA,
@@ -670,7 +672,7 @@ static void is1_action_set(struct ocelot *ocelot, struct vcap_data *data,
 static void is1_entry_set(struct ocelot *ocelot, int ix,
 			  struct ocelot_vcap_filter *filter)
 {
-	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
 	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
 	struct ocelot_vcap_u64 payload;
 	struct vcap_data data;
@@ -783,7 +785,7 @@ static void is1_entry_set(struct ocelot *ocelot, int ix,
 static void es0_action_set(struct ocelot *ocelot, struct vcap_data *data,
 			   const struct ocelot_vcap_filter *filter)
 {
-	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
 	const struct ocelot_vcap_action *a = &filter->action;
 
 	vcap_action_set(vcap, data, VCAP_ES0_ACT_PUSH_OUTER_TAG,
@@ -811,7 +813,7 @@ static void es0_action_set(struct ocelot *ocelot, struct vcap_data *data,
 static void es0_entry_set(struct ocelot *ocelot, int ix,
 			  struct ocelot_vcap_filter *filter)
 {
-	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
 	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
 	struct ocelot_vcap_u64 payload;
 	struct vcap_data data;
@@ -856,7 +858,7 @@ static void es0_entry_set(struct ocelot *ocelot, int ix,
 static void vcap_entry_get(struct ocelot *ocelot, int ix,
 			   struct ocelot_vcap_filter *filter)
 {
-	const struct vcap_props *vcap = &ocelot->vcap[filter->block_id];
+	const struct ocelot_vcap_props *vcap = &ocelot->vcap[filter->block_id];
 	struct vcap_data data;
 	int row, count;
 	u32 cnt;
@@ -1313,7 +1315,7 @@ int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
 }
 
 static void ocelot_vcap_init_one(struct ocelot *ocelot,
-				 const struct vcap_props *vcap)
+				 const struct ocelot_vcap_props *vcap)
 {
 	struct vcap_data data;
 
@@ -1332,7 +1334,7 @@ static void ocelot_vcap_init_one(struct ocelot *ocelot,
 }
 
 static void ocelot_vcap_detect_constants(struct ocelot *ocelot,
-					 struct vcap_props *vcap)
+					 struct ocelot_vcap_props *vcap)
 {
 	int counter_memory_width;
 	int num_default_actions;
@@ -1421,7 +1423,7 @@ int ocelot_vcap_init(struct ocelot *ocelot)
 
 	for (i = 0; i < OCELOT_NUM_VCAP_BLOCKS; i++) {
 		struct ocelot_vcap_block *block = &ocelot->block[i];
-		struct vcap_props *vcap = &ocelot->vcap[i];
+		struct ocelot_vcap_props *vcap = &ocelot->vcap[i];
 
 		INIT_LIST_HEAD(&block->rules);
 
diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
index 4f4a495a60ad..12c739cb89f9 100644
--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -344,7 +344,7 @@ static const struct ocelot_ops ocelot_ops = {
 	.netdev_to_port		= ocelot_netdev_to_port,
 };
 
-static struct vcap_props vsc7514_vcap_props[] = {
+static struct ocelot_vcap_props vsc7514_vcap_props[] = {
 	[VCAP_ES0] = {
 		.action_type_width = 0,
 		.action_table = {
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 9b4e6c78d0f4..42634183d062 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -727,7 +727,7 @@ struct ocelot {
 	struct list_head		dummy_rules;
 	struct ocelot_vcap_block	block[3];
 	struct ocelot_vcap_policer	vcap_pol;
-	struct vcap_props		*vcap;
+	struct ocelot_vcap_props	*vcap;
 	struct ocelot_mirror		*mirror;
 
 	struct ocelot_psfp_list		psfp;
diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
index 7b2bf9b1fe69..05bd73c63675 100644
--- a/include/soc/mscc/ocelot_vcap.h
+++ b/include/soc/mscc/ocelot_vcap.h
@@ -36,7 +36,7 @@ enum {
 
 #define OCELOT_NUM_VCAP_BLOCKS		__VCAP_COUNT
 
-struct vcap_props {
+struct ocelot_vcap_props {
 	u16 tg_width; /* Type-group width (in bits) */
 	u16 sw_count; /* Sub word count */
 	u16 entry_count; /* Entry count */
-- 
2.25.1


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

* [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props
  2022-04-29 23:30 [PATCH v1 net 0/2] fix shared vcap_props reference Colin Foster
  2022-04-29 23:30 ` [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member Colin Foster
@ 2022-04-29 23:30 ` Colin Foster
  2022-04-30  2:06   ` Jakub Kicinski
  2022-04-30 14:24   ` Vladimir Oltean
  2022-05-01 10:52 ` [PATCH v1 net 0/2] fix shared vcap_props reference Vladimir Oltean
  2 siblings, 2 replies; 13+ messages in thread
From: Colin Foster @ 2022-04-29 23:30 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: Paolo Abeni, Jakub Kicinski, Eric Dumazet, David S. Miller,
	Florian Fainelli, Vivien Didelot, Andrew Lunn, UNGLinuxDriver,
	Alexandre Belloni, Claudiu Manoil, Vladimir Oltean

Each instance of an ocelot struct has the ocelot_vcap_props structure being
referenced. During initialization (ocelot_init), these vcap_props are
detected and the structure contents are modified.

In the case of the standard ocelot driver, there will probably only be one
instance of struct ocelot, since it is part of the chip.

For the Felix driver, there could be multiple instances of struct ocelot.
In that scenario, the second time ocelot_init would get called, it would
corrupt what had been done in the first call because they both reference
*ocelot->vcap. Both of these instances were assigned the same memory
location.

Move this vcap_props memory to within struct ocelot, so that each instance
can modify the structure to their heart's content without corrupting other
instances.

Fixes: 2096805497e2b ("net: mscc: ocelot: automatically detect VCAP
constants")

Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
---
 drivers/net/dsa/ocelot/felix.c             |  3 +-
 drivers/net/dsa/ocelot/felix.h             |  2 +-
 drivers/net/dsa/ocelot/felix_vsc9959.c     |  2 +-
 drivers/net/ethernet/mscc/ocelot_vsc7514.c |  5 ++--
 include/soc/mscc/ocelot.h                  | 34 +++++++++++++++++++++-
 include/soc/mscc/ocelot_vcap.h             | 32 --------------------
 6 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 9e28219b223d..f6a1e8e90bda 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1199,7 +1199,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 	ocelot->stats_layout	= felix->info->stats_layout;
 	ocelot->num_stats	= felix->info->num_stats;
 	ocelot->num_mact_rows	= felix->info->num_mact_rows;
-	ocelot->vcap		= felix->info->vcap;
+	memcpy(&ocelot->vcap, felix->info->vcap,
+	       OCELOT_NUM_VCAP_BLOCKS * sizeof(*felix->info->vcap));
 	ocelot->vcap_pol.base	= felix->info->vcap_pol_base;
 	ocelot->vcap_pol.max	= felix->info->vcap_pol_max;
 	ocelot->vcap_pol.base2	= felix->info->vcap_pol_base2;
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index d6cf5e5a48c5..fb928c8bf544 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -27,7 +27,7 @@ struct felix_info {
 	unsigned int			num_stats;
 	int				num_ports;
 	int				num_tx_queues;
-	struct ocelot_vcap_props	*vcap;
+	const struct ocelot_vcap_props	*vcap;
 	u16				vcap_pol_base;
 	u16				vcap_pol_max;
 	u16				vcap_pol_base2;
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index a60dbedc1b1c..ddf4e8a9905c 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -845,7 +845,7 @@ static struct vcap_field vsc9959_vcap_is2_actions[] = {
 	[VCAP_IS2_ACT_HIT_CNT]			= { 44, 32},
 };
 
-static struct ocelot_vcap_props vsc9959_vcap_props[] = {
+static const struct ocelot_vcap_props vsc9959_vcap_props[] = {
 	[VCAP_ES0] = {
 		.action_type_width = 0,
 		.action_table = {
diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
index 12c739cb89f9..4fe51591afa8 100644
--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -344,7 +344,7 @@ static const struct ocelot_ops ocelot_ops = {
 	.netdev_to_port		= ocelot_netdev_to_port,
 };
 
-static struct ocelot_vcap_props vsc7514_vcap_props[] = {
+static const struct ocelot_vcap_props vsc7514_vcap_props[] = {
 	[VCAP_ES0] = {
 		.action_type_width = 0,
 		.action_table = {
@@ -638,7 +638,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
 	ocelot->num_phys_ports = of_get_child_count(ports);
 	ocelot->num_flooding_pgids = 1;
 
-	ocelot->vcap = vsc7514_vcap_props;
+	memcpy(&ocelot->vcap, &vsc7514_vcap_props,
+	       OCELOT_NUM_VCAP_BLOCKS * sizeof(*vsc7514_vcap_props));
 
 	ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE;
 	ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX;
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 42634183d062..b097b97993b0 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -525,6 +525,15 @@ enum {
 	VCAP_CONST_IF_CNT,
 };
 
+enum {
+	VCAP_ES0,
+	VCAP_IS1,
+	VCAP_IS2,
+	__VCAP_COUNT,
+};
+
+#define OCELOT_NUM_VCAP_BLOCKS		__VCAP_COUNT
+
 enum ocelot_ptp_pins {
 	PTP_PIN_0,
 	PTP_PIN_1,
@@ -583,6 +592,29 @@ struct ocelot_vcap_block {
 	int count;
 };
 
+struct ocelot_vcap_props {
+	u16 tg_width; /* Type-group width (in bits) */
+	u16 sw_count; /* Sub word count */
+	u16 entry_count; /* Entry count */
+	u16 entry_words; /* Number of entry words */
+	u16 entry_width; /* Entry width (in bits) */
+	u16 action_count; /* Action count */
+	u16 action_words; /* Number of action words */
+	u16 action_width; /* Action width (in bits) */
+	u16 action_type_width; /* Action type width (in bits) */
+	struct {
+		u16 width; /* Action type width (in bits) */
+		u16 count; /* Action type sub word count */
+	} action_table[2];
+	u16 counter_words; /* Number of counter words */
+	u16 counter_width; /* Counter width (in bits) */
+
+	enum ocelot_target		target;
+
+	const struct vcap_field		*keys;
+	const struct vcap_field		*actions;
+};
+
 struct ocelot_bridge_vlan {
 	u16 vid;
 	unsigned long portmask;
@@ -727,7 +759,7 @@ struct ocelot {
 	struct list_head		dummy_rules;
 	struct ocelot_vcap_block	block[3];
 	struct ocelot_vcap_policer	vcap_pol;
-	struct ocelot_vcap_props	*vcap;
+	struct ocelot_vcap_props	vcap[OCELOT_NUM_VCAP_BLOCKS];
 	struct ocelot_mirror		*mirror;
 
 	struct ocelot_psfp_list		psfp;
diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h
index 05bd73c63675..96ca1498f722 100644
--- a/include/soc/mscc/ocelot_vcap.h
+++ b/include/soc/mscc/ocelot_vcap.h
@@ -27,38 +27,6 @@
  * =================================================================
  */
 
-enum {
-	VCAP_ES0,
-	VCAP_IS1,
-	VCAP_IS2,
-	__VCAP_COUNT,
-};
-
-#define OCELOT_NUM_VCAP_BLOCKS		__VCAP_COUNT
-
-struct ocelot_vcap_props {
-	u16 tg_width; /* Type-group width (in bits) */
-	u16 sw_count; /* Sub word count */
-	u16 entry_count; /* Entry count */
-	u16 entry_words; /* Number of entry words */
-	u16 entry_width; /* Entry width (in bits) */
-	u16 action_count; /* Action count */
-	u16 action_words; /* Number of action words */
-	u16 action_width; /* Action width (in bits) */
-	u16 action_type_width; /* Action type width (in bits) */
-	struct {
-		u16 width; /* Action type width (in bits) */
-		u16 count; /* Action type sub word count */
-	} action_table[2];
-	u16 counter_words; /* Number of counter words */
-	u16 counter_width; /* Counter width (in bits) */
-
-	enum ocelot_target		target;
-
-	const struct vcap_field		*keys;
-	const struct vcap_field		*actions;
-};
-
 /* VCAP Type-Group values */
 #define VCAP_TG_NONE 0 /* Entry is invalid */
 #define VCAP_TG_FULL 1 /* Full entry */
-- 
2.25.1


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

* Re: [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props
  2022-04-29 23:30 ` [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props Colin Foster
@ 2022-04-30  2:06   ` Jakub Kicinski
  2022-04-30 17:27     ` Colin Foster
  2022-04-30 14:24   ` Vladimir Oltean
  1 sibling, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2022-04-30  2:06 UTC (permalink / raw)
  To: Colin Foster
  Cc: linux-kernel, netdev, Paolo Abeni, Eric Dumazet, David S. Miller,
	Florian Fainelli, Vivien Didelot, Andrew Lunn, UNGLinuxDriver,
	Alexandre Belloni, Claudiu Manoil, Vladimir Oltean

On Fri, 29 Apr 2022 16:30:49 -0700 Colin Foster wrote:
> Fixes: 2096805497e2b ("net: mscc: ocelot: automatically detect VCAP
> constants")
> 
> Signed-off-by: Colin Foster <colin.foster@in-advantage.com>

Please don't line-wrap tags and please don't add empty lines between
them. Let's give Vladimir a day or two to comment on the merits and
please repost with the tags fixed, thanks!

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

* Re: [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member
  2022-04-29 23:30 ` [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member Colin Foster
@ 2022-04-30  2:07   ` Jakub Kicinski
  2022-04-30 17:36     ` Colin Foster
  0 siblings, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2022-04-30  2:07 UTC (permalink / raw)
  To: Colin Foster
  Cc: linux-kernel, netdev, Paolo Abeni, Eric Dumazet, David S. Miller,
	Florian Fainelli, Vivien Didelot, Andrew Lunn, UNGLinuxDriver,
	Alexandre Belloni, Claudiu Manoil, Vladimir Oltean

On Fri, 29 Apr 2022 16:30:48 -0700 Colin Foster wrote:
> The vcap_props structure is part of the ocelot driver. It is in the process
> of being exported to a wider scope, so renaming it to match other structure
> definitions in the include/soc/mscc/ocelot.h makes sense.
> 
> I'm splitting the rename operation into this separate commit, since it
> should make the actual bug fix (next commit) easier to review.

Sure, but is it really necessary to do it now, or can we do it later 
in net-next? There's only one struct vcap_props in the tree AFAICT.

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

* Re: [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props
  2022-04-29 23:30 ` [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props Colin Foster
  2022-04-30  2:06   ` Jakub Kicinski
@ 2022-04-30 14:24   ` Vladimir Oltean
  2022-04-30 17:24     ` Colin Foster
  1 sibling, 1 reply; 13+ messages in thread
From: Vladimir Oltean @ 2022-04-30 14:24 UTC (permalink / raw)
  To: Colin Foster
  Cc: linux-kernel, netdev, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	UNGLinuxDriver, Alexandre Belloni, Claudiu Manoil

Hi Colin,

On Fri, Apr 29, 2022 at 04:30:49PM -0700, Colin Foster wrote:
> Each instance of an ocelot struct has the ocelot_vcap_props structure being
> referenced. During initialization (ocelot_init), these vcap_props are
> detected and the structure contents are modified.
> 
> In the case of the standard ocelot driver, there will probably only be one
> instance of struct ocelot, since it is part of the chip.
> 
> For the Felix driver, there could be multiple instances of struct ocelot.
> In that scenario, the second time ocelot_init would get called, it would
> corrupt what had been done in the first call because they both reference
> *ocelot->vcap. Both of these instances were assigned the same memory
> location.
> 
> Move this vcap_props memory to within struct ocelot, so that each instance
> can modify the structure to their heart's content without corrupting other
> instances.
> 
> Fixes: 2096805497e2b ("net: mscc: ocelot: automatically detect VCAP
> constants")
> 
> Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
> ---

To prove an issue, you must come with an example of two switches which
share the same struct vcap_props, but contain different VCAP constants
in the hardware registers. Otherwise, what you call "corruption" is just
"overwriting with the same values".

I would say that by definition, if two such switches have different VCAP
constants, they have different vcap_props structures, and if they have
the same vcap_props structure, they have the same VCAP constants.

Therefore, even in a multi-switch environment, a second call to
ocelot_vcap_detect_constants() would overwrite the vcap->entry_width,
vcap->tg_width, vcap->sw_count, vcap->entry_count, vcap->action_count,
vcap->action_width, vcap->counter_words, vcap->counter_width with the
exact same values.

I do not see the point in duplicating struct vcap_props per ocelot
instance.

I assume you are noticing some problems with VSC7512? What are they?
Note that since VSC7512 isn't currently supported by the kernel, even a
theoretical corruption issue doesn't qualify as a bug, since there is no
way to reproduce it. All the Microchip switches supported by the kernel
are internal to an SoC, are single switches, and they have different
vcap_props structures.

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

* Re: [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props
  2022-04-30 14:24   ` Vladimir Oltean
@ 2022-04-30 17:24     ` Colin Foster
  2022-04-30 21:56       ` Vladimir Oltean
  0 siblings, 1 reply; 13+ messages in thread
From: Colin Foster @ 2022-04-30 17:24 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: linux-kernel, netdev, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	UNGLinuxDriver, Alexandre Belloni, Claudiu Manoil

Hi Vladimir,

On Sat, Apr 30, 2022 at 02:24:57PM +0000, Vladimir Oltean wrote:
> Hi Colin,
> 
> On Fri, Apr 29, 2022 at 04:30:49PM -0700, Colin Foster wrote:
> > Each instance of an ocelot struct has the ocelot_vcap_props structure being
> > referenced. During initialization (ocelot_init), these vcap_props are
> > detected and the structure contents are modified.
> > 
> > In the case of the standard ocelot driver, there will probably only be one
> > instance of struct ocelot, since it is part of the chip.
> > 
> > For the Felix driver, there could be multiple instances of struct ocelot.
> > In that scenario, the second time ocelot_init would get called, it would
> > corrupt what had been done in the first call because they both reference
> > *ocelot->vcap. Both of these instances were assigned the same memory
> > location.
> > 
> > Move this vcap_props memory to within struct ocelot, so that each instance
> > can modify the structure to their heart's content without corrupting other
> > instances.
> > 
> > Fixes: 2096805497e2b ("net: mscc: ocelot: automatically detect VCAP
> > constants")
> > 
> > Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
> > ---
> 
> To prove an issue, you must come with an example of two switches which
> share the same struct vcap_props, but contain different VCAP constants
> in the hardware registers. Otherwise, what you call "corruption" is just
> "overwriting with the same values".
> 
> I would say that by definition, if two such switches have different VCAP
> constants, they have different vcap_props structures, and if they have
> the same vcap_props structure, they have the same VCAP constants.
> 
> Therefore, even in a multi-switch environment, a second call to
> ocelot_vcap_detect_constants() would overwrite the vcap->entry_width,
> vcap->tg_width, vcap->sw_count, vcap->entry_count, vcap->action_count,
> vcap->action_width, vcap->counter_words, vcap->counter_width with the
> exact same values.
> 
> I do not see the point in duplicating struct vcap_props per ocelot
> instance.
> 
> I assume you are noticing some problems with VSC7512? What are they?

I'm not seeing issues, no. I was looking to implement the shared
ocelot_vcap struct between the 7514 and (in-development 7512. In doing
so I came across this realization that these per-file structures could
be referenced multiple times, which was the point of this patch. If the
structure were simply a const configuration there would be no issue, but
since it is half const and half runtime populated it got more complicated.

(that is likely why I didn't make it shared initially... which feels
like ages ago at this point)

Whether or not hardware exists that could be affected by this corner
case I don't know.

> Note that since VSC7512 isn't currently supported by the kernel, even a
> theoretical corruption issue doesn't qualify as a bug, since there is no
> way to reproduce it. All the Microchip switches supported by the kernel
> are internal to an SoC, are single switches, and they have different
> vcap_props structures.

I see. So I do have a misunderstanding in the process.

I shouldn't have submitted this to net, because it isn't an actual "bug"
I observed. Instead it was a potential issue with existing code, and
could have affected certain hardware configurations. How should I have
sent this out? (RFC? net-next? separate conversation discussing the
validity?)

Back to this patch in particular:

You're saying there's no need to duplicate the vcap_props structure
array per ocelot instance. Understood. Would it be an improvement to
split up vcap into a const configuration section (one per hardware
layout) and a detected set? Or would you have any other suggestion?

And, of course, I can drag this along with my 7512 patch set for now, or
try to get this in now. This one feels like it is worth keeping
separate...

And thanks as always for your feedback!

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

* Re: [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props
  2022-04-30  2:06   ` Jakub Kicinski
@ 2022-04-30 17:27     ` Colin Foster
  0 siblings, 0 replies; 13+ messages in thread
From: Colin Foster @ 2022-04-30 17:27 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: linux-kernel, netdev, Paolo Abeni, Eric Dumazet, David S. Miller,
	Florian Fainelli, Vivien Didelot, Andrew Lunn, UNGLinuxDriver,
	Alexandre Belloni, Claudiu Manoil, Vladimir Oltean

Hi Jakub,

On Fri, Apr 29, 2022 at 07:06:22PM -0700, Jakub Kicinski wrote:
> On Fri, 29 Apr 2022 16:30:49 -0700 Colin Foster wrote:
> > Fixes: 2096805497e2b ("net: mscc: ocelot: automatically detect VCAP
> > constants")
> > 
> > Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
> 
> Please don't line-wrap tags and please don't add empty lines between
> them. Let's give Vladimir a day or two to comment on the merits and
> please repost with the tags fixed, thanks!

Yep. I saw that on patchwork. Oops. I'll fix it up in whatever future
patch comes.

Thanks!

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

* Re: [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member
  2022-04-30  2:07   ` Jakub Kicinski
@ 2022-04-30 17:36     ` Colin Foster
  0 siblings, 0 replies; 13+ messages in thread
From: Colin Foster @ 2022-04-30 17:36 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: linux-kernel, netdev, Paolo Abeni, Eric Dumazet, David S. Miller,
	Florian Fainelli, Vivien Didelot, Andrew Lunn, UNGLinuxDriver,
	Alexandre Belloni, Claudiu Manoil, Vladimir Oltean

Hi Jakub,

On Fri, Apr 29, 2022 at 07:07:52PM -0700, Jakub Kicinski wrote:
> On Fri, 29 Apr 2022 16:30:48 -0700 Colin Foster wrote:
> > The vcap_props structure is part of the ocelot driver. It is in the process
> > of being exported to a wider scope, so renaming it to match other structure
> > definitions in the include/soc/mscc/ocelot.h makes sense.
> > 
> > I'm splitting the rename operation into this separate commit, since it
> > should make the actual bug fix (next commit) easier to review.
> 
> Sure, but is it really necessary to do it now, or can we do it later 
> in net-next? There's only one struct vcap_props in the tree AFAICT.

I see your point. There wouldn't be a name collision, so the change
isn't absolutely necessary - just a nice convention. So I could have
patched the "bug" in net, then done the rename in net-next. I hadn't
considered this.

It seems like this patch set is bound for net-next in some way, shape,
or form, so it might be a non-issue.

Thanks for the feedback!

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

* Re: [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props
  2022-04-30 17:24     ` Colin Foster
@ 2022-04-30 21:56       ` Vladimir Oltean
  2022-04-30 22:26         ` Colin Foster
  0 siblings, 1 reply; 13+ messages in thread
From: Vladimir Oltean @ 2022-04-30 21:56 UTC (permalink / raw)
  To: Colin Foster
  Cc: linux-kernel, netdev, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	UNGLinuxDriver, Alexandre Belloni, Claudiu Manoil

On Sat, Apr 30, 2022 at 10:24:00AM -0700, Colin Foster wrote:
> Hi Vladimir,
> 
> On Sat, Apr 30, 2022 at 02:24:57PM +0000, Vladimir Oltean wrote:
> > Hi Colin,
> > 
> > On Fri, Apr 29, 2022 at 04:30:49PM -0700, Colin Foster wrote:
> > > Each instance of an ocelot struct has the ocelot_vcap_props structure being
> > > referenced. During initialization (ocelot_init), these vcap_props are
> > > detected and the structure contents are modified.
> > > 
> > > In the case of the standard ocelot driver, there will probably only be one
> > > instance of struct ocelot, since it is part of the chip.
> > > 
> > > For the Felix driver, there could be multiple instances of struct ocelot.
> > > In that scenario, the second time ocelot_init would get called, it would
> > > corrupt what had been done in the first call because they both reference
> > > *ocelot->vcap. Both of these instances were assigned the same memory
> > > location.
> > > 
> > > Move this vcap_props memory to within struct ocelot, so that each instance
> > > can modify the structure to their heart's content without corrupting other
> > > instances.
> > > 
> > > Fixes: 2096805497e2b ("net: mscc: ocelot: automatically detect VCAP
> > > constants")
> > > 
> > > Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
> > > ---
> > 
> > To prove an issue, you must come with an example of two switches which
> > share the same struct vcap_props, but contain different VCAP constants
> > in the hardware registers. Otherwise, what you call "corruption" is just
> > "overwriting with the same values".
> > 
> > I would say that by definition, if two such switches have different VCAP
> > constants, they have different vcap_props structures, and if they have
> > the same vcap_props structure, they have the same VCAP constants.
> > 
> > Therefore, even in a multi-switch environment, a second call to
> > ocelot_vcap_detect_constants() would overwrite the vcap->entry_width,
> > vcap->tg_width, vcap->sw_count, vcap->entry_count, vcap->action_count,
> > vcap->action_width, vcap->counter_words, vcap->counter_width with the
> > exact same values.
> > 
> > I do not see the point in duplicating struct vcap_props per ocelot
> > instance.
> > 
> > I assume you are noticing some problems with VSC7512? What are they?
> 
> I'm not seeing issues, no. I was looking to implement the shared
> ocelot_vcap struct between the 7514 and (in-development 7512. In doing
> so I came across this realization that these per-file structures could
> be referenced multiple times, which was the point of this patch. If the
> structure were simply a const configuration there would be no issue, but
> since it is half const and half runtime populated it got more complicated.
> 
> (that is likely why I didn't make it shared initially... which feels
> like ages ago at this point)
> 
> Whether or not hardware exists that could be affected by this corner
> case I don't know.

VSC7512 documentation at the following link, VCAP constants are laid out
in tables 72-74 starting with page 112:
https://ww1.microchip.com/downloads/en/DeviceDoc/VMDS-10489.pdf

VSC7514 documentation at the following link, VCAP constants are laid out
in tables 71-73 starting with page 111:
https://ww1.microchip.com/downloads/en/DeviceDoc/VMDS-10491.pdf

As you can see, they are identical. Coincidence? I think not. After all,
they are from the same generation and have the same port count.
So even if the new vsc7512 driver reuses the vsc7514 structure for VCAP
properties, and is instantiated in a system where a vsc7514 switch is
also instantiated, I claim that nothing bad will happen. Are you
claiming otherwise? What is that bad thing, exactly?

> 
> > Note that since VSC7512 isn't currently supported by the kernel, even a
> > theoretical corruption issue doesn't qualify as a bug, since there is no
> > way to reproduce it. All the Microchip switches supported by the kernel
> > are internal to an SoC, are single switches, and they have different
> > vcap_props structures.
> 
> I see. So I do have a misunderstanding in the process.
> 
> I shouldn't have submitted this to net, because it isn't an actual "bug"
> I observed. Instead it was a potential issue with existing code, and
> could have affected certain hardware configurations. How should I have
> sent this out? (RFC? net-next? separate conversation discussing the
> validity?)

I can't answer how you should have sent out this patch, since I don't
yet understand what is gained by making the change.

> Back to this patch in particular:
> 
> You're saying there's no need to duplicate the vcap_props structure
> array per ocelot instance. Understood. Would it be an improvement to
> split up vcap into a const configuration section (one per hardware
> layout) and a detected set? Or would you have any other suggestion?

Maybe, although I assume the only reason why you're proposing that is
that you want to then proceed and make the detected properties unique
per switch, which again would increase the memory footprint of the
driver for a reason I am not following.

I suppose there's also the option of leaving code that isn't broken
alone?

> And, of course, I can drag this along with my 7512 patch set for now,

Why?

> or try to get this in now. This one feels like it is worth keeping
> separate...
> 
> And thanks as always for your feedback!

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

* Re: [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props
  2022-04-30 21:56       ` Vladimir Oltean
@ 2022-04-30 22:26         ` Colin Foster
  0 siblings, 0 replies; 13+ messages in thread
From: Colin Foster @ 2022-04-30 22:26 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: linux-kernel, netdev, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	UNGLinuxDriver, Alexandre Belloni, Claudiu Manoil

On Sat, Apr 30, 2022 at 09:56:52PM +0000, Vladimir Oltean wrote:
> On Sat, Apr 30, 2022 at 10:24:00AM -0700, Colin Foster wrote:
> > Hi Vladimir,
> > 
> > On Sat, Apr 30, 2022 at 02:24:57PM +0000, Vladimir Oltean wrote:
> > > Hi Colin,
> > > 
> > > On Fri, Apr 29, 2022 at 04:30:49PM -0700, Colin Foster wrote:
> > > > Each instance of an ocelot struct has the ocelot_vcap_props structure being
> > > > referenced. During initialization (ocelot_init), these vcap_props are
> > > > detected and the structure contents are modified.
> > > > 
> > > > In the case of the standard ocelot driver, there will probably only be one
> > > > instance of struct ocelot, since it is part of the chip.
> > > > 
> > > > For the Felix driver, there could be multiple instances of struct ocelot.
> > > > In that scenario, the second time ocelot_init would get called, it would
> > > > corrupt what had been done in the first call because they both reference
> > > > *ocelot->vcap. Both of these instances were assigned the same memory
> > > > location.
> > > > 
> > > > Move this vcap_props memory to within struct ocelot, so that each instance
> > > > can modify the structure to their heart's content without corrupting other
> > > > instances.
> > > > 
> > > > Fixes: 2096805497e2b ("net: mscc: ocelot: automatically detect VCAP
> > > > constants")
> > > > 
> > > > Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
> > > > ---
> > > 
> > > To prove an issue, you must come with an example of two switches which
> > > share the same struct vcap_props, but contain different VCAP constants
> > > in the hardware registers. Otherwise, what you call "corruption" is just
> > > "overwriting with the same values".
> > > 
> > > I would say that by definition, if two such switches have different VCAP
> > > constants, they have different vcap_props structures, and if they have
> > > the same vcap_props structure, they have the same VCAP constants.
> > > 
> > > Therefore, even in a multi-switch environment, a second call to
> > > ocelot_vcap_detect_constants() would overwrite the vcap->entry_width,
> > > vcap->tg_width, vcap->sw_count, vcap->entry_count, vcap->action_count,
> > > vcap->action_width, vcap->counter_words, vcap->counter_width with the
> > > exact same values.
> > > 
> > > I do not see the point in duplicating struct vcap_props per ocelot
> > > instance.
> > > 
> > > I assume you are noticing some problems with VSC7512? What are they?
> > 
> > I'm not seeing issues, no. I was looking to implement the shared
> > ocelot_vcap struct between the 7514 and (in-development 7512. In doing
> > so I came across this realization that these per-file structures could
> > be referenced multiple times, which was the point of this patch. If the
> > structure were simply a const configuration there would be no issue, but
> > since it is half const and half runtime populated it got more complicated.
> > 
> > (that is likely why I didn't make it shared initially... which feels
> > like ages ago at this point)
> > 
> > Whether or not hardware exists that could be affected by this corner
> > case I don't know.
> 
> VSC7512 documentation at the following link, VCAP constants are laid out
> in tables 72-74 starting with page 112:
> https://ww1.microchip.com/downloads/en/DeviceDoc/VMDS-10489.pdf
> 
> VSC7514 documentation at the following link, VCAP constants are laid out
> in tables 71-73 starting with page 111:
> https://ww1.microchip.com/downloads/en/DeviceDoc/VMDS-10491.pdf
> 
> As you can see, they are identical. Coincidence? I think not. After all,
> they are from the same generation and have the same port count.
> So even if the new vsc7512 driver reuses the vsc7514 structure for VCAP
> properties, and is instantiated in a system where a vsc7514 switch is
> also instantiated, I claim that nothing bad will happen. Are you
> claiming otherwise? What is that bad thing, exactly?

I see your point - I misinterpreted the severity here. I agree at the
end of the day we'll possibly write the same values into a memory
location multiple times, and since there's no supported hardware that
differs there won't be a risk. If, at some point in the future, a
chip comes along with slightly different parameters it could become a
problem, but there's no need to solve a problem now that might never
exist.

Thanks for the feedback. I'll drop this patch, as it isn't necessary.

> 
> > 
> > > Note that since VSC7512 isn't currently supported by the kernel, even a
> > > theoretical corruption issue doesn't qualify as a bug, since there is no
> > > way to reproduce it. All the Microchip switches supported by the kernel
> > > are internal to an SoC, are single switches, and they have different
> > > vcap_props structures.
> > 
> > I see. So I do have a misunderstanding in the process.
> > 
> > I shouldn't have submitted this to net, because it isn't an actual "bug"
> > I observed. Instead it was a potential issue with existing code, and
> > could have affected certain hardware configurations. How should I have
> > sent this out? (RFC? net-next? separate conversation discussing the
> > validity?)
> 
> I can't answer how you should have sent out this patch, since I don't
> yet understand what is gained by making the change.
> 
> > Back to this patch in particular:
> > 
> > You're saying there's no need to duplicate the vcap_props structure
> > array per ocelot instance. Understood. Would it be an improvement to
> > split up vcap into a const configuration section (one per hardware
> > layout) and a detected set? Or would you have any other suggestion?
> 
> Maybe, although I assume the only reason why you're proposing that is
> that you want to then proceed and make the detected properties unique
> per switch, which again would increase the memory footprint of the
> driver for a reason I am not following.
> 
> I suppose there's also the option of leaving code that isn't broken
> alone?
> 
> > And, of course, I can drag this along with my 7512 patch set for now,
> 
> Why?
> 
> > or try to get this in now. This one feels like it is worth keeping
> > separate...
> > 
> > And thanks as always for your feedback!

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

* Re: [PATCH v1 net 0/2] fix shared vcap_props reference
  2022-04-29 23:30 [PATCH v1 net 0/2] fix shared vcap_props reference Colin Foster
  2022-04-29 23:30 ` [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member Colin Foster
  2022-04-29 23:30 ` [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props Colin Foster
@ 2022-05-01 10:52 ` Vladimir Oltean
  2022-05-01 21:09   ` Colin Foster
  2 siblings, 1 reply; 13+ messages in thread
From: Vladimir Oltean @ 2022-05-01 10:52 UTC (permalink / raw)
  To: Colin Foster
  Cc: linux-kernel, netdev, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	UNGLinuxDriver, Alexandre Belloni, Claudiu Manoil

On Fri, Apr 29, 2022 at 04:30:47PM -0700, Colin Foster wrote:
> I don't have any hardware to confidently test the vcap portions of
> Ocelot / Felix, so any testers would be appreciated.

You know about tools/testing/selftests/drivers/net/ocelot/tc_flower_chains.sh,
right?

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

* Re: [PATCH v1 net 0/2] fix shared vcap_props reference
  2022-05-01 10:52 ` [PATCH v1 net 0/2] fix shared vcap_props reference Vladimir Oltean
@ 2022-05-01 21:09   ` Colin Foster
  0 siblings, 0 replies; 13+ messages in thread
From: Colin Foster @ 2022-05-01 21:09 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: linux-kernel, netdev, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Florian Fainelli, Vivien Didelot, Andrew Lunn,
	UNGLinuxDriver, Alexandre Belloni, Claudiu Manoil

On Sun, May 01, 2022 at 10:52:09AM +0000, Vladimir Oltean wrote:
> On Fri, Apr 29, 2022 at 04:30:47PM -0700, Colin Foster wrote:
> > I don't have any hardware to confidently test the vcap portions of
> > Ocelot / Felix, so any testers would be appreciated.
> 
> You know about tools/testing/selftests/drivers/net/ocelot/tc_flower_chains.sh,
> right?

I'll add this to the (long) list of things you've taught / shown me.
Thanks! And thanks for testing.

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

end of thread, other threads:[~2022-05-01 21:10 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-29 23:30 [PATCH v1 net 0/2] fix shared vcap_props reference Colin Foster
2022-04-29 23:30 ` [PATCH v1 net 1/2] net: ethernet: ocelot: rename vcap_props to clearly be an ocelot member Colin Foster
2022-04-30  2:07   ` Jakub Kicinski
2022-04-30 17:36     ` Colin Foster
2022-04-29 23:30 ` [PATCH v1 net 2/2] net: mscc: ocelot: fix possible memory conflict for vcap_props Colin Foster
2022-04-30  2:06   ` Jakub Kicinski
2022-04-30 17:27     ` Colin Foster
2022-04-30 14:24   ` Vladimir Oltean
2022-04-30 17:24     ` Colin Foster
2022-04-30 21:56       ` Vladimir Oltean
2022-04-30 22:26         ` Colin Foster
2022-05-01 10:52 ` [PATCH v1 net 0/2] fix shared vcap_props reference Vladimir Oltean
2022-05-01 21:09   ` Colin Foster

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.