Ignore:
Timestamp:
Nov 16, 2008, 10:58:10 AM (11 years ago)
Author:
gb
Message:

Using i386_set_ldt() to point %fs at the tcr on 32-bit FreeBSD doesn't work
on a 64-bit kernel. Using i386_set_fsbase does work on both 32-bit and
64-bit kernels, but doesn't allow writing to %fs: at least by the time
we've called i386_set_fsbase() on thread startup, %fs contains an appropriate
selector and it never changes throughout the life of the thread.

File:
1 edited

Legend:

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

    r11345 r11370  
    11031103
    11041104/* It'd be tempting to use i386_set_fsbase() here, but there doesn't
    1105    seem to be any way to free the GDT entry it creates. */
     1105   seem to be any way to free the GDT entry it creates.  Actually,
     1106   it's not clear that that really sets a GDT entry; let's see */
     1107
     1108#define FREEBSD_USE_SET_FSBASE 1
    11061109void
    11071110setup_tcr_extra_segment(TCR *tcr)
    11081111{
     1112#if !FREEBSD_USE_SET_FSBASE
    11091113  struct segment_descriptor sd;
    11101114  uintptr_t addr = (uintptr_t)tcr;
     
    11161120  sd.sd_lobase = addr & ((1<<24)-1);
    11171121  sd.sd_hibase = (addr>>24)&0xff;
     1122
     1123
     1124
    11181125  sd.sd_type = 18;
    11191126  sd.sd_dpl = SEL_UPL;
     
    11301137    tcr->ldt_selector = LSEL(i,SEL_UPL);
    11311138  }
     1139#else
     1140  if (i386_set_fsbase((void*)tcr)) {
     1141    perror("i386_set_fsbase");
     1142    exit(1);
     1143  }
     1144  /* Once we've called i386_set_fsbase, we can't write to %fs. */
     1145  tcr->ldt_selector = GSEL(GUFS_SEL, SEL_UPL);
     1146#endif
    11321147}
    11331148
     
    11351150free_tcr_extra_segment(TCR *tcr)
    11361151{
     1152#if FREEBSD_USE_SET_FSBASE
     1153  /* On a 32-bit kernel, this allocates a GDT entry.  It's not clear
     1154     what it would mean to deallocate that entry. */
     1155  /* If we're running on a 64-bit kernel, we can't write to %fs */
     1156#else
    11371157  int idx = tcr->ldt_selector >> 3;
    11381158  /* load %fs with null segment selector */
     
    11401160  if (i386_set_ldt(idx, NULL, 1) < 0)
    11411161    perror("i386_set_ldt");
     1162#endif
    11421163  tcr->ldt_selector = 0;
    11431164}
    11441165#endif
     1166
    11451167#ifdef SOLARIS
    11461168#include <sys/sysi86.h>
Note: See TracChangeset for help on using the changeset viewer.