summaryrefslogblamecommitdiffstats
path: root/private/ntos/mm/ppc/setdirty.c
blob: 9217bb39afb3752b61fe1d5fe313f1766ab919f4 (plain) (tree)



























































































































                                                                                
/*++

Copyright (c) 1989  Microsoft Corporation
Copyright (c) 1993  IBM Corporation

Module Name:

   setdirty.c

Abstract:

    This module contains the setting dirty bit routine for memory management.

    PowerPC specific.

Author:

    Lou Perazzoli (loup) 10-Apr-1990.

    Modified for PowerPC by Mark Mergen (mergen@watson.ibm.com) 6-Oct-1993

Revision History:

--*/

#include "mi.h"

VOID
MiSetDirtyBit (
    IN PVOID FaultingAddress,
    IN PMMPTE PointerPte,
    IN ULONG PfnHeld
    )

/*++

Routine Description:

    This routine sets dirty in the specified PTE and the modify bit in the
    correpsonding PFN element.  If any page file space is allocated, it
    is deallocated.

Arguments:

    FaultingAddress - Supplies the faulting address.

    PointerPte - Supplies a pointer to the corresponding valid PTE.

    PfnHeld - Supplies TRUE if the PFN mutex is already held.

Return Value:

    None.

Environment:

    Kernel mode, APC's disabled, Working set mutex held.

--*/

{
    MMPTE TempPte;
    ULONG PageFrameIndex;
    PMMPFN Pfn1;
    KIRQL OldIrql;

    //
    // The page is NOT copy on write, update the PTE setting both the
    // dirty bit and the accessed bit. Note, that as this PTE is in
    // the TB, the TB must be flushed.
    //

    PageFrameIndex = PointerPte->u.Hard.PageFrameNumber;
    Pfn1 = MI_PFN_ELEMENT (PageFrameIndex);

    TempPte = *PointerPte;
    TempPte.u.Hard.Dirty = MM_PTE_DIRTY;
    MI_SET_ACCESSED_IN_PTE (&TempPte, 1);
    *PointerPte = TempPte;

    //
    // Check state of PFN mutex and if not held, don't update PFN database.
    //


    if (PfnHeld) {

        //
        // Set the modified field in the PFN database, also, if the phyiscal
        // page is currently in a paging file, free up the page file space
        // as the contents are now worthless.
        //

        if ((Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
                             (Pfn1->u3.e1.WriteInProgress == 0)) {

            //
            // This page is in page file format, deallocate the page file space.
            //

            MiReleasePageFileSpace (Pfn1->OriginalPte);

            //
            // Change original PTE to indicate no page file space is reserved,
            // otherwise the space will be deallocated when the PTE is
            // deleted.
            //

            Pfn1->OriginalPte.u.Soft.PageFileHigh = 0;
        }

        Pfn1->u3.e1.Modified = 1;
    }

    //
    // The TB entry must be flushed as the valid PTE with the dirty bit clear
    // has been fetched into the TB. If it isn't flushed, another fault
    // is generated as the dirty bit is not set in the cached TB entry.
    //

    KeFillEntryTb ((PHARDWARE_PTE)PointerPte, FaultingAddress, TRUE);

    return;
}