netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net: fix unaligned memory accesses in ASIX
@ 2009-03-26  6:52 Giuseppe CAVALLARO
  2009-03-26  8:08 ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Giuseppe CAVALLARO @ 2009-03-26  6:52 UTC (permalink / raw)
  To: netdev; +Cc: Giuseppe Cavallaro

Move in memory all the frames with an incorrect alignment.
This is to prevent unaligned memory accesses into the upper layers.
Note 1: this is a penalty for some architecture like SH.
Note 2: indeed, this patch restores an old one posted three years ago
(http://marc.info/?l=linux-usb-devel&m=116578791817830&w=2).

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
 drivers/net/usb/asix.c |   42 ++++++++++++++++++++++++------------------
 1 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 396f821..cea98be 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -298,26 +298,37 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
 
 static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
-	u8  *head;
-	u32  header;
-	char *packet;
-	struct sk_buff *ax_skb;
-	u16 size;
-
-	head = (u8 *) skb->data;
-	memcpy(&header, head, sizeof(header));
+	unsigned int header;
+
+	memcpy(&header, skb->data, sizeof(header));
 	le32_to_cpus(&header);
-	packet = head + sizeof(header);
 
 	skb_pull(skb, 4);
 
 	while (skb->len > 0) {
+		struct sk_buff *ax_skb;
+		unsigned int size;
+		int offset;
+
 		if ((short)(header & 0x0000ffff) !=
 		    ~((short)((header & 0xffff0000) >> 16))) {
 			deverr(dev,"asix_rx_fixup() Bad Header Length");
 		}
+
 		/* get the packet length */
-		size = (u16) (header & 0x0000ffff);
+		size = header & 0x0000ffff;
+
+		/* Move in memory frames with incorrect alignment.
+		 * This is to prevent unaligned memory accesses into
+		 * the upper layers. */
+		offset = NET_IP_ALIGN ? ((unsigned long)skb->data -
+			 NET_IP_ALIGN) & 3 : 0;
+
+		if (offset) {
+			skb->data -= offset;
+			skb->tail -= offset;
+			memmove(skb->data - offset, skb->data, skb->len);
+		}
 
 		if ((skb->len) - ((size + 1) & 0xfffe) == 0)
 			return 2;
@@ -327,23 +338,18 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 		}
 		ax_skb = skb_clone(skb, GFP_ATOMIC);
 		if (ax_skb) {
-			ax_skb->len = size;
-			ax_skb->data = packet;
-			skb_set_tail_pointer(ax_skb, size);
+			skb_trim(ax_skb, size);
 			usbnet_skb_return(dev, ax_skb);
-		} else {
+		} else
 			return 0;
-		}
 
 		skb_pull(skb, (size + 1) & 0xfffe);
 
 		if (skb->len == 0)
 			break;
 
-		head = (u8 *) skb->data;
-		memcpy(&header, head, sizeof(header));
+		memcpy(&header, skb->data, sizeof(header));
 		le32_to_cpus(&header);
-		packet = head + sizeof(header);
 		skb_pull(skb, 4);
 	}
 
-- 
1.6.0.6


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

* Re: [PATCH] net: fix unaligned memory accesses in ASIX
  2009-03-26  6:52 [PATCH] net: fix unaligned memory accesses in ASIX Giuseppe CAVALLARO
@ 2009-03-26  8:08 ` David Miller
  2009-03-26  8:40   ` Giuseppe CAVALLARO
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2009-03-26  8:08 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Thu, 26 Mar 2009 07:52:39 +0100

