RE: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-18 Thread David Laight
  Then the inc_deq() code could just be:
 
  ring-deq_updates++;
  ring-num_trbs_free++;
 
  if (last_trb(xhci, ring, ring-deq_seg, ++ring-dequeue)) {
  ring-deq_seg = ring-deq_seg-next;
  ring-dequeue = ring-deq_seg-trbs;
  if (ring-deq_seg == ring-first_seg) /* not sure of name */
  ring-cycle_state ^= 1;
  }
 
 The cycle state is only changed when the enqueue pointer makes it past
 the segment with the toggle bit.  It shouldn't be modified for the
 dequeue pointer.

Except for the event ring.
I did think that was a quick rewrite of the existing functionality.

Really the code for the event and command rings needs separating completely.
It would all then be clearer.

 And yes, inc_deq() could do with some simplification.  David, are you
 interested in creating a patch to simplify this code?  I haven't gotten
 v2 revisions from a couple of patches you previously sent, so I wasn't
 sure if you're still interested in creating xHCI patches.

I will sort out my existing patches hopefully today.
git managed to trash my source tree and I've been busy fixing some
of my own code.

I was waiting for the patches I'd posted to get processed before
adding many more.  Otherwise it all gets completely out of hand.

Also I've dropped you (Sarah) from the mail address list, our work email
server is getting very strange bounces for linux.intel.com and I think
the list carefully avoids delivering mails to addresses in the mail itself.

David



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-17 Thread David Laight
 From: Wang, Lin X 
 David is right, this patch may lead to the last trb in an event ring 
 unprocessed according to the
 current logic, you can reject this patch, although I think index 
 out-of-bounds is reasonable.
 
 If applying this patch, then corresponding function(inc_deq()) should be 
 modified, maybe like the
 following way:
 
 diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
 index d26cd94..0dbaa56 100644
 --- a/drivers/usb/host/xhci-ring.c
 +++ b/drivers/usb/host/xhci-ring.c
 @@ -185,7 +185,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct 
 xhci_ring *ring)
 } else {
 ring-dequeue++;
 }
 -   } while (last_trb(xhci, ring, ring-deq_seg, ring-dequeue));
 +   } while (last_trb(xhci, ring, ring-deq_seg, ring-dequeue)  
 ring-type != TYPE_EVENT);

There are far too many conditionals in this code already.
Adding an extra one that serves no purpose is silly.

The C language explicitly allows you to take the address of the first
item beyond the end of an array and to use that in expressions
involving pointers to other array members.

David



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-17 Thread David Laight
 From: Sarah Sharp
 On Mon, Dec 16, 2013 at 03:20:28PM -, David Laight wrote:
   I know all these difference clearly,  inc_deq() is indeed a common
   function for different rings, but lasr_trb()  last_trb_on_last_seg()
   inside it use different condition to determine the last trb in an
   event ring and an non-event ring; and sorry, i still not find why last
   trb in an event ring skipped by H/W according to the current logic.
  
   Thanks!
  
 
  Read the specs and the code.
 
 State your objections clearly.
 
 Based on my analysis, this patch will produce correct behavior with the
 event ring:
 
 http://marc.info/?l=linux-usbm=138697807827548w=2
 
 Am I missing something?

 -/* Is this TRB a link TRB or was the last TRB the last TRB in this event ring
 - * segment?  I.e. would the updated event TRB pointer step off the end of the
 - * event seg?
 +/* Is this TRB a link TRB or was the last TRB in this event ring segment?
 + * I.e. would the updated event TRB pointer step off the end of the event
 + * seg?
 */
 static int last_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
 struct xhci_segment *seg, union xhci_trb *trb)
 {
   if (ring == xhci-event_ring)
 - return trb == seg-trbs[TRBS_PER_SEGMENT];
 + return trb == seg-trbs[TRBS_PER_SEGMENT - 1];
   else
   return TRB_TYPE_LINK_LE32(trb-link.control);
 }


It would be extremely confusing for the above function to behave
differently for event and other rings.
Actually last_trb() could just be:
return trb == seg-last_trb;
provided an appropriate 'last_trb' field was set.

If we assume that there are no empty ring segments (ie adjacent LINK TRBs),
and that it is never actually called with a pointer to a link trb.
Then the inc_deq() code could just be:

ring-deq_updates++;
ring-num_trbs_free++;

if (last_trb(xhci, ring, ring-deq_seg, ++ring-dequeue)) {
ring-deq_seg = ring-deq_seg-next;
ring-dequeue = ring-deq_seg-trbs;
if (ring-deq_seg == ring-first_seg) /* not sure of name */
ring-cycle_state ^= 1;
}

David



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-17 Thread Sarah Sharp
On Tue, Dec 17, 2013 at 09:35:39AM -, David Laight wrote:
  From: Wang, Lin X 
  David is right, this patch may lead to the last trb in an event ring 
  unprocessed according to the
  current logic, you can reject this patch, although I think index 
  out-of-bounds is reasonable.
  
  If applying this patch, then corresponding function(inc_deq()) should be 
  modified, maybe like the
  following way:
  
  diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
  index d26cd94..0dbaa56 100644
  --- a/drivers/usb/host/xhci-ring.c
  +++ b/drivers/usb/host/xhci-ring.c
  @@ -185,7 +185,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct 
  xhci_ring *ring)
  } else {
  ring-dequeue++;
  }
  -   } while (last_trb(xhci, ring, ring-deq_seg, ring-dequeue));
  +   } while (last_trb(xhci, ring, ring-deq_seg, ring-dequeue)  
  ring-type != TYPE_EVENT);

Ah, ok, I see where I misread the code now.  Thanks for figuring that
out, David.

 There are far too many conditionals in this code already.
 Adding an extra one that serves no purpose is silly.
 
 The C language explicitly allows you to take the address of the first
 item beyond the end of an array and to use that in expressions
 involving pointers to other array members.

The out-of-bounds pointer math is fine as it stands.  I'll simply drop
this patch.

