Example #1
0
static int
pin_and_count_noncontigs (char *addr, u_int datalen)
{
  u_int data, next, ppn, prev_ppn;
  u_int noncontigs = 0;

  data = (u_int) addr;
  prev_ppn = si->si_nppages;

  while (datalen > 0) {
    ppn = PGNO (*va2ptep (data));
    if (ppn != (prev_ppn + 1)) {
      noncontigs++;
    }
    ppage_pin (&ppages[ppn]);
    prev_ppn = ppn;
    /* go to start of next page of data */
    next = (data & ~PGMASK) + NBPG;
    if (next - data >= datalen) break;
    datalen -= next - data;
    data = next;
  }

  return (noncontigs);
}
Example #2
0
static msgringent *
msgringent_setup (msgringent * u_msgringent)
{
  msgringent *ktmp;
  Pte *pte = NULL;
  int scatptr = 0;
  int total_len = 0;

  ktmp = (msgringent *) malloc (sizeof (msgringent));
  if (ktmp == NULL)
  {
    warn ("msgringent_setup: failed malloc");
    return (NULL);
  }

  ktmp->appaddr = u_msgringent;
  ktmp->owner = NULL;
  ktmp->body.n = 0;

  /* Verify and translate owner field */
  if ((((u_int) u_msgringent->owner % sizeof (int)) ||
       ! (pte = va2ptep ((u_int) u_msgringent->owner)) ||
         ((*pte & WRITE_MASK) != WRITE_MASK)))
  {
    warn ("msgringent_setup: owner field failed\n");
    msgringent_free (ktmp);
    return (NULL);
  }
  ktmp->owner = (u_int *) pa2kva (va2pa (u_msgringent->owner));
  ppage_pin (kva2pp ((u_long) ktmp->owner));

  
  /* Verify and translate data field */
  if (u_msgringent->body.n > 1)
  {
    warn ("msgringent_setup: not allowed to setup disjoint message body\n");
    msgringent_free (ktmp);
    return (NULL);
  }

  scatptr = 0;
  total_len = 0;
  
  {
    int len = u_msgringent->body.r[0].sz;
    caddr_t addr = u_msgringent->body.r[0].data;
    u_int pagebound = NBPG-(((u_long)addr)&(NBPG - 1));

    while (len > 0)
    {
      u_int slen = min (len, pagebound);
      if (!(pte = va2ptep ((u_int) addr)) || 
          ((*pte & READ_MASK) != READ_MASK))
      {
        /* physical page is not accessible */
        warn ("msgringent_setup: can't read scatter ptr\n");
        msgringent_free (ktmp);
        return (NULL);
      }
            
      ktmp->body.r[scatptr].data = (char *) pa2kva (va2pa (addr));
      ktmp->body.r[scatptr].sz = slen;
      ktmp->body.n++;
	
      /* pin the page to prevent re-allocation */
      ppage_pin (kva2pp ((u_long) ktmp->body.r[scatptr].data));
      len -= slen;
      addr += slen;
      total_len += slen;
      pagebound = NBPG;
      scatptr++;
    
      if (scatptr > IPC_MAX_SCATTER_PTR || total_len > IPC_MAX_MSG_SIZE)
      {
        msgringent_free (ktmp);
        warn ("msgringent_setup: message body too big\n");
        return (NULL);
      }
    }
  }

  return (ktmp);
}