// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#ifndef ZIRCON_KERNEL_VM_INCLUDE_VM_VM_COW_PAGES_H_
#define ZIRCON_KERNEL_VM_INCLUDE_VM_VM_COW_PAGES_H_

#include <assert.h>
#include <lib/user_copy/user_ptr.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <stdint.h>
#include <zircon/listnode.h>
#include <zircon/types.h>

#include <fbl/array.h>
#include <fbl/canary.h>
#include <fbl/enum_bits.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/macros.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <kernel/mutex.h>
#include <vm/page_source.h>
#include <vm/physical_page_borrowing_config.h>
#include <vm/pmm.h>
#include <vm/vm.h>
#include <vm/vm_aspace.h>
#include <vm/vm_object.h>
#include <vm/vm_page_list.h>

// Forward declare these so VmCowPages helpers can accept references.
class BatchPQRemove;
class VmObjectPaged;

namespace internal {
struct DiscardableListTag {};
}  // namespace internal

enum class VmCowPagesOptions : uint32_t {
  // Externally-usable flags:
  kNone = 0u,

  // With this clear, zeroing a page tries to decommit the page.  With this set, zeroing never
  // decommits the page.  Currently this is only set for contiguous VMOs.
  //
  // TODO(dustingreen): Once we're happy with the reliability of page borrowing, we should be able
  // to relax this restriction.  We may still need to flush zeroes to RAM during reclaim to mitigate
  // a hypothetical client incorrectly assuming that cache-clean status will remain intact while
  // pages aren't pinned, but that mitigation should be sufficient (even assuming such a client) to
  // allow implicit decommit when zeroing or when zero scanning, as long as no clients are doing DMA
  // to/from contiguous while not pinned.
  kCannotDecommitZeroPages = (1u << 0),

  // Internal-only flags:
  kHidden = (1u << 1),
  kSlice = (1u << 2),
  kUnpinOnDelete = (1u << 3),

  kInternalOnlyMask = kHidden | kSlice,
};
FBL_ENABLE_ENUM_BITS(VmCowPagesOptions)

