/* * Reallocate the maps for a process * * Subtlety: On a 32K box we have the udata area being copied to/from * the stash. As we always realloc for the live process we don't have * to worry about this in the 32K + common case because we'll switchin * at one size, and switchout at the other and the udata will just get * saved/restored to the right places. */ int pagemap_realloc(uint16_t size) { int have = maps_needed(udata.u_top); int want = maps_needed(size); uint8_t *ptr = (uint8_t *) & udata.u_page; /* If we are shrinking then free pages and propogate the common page into the freed spaces */ if (want == have) return 0; if (have > want) { pfree[pfptr++] = ptr[1]; udata.u_ptab->p_page = udata.u_page; return 0; } /* If we are adding then just insert the new pages, keeping the common unchanged at the top */ if (want - have > pfptr) return ENOMEM; /* We don't want to take an interrupt here while our page mappings are incomplete. We may restore bogus mappings and then take a second IRQ into hyperspace */ __critical { ptr[0] = pfree[--pfptr]; /* Copy the updated allocation into the ptab */ udata.u_ptab->p_page = udata.u_page; /* Now fix the vectors up - they've potentially teleported up to 32K up the user address space, we need to put a copy back in low memory before we switch to this memory map */ program_vectors(&udata.u_page); } return 0; }
/* * Reallocate the maps for a process */ int pagemap_realloc(usize_t size) { int8_t have = maps_needed(udata.u_top); int8_t want = maps_needed(size); uint8_t *ptr = (uint8_t *) & udata.u_page; int8_t i; uint8_t update = 0; irqflags_t irq; /* If we are shrinking then free pages and propogate the common page into the freed spaces */ if (want == have) return 0; /* We don't want to take an interrupt here while our page mappings are incomplete. We may restore bogus mappings and then take a second IRQ into hyperspace */ irq = di(); if (have > want) { for (i = want; i < have; i++) { pfree[pfptr++] = ptr[i - 1]; ptr[i - 1] = ptr[3]; } /* We collapsed top and bottom, so we need to sort our vectors and common space out */ if (want == 1) update = 1; } else if (want - have <= pfptr) { /* If we are adding then just insert the new pages, keeping the common unchanged at the top */ for (i = have; i < want; i++) ptr[i - 1] = pfree[--pfptr]; update = 1; } else { irqrestore(irq); return ENOMEM; } /* Copy the updated allocation into the ptab */ udata.u_ptab->p_page = udata.u_page; udata.u_ptab->p_page2 = udata.u_page2; /* Now fix the vectors up - they've potentially teleported up to 48K up the user address space, we need to put a copy back in low memory before we switch to this memory map */ if (update) program_vectors(&udata.u_page); irqrestore(irq); return 0; }
/* * Allocate the maps for this task post fork * We have a hackish fix for init that would be nice * resolve. * * FIXME: we need to move udata.u_top into p-> in order to * support banked swapping. */ int pagemap_alloc(ptptr p) { uint8_t *ptr = (uint8_t *) & p->p_page; int needed = maps_needed(udata.u_top); int i; #ifdef SWAPDEV /* Throw our toys out of our pram until we have enough room */ while (needed > pfptr) if (swapneeded(p, 1) == NULL) return ENOMEM; #else if (needed > pfptr) /* We have no swap so poof... */ return ENOMEM; #endif /* Pages in the low then repeat the top one */ for (i = 0; i < needed; i++) ptr[i] = pfree[--pfptr]; while (i < 4) { ptr[i] = ptr[i - 1]; i++; } return 0; }
/* * Reallocate the maps for a process */ int pagemap_realloc(uint16_t size) { int have = maps_needed(udata.u_top); int want = maps_needed(size); uint8_t *ptr = (uint8_t *) & udata.u_page; int i; irqflags_t irq; /* If we are shrinking then free pages and propogate the common page into the freed spaces */ if (want == have) return 0; if (have > want) { for (i = want; i < have; i++) { pfree[pfptr++] = ptr[i]; ptr[i] = ptr[3]; } udata.u_ptab->p_page = udata.u_page; udata.u_ptab->p_page2 = udata.u_page2; return 0; } /* If we are adding then just insert the new pages, keeping the common unchanged at the top */ if (want - have > pfptr) return ENOMEM; /* We have common low so we must only touch the higher pages. This is different from the high common case */ for (i = have; i < want; i++) ptr[i] = pfree[--pfptr]; while(i < 4) { ptr[i] = ptr[i-1]; i++; } /* Copy the updated allocation into the ptab */ udata.u_ptab->p_page = udata.u_page; udata.u_ptab->p_page2 = udata.u_page2; return 0; }
/* * Allocate the maps for this task post fork * We have a hackish fix for init that would be nice * resolve. */ int pagemap_alloc(ptptr p) { uint8_t *ptr = (uint8_t *) & p->p_page; int needed = maps_needed(udata.u_top); #ifdef SWAPDEV /* Throw our toys out of our pram until we have enough room */ while (needed > pfptr) if (swapneeded(p, 1) == NULL) return ENOMEM; #else if (needed > pfptr) /* We have no swap so poof... */ return ENOMEM; #endif *ptr = pfree[--pfptr]; if (needed == 1) ptr[1] = *ptr; else ptr[1] = pfree[--pfptr]; return 0; }