Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Oct 1998 10:11:01 -0400 (EDT)
From:      "Ron G. Minnich" <rminnich@Sarnoff.COM>
To:        Luigi Rizzo <luigi@labinfo.iet.unipi.it>
Cc:        hackers@FreeBSD.ORG
Subject:   Re: Handling page faults in user space ?
Message-ID:  <Pine.SUN.3.91.981021100807.6097I-100000@terra>
In-Reply-To: <199810210744.IAA09732@labinfo.iet.unipi.it>

next in thread | previous in thread | raw e-mail | index | archive | help
here's how I do it in zounds:

#ifdef bsd
void
zcfault (int sig, int code, struct sigcontext *scp, void *addr)
#endif
#ifdef linux
void
zcfault (int sig, mysigcontext scp)
#endif
{
  ZCINFO *zc;
  off_t off;
  size_t size = PAGESIZE;
#ifdef linux
  void *addr = (void *) scp.cr2;
#endif
  DEBUG(fprintf(stderr, "(%s):ZCFAULT: addr. 0x%x\n",
                stamp(),
                (unsigned int) addr););
  /* first find the zc for the fault */
  zc = zcfind(addr);
  /* round the address to page bounadry */

  if (! zc)
    {
      printf("(%s):zcfault: No handler for address 0x%x\n",
             stamp(),  (unsigned int) addr);
      abort();
    }
   
  /* round the address to page bounadry */
  addr = (void *) trunc_page(addr);
  /* now compute offset. size is simply pagesize */
  off = ((off_t) addr);
  off -= ((off_t) zc->v);
  DEBUG(fprintf(stderr, "(%s):ZCFAULT: call zcread now\n", stamp()););
  if ((zc->readfd >= 0) && (zc->writefd >= 0))
    {
#ifdef PRESENTBITS
    /* fill the page, given the zc, and using the presence bits */
    if (zc->use_present_bits)
      {
        zcfillregion(zc, off, size);
      }
    else
#endif
      zcread(zc, off, size);
    }
   else
    if (zc->multifd >= 0) /* we are a multicast client. Just create the 
memory */
      zcvalidate(zc, off, size);
     else
      {
        fprintf(stderr,
          "(%s):ZCFAULT: no tcp or multicast fd: can not handle fault\n",
          stamp());
        exit(1);
      }
  DEBUG(fprintf(stderr, "(%s):ZCFAULT: done zcread\n", stamp()););
#ifdef linux
  signal(SIGBUS, zcfault);
  signal(SIGSEGV, zcfault);
#endif
}


Note also that we have to catch sigbus and sigsegv; bsd has traditionally 
gotten bus and segv backwards. Openbsd has fixed this, and I've lost 
track of whether freebsd has. 

ron

Ron Minnich                |"Using Windows NT, which is known to have some 
rminnich@sarnoff.com       | failure modes, on a warship is similar to hoping 
(609)-734-3120             | that luck will be in our favor"- A. Digiorgio
ftp://ftp.sarnoff.com/pub/mnfs/www/docs/cluster.html 

   



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.SUN.3.91.981021100807.6097I-100000>