void as_destroy(struct addrspace *as) { pt_destroy(as->as_pgtbl); #if OPT_ASID tlb_flush_asid(as->as_id); #endif kfree(as); }
// NIY: think about real int safe static void alloc_asid(ADDRESS *adp) { static int asid_rotor = 1; int asid, i; ADDRESS *oldadp; /* * Be very, very careful in here. We can be allocating an asid for * somebody and have an interrupt go off. If the interrupt has a * handler routine, we will re-enterantly execute this code to set up * the address space for the routine. */ /* * Do a quick scan through the asid_map and see * if there are any unallocated entries. The * reason why we do this is because it is cheaper * to do this one scan than to steal an asid, * do a MemPageFlushAsid, and also possibly incur * tlb refills for the poor guy we stole from. * If there are no unallocated asids, then go * back to where we were in the asid_map. */ // asid 0 is reserved for system address space for(i = 1; i <= VM_ASID_BOUNDARY; ++i) { if(asid_map[i] == NULL) { asid_map[i] = adp; adp->cpu.asid = i; #ifdef VARIANT_smp /* * Indicate ASID needs purging on all cpus */ atomic_set(&adp->cpu.asid_flush, LEGAL_CPU_BITMASK); #endif return; } } /* have to steal one */ asid = asid_rotor; if(++asid_rotor > VM_ASID_BOUNDARY) { asid_rotor = 1; } adp->cpu.asid = asid; #ifdef VARIANT_smp /* * Indicate ASID needs purging on all cpus */ atomic_set(&adp->cpu.asid_flush, LEGAL_CPU_BITMASK); #endif oldadp = asid_map[asid]; asid_map[asid] = adp; if(oldadp != NULL) { /* * Mark his asid as invalid so * that when we switch to him he'll * pick up another one. */ oldadp->cpu.asid = ~0; #ifdef VARIANT_smp /* * We will flush the asid in vmm_aspace */ #else tlb_flush_asid(asid); #endif } }