Changeset 10727


Ignore:
Timestamp:
Sep 13, 2008, 7:12:18 AM (11 years ago)
Author:
gb
Message:

Provide LDT setup/free stuff for ia32 Linux.

File:
1 edited

Legend:

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

    r10700 r10727  
    868868  tcr->ldt_selector = NULL_SEL;
    869869}
     870#endif
     871
     872#ifdef LINUX
     873
     874#include <asm/ldt.h>
     875#include <sys/syscall.h>
     876
     877/* see desc_struct in kernel/include/asm-i386/processor.h */
     878typedef struct {
     879  uint32_t a;
     880  uint32_t b;
     881} linux_desc_struct;
     882
     883
     884#define desc_avail(d) (((d)->a) == 0)
     885
     886linux_desc_struct linux_ldt_entries[LDT_ENTRIES];
     887
     888/* We have to ask the Linux kernel for a copy of the ldt table
     889   and manage it ourselves.  It's not clear that this is
     890   thread-safe in general, but we can at least ensure that
     891   it's thread-safe wrt lisp threads. */
     892
     893pthread_mutex_t ldt_lock = PTHREAD_MUTEX_INITIALIZER;  /* simple, non-recursive mutex */
     894
     895int
     896modify_ldt(int func, void *ptr, unsigned long bytecount)
     897{
     898  return syscall(__NR_modify_ldt, func, ptr, bytecount);
     899}
     900
     901
     902void
     903setup_tcr_extra_segment(TCR *tcr)
     904{
     905  int i, n;
     906  short sel;
     907  struct user_desc u = {1, 0, 0, 1, MODIFY_LDT_CONTENTS_DATA, 0, 0, 0, 1};
     908  linux_desc_struct *d = linux_ldt_entries;
     909
     910  pthread_mutex_lock(&ldt_lock);
     911  n = modify_ldt(0,d,LDT_ENTRIES*LDT_ENTRY_SIZE)/LDT_ENTRY_SIZE;
     912  for (i = 0; i < n; i++,d++) {
     913    if (desc_avail(d)) {
     914      break;
     915    }
     916  }
     917  if (i == LDT_ENTRIES) {
     918    pthread_mutex_unlock(&ldt_lock);
     919    fprintf(stderr, "All 8192 ldt entries in use ?\n");
     920    _exit(1);
     921  }
     922  u.entry_number = i;
     923  u.base_addr = (uint32_t)tcr;
     924  u.limit = sizeof(tcr);
     925  u.limit_in_pages = 0;
     926  if (modify_ldt(1,&u,sizeof(struct user_desc)) != 0) {
     927    pthread_mutex_unlock(&ldt_lock);
     928    fprintf(stderr,"Can't assign LDT entry\n");
     929    _exit(1);
     930  }
     931  sel = (i << 3) | 7;
     932  tcr->ldt_selector = sel;
     933  pthread_mutex_unlock(&ldt_lock);
     934}
     935
     936void
     937free_tcr_extra_segment(TCR *tcr)
     938{
     939  struct user_desc u = {0, 0, 0, 0, MODIFY_LDT_CONTENTS_DATA, 0, 0, 0, 0};
     940  short sel = tcr->ldt_selector;
     941
     942  pthread_mutex_lock(&ldt_lock);
     943  /* load %fs with null segement selector */
     944  __asm__ volatile ("mov %0,%%fs" : : "r"(0));
     945  tcr->ldt_selector = 0;
     946  u.entry_number = (sel>>3);
     947  modify_ldt(1,&u,sizeof(struct user_desc));
     948  pthread_mutex_unlock(&ldt_lock);
     949 
     950}
     951
    870952#endif
    871953
Note: See TracChangeset for help on using the changeset viewer.