From nobody@FreeBSD.org  Sun Mar  4 16:41:27 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 902AB37B71A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  4 Mar 2001 16:41:25 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.1/8.11.1) id f250fP281920;
	Sun, 4 Mar 2001 16:41:25 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200103050041.f250fP281920@freefall.freebsd.org>
Date: Sun, 4 Mar 2001 16:41:25 -0800 (PST)
From: raymond@one.com.au
To: freebsd-gnats-submit@FreeBSD.org
Subject: unaligned access crash on stq
X-Send-Pr-Version: www-1.0

>Number:         25535
>Category:       alpha
>Synopsis:       unaligned access crash on stq
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-alpha
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Mar 04 16:50:03 PST 2001
>Closed-Date:    Mon Mar 5 08:56:46 PST 2001
>Last-Modified:  Mon Mar 05 08:57:42 PST 2001
>Originator:     Ray Newman
>Release:        FreeBSD 4.2-RELEASE alpha
>Organization:
One Management Australia
>Environment:
FreeBSD alpha.local 4.2-RELEASE FreeBSD 4.2-RELEASE #0: Tue Nov 21 09:42:09 GMT 2000     jkh@rawhide.osd.bsdi.com:/usr/src/sys/compile/GENERIC  alpha

>Description:
unaligned access crash on stq occurs where address MOD 8 equals 4.
>How-To-Repeat:
// crash.c
//
// Reproduce crash - do the following:
//
// cc -g -o crash crash.c
// ./crash
// lockstart = 0x12001404c
// pid 1804 (crash): unaligned access: va=0x12001404c pc=0x12000096c
// ra=0x120000934 op=stq
//

#include <stdio.h>                              // always include
#include <stdlib.h>                             // these two
#include <sys/types.h>                          // for u_char def

typedef unsigned long long      u_int64;        // unix unsigned quadword
typedef u_int64 chr_q;                          // our quadword special

typedef union VAR_U                             // get at this two ways
{ chr_q var_qu;                                 // variable name (quadword)
  u_char var_cu[8];                             // variable name (as char[])
} var_u;                                        // variable name union

typedef struct LOCKTAB                          // internal lock tables
{ struct LOCKTAB *fwd_link;                     // point at next one
  int size;                                     // how many bytes
  short job;                                    // int job (-1 = free)
  short lock_count;                             // how many times locked by job
  short byte_count;                             // size of following reference
  u_char vol;                                   // vol number
  u_char uci;                                   // uci number (255 = local)
  var_u name;                                   // var name
  u_char key[256];                              // and the key
} locktab;                                      // define locktab

typedef struct SYSTAB                           // system tables
{ void *jobtab;                                 // address of jobtab
  int maxjob;                                   // maximum jobs permitted
  int sem_id;                                   // GBD semaphore id
  int historic;                                 // Enn, tag+off, $NEXT etc
  int max_tt;                                   // max TRANTAB used
  int start_user;                               // he's priv too
  void *lockstart;                              // head of lock table
  int locksize;                                 // how many bytes
  locktab *lockhead;                            // head of used locks
  locktab *lockfree;                            // head of lock free space
  void *vol[1];                        		// array of vol ptrs
  u_int last_blk_used[1];                       // actually setup for real jobs
} systab_struct;                                // end of systab


int main(int argc,char **argv)                  // main entry point
{ int c = 8192;                                 // for case 
  struct SYSTAB *systab;			// for test

  systab = malloc(sizeof(struct SYSTAB) + c);
  bzero(systab, sizeof(struct SYSTAB) + c);

  systab->lockstart = ((char *) systab->last_blk_used + 4);

  printf("lockstart = %p\n", systab->lockstart);

  systab->locksize = c;                  	// the size
  systab->lockhead = NULL;                      // no locks currently

  systab->lockfree = (locktab *) systab->lockstart; // free space
  systab->lockfree->fwd_link = NULL;            // only one

  systab->lockfree->size = c;
  c = 0;
  exit (0);
}

>Fix:

>Release-Note:
>Audit-Trail:

From: Matthew Jacob <mjacob@feral.com>
To: raymond@one.com.au
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: alpha/25535: unaligned access crash on stq
Date: Sun, 4 Mar 2001 16:54:48 -0800 (PST)

 How is this a bug? If you try and access unaligned values you'll get unaligned
 traps.
 
 
 
State-Changed-From-To: open->closed 
State-Changed-By: mjacob 
State-Changed-When: Sun Mar 4 17:02:42 PST 2001 
State-Changed-Why:  
Not a bug. See audit trail in email. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=25535 

