165 struct as *as = p->p_as;
166 char *eaddr = addr + size;
167 int prot_rw = rw_to_prot(rw);
168 int xrw = rw_to_index(rw);
169 int rv = 0;
170 struct watched_page *pwp;
171 struct watched_page tpw;
172 avl_index_t where;
173 uint_t prot;
174
175 ASSERT(as != &kas);
176
177 startover:
178 ASSERT(rv == 0);
179 if (avl_numnodes(&as->a_wpage) == 0)
180 return (0);
181
182 /*
183 * as->a_wpage can only be changed while the process is totally stopped.
184 * Don't grab p_lock here. Holding p_lock while grabbing the address
185 * space lock leads to deadlocks with the clock thread. Note that if an
186 * as_fault() is servicing a fault to a watched page on behalf of an
187 * XHAT provider, watchpoint will be temporarily cleared (and wp_prot
188 * will be set to wp_oprot). Since this is done while holding as writer
189 * lock, we need to grab as lock (reader lock is good enough).
190 *
191 * p_maplock prevents simultaneous execution of this function. Under
192 * normal circumstances, holdwatch() will stop all other threads, so the
193 * lock isn't really needed. But there may be multiple threads within
194 * stop() when SWATCHOK is set, so we need to handle multiple threads
195 * at once. See holdwatch() for the details of this dance.
196 */
197
198 mutex_enter(&p->p_maplock);
199 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
200
201 tpw.wp_vaddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
202 if ((pwp = avl_find(&as->a_wpage, &tpw, &where)) == NULL)
203 pwp = avl_nearest(&as->a_wpage, where, AVL_AFTER);
204
205 for (; pwp != NULL && pwp->wp_vaddr < eaddr;
206 pwp = AVL_NEXT(&as->a_wpage, pwp)) {
207
208 /*
209 * If the requested protection has not been
487 }
488 }
489
490 return (rv);
491 }
492
493
494 /*
495 * trap() calls here to determine if a fault is in a watched page.
496 * We return nonzero if this is true and the load/store would fail.
497 */
498 int
499 pr_is_watchpage(caddr_t addr, enum seg_rw rw)
500 {
501 struct as *as = curproc->p_as;
502 int rv;
503
504 if ((as == &kas) || avl_numnodes(&as->a_wpage) == 0)
505 return (0);
506
507 /* Grab the lock because of XHAT (see comment in pr_mappage()) */
508 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
509 rv = pr_is_watchpage_as(addr, rw, as);
510 AS_LOCK_EXIT(as, &as->a_lock);
511
512 return (rv);
513 }
514
515
516
517 /*
518 * trap() calls here to determine if a fault is a watchpoint.
519 */
520 int
521 pr_is_watchpoint(caddr_t *paddr, int *pta, size_t size, size_t *plen,
522 enum seg_rw rw)
523 {
524 proc_t *p = curproc;
525 caddr_t addr = *paddr;
526 caddr_t eaddr = addr + size;
527 register struct watched_area *pwa;
|
165 struct as *as = p->p_as;
166 char *eaddr = addr + size;
167 int prot_rw = rw_to_prot(rw);
168 int xrw = rw_to_index(rw);
169 int rv = 0;
170 struct watched_page *pwp;
171 struct watched_page tpw;
172 avl_index_t where;
173 uint_t prot;
174
175 ASSERT(as != &kas);
176
177 startover:
178 ASSERT(rv == 0);
179 if (avl_numnodes(&as->a_wpage) == 0)
180 return (0);
181
182 /*
183 * as->a_wpage can only be changed while the process is totally stopped.
184 * Don't grab p_lock here. Holding p_lock while grabbing the address
185 * space lock leads to deadlocks with the clock thread.
186 *
187 * p_maplock prevents simultaneous execution of this function. Under
188 * normal circumstances, holdwatch() will stop all other threads, so the
189 * lock isn't really needed. But there may be multiple threads within
190 * stop() when SWATCHOK is set, so we need to handle multiple threads
191 * at once. See holdwatch() for the details of this dance.
192 */
193
194 mutex_enter(&p->p_maplock);
195 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
196
197 tpw.wp_vaddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
198 if ((pwp = avl_find(&as->a_wpage, &tpw, &where)) == NULL)
199 pwp = avl_nearest(&as->a_wpage, where, AVL_AFTER);
200
201 for (; pwp != NULL && pwp->wp_vaddr < eaddr;
202 pwp = AVL_NEXT(&as->a_wpage, pwp)) {
203
204 /*
205 * If the requested protection has not been
483 }
484 }
485
486 return (rv);
487 }
488
489
490 /*
491 * trap() calls here to determine if a fault is in a watched page.
492 * We return nonzero if this is true and the load/store would fail.
493 */
494 int
495 pr_is_watchpage(caddr_t addr, enum seg_rw rw)
496 {
497 struct as *as = curproc->p_as;
498 int rv;
499
500 if ((as == &kas) || avl_numnodes(&as->a_wpage) == 0)
501 return (0);
502
503 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
504 rv = pr_is_watchpage_as(addr, rw, as);
505 AS_LOCK_EXIT(as, &as->a_lock);
506
507 return (rv);
508 }
509
510
511
512 /*
513 * trap() calls here to determine if a fault is a watchpoint.
514 */
515 int
516 pr_is_watchpoint(caddr_t *paddr, int *pta, size_t size, size_t *plen,
517 enum seg_rw rw)
518 {
519 proc_t *p = curproc;
520 caddr_t addr = *paddr;
521 caddr_t eaddr = addr + size;
522 register struct watched_area *pwa;
|