Sarah Sharp
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-16 Thread David Laight
 From: Of Wang, Lin X
 Sent: 15 December 2013 14:21
 To: Sarah Sharp (sarah.a.sh...@linux.intel.com)
 Cc: linux-usb@vger.kernel.org
 Subject: [PATCH] xhci: fix array index out of the bounds in function 
 last_trb() and
 last_trb_on_last_seg()
 
 In function last_trb() and last_trb_on_last_seg(), incorrect array index 
 value 'TRBS_PER_SEGMENT' is
 used to determine the last element in an event ring segment, which lead to 
 the out-of-bounds
 of index. But according to the current logic of event ring operation, this 
 bug brings no problems
 and the driver works as desired. This patch only fix this array index 
 out-of-bounds issue and there is
 no need no modify corresponding ring operation.
 
 Signed-off-by: Lin Wang lin.x.w...@intel.com
 ---
  drivers/usb/host/xhci-ring.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)
 
 diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
 index d26cd94..3f93b07 100644
 --- a/drivers/usb/host/xhci-ring.c
 +++ b/drivers/usb/host/xhci-ring.c
 @@ -98,21 +98,21 @@ static bool last_trb_on_last_seg(struct xhci_hcd *xhci, 
 struct xhci_ring *ring,
 struct xhci_segment *seg, union xhci_trb *trb)
  {
 if (ring == xhci-event_ring)
 -   return (trb == seg-trbs[TRBS_PER_SEGMENT]) 
 +   return (trb == seg-trbs[TRBS_PER_SEGMENT - 1]) 

Taking the address of the element beyond the end of an array is valid C.
So there is nothing wrong with this code.
Apply the patch and the last event written by the hardware won't be processed.

David


--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-16 Thread 王林
2013/12/16 David Laight david.lai...@aculab.com:
 From: Of Wang, Lin X
 Sent: 15 December 2013 14:21
 To: Sarah Sharp (sarah.a.sh...@linux.intel.com)
 Cc: linux-usb@vger.kernel.org
 Subject: [PATCH] xhci: fix array index out of the bounds in function 
 last_trb() and
 last_trb_on_last_seg()

 In function last_trb() and last_trb_on_last_seg(), incorrect array index 
 value 'TRBS_PER_SEGMENT' is
 used to determine the last element in an event ring segment, which lead to 
 the out-of-bounds
 of index. But according to the current logic of event ring operation, this 
 bug brings no problems
 and the driver works as desired. This patch only fix this array index 
 out-of-bounds issue and there is
 no need no modify corresponding ring operation.

 Signed-off-by: Lin Wang lin.x.w...@intel.com
 ---
  drivers/usb/host/xhci-ring.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

 diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
 index d26cd94..3f93b07 100644
 --- a/drivers/usb/host/xhci-ring.c
 +++ b/drivers/usb/host/xhci-ring.c
 @@ -98,21 +98,21 @@ static bool last_trb_on_last_seg(struct xhci_hcd *xhci, 
 struct xhci_ring *ring,
 struct xhci_segment *seg, union xhci_trb *trb)
  {
 if (ring == xhci-event_ring)
 -   return (trb == seg-trbs[TRBS_PER_SEGMENT]) 
 +   return (trb == seg-trbs[TRBS_PER_SEGMENT - 1]) 

 Taking the address of the element beyond the end of an array is valid C.

It's vaild in C doesn't mean that it‘s reasonable, besides,
'TRBS_PER_SEGMENT - 1' is widely used in current implementation to
identily the last element in an array, using 'TRBS_PER_SEGMENT' here
result in
a lack of unity in style and easy to get lost.

 So there is nothing wrong with this code.
 Apply the patch and the last event written by the hardware won't be processed.

The only function affected here is inc_deq(), and i did not find trb
skipped by H/W, please let me know if i missed something.

Thanks!

Lin


 David


 --
 To unsubscribe from this list: send the line unsubscribe linux-usb in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-16 Thread David Laight
 From: Wang, Lin X
 2013/12/16 David Laight david.lai...@aculab.com:
  From: Of Wang, Lin X
  Sent: 15 December 2013 14:21
  To: Sarah Sharp (sarah.a.sh...@linux.intel.com)
  Cc: linux-usb@vger.kernel.org
  Subject: [PATCH] xhci: fix array index out of the bounds in function 
  last_trb() and
  last_trb_on_last_seg()
 
  In function last_trb() and last_trb_on_last_seg(), incorrect array index 
  value 'TRBS_PER_SEGMENT'
 is
  used to determine the last element in an event ring segment, which lead to 
  the out-of-bounds
  of index. But according to the current logic of event ring operation, this 
  bug brings no problems
  and the driver works as desired. This patch only fix this array index 
  out-of-bounds issue and there
 is
  no need no modify corresponding ring operation.
 
  Signed-off-by: Lin Wang lin.x.w...@intel.com
  ---
   drivers/usb/host/xhci-ring.c | 10 +-
   1 file changed, 5 insertions(+), 5 deletions(-)
 
  diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
  index d26cd94..3f93b07 100644
  --- a/drivers/usb/host/xhci-ring.c
  +++ b/drivers/usb/host/xhci-ring.c
  @@ -98,21 +98,21 @@ static bool last_trb_on_last_seg(struct xhci_hcd 
  *xhci, struct xhci_ring *ring,
  struct xhci_segment *seg, union xhci_trb *trb)
   {
  if (ring == xhci-event_ring)
  -   return (trb == seg-trbs[TRBS_PER_SEGMENT]) 
  +   return (trb == seg-trbs[TRBS_PER_SEGMENT - 1]) 
 
  Taking the address of the element beyond the end of an array is valid C.
 
 It's vaild in C doesn't mean that it‘s reasonable, besides,
 'TRBS_PER_SEGMENT - 1' is widely used in current implementation to
 identily the last element in an array, using 'TRBS_PER_SEGMENT' here
 result in
 a lack of unity in style and easy to get lost.

There is a big difference between the 'event' ring (written by the xhci 
hardware)
and all the other rings (read by the hardware).
The last entry of the non-event rings is always a LINK trb (pointing to the
next ring segment) so must not be overwritten.
The event rings have a separate array that defines the segments and the hardware
writes real data into the last ring entry.

The operation of the event ring is different from the other rings and it was
(IMHO) a mistake to have used common functions for the two.

David



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-16 Thread Lin
2013/12/16 David Laight david.lai...@aculab.com:
 From: Wang, Lin X
 2013/12/16 David Laight david.lai...@aculab.com:
  From: Of Wang, Lin X
  Sent: 15 December 2013 14:21
  To: Sarah Sharp (sarah.a.sh...@linux.intel.com)
  Cc: linux-usb@vger.kernel.org
  Subject: [PATCH] xhci: fix array index out of the bounds in function 
  last_trb() and
  last_trb_on_last_seg()
 
  In function last_trb() and last_trb_on_last_seg(), incorrect array index 
  value 'TRBS_PER_SEGMENT'
 is
  used to determine the last element in an event ring segment, which lead 
  to the out-of-bounds
  of index. But according to the current logic of event ring operation, 
  this bug brings no problems
  and the driver works as desired. This patch only fix this array index 
  out-of-bounds issue and there
 is
  no need no modify corresponding ring operation.
 
  Signed-off-by: Lin Wang lin.x.w...@intel.com
  ---
   drivers/usb/host/xhci-ring.c | 10 +-
   1 file changed, 5 insertions(+), 5 deletions(-)
 
  diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
  index d26cd94..3f93b07 100644
  --- a/drivers/usb/host/xhci-ring.c
  +++ b/drivers/usb/host/xhci-ring.c
  @@ -98,21 +98,21 @@ static bool last_trb_on_last_seg(struct xhci_hcd 
  *xhci, struct xhci_ring *ring,
  struct xhci_segment *seg, union xhci_trb *trb)
   {
  if (ring == xhci-event_ring)
  -   return (trb == seg-trbs[TRBS_PER_SEGMENT]) 
  +   return (trb == seg-trbs[TRBS_PER_SEGMENT - 1]) 
 
  Taking the address of the element beyond the end of an array is valid C.

 It's vaild in C doesn't mean that it‘s reasonable, besides,
 'TRBS_PER_SEGMENT - 1' is widely used in current implementation to
 identily the last element in an array, using 'TRBS_PER_SEGMENT' here
 result in
 a lack of unity in style and easy to get lost.

 There is a big difference between the 'event' ring (written by the xhci 
 hardware)
 and all the other rings (read by the hardware).
 The last entry of the non-event rings is always a LINK trb (pointing to the
 next ring segment) so must not be overwritten.
 The event rings have a separate array that defines the segments and the 
 hardware
 writes real data into the last ring entry.

Hi David,

I know all these difference clearly,  inc_deq() is indeed a common
function for different rings, but lasr_trb()  last_trb_on_last_seg()
inside it use different condition to determine the last trb in an
event ring and an non-event ring; and sorry, i still not find why last
trb in an event ring skipped by H/W according to the current logic.

Thanks!

Lin


 The operation of the event ring is different from the other rings and it was
 (IMHO) a mistake to have used common functions for the two.

 David



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-16 Thread David Laight
 I know all these difference clearly,  inc_deq() is indeed a common
 function for different rings, but lasr_trb()  last_trb_on_last_seg()
 inside it use different condition to determine the last trb in an
 event ring and an non-event ring; and sorry, i still not find why last
 trb in an event ring skipped by H/W according to the current logic.
 
 Thanks!
 

Read the specs and the code.

David



--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] xhci: fix array index out of the bounds in function last_trb() and last_trb_on_last_seg()

2013-12-16 Thread Sarah Sharp
On Mon, Dec 16, 2013 at 03:20:28PM -, David Laight wrote:
  I know all these difference clearly,  inc_deq() is indeed a common
  function for different rings, but lasr_trb()  last_trb_on_last_seg()
  inside it use different condition to determine the last trb in an
  event ring and an non-event ring; and sorry, i still not find why last
  trb in an event ring skipped by H/W according to the current logic.
  
  Thanks!
  
 
 Read the specs and the code.

State your objections clearly.

Based on my analysis, this patch will produce correct behavior with the
event ring:

http://marc.info/?l=linux-usbm=138697807827548w=2

Am I missing something?

Sarah Sharp
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html