2123 }
2124
2125 seg = AS_SEGNEXT(as, seg);
2126
2127 if (seg != NULL)
2128 addr = seg->s_base;
2129 }
2130
2131 *basep = addr;
2132
2133 if (segend > eaddr)
2134 *lenp = eaddr - addr;
2135 else
2136 *lenp = segend - addr;
2137
2138 AS_LOCK_EXIT(as, &as->a_lock);
2139 return (0);
2140 }
2141
2142 /*
2143 * Swap the pages associated with the address space as out to
2144 * secondary storage, returning the number of bytes actually
2145 * swapped.
2146 *
2147 * The value returned is intended to correlate well with the process's
2148 * memory requirements. Its usefulness for this purpose depends on
2149 * how well the segment-level routines do at returning accurate
2150 * information.
2151 */
2152 size_t
2153 as_swapout(struct as *as)
2154 {
2155 struct seg *seg;
2156 size_t swpcnt = 0;
2157
2158 /*
2159 * Kernel-only processes have given up their address
2160 * spaces. Of course, we shouldn't be attempting to
2161 * swap out such processes in the first place...
2162 */
2163 if (as == NULL)
2164 return (0);
2165
2166 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
2167
2168 /* Prevent XHATs from attaching */
2169 mutex_enter(&as->a_contents);
2170 AS_SETBUSY(as);
2171 mutex_exit(&as->a_contents);
2172
2173
2174 /*
2175 * Free all mapping resources associated with the address
2176 * space. The segment-level swapout routines capitalize
2177 * on this unmapping by scavanging pages that have become
2178 * unmapped here.
2179 */
2180 hat_swapout(as->a_hat);
2181 if (as->a_xhat != NULL)
2182 xhat_swapout_all(as);
2183
2184 mutex_enter(&as->a_contents);
2185 AS_CLRBUSY(as);
2186 mutex_exit(&as->a_contents);
2187
2188 /*
2189 * Call the swapout routines of all segments in the address
2190 * space to do the actual work, accumulating the amount of
2191 * space reclaimed.
2192 */
2193 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
2194 struct seg_ops *ov = seg->s_ops;
2195
2196 /*
2197 * We have to check to see if the seg has
2198 * an ops vector because the seg may have
2199 * been in the middle of being set up when
2200 * the process was picked for swapout.
2201 */
2202 if ((ov != NULL) && (ov->swapout != NULL))
2203 swpcnt += SEGOP_SWAPOUT(seg);
2204 }
2205 AS_LOCK_EXIT(as, &as->a_lock);
2206 return (swpcnt);
2207 }
2208
2209 /*
2210 * Determine whether data from the mappings in interval [addr, addr + size)
2211 * are in the primary memory (core) cache.
2212 */
2213 int
2214 as_incore(struct as *as, caddr_t addr,
2215 size_t size, char *vec, size_t *sizep)
2216 {
2217 struct seg *seg;
2218 size_t ssize;
2219 caddr_t raddr; /* rounded down addr */
2220 size_t rsize; /* rounded up size */
2221 size_t isize; /* iteration size */
2222 int error = 0; /* result, assume success */
2223
2224 *sizep = 0;
2225 raddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
2226 rsize = ((((size_t)addr + size) + PAGEOFFSET) & PAGEMASK) -
2227 (size_t)raddr;
2228
2229 if (raddr + rsize < raddr) /* check for wraparound */
|
2123 }
2124
2125 seg = AS_SEGNEXT(as, seg);
2126
2127 if (seg != NULL)
2128 addr = seg->s_base;
2129 }
2130
2131 *basep = addr;
2132
2133 if (segend > eaddr)
2134 *lenp = eaddr - addr;
2135 else
2136 *lenp = segend - addr;
2137
2138 AS_LOCK_EXIT(as, &as->a_lock);
2139 return (0);
2140 }
2141
2142 /*
2143 * Determine whether data from the mappings in interval [addr, addr + size)
2144 * are in the primary memory (core) cache.
2145 */
2146 int
2147 as_incore(struct as *as, caddr_t addr,
2148 size_t size, char *vec, size_t *sizep)
2149 {
2150 struct seg *seg;
2151 size_t ssize;
2152 caddr_t raddr; /* rounded down addr */
2153 size_t rsize; /* rounded up size */
2154 size_t isize; /* iteration size */
2155 int error = 0; /* result, assume success */
2156
2157 *sizep = 0;
2158 raddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
2159 rsize = ((((size_t)addr + size) + PAGEOFFSET) & PAGEMASK) -
2160 (size_t)raddr;
2161
2162 if (raddr + rsize < raddr) /* check for wraparound */
|