From: Matthew Jacob <mjacob@feral.com>
To: User Raymond <raymond@one.com.au>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: alpha/25535: unaligned access crash on stq
Date: Sun, 4 Mar 2001 17:02:21 -0800 (PST)

 (let's keep the audit trail in the PR)
 
 On Mon, 5 Mar 2001, User Raymond wrote:
 
 > Subj: alpha/25535: unaligned access crash on stq
 > To:   mjacob@feral.com
 > From: raymond@one.com.au
 > 
 > 
 > > How is this a bug? If you try and access unaligned values you'll get
 > > unaligned traps.
 > 
 > Sorry - I didn't explain myself at all well did I?
 > 
 > The example was the only way I could force that to happen and I don't
 > know whether the OS is supposed to trap that and fix it on the fly.
 > 
 > The original is in a much larger piece of code that ends up with a structure
 > unalligned and I can't work out how to get around it.  I am porting the
 > code from the x86 platform and not having much luck.
 > 
 > Any pointers would be appreciated.
 > 
 > Ray Newman
 > 
 
 Pointers indeed! :-)
 
 farrago.feral.com > uname -a
 FreeBSD farrago.feral.com 4.2-STABLE FreeBSD 4.2-STABLE #6: Sun Mar  4
 13:33:54 PST 2001     mjacob@farrago.feral.com:/tstsys/compile/GPLUS  alpha
 farrago.feral.com > sysctl -a|grep alig
 vfs.nfs.realign_test: 20065
 vfs.nfs.realign_count: 0
 machdep.unaligned_print: 1
 machdep.unaligned_fix: 1
 machdep.unaligned_sigbus: 0
 
 
 If you set machdep.unaligned_fix to 0, it will stop fixups. The default is to
 do the fixup. If you set machdep.unaligned_print to 0, it won't print.
 
 You might consider how to get the structure aligned as it's much more than
 just alpha that has this issue.
 
 -matt
 
 
State-Changed-From-To: closed->open 
State-Changed-By: mjacob 
State-Changed-When: Sun Mar 4 17:32:37 PST 2001 
State-Changed-Why:  
I re-opened this because, in fact, a SIGBUS is being delivered even when 
this should be a recoverable, if noice trap. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=25535 

From: Matthew Jacob <mjacob@feral.com>
To: User Raymond <raymond@one.com.au>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: alpha/25535: unaligned access crash on stq
Date: Sun, 4 Mar 2001 17:34:28 -0800 (PST)

 Hmm. You're right. It's not recovering. We'll have to look into why.
 
 
 On Mon, 5 Mar 2001, User Raymond wrote:
 
 > Subj: alpha/25535: unaligned access crash on stq
 > To:   mjacob@feral.com
 > From: raymond@one.com.au
 > 
 > > If you set machdep.unaligned_fix to 0, it will stop fixups. The default is to
 > > do the fixup. If you set machdep.unaligned_print to 0, it won't print.
 > 
 > %uname -a
 > FreeBSD alpha.local 4.2-RELEASE FreeBSD 4.2-RELEASE #0: Tue Nov 21 09:42:09 GMT
 > 2000     jkh@rawhide.osd.bsdi.com:/usr/src/sys/compile/GENERIC  alpha
 > %sysctl -a|grep alig
 > vfs.nfs.realign_test: 0
 > vfs.nfs.realign_count: 0
 > machdep.unaligned_print: 1
 > machdep.unaligned_fix: 1
 > machdep.unaligned_sigbus: 0
 > %
 > 
 > I really must be doing something wrong as machdep.unaligned_fix is set.
 > 
 > Ray Newman
 > 
 
 
State-Changed-From-To: open->closed 
State-Changed-By: gallatin 
State-Changed-When: Mon Mar 5 08:56:46 PST 2001 
State-Changed-Why:  
fixed in -stable and -current with rev 1.51 and 1.15.2.3 of alpha/alpha/trap.c 


http://www.freebsd.org/cgi/query-pr.cgi?pr=25535 
>Unformatted:

We were not handling unaligned stores of zeros properly.
The following patch fixes the problem and has been comitted 
to -current and -stable:

Index: trap.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/trap.c,v
retrieving revision 1.26.2.2
diff -u -r1.26.2.2 trap.c
--- trap.c	2000/05/24 14:20:57	1.26.2.2
+++ trap.c	2001/03/05 16:04:23
@@ -777,8 +777,9 @@
 
 #define	unaligned_store(storage, ptrf, mod)				\
 	if ((regptr = ptrf(p, reg)) == NULL)				\
-		break;							\
-	(storage) = mod (*regptr);					\
+		(storage) = 0;						\
+	else								\
+		(storage) = mod (*regptr);				\
 	if (copyout(&(storage), (caddr_t)va, sizeof (storage)) == 0)	\
 		signal = 0;						\
 	else								\