> Move in memory all the frames with an incorrect alignment.
> This is to prevent unaligned memory accesses into the upper layers.
> Note 1: this is a penalty for some architecture like SH.
> Note 2: indeed, this patch restores an old one posted three years ago
> (http://marc.info/?l=linux-usb-devel&m=116578791817830&w=2).
> 
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>

There are some gratuitous (and wrong) changes in here:

> -	u32  header;
 ...
> +	unsigned int header;

It's a u32 whether you like it or not.  Please don't
change away from fixed sized types.

Also isn't there a way we can prefixed what this packet
offset is going to be?  If so, we can adjust the skb_reserve()
call the generic USB net code uses.

Thanks.

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

* Re: [PATCH] net: fix unaligned memory accesses in ASIX
  2009-03-26  8:08 ` David Miller
@ 2009-03-26  8:40   ` Giuseppe CAVALLARO
  2009-03-26  9:00     ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Giuseppe CAVALLARO @ 2009-03-26  8:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

David Miller wrote:
> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Thu, 26 Mar 2009 07:52:39 +0100
>
>   
>> Move in memory all the frames with an incorrect alignment.
>> This is to prevent unaligned memory accesses into the upper layers.
>> Note 1: this is a penalty for some architecture like SH.
>> Note 2: indeed, this patch restores an old one posted three years ago
>> (http://marc.info/?l=linux-usb-devel&m=116578791817830&w=2).
>>
>> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>>     
>
> There are some gratuitous (and wrong) changes in here:
>
>   
>> -	u32  header;
>>     
>  ...
>   
>> +	unsigned int header;
>>     
>
> It's a u32 whether you like it or not.  Please don't
> change away from fixed sized types.
>   
I agree... it's a typo error.
> Also isn't there a way we can prefixed what this packet
> offset is going to be?  If so, we can adjust the skb_reserve()
> call the generic USB net code uses.
>   
This was my first test. I had tried to change/adjust headroom but no
success.

Unfortunately, unaligned memory accesses seems to depend on the Asix HW
that packs several incoming frames.
So when these frames are 'unpacked' within the fix-up function, and
pushed to the upper layer, they can have a wrong alignment, indeed.
When no frame is packed all works fine and the IP never works with
unaligned addresses.
I think, the skb_reserve could actually help us, if this last scenario
generated misaligned accesses.
Please let me know if I'm missing something.

Thanks for your feedback!
Regards,
Peppe
> Thanks.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>   


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

* Re: [PATCH] net: fix unaligned memory accesses in ASIX
  2009-03-26  8:40   ` Giuseppe CAVALLARO
@ 2009-03-26  9:00     ` David Miller
  2009-03-26 10:01       ` Giuseppe CAVALLARO
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2009-03-26  9:00 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Thu, 26 Mar 2009 09:40:13 +0100

> Unfortunately, unaligned memory accesses seems to depend on the Asix HW
> that packs several incoming frames.
> So when these frames are 'unpacked' within the fix-up function, and
> pushed to the upper layer, they can have a wrong alignment, indeed.
> When no frame is packed all works fine and the IP never works with
> unaligned addresses.
> I think, the skb_reserve could actually help us, if this last scenario
> generated misaligned accesses.
> Please let me know if I'm missing something.

The unpacker is taking a set of packet(s) in a USB buffer
and copying them into SKB's right?  That code should be where
the offset is checked in the child driver, and adjustments
made as-needed.

This code seems to call the downstream driver callback after
the damage is done.  I think it needs to ask the driver to
look for and indicate the offset before the building of the
SKB is performed.

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

* Re: [PATCH] net: fix unaligned memory accesses in ASIX
  2009-03-26  9:00     ` David Miller
@ 2009-03-26 10:01       ` Giuseppe CAVALLARO
  2009-04-15 10:14         ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Giuseppe CAVALLARO @ 2009-03-26 10:01 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

David Miller wrote:
> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Thu, 26 Mar 2009 09:40:13 +0100
>
>   
>> Unfortunately, unaligned memory accesses seems to depend on the Asix HW
>> that packs several incoming frames.
>> So when these frames are 'unpacked' within the fix-up function, and
>> pushed to the upper layer, they can have a wrong alignment, indeed.
>> When no frame is packed all works fine and the IP never works with
>> unaligned addresses.
>> I think, the skb_reserve could actually help us, if this last scenario
>> generated misaligned accesses.
>> Please let me know if I'm missing something.
>>     
>
> The unpacker is taking a set of packet(s) in a USB buffer
> and copying them into SKB's right?  That code should be where
> the offset is checked in the child driver, and adjustments
> made as-needed.
>
> This code seems to call the downstream driver callback after
> the damage is done.  I think it needs to ask the driver to
> look for and indicate the offset before the building of the
> SKB is performed.
>   
I understand your point of view.

In any case, at first glance, I understand that the urb->transfer_buffer
directly points to the preallocated skb data.
These are filled by the HWs. I mean, the buffers are treated by the HW.
So I guess, the meaning of the rx_fixup functions is just to solve this
kind of situations.
In fact, each usb net driver has an own fixup code according to their HW
specifications.

Peppe

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

* Re: [PATCH] net: fix unaligned memory accesses in ASIX
  2009-03-26 10:01       ` Giuseppe CAVALLARO
@ 2009-04-15 10:14         ` David Miller
  0 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2009-04-15 10:14 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Thu, 26 Mar 2009 11:01:50 +0100

> In any case, at first glance, I understand that the urb->transfer_buffer
> directly points to the preallocated skb data.
> These are filled by the HWs. I mean, the buffers are treated by the HW.
> So I guess, the meaning of the rx_fixup functions is just to solve this
> kind of situations.
> In fact, each usb net driver has an own fixup code according to their HW
> specifications.

Now I understand, thanks for the explanation.

Please resubmit your patch for ASIX, and I will apply it.

Thanks!

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

end of thread, other threads:[~2009-04-15 10:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-26  6:52 [PATCH] net: fix unaligned memory accesses in ASIX Giuseppe CAVALLARO
2009-03-26  8:08 ` David Miller
2009-03-26  8:40   ` Giuseppe CAVALLARO
2009-03-26  9:00     ` David Miller
2009-03-26 10:01       ` Giuseppe CAVALLARO
2009-04-15 10:14         ` David Miller

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).