// Implements a copy-on-write hierarchy of pages in a VmPageList.
class VmCowPages final
    : public VmHierarchyBase,
      public fbl::ContainableBaseClasses<
          // Guarded by lock_.
          fbl::TaggedDoublyLinkedListable<VmCowPages*, internal::ChildListTag>,
          // Guarded by DiscardableVmosLock::Get().
          fbl::TaggedDoublyLinkedListable<VmCowPages*, internal::DiscardableListTag>>,
      public fbl::Recyclable<VmCowPages> {
 public:
  static zx_status_t Create(fbl::RefPtr<VmHierarchyState> root_lock, VmCowPagesOptions options,
                            uint32_t pmm_alloc_flags, uint64_t size,
                            fbl::RefPtr<VmCowPages>* cow_pages);

  static zx_status_t CreateExternal(fbl::RefPtr<PageSource> src, VmCowPagesOptions options,
                                    fbl::RefPtr<VmHierarchyState> root_lock, uint64_t size,
                                    fbl::RefPtr<VmCowPages>* cow_pages);

  // Creates a copy-on-write clone with the desired parameters. This can fail due to various
  // internal states not being correct.
  zx_status_t CreateCloneLocked(CloneType type, uint64_t offset, uint64_t size,
                                fbl::RefPtr<VmCowPages>* child_cow) TA_REQ(lock_);

  // Creates a child that looks back to this VmCowPages for all operations. Once a child slice is
  // created this node should not ever be Resized.
  zx_status_t CreateChildSliceLocked(uint64_t offset, uint64_t size,
                                     fbl::RefPtr<VmCowPages>* cow_slice) TA_REQ(lock_);

  // Returns the size in bytes of this cow pages range. This will always be a multiple of the page
  // size.
  uint64_t size_locked() const TA_REQ(lock_) { return size_; }

  // Returns whether this cow pages node is ultimately backed by a user pager to fulfill initial
  // content, and not zero pages.  Contiguous VMOs have page_source_ set, but are not pager backed
  // in this sense.
  //
  // This should only be used to report to user mode whether a VMO is user-pager backed, not for any
  // other purpose.
  bool is_root_source_user_pager_backed_locked() const TA_REQ(lock_) {
    auto root = GetRootLocked();
    // The root will never be null. It will either point to a valid parent, or |this| if there's no
    // parent.
    DEBUG_ASSERT(root);
    return root->page_source_ && root->page_source_->properties().is_user_pager;
  }

  bool debug_is_user_pager_backed_locked() const TA_REQ(lock_) {
    return page_source_ && page_source_->properties().is_user_pager;
  }

  bool debug_is_contiguous() const TA_REQ(lock_) {
    return page_source_ && page_source_->properties().is_providing_specific_physical_pages;
  }

  bool is_private_pager_copy_supported() const TA_REQ(lock_) {
    auto root = GetRootLocked();
    // The root will never be null. It will either point to a valid parent, or |this| if there's no
    // parent.
    DEBUG_ASSERT(root);
    bool result = root->page_source_ && root->page_source_->properties().is_preserving_page_content;
    DEBUG_ASSERT(result == is_root_source_user_pager_backed_locked());
    return result;
  }

  bool is_cow_clonable_locked() const TA_REQ(lock_) {
    // Copy-on-write clones of pager vmos or their descendants aren't supported as we can't
    // efficiently make an immutable snapshot.
    if (can_root_source_evict_locked()) {
      return false;
    }

    // We also don't support COW clones for contiguous VMOs.
    if (is_source_supplying_specific_physical_pages_locked()) {
      return false;
    }

    // Copy-on-write clones of slices aren't supported at the moment due to the resulting VMO chains
    // having non hidden VMOs between hidden VMOs. This case cannot be handled be CloneCowPageLocked
    // at the moment and so we forbid the construction of such cases for the moment.
    // Bug: 36841
    if (is_slice_locked()) {
      return false;
    }

    return true;
  }

  bool can_evict_locked() const TA_REQ(lock_) {
    bool result = page_source_ && page_source_->properties().is_preserving_page_content;
    DEBUG_ASSERT(result == debug_is_user_pager_backed_locked());
    return result;
  }

  bool can_root_source_evict_locked() const TA_REQ(lock_) {
    auto root = GetRootLocked();
    // The root will never be null. It will either point to a valid parent, or |this| if there's no
    // parent.
    DEBUG_ASSERT(root);
    AssertHeld(root->lock_);
    bool result = root->can_evict_locked();
    DEBUG_ASSERT(result == is_root_source_user_pager_backed_locked());
    return result;
  }

  bool has_pager_backlinks_locked() const TA_REQ(lock_) {
    bool result = can_evict_locked();
    DEBUG_ASSERT(result == debug_is_user_pager_backed_locked());
    return result;
  }

  // Returns whether this cow pages node is dirty tracked.
  bool is_dirty_tracked_locked() const TA_REQ(lock_) {
    // Pager-backed VMOs require dirty tracking either if:
    // 1. They are directly backed by the pager, i.e. the root VMO.
    // OR
    // 2. They are slice children of root pager-backed VMOs, since slices directly reference the
    // parent's pages.
    auto* which_cow = is_slice_locked() ? parent_.get() : this;
    bool result =
        which_cow->page_source_ && which_cow->page_source_->properties().is_preserving_page_content;
    AssertHeld(which_cow->lock_);
    DEBUG_ASSERT(result == which_cow->debug_is_user_pager_backed_locked());
    return result;
  }

  // The modified state is only supported for root pager-backed VMOs, and will get queried (and
  // possibly reset) on the next QueryPagerVmoStatsLocked() call.
  void mark_modified_locked() TA_REQ(lock_) {
    if (!is_source_preserving_page_content_locked()) {
      return;
    }
    pager_stats_modified_ = true;
  }

  bool is_source_preserving_page_content_locked() const TA_REQ(lock_) {
    bool result = page_source_ && page_source_->properties().is_preserving_page_content;
    DEBUG_ASSERT(result == debug_is_user_pager_backed_locked());
    return result;
  }

  bool is_source_supplying_specific_physical_pages_locked() const TA_REQ(lock_) {
    bool result = page_source_ && page_source_->properties().is_providing_specific_physical_pages;
    DEBUG_ASSERT(result == debug_is_contiguous());
    return result;
  }

  // When attributing pages hidden nodes must be attributed to either their left or right
  // descendants. The attribution IDs of all involved determine where attribution goes. For
  // historical and practical reasons actual user ids are used, although any consistent naming
  // scheme will have the same effect.
  void set_page_attribution_user_id_locked(uint64_t id) TA_REQ(lock_) {
    page_attribution_user_id_ = id;
  }

  // See description on |pinned_page_count_| for meaning.
  uint64_t pinned_page_count_locked() const TA_REQ(lock_) { return pinned_page_count_; }

  // Sets the VmObjectPaged backlink for this copy-on-write node. This object has no tracking of
  // mappings, but understands that they exist. When it manipulates pages in a way that could effect
  // mappings it uses the backlink to notify the VmObjectPaged.
  // Currently it is assumed that all nodes always have backlinks with the 1:1 hierarchy mapping.
  void set_paged_backlink_locked(VmObjectPaged* ref) TA_REQ(lock_) { paged_ref_ = ref; }

  uint64_t HeapAllocationBytesLocked() const TA_REQ(lock_) {
    return page_list_.HeapAllocationBytes();
  }

  uint64_t EvictionEventCountLocked() const TA_REQ(lock_) { return eviction_event_count_; }

  void DetachSourceLocked() TA_REQ(lock_);

  // Resizes the range of this cow pages. |size| must be a multiple of the page size and this must
  // not be called on slices or nodes with slice children.
  zx_status_t ResizeLocked(uint64_t size) TA_REQ(lock_);

  // See VmObject::Lookup
  zx_status_t LookupLocked(uint64_t offset, uint64_t len, VmObject::LookupFunction lookup_fn)
      TA_REQ(lock_);

  // Similar to LookupLocked, but enumerate all readable pages in the hierarchy within the requested
  // range. The offset passed to the |lookup_fn| is the offset this page is visible at in this
  // object, even if the page itself is committed in a parent object. The physical addresses given
  // to the lookup_fn should not be retained in any way unless the range has also been pinned by the
  // caller.
  // Ranges of length zero are considered invalid and will return ZX_ERR_INVALID_ARGS. The lookup_fn
  // can terminate iteration early by returning ZX_ERR_STOP.
  using LookupReadableFunction =
      fit::inline_function<zx_status_t(uint64_t offset, paddr_t pa), 4 * sizeof(void*)>;
  zx_status_t LookupReadableLocked(uint64_t offset, uint64_t len, LookupReadableFunction lookup_fn)
      TA_REQ(lock_);

  // See VmObject::TakePages
  zx_status_t TakePagesLocked(uint64_t offset, uint64_t len, VmPageSpliceList* pages) TA_REQ(lock_);

  // See VmObject::SupplyPages
  //
  // The new_zeroed_pages parameter should be true if the pages are new pages that need to be
  // initialized, or false if the pages are from a different VmCowPages and are being moved to this
  // VmCowPages.
  zx_status_t SupplyPagesLocked(uint64_t offset, uint64_t len, VmPageSpliceList* pages,
                                bool new_zeroed_pages) TA_REQ(lock_);

  // The new_zeroed_pages parameter should be true if the pages are new pages that need to be
  // initialized, or false if the pages are from a different VmCowPages and are being moved to this
  // VmCowPages.
  zx_status_t SupplyPages(uint64_t offset, uint64_t len, VmPageSpliceList* pages,
                          bool new_zeroed_pages) TA_EXCL(lock_);

  // See VmObject::FailPageRequests
  zx_status_t FailPageRequestsLocked(uint64_t offset, uint64_t len, zx_status_t error_status)
      TA_REQ(lock_);

  // Used to track dirty_state in the vm_page_t.
  //
  // The transitions between the three states can roughly be summarized as follows:
  // 1. A page starts off as Clean when supplied.
  // 2. A write transitions the page from Clean to Dirty.
  // 3. A writeback_begin moves the Dirty page to AwaitingClean.
  // 4. A writeback_end moves the AwaitingClean page to Clean.
  // 5. A write that comes in while the writeback is in progress (i.e. the page is AwaitingClean)
  // moves the AwaitingClean page back to Dirty.
  enum class DirtyState : uint8_t {
    // The page does not track dirty state. Used for non pager backed pages.
    Untracked = 0,
    // The page is clean, i.e. its contents have not been altered from when the page was supplied.
    Clean,
    // The page's contents have been modified from the time of supply, and should be written back to
    // the page source at some point.
    Dirty,
    // The page still has modified contents, but the page source is in the process of writing back
    // the changes. This is used to ensure that a consistent version is written back, and that any
    // new modifications that happen during the writeback are not lost. The page source will mark
    // pages AwaitingClean before starting any writeback.
    AwaitingClean,
    NumStates,
  };
  // Make sure that the state can be encoded in the vm_page_t's dirty_state field.
  static_assert(static_cast<uint8_t>(DirtyState::NumStates) <= VM_PAGE_OBJECT_MAX_DIRTY_STATES);

  static bool is_page_dirty_tracked(const vm_page_t* page) {
    return DirtyState(page->object.dirty_state) != DirtyState::Untracked;
  }
  static bool is_page_dirty(const vm_page_t* page) {
    return DirtyState(page->object.dirty_state) == DirtyState::Dirty;
  }
  static bool is_page_clean(const vm_page_t* page) {
    return DirtyState(page->object.dirty_state) == DirtyState::Clean;
  }
  static bool is_page_awaiting_clean(const vm_page_t* page) {
    return DirtyState(page->object.dirty_state) == DirtyState::AwaitingClean;
  }

  // See VmObject::DirtyPages
  zx_status_t DirtyPagesLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);

  using DirtyRangeEnumerateFunction = VmObject::DirtyRangeEnumerateFunction;
  // See VmObject::EnumerateDirtyRanges
  zx_status_t EnumerateDirtyRangesLocked(uint64_t offset, uint64_t len,
                                         DirtyRangeEnumerateFunction&& dirty_range_fn)
      TA_REQ(lock_);

  // Query pager VMO |stats|, and reset them too if |reset| is set to true.
  zx_status_t QueryPagerVmoStatsLocked(bool reset, zx_pager_vmo_stats_t* stats) TA_REQ(lock_) {
    DEBUG_ASSERT(stats);
    // The modified state should only be set for VMOs directly backed by a pager.
    DEBUG_ASSERT(!pager_stats_modified_ || is_source_preserving_page_content_locked());

    if (!is_source_preserving_page_content_locked()) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    stats->modified = pager_stats_modified_ ? ZX_PAGER_VMO_STATS_MODIFIED : 0;
    if (reset) {
      pager_stats_modified_ = false;
    }
    return ZX_OK;
  }

  // See VmObject::WritebackBegin
  zx_status_t WritebackBeginLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);

  // See VmObject::WritebackEnd
  zx_status_t WritebackEndLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);

  using LookupInfo = VmObject::LookupInfo;
  using DirtyTrackingAction = VmObject::DirtyTrackingAction;
  // See VmObject::GetPage
  // The pages returned from this are assumed to be used in the following ways.
  //  * Our VmObjectPaged backlink, or any of children's backlinks, are allowed to have readable
  //    mappings, and will be informed to unmap via the backlinks when needed.
  //  * Our VmObjectPaged backlink and our *slice* children are allowed to have writable mappings,
  //    and will be informed to either unmap or remove writability when needed.
  zx_status_t LookupPagesLocked(uint64_t offset, uint pf_flags, DirtyTrackingAction mark_dirty,
                                uint64_t max_out_pages, list_node* alloc_list,
                                LazyPageRequest* page_request, LookupInfo* out) TA_REQ(lock_);

  // Controls the type of content that can be overwritten by the Add[New]Page[s]Locked functions.
  enum class CanOverwriteContent : uint8_t {
    // Do not overwrite any kind of content, i.e. only add a page at the slot if there is true
    // absence of content.
    None,
    // Only overwrite slots that represent zeros. In the case of anonymous VMOs, both gaps and zero
    // page markers represent zeros, as the entire VMO is implicitly zero on creation. For pager
    // backed VMOs, zero page markers and gaps after supply_zero_offset_ represent zeros.
    Zero,
    // Overwrite any slots, regardless of the type of content.
    NonZero,
  };
  // Adds an allocated page to this cow pages at the specified offset, can be optionally zeroed and
  // any mappings invalidated. If an error is returned the caller retains ownership of |page|.
  // Offset must be page aligned.
  //
  // |overwrite| controls how the function handles pre-existing content at |offset|. If |overwrite|
  // does not permit replacing the content, ZX_ERR_ALREADY_EXISTS will be returned. If a page is
  // released from the page list as a result of overwriting, it is returned through |released_page|
  // and the caller takes ownership of this page. If the |overwrite| action is such that a page
  // cannot be released, it is valid for the caller to pass in nullptr for |released_page|.
  zx_status_t AddNewPageLocked(uint64_t offset, vm_page_t* page, CanOverwriteContent overwrite,
                               ktl::optional<vm_page_t*>* released_page, bool zero = true,
                               bool do_range_update = true) TA_REQ(lock_);

  // Adds a set of pages consecutively starting from the given offset. Regardless of the return
  // result ownership of the pages is taken. Pages are assumed to be in the ALLOC state and can be
  // optionally zeroed before inserting. start_offset must be page aligned.
  //
  // |overwrite| controls how the function handles pre-existing content in the range. If |overwrite|
  // does not permit replacing the content, ZX_ERR_ALREADY_EXISTS will be returned. Pages released
  // from the page list as a result of overwriting are returned through |released_pages| and the
  // caller takes ownership of these pages. If the |overwrite| action is such that pages cannot be
  // released, it is valid for the caller to pass in nullptr for |released_pages|.
  zx_status_t AddNewPagesLocked(uint64_t start_offset, list_node_t* pages,
                                CanOverwriteContent overwrite, list_node_t* released_pages,
                                bool zero = true, bool do_range_update = true) TA_REQ(lock_);

  // Attempts to release pages in the pages list causing the range to become copy-on-write again.
  // For consistency if there is a parent or a backing page source, such that the range would not
  // explicitly copy-on-write the zero page then this will fail. Use ZeroPagesLocked for an
  // operation that is guaranteed to succeed, but may not release memory.
  zx_status_t DecommitRangeLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);

  // After successful completion the range of pages will all read as zeros. The mechanism used to
  // achieve this is not guaranteed to decommit, but it will try to.
  // |page_start_base| and |page_end_base| must be page aligned offsets within the range of the
  // object. |zeroed_len_out| will contain the length (in bytes) starting at |page_start_base| that
  // was successfully zeroed.
  //
  // Returns one of the following:
  //  ZX_OK => The whole range was successfully zeroed.
  //  ZX_ERR_SHOULD_WAIT => The caller needs to wait on the |page_request| and then retry the
  //  operation. |zeroed_len_out| will contain the range that was partially zeroed, so the caller
  //  can advance the start offset before retrying.
  //  Any other error code indicates a failure to zero a part of the range or the whole range.
  zx_status_t ZeroPagesLocked(uint64_t page_start_base, uint64_t page_end_base,
                              LazyPageRequest* page_request, uint64_t* zeroed_len_out)
      TA_REQ(lock_);

  // Attempts to commit a range of pages. This has three kinds of return status
  //  ZX_OK => The whole range was successfully committed and |len| will be written to
  //           |committed_len|
  //  ZX_ERR_SHOULD_WAIT => A partial (potentially 0) range was committed (output in |committed_len|
  //                        and the passed in |page_request| should be waited on before retrying
  //                        the commit operation. The portion that was successfully committed does
  //                        not need to retried.
  //  * => Any other error, the number of pages committed is undefined.
  // The |offset| and |len| are assumed to be page aligned and within the range of |size_|.
  zx_status_t CommitRangeLocked(uint64_t offset, uint64_t len, uint64_t* committed_len,
                                LazyPageRequest* page_request) TA_REQ(lock_);

  // Increases the pin count of the range of pages given by |offset| and |len|. The full range must
  // already be committed and this either pins all pages in the range, or pins no pages and returns
  // an error. The caller can assume that on success len / PAGE_SIZE pages were pinned.
  // The |offset| and |len| are assumed to be page aligned and within the range of |size_|.
  //
  // This method also replaces any loaned pages with non-loaned pages.
  zx_status_t PinRangeLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);

  // See VmObject::Unpin
  void UnpinLocked(uint64_t offset, uint64_t len, bool allow_gaps) TA_REQ(lock_);

  // Returns true if a page is not currently committed, and if the offset were to be read from, it
  // would be read as zero. Requested offset must be page aligned and within range.
  bool PageWouldReadZeroLocked(uint64_t page_offset) TA_REQ(lock_);

  // Returns whether this node is currently suitable for having a copy-on-write child made of it.
  bool IsCowClonableLocked() const TA_REQ(lock_);

  // see VmObjectPaged::AttributedPagesInRange
  size_t AttributedPagesInRangeLocked(uint64_t offset, uint64_t len) const TA_REQ(lock_);

  // Scans this cow pages range for zero pages and frees them if |reclaim| is set to true. Returns
  // the number of pages freed or scanned.
  uint32_t ScanForZeroPagesLocked(bool reclaim) TA_REQ(lock_);

  enum class EvictionHintAction : uint8_t {
    Follow,
    Ignore,
  };

  // Asks the VMO to attempt to evict the specified page. This returns true if the page was
  // actually from this VMO and was successfully evicted, at which point the caller now has
  // ownership of the page. Otherwise eviction is allowed to fail for any reason, specifically
  // if the page is considered in use, or the VMO has no way to recreate the page then eviction
  // will fail. Although eviction may fail for any reason, if it does the caller is able to assume
  // that either the page was not from this vmo, or that the page is not in any evictable page queue
  // (such as the pager_backed_ queue).
  // |hint_action| indicates whether the |always_need| eviction hint should be respected or ignored.
  // If this page is not evicted as a result of the hint, the caller can assume that the page has
  // been moved out from the evictable page queue(s) into the active queue(s).
  bool RemovePageForEviction(vm_page_t* page, uint64_t offset, EvictionHintAction hint_action);

  // Swap an old page for a new page.  The old page must be at offset.  The new page must be in
  // ALLOC state.  On return, the old_page is owned by the caller.  Typically the caller will
  // remove the old_page from pmm_page_queues() and free the old_page.
  void SwapPageLocked(uint64_t offset, vm_page_t* old_page, vm_page_t* new_page) TA_REQ(lock_);

  // If page is still at offset, replace it with a loaned page.
  zx_status_t ReplacePageWithLoaned(vm_page_t* before_page, uint64_t offset) TA_EXCL(lock_);

  // If page is still at offset, replace it with a different page.  If with_loaned is true, replace
  // with a loaned page.  If with_loaned is false, replace with a non-loaned page and a page_request
  // is required to be provided.
  zx_status_t ReplacePageLocked(vm_page_t* before_page, uint64_t offset, bool with_loaned,
                                vm_page_t** after_page, LazyPageRequest* page_request)
      TA_REQ(lock_);

  // Attempts to dedup the given page at the specified offset with the zero page. The only
  // correctness requirement for this is that `page` must be *some* valid vm_page_t, meaning that
  // all race conditions are handled internally. This function returns false if
  //  * page is either not from this VMO, or not found at the specified offset
  //  * page is pinned
  //  * vmo is uncached
  //  * page is not all zeroes
  // Otherwise 'true' is returned and the page will have been returned to the pmm with a zero page
  // marker put in its place.
  bool DedupZeroPage(vm_page_t* page, uint64_t offset);

  void DumpLocked(uint depth, bool verbose) const TA_REQ(lock_);

  // VMO_VALIDATION
  bool DebugValidatePageSplitsLocked() const TA_REQ(lock_);
  bool DebugValidateBacklinksLocked() const TA_REQ(lock_);
  // Calls DebugValidatePageSplitsLocked on this and every parent in the chain, returning true if
  // all return true.  Also calls DebugValidateBacklinksLocked() on every node in the hierarchy.
  bool DebugValidatePageSplitsHierarchyLocked() const TA_REQ(lock_);

  // VMO_FRUGAL_VALIDATION
  bool DebugValidateVmoPageBorrowingLocked() const TA_REQ(lock_);

  // Different operations that RangeChangeUpdate* can perform against any VmMappings that are found.
  enum class RangeChangeOp {
    Unmap,
    RemoveWrite,
  };
  // Apply the specified operation to all mappings in the given range. This is applied to all
  // descendants within the range.
  void RangeChangeUpdateLocked(uint64_t offset, uint64_t len, RangeChangeOp op) TA_REQ(lock_);

  // Promote pages in the specified range for reclamation under memory pressure. |offset| will be
  // rounded down to the page boundary, and |len| will be rounded up to the page boundary.
  // Currently used only for pager-backed VMOs to move their pages to the end of the
  // pager-backed queue, so that they can be evicted first.
  void PromoteRangeForReclamationLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);

  // Protect pages in the specified range from reclamation under memory pressure. |offset| will be
  // rounded down to the page boundary, and |len| will be rounded up to the page boundary. Used to
  // set the |always_need| hint for pages in pager-backed VMOs. Any absent pages in the range will
  // be committed first, and the call will block on the fulfillment of the page request(s), dropping
  // |guard| while waiting (multiple times if multiple pages need to be supplied).
  void ProtectRangeFromReclamationLocked(uint64_t offset, uint64_t len, Guard<Mutex>* guard)
      TA_REQ(lock_);

  void MarkAsLatencySensitiveLocked() TA_REQ(lock_);

  zx_status_t LockRangeLocked(uint64_t offset, uint64_t len, zx_vmo_lock_state_t* lock_state_out);
  zx_status_t TryLockRangeLocked(uint64_t offset, uint64_t len);
  zx_status_t UnlockRangeLocked(uint64_t offset, uint64_t len);

  // Exposed for testing.
  uint64_t DebugGetLockCount() const {
    Guard<Mutex> guard{&lock_};
    return lock_count_;
  }
  uint64_t DebugGetPageCountLocked() const TA_REQ(lock_);
  bool DebugIsReclaimable() const;
  bool DebugIsUnreclaimable() const;
  bool DebugIsDiscarded() const;
  bool DebugIsPage(uint64_t offset) const;
  bool DebugIsMarker(uint64_t offset) const;
  bool DebugIsEmpty(uint64_t offset) const;
  vm_page_t* DebugGetPage(uint64_t offset) const TA_EXCL(lock_);
  vm_page_t* DebugGetPageLocked(uint64_t offset) const TA_REQ(lock_);
  uint64_t DebugGetSupplyZeroOffset() const TA_EXCL(lock_);

  // Discard all the pages from a discardable vmo in the |kReclaimable| state. For this call to
  // succeed, the vmo should have been in the reclaimable state for at least
  // |min_duration_since_reclaimable|. If successful, the |discardable_state_| is set to
  // |kDiscarded|, and the vmo is moved from the reclaim candidates list. The pages are removed /
  // discarded from the vmo and appended to the |freed_list| passed in; the caller takes ownership
  // of the removed pages and is responsible for freeing them. Returns the number of pages
  // discarded.
  uint64_t DiscardPages(zx_duration_t min_duration_since_reclaimable, list_node_t* freed_list)
      TA_EXCL(DiscardableVmosLock::Get()) TA_EXCL(lock_);

  struct DiscardablePageCounts {
    uint64_t locked;
    uint64_t unlocked;
  };

  // Returns the total number of pages locked and unlocked across all discardable vmos.
  // Note that this might not be exact and we might miss some vmos, because the
  // |DiscardableVmosLock| is dropped after processing each vmo on the global discardable lists.
  // That is fine since these numbers are only used for accounting.
  static DiscardablePageCounts DebugDiscardablePageCounts() TA_EXCL(DiscardableVmosLock::Get());

  // Walks through the LRU reclaimable list of discardable vmos and discards pages from each, until
  // |target_pages| have been discarded, or the list of candidates is exhausted. Only vmos that have
  // become reclaimable more than |min_duration_since_reclaimable| in the past will be discarded;
  // this prevents discarding reclaimable vmos that were recently accessed. The discarded pages are
  // appended to the |freed_list| passed in; the caller takes ownership of the discarded pages and
  // is responsible for freeing them. Returns the total number of pages discarded.
  static uint64_t ReclaimPagesFromDiscardableVmos(uint64_t target_pages,
                                                  zx_duration_t min_duration_since_reclaimable,
                                                  list_node_t* freed_list)
      TA_EXCL(DiscardableVmosLock::Get());

  // Walks up the parent tree and returns the root, or |this| if there is no parent.
  const VmCowPages* GetRootLocked() const TA_REQ(lock_);

  // Only for use by loaned page reclaim.
  VmCowPagesContainer* raw_container();

 private:
  // private constructor (use Create...())
  VmCowPages(ktl::unique_ptr<VmCowPagesContainer> cow_container,
             fbl::RefPtr<VmHierarchyState> root_lock, VmCowPagesOptions options,
             uint32_t pmm_alloc_flags, uint64_t size, fbl::RefPtr<PageSource> page_source);
  friend class VmCowPagesContainer;

  ~VmCowPages() override;

  // This takes all the constructor parameters including the VmCowPagesContainer, which avoids any
  // possiblity of allocation failure.
  template <class... Args>
  static fbl::RefPtr<VmCowPages> NewVmCowPages(ktl::unique_ptr<VmCowPagesContainer> cow_container,
                                               Args&&... args);

  // This takes all the constructor parameters except for the VmCowPagesContainer which is
  // allocated. The AllocChecker will reflect whether allocation was successful.
  template <class... Args>
  static fbl::RefPtr<VmCowPages> NewVmCowPages(fbl::AllocChecker* ac, Args&&... args);

  // fbl_recycle() does all the explicit cleanup, and the destructor does all the implicit cleanup.
  void fbl_recycle() override;
  friend class fbl::Recyclable<VmCowPages>;

  DISALLOW_COPY_ASSIGN_AND_MOVE(VmCowPages);

  bool is_hidden_locked() const TA_REQ(lock_) { return !!(options_ & VmCowPagesOptions::kHidden); }
  bool is_slice_locked() const TA_REQ(lock_) { return !!(options_ & VmCowPagesOptions::kSlice); }
  bool can_decommit_zero_pages_locked() const TA_REQ(lock_) {
    bool result = !(options_ & VmCowPagesOptions::kCannotDecommitZeroPages);
    DEBUG_ASSERT(result == !debug_is_contiguous());
    return result;
  }

  // can_borrow_locked() returns true if the VmCowPages is capable of borrowing pages, but whether
  // the VmCowPages should actually borrow pages also depends on a borrowing-site-specific flag that
  // the caller is responsible for checking (in addition to checking can_borrow_locked()).  Only if
  // both are true should the caller actually borrow at the caller's specific potential borrowing
  // site.  For example, see is_borrowing_in_supplypages_enabled() and
  // is_borrowing_on_mru_enabled().
  bool can_borrow_locked() const TA_REQ(lock_) {
    // TODO(dustingreen): Or rashaeqbal@.  We can only borrow while the page is not dirty.
    // Currently we enforce this by checking ShouldTrapDirtyTransitions() below and leaning on the
    // fact that !ShouldTrapDirtyTransitions() dirtying isn't implemented yet.  We currently evict
    // to reclaim instead of replacing the page, and we can't evict a dirty page since the contents
    // would be lost.  Option 1: When a loaned page is about to become dirty, we could replace it
    // with a non-loaned page.  Option 2: When reclaiming a loaned page we could replace instead of
    // evicting (this may be simpler).

    // Currently we can only borrow if we have a suitable PageSource, since this suitable page
    // source is currently 1:1 with having the needed backlinks for reclaim.
    bool source_is_suitable = page_source_ && page_source_->properties().is_preserving_page_content;
    // This ensures that if borrowing is globally disabled (no borrowing sites enabled), that we'll
    // return false.  We could delete this bool without damaging correctness, but we want to
    // mitigate a call site that maybe fails to check its call-site-specific settings such as
    // is_borrowing_in_supplypages_enabled().
    //
    // We also don't technically need to check is_any_borrowing_enabled() here since pmm will check
    // also, but by checking here, we minimize the amount of code that will run when
    // !is_any_borrowing_enabled() (in case we have it disabled due to late discovery of a problem
    // with borrowing).
    bool borrowing_is_generally_acceptable =
        pmm_physical_page_borrowing_config()->is_any_borrowing_enabled();
    // Exclude is_latency_sensitive_ to avoid adding latency due to reclaim.
    //
    // Currently we evict instead of replacing a page when reclaiming, so we want to avoid evicting
    // pages that are latency sensitive or are fairly likely to be pinned at some point.
    //
    // We also don't want to borrow a page that might get pinned again since we want to mitigate the
    // possibility of an invalid DMA-after-free.
    bool excluded_from_borrowing_for_latency_reasons = is_latency_sensitive_ || ever_pinned_;
    // Avoid borrowing and trapping dirty transitions overlapping for now; nothing really stops
    // these from being compatible AFAICT - we're just avoiding overlap of these two things until
    // later.
    bool overlapping_with_other_features = page_source_->ShouldTrapDirtyTransitions();

    bool result = source_is_suitable && borrowing_is_generally_acceptable &&
                  !excluded_from_borrowing_for_latency_reasons && !overlapping_with_other_features;

    DEBUG_ASSERT(result == (debug_is_user_pager_backed_locked() &&
                            pmm_physical_page_borrowing_config()->is_any_borrowing_enabled() &&
                            !is_latency_sensitive_ && !ever_pinned_ &&
                            !page_source_->ShouldTrapDirtyTransitions()));

    return result;
  }

  bool direct_source_supplies_zero_pages_locked() const TA_REQ(lock_) {
    bool result = page_source_ && !page_source_->properties().is_preserving_page_content;
    DEBUG_ASSERT(result == debug_is_contiguous());
    return result;
  }

  bool can_decommit_locked() const TA_REQ(lock_) {
    bool result = !page_source_ || !page_source_->properties().is_preserving_page_content;
    DEBUG_ASSERT(result == !debug_is_user_pager_backed_locked());
    return result;
  }

  // Add a page to the object at |offset|.
  //
  // |overwrite| controls how the function handles pre-existing content at |offset|. If |overwrite|
  // does not permit replacing the content, ZX_ERR_ALREADY_EXISTS will be returned. If a page is
  // released from the page list as a result of overwriting, it is returned through |released_page|
  // and the caller takes ownership of this page. If the |overwrite| action is such that a page
  // cannot be released, it is valid for the caller to pass in nullptr for |released_page|.
  //
  // This operation unmaps the corresponding offset from any existing mappings, unless
  // |do_range_update| is false, in which case it will skip updating mappings.
  //
  // On success the page to add is moved out of `*p`, otherwise it is left there.
  zx_status_t AddPageLocked(VmPageOrMarker* p, uint64_t offset, CanOverwriteContent overwrite,
                            ktl::optional<vm_page_t*>* released_page, bool do_range_update = true)
      TA_REQ(lock_);

  // Unmaps and removes all the committed pages in the specified range.
  // Called from DecommitRangeLocked() to perform the actual decommit action after some of the
  // initial sanity checks have succeeded. Also called from DiscardPages() to reclaim pages from a
  // discardable VMO. Upon success the removed pages are placed in |freed_list|. The caller has
  // ownership of these pages and is responsible for freeing them.
  //
  // Unlike DecommitRangeLocked(), this function only operates on |this| node, which must have no
  // parent.
  // |offset| must be page aligned. |len| must be less than or equal to |size_ - offset|. If |len|
  // is less than |size_ - offset| it must be page aligned.
  // Optionally returns the number of pages removed if |pages_freed_out| is not null.
  zx_status_t UnmapAndRemovePagesLocked(uint64_t offset, uint64_t len, list_node_t* freed_list,
                                        uint64_t* pages_freed_out = nullptr) TA_REQ(lock_);

  // internal check if any pages in a range are pinned
  bool AnyPagesPinnedLocked(uint64_t offset, size_t len) TA_REQ(lock_);

  // Helper function for ::AllocatedPagesInRangeLocked. Counts the number of pages in ancestor's
  // vmos that should be attributed to this vmo for the specified range. It is an error to pass in a
  // range that does not need attributing (i.e. offset must be < parent_limit_), although |len| is
  // permitted to be sized such that the range exceeds parent_limit_.
  // The return value is the length of the processed region, which will be <= |size| and is
  // guaranteed to be > 0. The |count| is the number of pages in this region that should be
  // attributed to this vmo, versus some other vmo.
  uint64_t CountAttributedAncestorPagesLocked(uint64_t offset, uint64_t size, uint64_t* count) const
      TA_REQ(lock_);

  // Searches for the the initial content for |this| at |offset|. The result could be used to
  // initialize a commit, or compare an existing commit with the original. The initial content
  // is a reference to a VmPageOrMarker as there could be an explicit vm_page of content, an
  // explicit zero page of content via a marker, or no initial content. Determining the meaning of
  // no initial content (i.e. whether it is zero or something else) is left up to the caller.
  //
  // If an ancestor has a committed page which corresponds to |offset|, returns that page
  // as well as the VmCowPages and offset which own the page. If no ancestor has a committed
  // page for the offset, returns null as well as the VmCowPages/offset which need to be queried
  // to populate the page.
  //
  // If the passed |owner_length| is not null, then the visible range of the owner is calculated and
  // stored back into |owner_length| on the walk up. The |owner_length| represents the size of the
  // range in the owner for which no other VMO in the chain had forked a page.
  const VmPageOrMarker* FindInitialPageContentLocked(uint64_t offset, VmCowPages** owner_out,
                                                     uint64_t* owner_offset_out,
                                                     uint64_t* owner_length) TA_REQ(lock_);

  // LookupPagesLocked helper function that 'forks' the page at |offset| of the current vmo. If
  // this function successfully inserts a page into |offset| of the current vmo, it returns ZX_OK
  // and populates |out_page|. |page_request| must be provided and if ZX_ERR_SHOULD_WAIT is returned
  // then this indicates a transient failure that should be resolved by waiting on the page_request.
  //
  // The source page that is being forked has already been calculated - it is |page|, which
  // is currently in |page_owner| at offset |owner_offset|.
  //
  // This function is responsible for ensuring that COW clones never result in worse memory
  // consumption than simply creating a new vmo and memcpying the content. It does this by
  // migrating a page from a hidden vmo into one child if that page is not 'accessible' to the
  // other child (instead of allocating a new page into the child and making the hidden vmo's
  // page inaccessible).
  //
  // Whether a particular page in a hidden vmo is 'accessible' to a particular child is
  // determined by a combination of two factors. First, if the page lies outside of the range
  // in the hidden vmo the child can see (specified by parent_offset_ and parent_limit_), then
  // the page is not accessible. Second, if the page has already been copied into the child,
  // then the page in the hidden vmo is not accessible to that child. This is tracked by the
  // cow_X_split bits in the vm_page_t structure.
  //
  // To handle memory allocation failure, this function performs the fork operation from the
  // root vmo towards the leaf vmo. This allows the COW invariants to always be preserved.
  //
  // |page| must not be the zero-page, as there is no need to do the complex page
  // fork logic to reduce memory consumption in that case.
  zx_status_t CloneCowPageLocked(uint64_t offset, list_node_t* alloc_list, VmCowPages* page_owner,
                                 vm_page_t* page, uint64_t owner_offset,
                                 LazyPageRequest* page_request, vm_page_t** out_page) TA_REQ(lock_);

  // This is an optimized wrapper around CloneCowPageLocked for when an initial content page needs
  // to be forked to preserve the COW invariant, but you know you are immediately going to overwrite
  // the forked page with zeros.
  //
  // The optimization it can make is that it can fork the page up to the parent and then, instead
  // of forking here and then having to immediately free the page, it can insert a marker here and
  // set the split bits in the parent page as if it had been forked.
  zx_status_t CloneCowPageAsZeroLocked(uint64_t offset, list_node_t* freed_list,
                                       VmCowPages* page_owner, vm_page_t* page,
                                       uint64_t owner_offset, LazyPageRequest* page_request)
      TA_REQ(lock_);

  // Returns true if |page| (located at |offset| in this vmo) is only accessible by one
  // child, where 'accessible' is defined by ::CloneCowPageLocked.
  bool IsUniAccessibleLocked(vm_page_t* page, uint64_t offset) const TA_REQ(lock_);

  // Releases this vmo's reference to any ancestor vmo's COW pages, for the range [start, end)
  // in this vmo. This is done by either setting the pages' split bits (if something else
  // can access the pages) or by freeing the pages using the |page_remover|
  //
  // This function recursively invokes itself for regions of the parent vmo which are
  // not accessible by the sibling vmo.
  void ReleaseCowParentPagesLocked(uint64_t start, uint64_t end, BatchPQRemove* page_remover)
      TA_REQ(lock_);

  // Helper function for ReleaseCowParentPagesLocked that processes pages which are visible
  // to at least this VMO, and possibly its sibling, as well as updates parent_(offset_)limit_.
  void ReleaseCowParentPagesLockedHelper(uint64_t start, uint64_t end, bool sibling_visible,
                                         BatchPQRemove* page_remover) TA_REQ(lock_);

  // Updates the parent limits of all children so that they will never be able to
  // see above |new_size| in this vmo, even if the vmo is enlarged in the future.
  void UpdateChildParentLimitsLocked(uint64_t new_size) TA_REQ(lock_);

  // When cleaning up a hidden vmo, merges the hidden vmo's content (e.g. page list, view
  // of the parent) into the remaining child.
  void MergeContentWithChildLocked(VmCowPages* removed, bool removed_left) TA_REQ(lock_);

  // Only valid to be called when is_slice_locked() is true and returns the first parent of this
  // hierarchy that is not a slice. The offset of this slice within that VmObjectPaged is set as
  // the output.
  VmCowPages* PagedParentOfSliceLocked(uint64_t* offset) TA_REQ(lock_);

  // Unpins a page and potentially moves it into a different page queue should its pin
  // count reach zero.
  void UnpinPageLocked(vm_page_t* page, uint64_t offset) TA_REQ(lock_);

  // Moves an existing page to the wired queue, retaining backlink information if applicable.
  void MoveToWiredLocked(vm_page_t* page, uint64_t offset) TA_REQ(lock_);

  // Updates the page queue of an existing page, moving it to whichever non wired queue
  // is appropriate.
  void MoveToNotWiredLocked(vm_page_t* page, uint64_t offset) TA_REQ(lock_);

  // Places a newly added page into the appropriate non wired page queue.
  void SetNotWiredLocked(vm_page_t* page, uint64_t offset) TA_REQ(lock_);

  // Updates any meta data for accessing a page. Currently this moves pager backed pages around in
  // the page queue to track which ones were recently accessed for the purposes of eviction. In
  // terms of functional correctness this never has to be called.
  void UpdateOnAccessLocked(vm_page_t* page, uint pf_flags) TA_REQ(lock_);

  // Updates the page's dirty state to the one specified, and also moves the page between page
  // queues if required by the dirty state. |dirty_state| should be a valid dirty tracking state,
  // i.e. one of Clean, AwaitingClean, or Dirty.
  //
  // |offset| is the page-aligned offset of the page in this object.
  //
  // |is_pending_add| indicates whether this page is yet to be added to this object's page list,
  // false by default. If the page is yet to be added, this function will skip updating the page
  // queue as an optimization, since the page queue will be updated later when the page gets added
  // to the page list. |is_pending_add| also helps determine certain validation checks that can be
  // performed on the page.
  void UpdateDirtyStateLocked(vm_page_t* page, uint64_t offset, DirtyState dirty_state,
                              bool is_pending_add = false) TA_REQ(lock_);

  // Tries to prepare the range [offset, offset + len) for writing by marking pages dirty or
  // verifying that they are already dirty. It is possible for only some or none of the pages in the
  // range to be dirtied at the end of this call. |dirty_len_out| will return the (page-aligned)
  // length starting at |offset| that contains dirty pages, either already dirty before making the
  // call or dirtied during the call. In other words, the range [offset, offset + dirty_len_out)
  // will be dirty when this call returns, i.e. prepared for the write to proceed, where
  // |dirty_len_out| <= |len|.
  //
  // If the specified range starts with pages that are not already dirty and need to request the
  // page source before transitioning to dirty, a DIRTY page request will be forwarded to the page
  // source. In this case |dirty_len_out| will be set to 0, ZX_ERR_SHOULD_WAIT will be returned and
  // the caller should wait on |page_request|. If no page requests need to be generated, i.e. we
  // could find some pages that are already dirty at the start of the range, or if the VMO does not
  // require dirty transitions to be trapped, ZX_OK is returned.
  //
  // |offset| and |len| should be page-aligned.
  zx_status_t PrepareForWriteLocked(LazyPageRequest* page_request, uint64_t offset, uint64_t len,
                                    uint64_t* dirty_len_out) TA_REQ(lock_);

  // If supply_zero_offset_ falls within the specified range [start_offset, end_offset), try to
  // advance supply_zero_offset_ over any pages in the range that might have been committed
  // immediately following supply_zero_offset_. |start_offset| and |end_offset| should be
  // page-aligned.
  void TryAdvanceSupplyZeroOffsetLocked(uint64_t start_offset, uint64_t end_offset) TA_REQ(lock_);

  // Initializes and adds as a child the given VmCowPages as a full clone of this one such that the
  // VmObjectPaged backlink can be moved from this to the child, keeping all page offsets, sizes and
  // other requirements (see VmObjectPaged::SetCowPagesReferenceLocked) are valid. This does also
  // move our paged_ref_ into child_ and update the VmObjectPaged backlinks.
  void CloneParentIntoChildLocked(fbl::RefPtr<VmCowPages>& child) TA_REQ(lock_);

  // Removes the specified child from this objects |children_list_| and performs any hierarchy
  // updates that need to happen as a result. This does not modify the |parent_| member of the
  // removed child and if this is not being called due to |removed| being destructed it is the
  // callers responsibility to correct parent_.
  void RemoveChildLocked(VmCowPages* removed) TA_REQ(lock_);

  // Inserts a newly created VmCowPages into this hierarchy as a child of this VmCowPages.
  // Initializes child members based on the passed in values that only have meaning when an object
  // is a child. This updates the parent_ field in child to hold a refptr to |this|.
  void AddChildLocked(VmCowPages* child, uint64_t offset, uint64_t root_parent_offset,
                      uint64_t parent_limit) TA_REQ(lock_);

  // Outside of initialization/destruction, hidden vmos always have two children. For
  // clarity, whichever child is first in the list is the 'left' child, and whichever
  // child is second is the 'right' child. Children of a paged vmo will always be paged
  // vmos themselves.
  VmCowPages& left_child_locked() TA_REQ(lock_) TA_ASSERT(left_child_locked().lock()) {
    DEBUG_ASSERT(is_hidden_locked());
    DEBUG_ASSERT(children_list_len_ == 2);

    auto& ret = children_list_.front();
    AssertHeld(ret.lock_);
    return ret;
  }
  VmCowPages& right_child_locked() TA_REQ(lock_) TA_ASSERT(right_child_locked().lock()) {
    DEBUG_ASSERT(is_hidden_locked());
    DEBUG_ASSERT(children_list_len_ == 2);
    auto& ret = children_list_.back();
    AssertHeld(ret.lock_);
    return ret;
  }
  const VmCowPages& left_child_locked() const TA_REQ(lock_) TA_ASSERT(left_child_locked().lock()) {
    DEBUG_ASSERT(is_hidden_locked());
    DEBUG_ASSERT(children_list_len_ == 2);
    const auto& ret = children_list_.front();
    AssertHeld(ret.lock_);
    return ret;
  }
  const VmCowPages& right_child_locked() const TA_REQ(lock_)
      TA_ASSERT(right_child_locked().lock()) {
    DEBUG_ASSERT(is_hidden_locked());
    DEBUG_ASSERT(children_list_len_ == 2);
    const auto& ret = children_list_.back();
    AssertHeld(ret.lock_);
    return ret;
  }

  void ReplaceChildLocked(VmCowPages* old, VmCowPages* new_child) TA_REQ(lock_);

  void DropChildLocked(VmCowPages* c) TA_REQ(lock_);

  // Types for an additional linked list over the VmCowPages for use when doing a
  // RangeChangeUpdate.
  //
  // To avoid unbounded stack growth we need to reserve the memory to exist on a
  // RangeChange list in our object so that we can have a flat iteration over a
  // work list. RangeChangeLists should only be used by the RangeChangeUpdate
  // code.
  using RangeChangeNodeState = fbl::SinglyLinkedListNodeState<VmCowPages*>;
  struct RangeChangeTraits {
    static RangeChangeNodeState& node_state(VmCowPages& cow) { return cow.range_change_state_; }
  };
  using RangeChangeList =
      fbl::SinglyLinkedListCustomTraits<VmCowPages*, VmCowPages::RangeChangeTraits>;
  friend struct RangeChangeTraits;

  // Given an initial list of VmCowPages performs RangeChangeUpdate on it until the list is empty.
  static void RangeChangeUpdateListLocked(RangeChangeList* list, RangeChangeOp op);

  void RangeChangeUpdateFromParentLocked(uint64_t offset, uint64_t len, RangeChangeList* list)
      TA_REQ(lock_);

  // Helper to check whether the requested range for LockRangeLocked() / TryLockRangeLocked() /
  // UnlockRangeLocked() is valid.
  bool IsLockRangeValidLocked(uint64_t offset, uint64_t len) const TA_REQ(lock_);

  // Lock that protects the global discardable lists.
  // This lock can be acquired with the vmo's |lock_| held. To prevent deadlocks, if both locks are
  // required the order of locking should always be 1) vmo's lock, and then 2) DiscardableVmosLock.
  DECLARE_SINGLETON_MUTEX(DiscardableVmosLock);

  enum class DiscardableState : uint8_t {
    kUnset = 0,
    kReclaimable,
    kUnreclaimable,
    kDiscarded,
  };

  using DiscardableList = fbl::TaggedDoublyLinkedList<VmCowPages*, internal::DiscardableListTag>;

  // Two global lists of discardable vmos:
  // - |discardable_reclaim_candidates_| tracks discardable vmos that are eligible for reclamation
  // and haven't been reclaimed yet.
  // - |discardable_non_reclaim_candidates_| tracks all other discardable VMOs.
  // The lists are protected by the |DiscardableVmosLock|, and updated based on a discardable vmo's
  // state changes (lock, unlock, or discard).
  static DiscardableList discardable_reclaim_candidates_ TA_GUARDED(DiscardableVmosLock::Get());
  static DiscardableList discardable_non_reclaim_candidates_ TA_GUARDED(DiscardableVmosLock::Get());

  // Helper function to move an object from the |discardable_non_reclaim_candidates_| list to the
  // |discardable_reclaim_candidates_| list.
  void MoveToReclaimCandidatesListLocked() TA_REQ(lock_) TA_REQ(DiscardableVmosLock::Get());

  // Helper function to move an object from the |discardable_reclaim_candidates_| list to the
  // |discardable_non_reclaim_candidates_| list. If |new_candidate| is true, that indicates that the
  // object was not yet being tracked on any list, and should only be inserted into the
  // |discardable_non_reclaim_candidates_| list without a corresponding list removal.
  void MoveToNonReclaimCandidatesListLocked(bool new_candidate = false) TA_REQ(lock_)
      TA_REQ(DiscardableVmosLock::Get());

  // Updates the |discardable_state_| of a discardable vmo, and moves it from one discardable list
  // to another.
  void UpdateDiscardableStateLocked(DiscardableState state) TA_REQ(lock_)
      TA_EXCL(DiscardableVmosLock::Get());

  // Remove a discardable object from whichever global discardable list it is in. Called from the
  // VmCowPages destructor.
  void RemoveFromDiscardableListLocked() TA_REQ(lock_) TA_EXCL(DiscardableVmosLock::Get());

  // Returns whether the vmo is in either one of the |discardable_reclaim_candidates_| or
  // |discardable_reclaim_candidates_| lists, depending on whether it is a |reclaim_candidate|
  // or not.
  bool DebugIsInDiscardableListLocked(bool reclaim_candidate) const TA_REQ(lock_)
      TA_EXCL(DiscardableVmosLock::Get());

  DiscardablePageCounts GetDiscardablePageCounts() const TA_EXCL(lock_);

  // Returns the root parent's page source.
  fbl::RefPtr<PageSource> GetRootPageSourceLocked() const TA_REQ(lock_);

  void FreePages(list_node* pages) {
    if (!page_source_ || !page_source_->properties().is_handling_free) {
      pmm_free(pages);
      return;
    }
    page_source_->FreePages(pages);
  }

  void FreePage(vm_page_t* page) {
    DEBUG_ASSERT(!list_in_list(&page->queue_node));
    if (!page_source_ || !page_source_->properties().is_handling_free) {
      pmm_free_page(page);
      return;
    }
    list_node_t list;
    list_initialize(&list);
    list_add_tail(&list, &page->queue_node);
    page_source_->FreePages(&list);
  }

  void CopyPageForReplacementLocked(vm_page_t* dst_page, vm_page_t* src_page) TA_REQ(lock_);

  // Update supply_zero_offset_ to the specified page-aligned |offset|, and potentially also reset
  // awaiting_clean_zero_range_end_ if required. (See comments near declaration of
  // awaiting_clean_zero_range_end_ for additional context.)
  void UpdateSupplyZeroOffsetLocked(uint64_t offset) TA_REQ(lock_) {
    DEBUG_ASSERT(IS_PAGE_ALIGNED(offset));
    uint64_t prev_supply_zero_offset = supply_zero_offset_;
    supply_zero_offset_ = offset;

    // If there was no zero range AwaitingClean, there is nothing more to do.
    if (awaiting_clean_zero_range_end_ == 0) {
      return;
    }
    DEBUG_ASSERT(prev_supply_zero_offset < awaiting_clean_zero_range_end_);

    // The AwaitingClean zero range we were tracking was [prev_supply_zero_offset,
    // awaiting_clean_zero_range_end_). If |offset| lies within this range, we still have a valid
    // AwaitingClean sub-range that we can continue tracking i.e. [offset,
    // awaiting_clean_zero_range_end_). Otherwise, the AwaitingClean zero range is no longer valid
    // and must be reset.
    if (!(offset >= prev_supply_zero_offset && offset < awaiting_clean_zero_range_end_)) {
      awaiting_clean_zero_range_end_ = 0;
    }

    // If awaiting_clean_zero_range_end_ is non-zero, it should be strictly greater than
    // supply_zero_offset_, as it is used to track the range [supply_zero_offset_,
    // awaiting_clean_zero_range_end_).
    DEBUG_ASSERT(awaiting_clean_zero_range_end_ == 0 ||
                 supply_zero_offset_ < awaiting_clean_zero_range_end_);
  }

  // Consider trimming the AwaitingClean zero range (if there is one) to end at the specified
  // page-aligned |end_offset|. The AwaitingClean zero range always starts at supply_zero_offset_.
  // (See comments near declaration of awaiting_clean_zero_range_end_ for additional context.)
  //
  // Three scenarios are possible here:
  //  - If awaiting_clean_zero_range_end_ is 0, no AwaitingClean zero range is being tracked, so
  //  nothing needs to be done.
  //  - If |end_offset| lies within [supply_zero_offset_, awaiting_clean_zero_range_end_), the zero
  //  range should now end at |end_offset|. The new AwaitingClean zero range becomes
  //  [supply_zero_offset_, end_offset).
  //  - If |end_offset| lies outside of [supply_zero_offset_, awaiting_clean_zero_range_end_), it
  //  does not affect the AwaitingClean zero range.
  void ConsiderTrimAwaitingCleanZeroRangeLocked(uint64_t end_offset) TA_REQ(lock_) {
    DEBUG_ASSERT(IS_PAGE_ALIGNED(end_offset));

    // No AwaitingClean zero range was being tracked.
    if (awaiting_clean_zero_range_end_ == 0) {
      return;
    }
    DEBUG_ASSERT(supply_zero_offset_ < awaiting_clean_zero_range_end_);

    // Trim the zero range to the new end offset.
    if (end_offset >= supply_zero_offset_ && end_offset < awaiting_clean_zero_range_end_) {
      awaiting_clean_zero_range_end_ = end_offset;
      // Reset awaiting_clean_zero_range_end_ if this leaves us with no valid range.
      if (awaiting_clean_zero_range_end_ == supply_zero_offset_) {
        awaiting_clean_zero_range_end_ = 0;
      }
    }

    // If awaiting_clean_zero_range_end_ is non-zero, it should be strictly greater than
    // supply_zero_offset_, as it is used to track the range [supply_zero_offset_,
    // awaiting_clean_zero_range_end_).
    DEBUG_ASSERT(awaiting_clean_zero_range_end_ == 0 ||
                 supply_zero_offset_ < awaiting_clean_zero_range_end_);
  }

  // magic value
  fbl::Canary<fbl::magic("VMCP")> canary_;

  // VmCowPages keeps this ref on VmCowPagesContainer until the end of VmCowPages::fbl_recycle().
  // This allows loaned page reclaim to upgrade a raw container pointer until _after_ all the pages
  // have been removed from the VmCowPages.  This way there's always something for loaned page
  // reclaim to block on that'll do priority inheritance to the thread that needs to finish moving
  // pages.
  fbl::RefPtr<VmCowPagesContainer> container_;
  VmCowPagesContainer* debug_retained_raw_container_ = nullptr;

  VmCowPagesOptions options_ TA_GUARDED(lock_);

  uint64_t size_ TA_GUARDED(lock_);
  // Offset in the *parent* where this object starts.
  uint64_t parent_offset_ TA_GUARDED(lock_) = 0;
  // Offset in *this object* above which accesses will no longer access the parent.
  uint64_t parent_limit_ TA_GUARDED(lock_) = 0;
  // Offset in *this object* below which this vmo stops referring to its parent. This field
  // is only useful for hidden vmos, where it is used by ::ReleaseCowPagesParentLocked
  // together with parent_limit_ to reduce how often page split bits need to be set. It is
  // effectively a summary of the parent_offset_ values of all descendants - unlike
  // parent_limit_, this value does not directly impact page lookup. See partial_cow_release_ flag
  // for more details on usage of this limit.
  uint64_t parent_start_limit_ TA_GUARDED(lock_) = 0;
  // Offset in our root parent where this object would start if projected onto it. This value is
  // used as an efficient summation of accumulated offsets to ensure that an offset projected all
  // the way to the root would not overflow a 64-bit integer. Although actual page resolution
  // would never reach the root in such a case, a childs full range projected onto its parent is
  // used to simplify some operations and so this invariant of not overflowing accumulated offsets
  // needs to be maintained.
  uint64_t root_parent_offset_ TA_GUARDED(lock_) = 0;
  const uint32_t pmm_alloc_flags_;

  // Flag which is true if there was a call to ::ReleaseCowParentPagesLocked which was
  // not able to update the parent limits. When this is not set, it is sometimes
  // possible for ::MergeContentWithChildLocked to do significantly less work. This flag acts as a
  // proxy then for how precise the parent_limit_ and parent_start_limit_ are. It is always an
  // absolute guarantee that descendants cannot see outside of the limits, but when this flag is
  // true there is a possibility that there is a sub range inside the limits that they also cannot
  // see.
  // Imagine a two siblings that see the parent range [0x1000-0x2000) and [0x3000-0x4000)
  // respectively. The parent can have the start_limit of 0x1000 and limit of 0x4000, but without
  // additional allocations it cannot track the free region 0x2000-0x3000, and so
  // partial_cow_release_ must be set to indicate in the future we need to do more expensive
  // processing to check for such free regions.
  bool partial_cow_release_ TA_GUARDED(lock_) = false;

  // parent pointer (may be null)
  fbl::RefPtr<VmCowPages> parent_ TA_GUARDED(lock_);

  // list of every child
  fbl::TaggedDoublyLinkedList<VmCowPages*, internal::ChildListTag> children_list_ TA_GUARDED(lock_);

  // length of children_list_
  uint32_t children_list_len_ TA_GUARDED(lock_) = 0;

  // Flag used for walking back up clone tree without recursion. See ::CloneCowPageLocked.
  enum class StackDir : bool {
    Left,
    Right,
  };
  struct {
    uint64_t scratch : 63;
    StackDir dir_flag : 1;
  } stack_ TA_GUARDED(lock_);

  // This value is used when determining against which user-visible vmo a hidden vmo's
  // pages should be attributed. It serves as a tie-breaker for pages that are accessible by
  // multiple user-visible vmos. See ::HasAttributedAncestorPageLocked for more details.
  //
  // For non-hidden vmobjects, this always equals user_id_. For hidden vmobjects, this
  // is the page_attribution_user_id_ of one of their children (i.e. the user_id_ of one
  // of their non-hidden descendants).
  uint64_t page_attribution_user_id_ TA_GUARDED(lock_) = 0;

  // Counts the total number of pages pinned by ::CommitRange. If one page is pinned n times, it
  // contributes n to this count.
  uint64_t pinned_page_count_ TA_GUARDED(lock_) = 0;

  // The page source, if any.
  const fbl::RefPtr<PageSource> page_source_;

  // The offset beyond which new page requests are fulfilled by supplying zero pages, rather than
  // having the page source supply pages. Only relevant if there is a valid page_source_ and it
  // preserves page content.
  //
  // Updating supply_zero_offset_ might affect the AwaitingClean zero range being tracked by
  // [supply_zero_offset_, awaiting_clean_zero_range_end_), and so supply_zero_offset_ should not
  // be directly assigned. Use the UpdateSupplyZeroOffsetLocked() helper instead. See comments near
  // awaiting_clean_zero_range_end_ for more context.
  uint64_t supply_zero_offset_ TA_GUARDED(lock_) = UINT64_MAX;

  // If supply_zero_offset_ is relevant, and there is a zero range that is AwaitingClean, i.e. a
  // zero range starting at supply_zero_offset_, on which WritebackBegin was called but not
  // WritebackEnd, awaiting_clean_zero_range_end_ tracks the end of that range. In other words, if
  // there exists a zero range that is AwaitingClean, that range is [supply_zero_offset_,
  // awaiting_clean_zero_range_end_).
  //
  // Will be set to 0 otherwise. So awaiting_clean_zero_range_end_ will either be 0, or will be
  // strictly greater than supply_zero_offset_.
  //
  // Note that there can be at most one zero range that is AwaitingClean at a time.
  //
  // The motivation for this value is to be able to transition the zero range starting at
  // supply_zero_offset_ to Clean once it has been written back by the user pager, without having to
  // track per-page dirty state for this zero range, which is represented in the page list by a gap.
  // TODO(rashaeqbal): Consider removing this once page lists can support custom zero ranges.
  uint64_t awaiting_clean_zero_range_end_ TA_GUARDED(lock_) = 0;

  // Count eviction events so that we can report them to the user.
  uint64_t eviction_event_count_ TA_GUARDED(lock_) = 0;

  // Count of outstanding lock operations. A non-zero count prevents the kernel from discarding /
  // evicting pages from the VMO to relieve memory pressure (currently only applicable if
  // |kDiscardable| is set). Note that this does not prevent removal of pages by other means, like
  // decommitting or resizing, since those are explicit actions driven by the user, not by the
  // kernel directly.
  uint64_t lock_count_ TA_GUARDED(lock_) = 0;

  // Timestamp of the last unlock operation that changed a discardable vmo's state to
  // |kReclaimable|. Used to determine whether the vmo was accessed too recently to be discarded.
  zx_time_t last_unlock_timestamp_ TA_GUARDED(lock_) = ZX_TIME_INFINITE;

  // The current state of a discardable vmo, depending on the lock count and whether it has been
  // discarded.
  // State transitions work as follows:
  // 1. kUnreclaimable -> kReclaimable: When the lock count changes from 1 to 0.
  // 2. kReclaimable -> kUnreclaimable: When the lock count changes from 0 to 1. The vmo remains
  // kUnreclaimable for any non-zero lock count.
  // 3. kReclaimable -> kDiscarded: When a vmo with lock count 0 is discarded.
  // 4. kDiscarded -> kUnreclaimable: When a discarded vmo is locked again.
  //
  // We start off with state kUnset, so a discardable vmo must be locked at least once to opt into
  // the above state transitions. For non-discardable vmos, the state will always remain kUnset.
  DiscardableState discardable_state_ TA_GUARDED(lock_) = DiscardableState::kUnset;

  // a tree of pages
  VmPageList page_list_ TA_GUARDED(lock_);

  RangeChangeNodeState range_change_state_;
  uint64_t range_change_offset_ TA_GUARDED(lock_);
  uint64_t range_change_len_ TA_GUARDED(lock_);

  // optional reference back to a VmObjectPaged so that we can perform mapping updates. This is a
  // raw pointer to avoid circular references, the VmObjectPaged destructor needs to update it.
  VmObjectPaged* paged_ref_ TA_GUARDED(lock_) = nullptr;

  // TODO(fxb/85056): This is a temporary solution and needs to be replaced with something that is
  // formalized.
  // Marks whether or not this VMO is considered a latency sensitive object. For a VMO being latency
  // sensitive means pages that get committed should not be decommitted (or made expensive to
  // access) by any background kernel process, such as the zero page deduper.
  // Note: This does not presently protect against user pager eviction, as there is already a
  // separate mechanism for that. Once fxb/85056 is resolved this might change.
  bool is_latency_sensitive_ TA_GUARDED(lock_) = false;

  using Cursor =
      VmoCursor<VmCowPages, DiscardableVmosLock, DiscardableList, DiscardableList::iterator>;

  // The list of all outstanding cursors iterating over the discardable lists:
  // |discardable_reclaim_candidates_| and |discardable_non_reclaim_candidates_|. The cursors should
  // be advanced (by calling AdvanceIf()) before removing any element from the discardable lists.
  static fbl::DoublyLinkedList<Cursor*> discardable_vmos_cursors_
      TA_GUARDED(DiscardableVmosLock::Get());

  // With this bool we achieve these things:
  //  * Avoid using loaned pages for a VMO that will just get pinned and replace the loaned pages
  //    with non-loaned pages again, possibly repeatedly.
  //  * Avoid increasing pin latency in the (more) common case of pinning a VMO the 2nd or
  //    subsequent times (vs the 1st time).
  //  * Once we have any form of active sweeping (of data from non-loaned to loaned physical pages)
  //    this bool is part of mitigating any potential DMA-while-not-pinned (which is not permitted
  //    but is also difficult to detect or prevent without an IOMMU).
  bool ever_pinned_ TA_GUARDED(lock_) = false;

  // Tracks whether this VMO was modified (written / resized) if backed by a pager. This gets reset
  // to false if QueryPagerVmoStatsLocked() is called with |reset| set to true.
  bool pager_stats_modified_ TA_GUARDED(lock_) = false;
};

