Module Name:    src
Committed By:   martin
Date:           Tue Feb  6 12:18:56 UTC 2024

Modified Files:
        src/sys/dev/usb [netbsd-10]: ehci.c ehcireg.h

Log Message:
Pull up following revision(s) (requested by jmcneill in ticket #585):

        sys/dev/usb/ehcireg.h: revision 1.38
        sys/dev/usb/ehci.c: revision 1.321

Fix DMA sync flags in ehci_append_sqtd

Ensure proper alignment/padding of EHCI hardware descriptors.

These descriptor structs are embedded in structs that contain additional
context for software. With a non cache coherent device and non-padded
descriptors, the device may issue a read/modify/write past the end of
the descriptor, clobbering software state in the process. This was the
root cause of multiple crashes on evbppc with a non cache coherent EHCI.


To generate a diff of this commit:
cvs rdiff -u -r1.315.2.2 -r1.315.2.3 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.37 -r1.37.50.1 src/sys/dev/usb/ehcireg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.315.2.2 src/sys/dev/usb/ehci.c:1.315.2.3
--- src/sys/dev/usb/ehci.c:1.315.2.2	Mon Oct 30 17:45:10 2023
+++ src/sys/dev/usb/ehci.c	Tue Feb  6 12:18:55 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.315.2.2 2023/10/30 17:45:10 martin Exp $ */
+/*	$NetBSD: ehci.c,v 1.315.2.3 2024/02/06 12:18:55 martin Exp $ */
 
 /*
  * Copyright (c) 2004-2012,2016,2020 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.315.2.2 2023/10/30 17:45:10 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.315.2.3 2024/02/06 12:18:55 martin Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -3060,7 +3060,7 @@ ehci_append_sqtd(ehci_soft_qtd_t *sqtd, 
 		prev->qtd.qtd_next = htole32(sqtd->physaddr);
 		prev->qtd.qtd_altnext = prev->qtd.qtd_next;
 		usb_syncmem(&prev->dma, prev->offs, sizeof(prev->qtd),
-		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 	}
 }
 

Index: src/sys/dev/usb/ehcireg.h
diff -u src/sys/dev/usb/ehcireg.h:1.37 src/sys/dev/usb/ehcireg.h:1.37.50.1
--- src/sys/dev/usb/ehcireg.h:1.37	Sat Apr 23 10:15:31 2016
+++ src/sys/dev/usb/ehcireg.h	Tue Feb  6 12:18:55 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehcireg.h,v 1.37 2016/04/23 10:15:31 skrll Exp $	*/
+/*	$NetBSD: ehcireg.h,v 1.37.50.1 2024/02/06 12:18:55 martin Exp $	*/
 
 /*
  * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
@@ -203,6 +203,7 @@ typedef uint32_t ehci_isoc_trans_t;
 typedef uint32_t ehci_isoc_bufr_ptr_t;
 
 /* Isochronous Transfer Descriptor */
+#define EHCI_ITD_ALIGN 32
 #define EHCI_ITD_NUFRAMES USB_UFRAMES_PER_FRAME
 #define EHCI_ITD_NBUFFERS 7
 typedef struct {
@@ -247,10 +248,10 @@ typedef struct {
 #define EHCI_ITD_GET_MULTI(x)	__SHIFTOUT((x), EHCI_ITD_MULTI_MASK)
 #define EHCI_ITD_SET_MULTI(x)	__SHIFTIN((x), EHCI_ITD_MULTI_MASK)
 	volatile ehci_isoc_bufr_ptr_t	itd_bufr_hi[EHCI_ITD_NBUFFERS];
-} ehci_itd_t;
-#define EHCI_ITD_ALIGN 32
+} __aligned(EHCI_ITD_ALIGN) ehci_itd_t;
 
 /* Split Transaction Isochronous Transfer Descriptor */
+#define EHCI_SITD_ALIGN 32
 typedef struct {
 	volatile ehci_link_t	sitd_next;
 	volatile uint32_t	sitd_endp;
@@ -294,12 +295,12 @@ typedef struct {
 
 	volatile ehci_link_t	sitd_back;
 	volatile uint32_t	sitd_buffer_hi[EHCI_SITD_BUFFERS];
-} ehci_sitd_t;
-#define EHCI_SITD_ALIGN 32
+} __aligned(EHCI_SITD_ALIGN) ehci_sitd_t;
 
 /* Queue Element Transfer Descriptor */
 #define EHCI_QTD_NBUFFERS	5
 #define EHCI_QTD_MAXTRANSFER	(EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE)
+#define EHCI_QTD_ALIGN 32
 typedef struct {
 	volatile ehci_link_t	qtd_next;
 	volatile ehci_link_t	qtd_altnext;
@@ -338,10 +339,10 @@ typedef struct {
 #define	EHCI_QTD_SET_TOGGLE(x)	__SHIFTIN((x), EHCI_QTD_TOGGLE_MASK)
 	volatile ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
 	volatile ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
-} ehci_qtd_t;
-#define EHCI_QTD_ALIGN 32
+} __aligned(EHCI_QTD_ALIGN) ehci_qtd_t;
 
 /* Queue Head */
+#define EHCI_QH_ALIGN 32
 typedef struct {
 	volatile ehci_link_t	qh_link;
 	volatile uint32_t	qh_endp;
@@ -388,16 +389,26 @@ typedef struct {
 #define EHCI_QH_GET_MULT(x)	__SHIFTOUT((x), EHCI_QH_MULTI_MASK)
 #define EHCI_QH_SET_MULT(x)	__SHIFTIN((x), EHCI_QH_MULTI_MASK)
 	volatile ehci_link_t	qh_curqtd;
-	ehci_qtd_t		qh_qtd;
-} ehci_qh_t;
-#define EHCI_QH_ALIGN 32
+	/*
+	 * The QH descriptor contains a TD overlay, but it is not
+	 * 32-byte aligned, so declare the fields instead of embedding
+	 * a ehci_qtd_t directly.
+	 */
+	struct {
+		volatile ehci_link_t	qtd_next;
+		volatile ehci_link_t	qtd_altnext;
+		volatile uint32_t	qtd_status;
+		volatile ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
+		volatile ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
+	} qh_qtd;
+} __aligned(EHCI_QH_ALIGN) ehci_qh_t;
 
 /* Periodic Frame Span Traversal Node */
+#define EHCI_FSTN_ALIGN 32
 typedef struct {
 	volatile ehci_link_t	fstn_link;
 	volatile ehci_link_t	fstn_back;
-} ehci_fstn_t;
-#define EHCI_FSTN_ALIGN 32
+} __aligned(EHCI_FSTN_ALIGN) ehci_fstn_t;
 
 /* Debug Port */
 #define PCI_CAP_DEBUGPORT_OFFSET __BITS(28,16)

Reply via email to