Changeset 11608


Ignore:
Timestamp:
Jan 11, 2009, 12:56:26 AM (11 years ago)
Author:
gb
Message:

FreeBSD 7.1 on i386 doesn't seem able to ensure that 'current_tcr'
is aligned correctly (I tried several approaches.) It's possible
that previous versions didn't do this right either, and that
changes in TLS in libraries just causes misalignment. Whatever ...
Reserve a thread-local "tcrbuf" (large enough to hold a TCR +
alignment overhead) and a make current_tcr be a thread-local
pointer to (or slightly into) that buffer.

On FreeBSD, i386_set_fsbase() should have the side-effect of
loading the global user fs selector into %fs. On a 64-bit
7.1 kernel, it doesn't change %fs (or at least doesn't change
it in a way that persists across context switches.) I don't yet
know whether or not that's a bug, but for now, try to check the
value in %fs on return from the i386_set_fsbase call. (I submitted
a FreeBSD bug report on this (amd64/130355) ; we'll see what happens.)

Note that this only affects trying to run a 32-bit CCL on a 64-bit
7.1 kernel.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/thread_manager.c

    r11581 r11608  
    2626
    2727#ifdef HAVE_TLS
    28 __thread TCR __attribute__ ((aligned (16))) current_tcr;
     28__thread char tcrbuf[sizeof(TCR)+16];
     29__thread TCR *current_tcr;
    2930#endif
    3031
     
    11611162  }
    11621163#else
    1163   if (i386_set_fsbase((void*)tcr)) {
     1164  extern unsigned short get_fs_register(void);
     1165
     1166  if ((i386_set_fsbase((void*)tcr))) {
    11641167    perror("i386_set_fsbase");
    11651168    exit(1);
    11661169  }
     1170  if (get_fs_register() != GSEL(GUFS_SEL, SEL_UPL)) {
     1171    fprintf(stderr,"i386_set_fsbase didn't set %%fs properly; this my be a problem with the 7.1 FreeBSD-amd64 kernel\n");
     1172    exit(1);
     1173  }
     1174
    11671175  /* Once we've called i386_set_fsbase, we can't write to %fs. */
    11681176  tcr->ldt_selector = GSEL(GUFS_SEL, SEL_UPL);
     
    12871295
    12881296#ifdef HAVE_TLS
    1289   TCR *tcr = &current_tcr;
     1297  TCR *tcr = (TCR *) ((((natural)&tcrbuf)+((natural)15)) & ~((natural)15));
     1298  current_tcr = tcr;
    12901299#else /* no TLS */
    12911300  TCR *tcr = allocate_tcr();
     
    18171826{
    18181827#ifdef HAVE_TLS
    1819   TCR *current = current_tcr.linear;
     1828  TCR *current = current_tcr;
    18201829#else
    18211830  void *tsd = (void *)tsd_get(lisp_global(TCR_KEY));
Note: See TracChangeset for help on using the changeset viewer.