// VmCowPagesContainer exists to essentially split the VmCowPages ref_count_ into two counts, so
// that it remains possible to upgrade from a raw container pointer until after the VmCowPages
// fbl_recycle() has mostly completed and has removed and freed all the pages.
//
// This way, if we can upgrade, then we can call RemovePageForEviction() and it'll either work or
// the page will already have been removed from that location in the VmCowPages, or we can't
// upgrade, in which case all the pages have already been removed and freed.
//
// In contrast if we were to attempt upgrade of a raw VmCowPages pointer to VmCowPages ref, the
// ability to upgrade would disappear before the backlink is removed to make room for a
// StackOwnedLoanedPagesInterval, so loaned page reclaim would need to wait (somehow) for the page
// to be removed from the VmCowPages and at least have a backlink.  That wait is problematic since
// it would also need to propagate priority inheritance properly like StackOwnedLoanedPagesInterval
// does, but the interval begins at the moment the refcount goes from 1 to 0, and reliably wrapping
// that 1 to 0 transition, while definitely posssible with some RefPtr changes etc etc, is more
// complicated than having a VmCowPagesContainer whose ref can still be obtained up until after the
// pages have become FREE.  There may of course be yet other options that are overall better; please
// suggest if you think of one.
//
// All the explicit cleanup of VmCowPages happens in VmCowPages::fbl_recycle(), with the final
// explicit fbl_recycle() step being release of the containing VmCowPagesContainer which in turn
// triggers ~VmCowPages which finishes up with implicit cleanup of VmCowPages (but possibly delayed
// slightly by loaned page reclaimer(s) that can have a VmCowPagesContainer ref transiently).
//
// Those paying close attention may note that under high load with potential low priority thread
// starvation (with a hypothetical scheduling policy that is assumed to let thread starvation be
// possible), each low priority loaned page reclaiming thread may essentially be thought of as
// having up to one VmCowPagesContainer + contained de-populated VmCowPages as additional memory
// overhead that can be thought of as being essentially attributed to the memory cost of the low
// priority thread.  I think this is completely fine and completely analogous to many other similar
// situations.  In a sense it's priority inversion of the rest of cleanup of the VmCowPages memory,
// but since it's a depopulated VmCowPages, the symptom isn't enough of a problem to justify any
// mitigation other than mentally accounting for it in the low priority thread's memory cost.  We
// should be careful not to let a refcount held by a lower priority thread potentially keep
// unbounded memory allocated of course, but in this case it's well bounded.
//
// We restrict visibility of VmCowPages via its VmCowPagesContainer, to control which methods are
// ok to call on the VmCowPages via a VmCowPagesContainer ref while lacking any direct VmCowPages
// ref.  The methods that are ok to call with only a VmCowPagesContainer ref are called via a
// corresponding method on VmCowPagesContainer.
class VmCowPagesContainer : public fbl::RefCountedUpgradeable<VmCowPagesContainer> {
 public:
  VmCowPagesContainer() = default;
  ~VmCowPagesContainer();

