Beispiel #1
0
int
set_page_data(struct DataTable *tbl, void *va, data_t id)
{
  int i;

  pge_t *pge = &(tbl->table)[PGX(va)];
  if(! *pge) {
    pthread_mutex_lock(&tbl->lock);
    *pge = malloc(sizeof(pue_t) * TBLENTRIES);
    memset(*pge, 0, sizeof(pue_t) * TBLENTRIES);
    pthread_mutex_unlock(&tbl->lock);
  }
  
  pue_t *pue = &(*pge)[PUX(va)];
  if(! *pue) {
    pthread_mutex_lock(&tbl->lock);
    *pue = malloc(sizeof(pme_t) * TBLENTRIES);
    memset(*pue, 0, sizeof(pme_t) * TBLENTRIES);
    pthread_mutex_unlock(&tbl->lock);
  }

  pme_t *pme = &(*pue)[PMX(va)];
  if(! *pme) {
    pthread_mutex_lock(&tbl->lock);
    *pme = malloc(sizeof(data_t) * TBLENTRIES);
    memset(*pme, 0, sizeof(data_t) * TBLENTRIES);
    pthread_mutex_unlock(&tbl->lock);
  }

  DEBUG_LOG("set_page_data of %p from %lu to %lu", va, (*pme)[PTX(va)], id);
  (*pme)[PTX(va)] = id;

  return 0;
}
Beispiel #2
0
pud_t *
get_pud(pgd_t *pgdir, uintptr_t la, bool create) {
#if PUXSHIFT == PGXSHIFT
	return get_pgd(pgdir, la, create);
#else /* PUXSHIFT == PGXSHIFT */
    pgd_t *pgdp;
    if ((pgdp = get_pgd(pgdir, la, create)) == NULL) {
        return NULL;
    }
    if (! ptep_present(pgdp)) {
        struct Page *page;
        if (!create || (page = alloc_page()) == NULL) {
            return NULL;
        }
        set_page_ref(page, 1);
        uintptr_t pa = page2pa(page);
        memset(KADDR(pa), 0, PGSIZE);
        ptep_map(pgdp, pa);
        ptep_set_u_write(pgdp);
        ptep_set_accessed(pgdp);
        ptep_set_dirty(pgdp);
    }
    return &((pud_t *)KADDR(PGD_ADDR(*pgdp)))[PUX(la)];
#endif /* PUXSHIFT == PGXSHIFT */
}
Beispiel #3
0
void
kmm_pgfault(struct trapframe *tf)
{
	// uint64_t  err  = tf->tf_err;
	uintptr_t addr = rcr2();

	if (addr >= PBASE && addr < PBASE + PSIZE)
	{
		pgd_t *pgd = KADDR_DIRECT(PTE_ADDR(rcr3()));
		pud_t *pud;
		pmd_t *pmd;
		pte_t *ptd;
		
		/* PHYSICAL ADDRRESS ACCESSING */
		if (last_pgd != NULL)
		{
			pud = KADDR_DIRECT(PGD_ADDR(last_pgd[PGX(last_addr)]));
			pmd = KADDR_DIRECT(PUD_ADDR(pud[PUX(last_addr)]));
			ptd = KADDR_DIRECT(PMD_ADDR(pmd[PMX(last_addr)]));

			ptd[PTX(last_addr)] = 0;
			if (ptd == temp_ptd)
			{
				pmd[PUX(last_addr)] = 0;
				if (pmd == temp_pmd)
				{
					pud[PUX(last_addr)] = 0;
					if (pud == temp_pud)
						last_pgd[PGX(last_addr)] = 0;
				}
				
				if (last_pgd == pgd)
				{
					invlpg((void *)last_addr);
				}
			}
		}

		if (pgd[PGX(last_addr)] == 0)
			pgd[PGX(last_addr)] = PADDR_DIRECT(temp_pud) | PTE_W | PTE_P;
		pud = KADDR_DIRECT(PGD_ADDR(pgd[PGX(last_addr)]));
		if (pud[PUX(last_addr)] == 0)
			pud[PUX(last_addr)] = PADDR_DIRECT(temp_pmd) | PTE_W | PTE_P;
		pmd = KADDR_DIRECT(PUD_ADDR(pud[PUX(last_addr)]));
		if (pmd[PMX(last_addr)] == 0)
			pmd[PMX(last_addr)] = PADDR_DIRECT(temp_ptd) | PTE_W | PTE_P;
		ptd = KADDR_DIRECT(PMD_ADDR(pmd[PMX(last_addr)]));

		ptd[PTX(last_addr)] = PADDR_DIRECT(addr) | PTE_W | PTE_P;

		last_pgd = pgd;
		last_addr = addr;

		/* XXX? */
		// invlpg((void *)addr);
	}
}
Beispiel #4
0
static void
exit_range_pud(pud_t *pud) {
#if PUXSHIFT == PGXSHIFT
	exit_range_pmd(pud);
#else
    uintptr_t la = 0;
    do {
        pud_t *pudp = &pud[PUX(la)];
        if (ptep_present(pudp)) {
            exit_range_pmd(KADDR(PUD_ADDR(*pudp)));
            free_page(pud2page(*pudp)), *pudp = 0;
        }
        la += PMSIZE;
    } while (la != PUSIZE);
#endif
}
Beispiel #5
0
int
get_page_data(struct DataTable *tbl, void *va, data_t *id_out)
{
  pge_t *pge = &(tbl->table)[PGX(va)];
  if(! *pge) goto get_fault;
  
  pue_t *pue = &(*pge)[PUX(va)];
  if(! *pue) goto get_fault;

  pme_t *pme = &(*pue)[PMX(va)];
  if(! *pme) goto get_fault;

  *id_out = (*pme)[PTX(va)];
  return 0;
  
 get_fault:
  if (tbl->do_get_faults)
    return -E_NO_ENTRY;
  *id_out = 0;
  return 0;
}
Beispiel #6
0
static void
unmap_range_pud(pgd_t *pgdir, pud_t *pud, uintptr_t base, uintptr_t start, uintptr_t end) {
#if PUXSHIFT == PGXSHIFT
	unmap_range_pmd (pgdir, pud, base, start, end);
#else
    assert(start >= 0 && start < end && end <= PUSIZE);
    size_t off, size;
    uintptr_t la = ROUNDDOWN(start, PMSIZE);
    do {
        off = start - la, size = PMSIZE - off;
        if (size > end - start) {
            size = end - start;
        }
        pud_t *pudp = &pud[PUX(la)];
        if (ptep_present(pudp)) {
            unmap_range_pmd(pgdir, KADDR(PUD_ADDR(*pudp)), base + la, off, off + size);
        }
        start += size, la += PMSIZE;
    } while (start != 0 && start < end);
#endif
}
Beispiel #7
0
pud_t *
get_pud(pgd_t *pgdir, uintptr_t la, bool create) {
#if PUXSHIFT == PGXSHIFT
	return get_pgd(pgdir, la, create);
#else /* PUXSHIFT == PGXSHIFT */
    pgd_t *pgdp;
    if ((pgdp = get_pgd(pgdir, la, create)) == NULL) {
        return NULL;
    }
    if (!(*pgdp & PTE_P)) {
        struct Page *page;
        if (!create || (page = alloc_page()) == NULL) {
            return NULL;
        }
        set_page_ref(page, 1);
        uintptr_t pa = page2pa(page);
        memset(VADDR_DIRECT(pa), 0, PGSIZE);
        *pgdp = pa | PTE_U | PTE_W | PTE_P;
    }
    return &((pud_t *)VADDR_DIRECT(PGD_ADDR(*pgdp)))[PUX(la)];
#endif /* PUXSHIFT == PGXSHIFT */
}