MCPcopy Create free account
hub / github.com/F-Stack/f-stack / pmap_emulate_modified

Function pmap_emulate_modified

freebsd/mips/mips/pmap.c:3498–3571  ·  view source on GitHub ↗

* pmap_emulate_modified : do dirty bit emulation * * On SMP, update just the local TLB, other CPUs will update their * TLBs from PTE lazily, if they get the exception. * Returns 0 in case of sucess, 1 if the page is read only and we * need to fault. */

Source from the content-addressed store, hash-verified

3496 * need to fault.
3497 */
3498int
3499pmap_emulate_modified(pmap_t pmap, vm_offset_t va)
3500{
3501 pt_entry_t *pte;
3502
3503 PMAP_LOCK(pmap);
3504 pte = pmap_pte(pmap, va);
3505
3506 /*
3507 * It is possible that some other CPU or thread changed the pmap while
3508 * we weren't looking; in the SMP case, this is readily apparent, but
3509 * it can even happen in the UP case, because we may have been blocked
3510 * on PMAP_LOCK(pmap) above while someone changed this out from
3511 * underneath us.
3512 */
3513
3514 if (pte == NULL) {
3515 /*
3516 * This PTE's PTP (or one of its ancestors) has been reclaimed;
3517 * trigger a full fault to reconstruct it via pmap_enter.
3518 */
3519 PMAP_UNLOCK(pmap);
3520 return (1);
3521 }
3522
3523 if (!pte_test(pte, PTE_V)) {
3524 /*
3525 * This PTE is no longer valid; the other thread or other
3526 * processor must have arranged for our TLB to no longer
3527 * have this entry, possibly by IPI, so no tlb_update is
3528 * required. Fall out of the fast path and go take a
3529 * general fault before retrying the instruction (or taking
3530 * a signal).
3531 */
3532 PMAP_UNLOCK(pmap);
3533 return (1);
3534 }
3535
3536 if (pte_test(pte, PTE_D)) {
3537 /*
3538 * This PTE is valid and has the PTE_D bit asserted; since
3539 * this is an increase in permission, we may have been expected
3540 * to update the TLB lazily. Do so here and return, on the
3541 * fast path, to retry the instruction.
3542 */
3543 tlb_update(pmap, va, *pte);
3544 PMAP_UNLOCK(pmap);
3545 return (0);
3546 }
3547
3548 if (pte_test(pte, PTE_RO)) {
3549 /*
3550 * This PTE is valid, not dirty, and read-only. Go take a
3551 * full fault (most likely to upgrade this part of the address
3552 * space to writeable).
3553 */
3554 PMAP_UNLOCK(pmap);
3555 return (1);

Callers 1

trapFunction · 0.85

Calls 3

tlb_updateFunction · 0.85
pmap_pteFunction · 0.70
panicFunction · 0.50

Tested by

no test coverage detected