qemu/accel/tcg/cputlb.c
/*
 * Dirty write flag handling
 *
 * When the TCG code writes to a location it looks up the address in
 * the TLB and uses that data to compute the final address. If any of
 * the lower bits of the address are set then the slow path is forced.
 * There are a number of reasons to do this but for normal RAM the
 * most usual is detecting writes to code regions which may invalidate
 * generated code.
 *
 * Other vCPUs might be reading their TLBs during guest execution, so we update
 * te->addr_write with atomic_set. We don't need to worry about this for
 * oversized guests as MTTCG is disabled for them.
 *
 * Called with tlb_c.lock held.
 */
Dirty write flag handling
When the TCG code writes to a location it looks up the address in
the TLB and uses that data to compute the final address. If any of
the lower bits of the address are set then the slow path is forced.
There are a number of reasons to do this but for normal RAM the
most usual is detecting writes to code regions which may invalidate
generated code.

Other vCPUs might be reading their TLBs during guest execution, so we update
te->addr_write with atomic_set. We don't need to worry about this for
oversized guests as MTTCG is disabled for them.


Dirty write flag handling When the TCG code writes to a location it looks up the address in the TLB and uses that data to compute the final address . If any of the lower bits of the address are set then the slow path is forced . There are a number of reasons to do this but for normal RAM the most usual is detecting writes to code regions which may invalidate generated code . Other vCPUs might be reading their TLBs during guest execution so we update te - > addr_write with atomic_set . We don ' t need to worry about this for oversized guests as MTTCG is disabled for them .
static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
                                         uintptr_t start, uintptr_t length)
{
    uintptr_t addr = tlb_entry->addr_write;
    if ((addr & (TLB_INVALID_MASK | TLB_MMIO | TLB_NOTDIRTY)) == 0) {
        addr &= TARGET_PAGE_MASK;
        addr += tlb_entry->addend;
        if ((addr - start) < length) {
#if TCG_OVERSIZED_GUEST
            tlb_entry->addr_write |= TLB_NOTDIRTY;
#else
            atomic_set(&tlb_entry->addr_write,
                       tlb_entry->addr_write | TLB_NOTDIRTY);
#endif
        }
    }
}
static void tlb_reset_dirty_range_locked ( CPUTLBEntry * tlb_entry , uintptr_t start , uintptr_t length ) { uintptr_t addr = tlb_entry -> addr_write ; if ( ( addr & ( TLB_INVALID_MASK | TLB_MMIO | TLB_NOTDIRTY ) ) == 0 ) { addr &= TARGET_PAGE_MASK ; addr += tlb_entry -> addend ; if ( ( addr - start ) < length ) { #if TCG_OVERSIZED_GUEST tlb_entry -> addr_write |= TLB_NOTDIRTY ; #else atomic_set ( & tlb_entry -> addr_write , tlb_entry -> addr_write | TLB_NOTDIRTY ) ; #endif } } }
Dirty write flag handling
 When the TCG code writes to a location it looks up the address in
 the TLB and uses that data to compute the final address.
Dirty write flag handling When the TCG code writes to a location it looks up the address in the TLB and uses that data to compute the final address .