  // These are the only VmCowPages methods that are ok to call via ref on VmCowPagesContainer while
  // holding no ref on the contained VmCowPages.  These will operate correctly despite potential
  // concurrent VmCowPages::fbl_recycle() on a different thread and despite VmCowPages refcount_
  // potentially being 0.  The VmCowPagesContainer ref held by the caller keeps the actual
  // VmCowPages object alive during this call.
  bool RemovePageForEviction(vm_page_t* page, uint64_t offset,
                             VmCowPages::EvictionHintAction hint_action);

  zx_status_t ReplacePageWithLoaned(vm_page_t* page, uint64_t offset);

 private:
  friend class VmCowPages;

  // We'd use ktl::optional<VmCowPages> or std::variant<monostate, VmCowPages>, but both those
  // require is_constructible_v<VmCowPages, ...>, which in turn requires the VmCowPages constructor
  // to be public, which we don't want.

  // Used for construction of contained VmCowPages.
  template <class... Args>
  void EmplaceCow(Args&&... args);

  VmCowPages& cow();

  ktl::aligned_storage_t<sizeof(VmCowPages), alignof(VmCowPages)> cow_space_;
  bool is_cow_present_ = false;
};

#endif  // ZIRCON_KERNEL_VM_INCLUDE_VM_VM_COW_PAGES_H_
