Subject: port-sparc64/18453: wrong time comparison in iommu_strbuf_flush_done
To: None <gnats-bugs@gnats.netbsd.org>
From: None <t-nkyma@tcp-ip.or.jp>
List: netbsd-bugs
Date: 09/29/2002 04:21:05
>Number:         18453
>Category:       port-sparc64
>Synopsis:       wrong time comparison in iommu_strbuf_flush_done
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-sparc64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Sep 28 12:22:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Takeshi Nakayama
>Release:        NetBSD 1.6
>Organization:
Private
>Environment:
System: NetBSD nyx 1.6 NetBSD 1.6 (NYX32) #39: Fri Sep 27 18:42:10 JST 2002
 takeshi@nyx:/usr/src/sys/arch/sparc64/compile/NYX32 sparc64
Architecture: sparc
Machine: sparc64
>Description:
	In iommu_strbuf_flush_done(), loops while `cur' less or
	equal `flushtimeout`, but loop ends the next case.

		cur < flushtimeout:
			cur.tv_sec  < flushtimeout.tv_sec
			cur.tv_usec > flushtimeout.tv_usec
>How-To-Repeat:
	code inspection.
>Fix:
	Apply the following patch (this code is from OpenBSD).

Index: iommu.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/dev/iommu.c,v
retrieving revision 1.58
diff -u -d -u -r1.58 iommu.c
--- iommu.c	2002/09/22 07:19:43	1.58
+++ iommu.c	2002/09/28 19:09:17
@@ -69,6 +69,7 @@
 	} while (0)
 
 static	int iommu_strbuf_flush_done __P((struct strbuf_ctl *));
+static	int iommu_tv_comp(struct timeval *, struct timeval *);
 
 /*
  * initialise the UltraSPARC IOMMU (SBUS or PCI):
@@ -340,6 +341,22 @@
 }
 
 static int
+iommu_tv_comp(t1, t2)
+	struct timeval *t1, *t2;
+{
+	if (t1->tv_sec < t2->tv_sec)
+		return (-1);
+	if (t1->tv_sec > t2->tv_sec)
+		return (1);
+	/* t1->tv_sec == t2->tv_sec */
+	if (t1->tv_usec < t2->tv_usec)
+		return (-1);
+	if (t1->tv_usec > t2->tv_usec)
+		return (1);
+	return (0);
+}
+
+static int 
 iommu_strbuf_flush_done(sb)
 	struct strbuf_ctl *sb;
 {
@@ -389,8 +406,7 @@
 
 	/* Bypass non-coherent D$ */
 	while ((!ldxa(sb->sb_flushpa, ASI_PHYS_CACHED)) &&
-		((cur.tv_sec <= flushtimeout.tv_sec) &&
-			(cur.tv_usec <= flushtimeout.tv_usec)))
+		(iommu_tv_comp(&cur, &flushtimeout) <= 0))
 		microtime(&cur);
 
 #ifdef DIAGNOSTIC

>Release-Note:
>Audit-Trail:
>Unformatted: