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: