// Copyright 2016 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

#include <bits.h>
#include <lib/fit/defer.h>
#include <lib/unittest/unittest.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <arch/aspace.h>
#include <ktl/iterator.h>
#include <vm/arch_vm_aspace.h>
#include <vm/pmm.h>
#include <vm/vm_aspace.h>

#include <ktl/enforce.h>

#ifdef __x86_64__
#include <arch/x86/mmu.h>
#define PGTABLE_L1_SHIFT PDP_SHIFT
#define PGTABLE_L2_SHIFT PD_SHIFT
#else
#define PGTABLE_L1_SHIFT MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 1)
#define PGTABLE_L2_SHIFT MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 2)
#endif

// Most mmu tests want a 'sufficiently large' aspace to play in, these constants define an aspace
// that is large without having a discontinuity over the sign extended canonical addresses.
constexpr vaddr_t kAspaceBase = 1UL << 20;
constexpr size_t kAspaceSize = (1UL << 47) - kAspaceBase - (1UL << 20);

static bool test_large_unaligned_region() {
  BEGIN_TEST;
  ArchVmAspace aspace(kAspaceBase, kAspaceSize, 0);
  zx_status_t err = aspace.Init();
  EXPECT_EQ(err, ZX_OK, "init aspace");

  const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;

  // We want our region to be misaligned by at least a page, and for
  // it to straddle the PDP.
  vaddr_t va = (1UL << PGTABLE_L1_SHIFT) - (1UL << PGTABLE_L2_SHIFT) + 2 * PAGE_SIZE;
  // Make sure alloc_size is less than 1 PD page, to exercise the
  // non-terminal code path.
  static const size_t alloc_size = (1UL << PGTABLE_L2_SHIFT) - PAGE_SIZE;

  // Map a single page to force the lower PDP of the target region
  // to be created
  size_t mapped;
  err = aspace.MapContiguous(va - 3 * PAGE_SIZE, 0, 1, arch_rw_flags, &mapped);
  EXPECT_EQ(err, ZX_OK, "map single page");
  EXPECT_EQ(mapped, 1u, "map single page");

  // Map the last page of the region
  err = aspace.MapContiguous(va + alloc_size - PAGE_SIZE, 0, 1, arch_rw_flags, &mapped);
  EXPECT_EQ(err, ZX_OK, "map last page");
  EXPECT_EQ(mapped, 1u, "map single page");

  paddr_t pa;
  uint flags;
  err = aspace.Query(va + alloc_size - PAGE_SIZE, &pa, &flags);
  EXPECT_EQ(err, ZX_OK, "last entry is mapped");

  // Attempt to unmap the target region (analogous to unmapping a demand
  // paged region that has only had its last page touched)
  size_t unmapped;
  err = aspace.Unmap(va, alloc_size / PAGE_SIZE, ArchVmAspace::EnlargeOperation::Yes, &unmapped);
  EXPECT_EQ(err, ZX_OK, "unmap unallocated region");
  EXPECT_EQ(unmapped, alloc_size / PAGE_SIZE, "unmap unallocated region");

  err = aspace.Query(va + alloc_size - PAGE_SIZE, &pa, &flags);
  EXPECT_EQ(err, ZX_ERR_NOT_FOUND, "last entry is not mapped anymore");

  // Unmap the single page from earlier
  err = aspace.Unmap(va - 3 * PAGE_SIZE, 1, ArchVmAspace::EnlargeOperation::Yes, &unmapped);
  EXPECT_EQ(err, ZX_OK, "unmap single page");
  EXPECT_EQ(unmapped, 1u, "unmap unallocated region");

  err = aspace.Destroy();
  EXPECT_EQ(err, ZX_OK, "destroy aspace");

  END_TEST;
}

static bool test_large_unaligned_region_without_map() {
  BEGIN_TEST;

  {
    ArchVmAspace aspace(kAspaceBase, kAspaceSize, 0);
    zx_status_t err = aspace.Init();
    EXPECT_EQ(err, ZX_OK, "init aspace");

    const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;

    // We want our region to be misaligned by a page, and for it to
    // straddle the PDP
    vaddr_t va = (1UL << PGTABLE_L1_SHIFT) - (1UL << PGTABLE_L2_SHIFT) + PAGE_SIZE;
    // Make sure alloc_size is bigger than 1 PD page, to exercise the
    // non-terminal code path.
    static const size_t alloc_size = 3UL << PGTABLE_L2_SHIFT;

    // Map a single page to force the lower PDP of the target region
    // to be created
    size_t mapped;
    err = aspace.MapContiguous(va - 2 * PAGE_SIZE, 0, 1, arch_rw_flags, &mapped);
    EXPECT_EQ(err, ZX_OK, "map single page");
    EXPECT_EQ(mapped, 1u, "map single page");

    // Attempt to unmap the target region (analogous to unmapping a demand
    // paged region that has not been touched)
    size_t unmapped;
    err = aspace.Unmap(va, alloc_size / PAGE_SIZE, ArchVmAspace::EnlargeOperation::Yes, &unmapped);
    EXPECT_EQ(err, ZX_OK, "unmap unallocated region");
    EXPECT_EQ(unmapped, alloc_size / PAGE_SIZE, "unmap unallocated region");

    // Unmap the single page from earlier
    err = aspace.Unmap(va - 2 * PAGE_SIZE, 1, ArchVmAspace::EnlargeOperation::Yes, &unmapped);
    EXPECT_EQ(err, ZX_OK, "unmap single page");
    EXPECT_EQ(unmapped, 1u, "unmap single page");

    err = aspace.Destroy();
    EXPECT_EQ(err, ZX_OK, "destroy aspace");
  }

  END_TEST;
}

static bool test_large_region_protect() {
  BEGIN_TEST;

  static const vaddr_t va = 1UL << PGTABLE_L1_SHIFT;
  // Force a large page.
  static const size_t alloc_size = 1UL << PGTABLE_L2_SHIFT;
  static const vaddr_t alloc_end = va + alloc_size;

  vaddr_t target_vaddrs[] = {
      va,
      va + PAGE_SIZE,
      va + 2 * PAGE_SIZE,
      alloc_end - 3 * PAGE_SIZE,
      alloc_end - 2 * PAGE_SIZE,
      alloc_end - PAGE_SIZE,
  };

  for (unsigned i = 0; i < ktl::size(target_vaddrs); i++) {
    ArchVmAspace aspace(kAspaceBase, kAspaceSize, 0);
    zx_status_t err = aspace.Init();
    EXPECT_EQ(err, ZX_OK, "init aspace");

    const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;

    size_t mapped;
    err = aspace.MapContiguous(va, 0, alloc_size / PAGE_SIZE, arch_rw_flags, &mapped);
    EXPECT_EQ(err, ZX_OK, "map large page");
    EXPECT_EQ(mapped, 512u, "map large page");

    err = aspace.Protect(target_vaddrs[i], 1, ARCH_MMU_FLAG_PERM_READ);
    EXPECT_EQ(err, ZX_OK, "protect single page");

    for (unsigned j = 0; j < ktl::size(target_vaddrs); j++) {
      uint retrieved_flags = 0;
      paddr_t pa;
      EXPECT_EQ(ZX_OK, aspace.Query(target_vaddrs[j], &pa, &retrieved_flags));
      EXPECT_EQ(target_vaddrs[j] - va, pa);

      EXPECT_EQ(i == j ? ARCH_MMU_FLAG_PERM_READ : arch_rw_flags, retrieved_flags);
    }

    err = aspace.Unmap(va, alloc_size / PAGE_SIZE, ArchVmAspace::EnlargeOperation::Yes, &mapped);
    EXPECT_EQ(err, ZX_OK, "unmap large page");
    EXPECT_EQ(mapped, 512u, "unmap large page");
    err = aspace.Destroy();
    EXPECT_EQ(err, ZX_OK, "destroy aspace");
  }

  END_TEST;
}

// Since toggle_page_alloc_fn needs global state to operate, define a lock to ensure we are only
// running a single instance of these tests at a time.
DECLARE_SINGLETON_MUTEX(TogglePageAllocLock);
static bool fail_page_allocs = false;
static zx_status_t toggle_page_alloc_fn(uint mmu_flags, vm_page** p, paddr_t* pa) {
  if (fail_page_allocs) {
    return ZX_ERR_NO_MEMORY;
  }
  return pmm_alloc_page(mmu_flags, p, pa);
}

static bool test_large_region_unmap() {
  BEGIN_TEST;

  Guard<Mutex> guard{TogglePageAllocLock::Get()};

  static const vaddr_t va = 1UL << PGTABLE_L1_SHIFT;
  // Force a large page.
  static const size_t alloc_size = 1UL << PGTABLE_L2_SHIFT;
  static const vaddr_t alloc_end = va + alloc_size;

  vaddr_t target_vaddrs[] = {
      va,
      va + PAGE_SIZE,
      va + 2 * PAGE_SIZE,
      alloc_end - 3 * PAGE_SIZE,
      alloc_end - 2 * PAGE_SIZE,
      alloc_end - PAGE_SIZE,
  };

  for (unsigned i = 0; i < ktl::size(target_vaddrs); i++) {
    fail_page_allocs = false;
    ArchVmAspace aspace(kAspaceBase, kAspaceSize, 0, toggle_page_alloc_fn);
    zx_status_t err = aspace.Init();
    EXPECT_EQ(err, ZX_OK, "init aspace");

    const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;

    size_t mapped;
    // Use MapContiguous to create a mapping that should get backed by a large page.
    err = aspace.MapContiguous(va, 0, alloc_size / PAGE_SIZE, arch_rw_flags, &mapped);
    EXPECT_EQ(err, ZX_OK, "map large page");
    EXPECT_EQ(mapped, 512u, "map large page");

    // Unmap a single small page out of the larger page.
    err = aspace.Unmap(target_vaddrs[i], 1, ArchVmAspace::EnlargeOperation::Yes, &mapped);
    EXPECT_EQ(err, ZX_OK, "unmap single page");
    EXPECT_EQ(mapped, 1u, "unmap single page");

    // Ensure the single page was unmapped, but the rest of the large page is still present.
    for (unsigned j = 0; j < ktl::size(target_vaddrs); j++) {
      uint retrieved_flags = 0;
      paddr_t pa;
      zx_status_t result = aspace.Query(target_vaddrs[j], &pa, &retrieved_flags);
      EXPECT_EQ(i == j ? ZX_ERR_NOT_FOUND : ZX_OK, result, "query page");
    }

    err = aspace.Unmap(va, alloc_size / PAGE_SIZE, ArchVmAspace::EnlargeOperation::Yes, &mapped);
    EXPECT_EQ(err, ZX_OK, "unmap remaining pages");
    EXPECT_EQ(mapped, 512u, "unmap remaining pages");

    // Map in the large page again.
    err = aspace.MapContiguous(va, 0, alloc_size / PAGE_SIZE, arch_rw_flags, &mapped);
    EXPECT_EQ(err, ZX_OK, "map large page");
    EXPECT_EQ(mapped, 512u, "map large page");

    // Simulate OOM by failing allocations.
    fail_page_allocs = true;
    // Attempt to unmap a single small page, but allow over unmapping.
    err = aspace.Unmap(target_vaddrs[i], 1, ArchVmAspace::EnlargeOperation::Yes, &mapped);
    EXPECT_EQ(err, ZX_OK, "unmap single page");
    EXPECT_EQ(mapped, 1u, "unmap single page");

    // The entire large page should have ended up unmapped.
    for (unsigned j = 0; j < ktl::size(target_vaddrs); j++) {
      uint retrieved_flags = 0;
      paddr_t pa;
      zx_status_t result = aspace.Query(target_vaddrs[j], &pa, &retrieved_flags);
      EXPECT_EQ(ZX_ERR_NOT_FOUND, result, "query page");
    }

    err = aspace.Unmap(va, alloc_size / PAGE_SIZE, ArchVmAspace::EnlargeOperation::Yes, &mapped);
    EXPECT_EQ(err, ZX_OK, "unmap remaining pages");
    EXPECT_EQ(mapped, 512u, "unmap remaining pages");

    // Map in the large page again.
    fail_page_allocs = false;
    err = aspace.MapContiguous(va, 0, alloc_size / PAGE_SIZE, arch_rw_flags, &mapped);
    EXPECT_EQ(err, ZX_OK, "map large page");
    EXPECT_EQ(mapped, 512u, "map large page");

    // Simulate OOM by failing allocations.
    fail_page_allocs = true;
    // Attempt to unmap a single small page, but disallow over unmapping.
    err = aspace.Unmap(target_vaddrs[i], 1, ArchVmAspace::EnlargeOperation::No, &mapped);
    EXPECT_EQ(err, ZX_ERR_NO_MEMORY, "unmap single page");

    // All mappings should still be present.
    // The entire large page should have ended up unmapped.
    for (unsigned j = 0; j < ktl::size(target_vaddrs); j++) {
      uint retrieved_flags = 0;
      paddr_t pa;
      zx_status_t result = aspace.Query(target_vaddrs[j], &pa, &retrieved_flags);
      EXPECT_EQ(ZX_OK, result, "query page");
    }

    err = aspace.Unmap(va, alloc_size / PAGE_SIZE, ArchVmAspace::EnlargeOperation::Yes, &mapped);
    EXPECT_EQ(err, ZX_OK, "unmap remaining pages");
    EXPECT_EQ(mapped, 512u, "unmap remaining pages");
    err = aspace.Destroy();
    EXPECT_EQ(err, ZX_OK, "destroy aspace");
  }

  END_TEST;
}

static list_node node = LIST_INITIAL_VALUE(node);
static zx_status_t test_page_alloc_fn(uint unused, vm_page** p, paddr_t* pa) {
  if (list_is_empty(&node)) {
    return ZX_ERR_NO_MEMORY;
  }
  vm_page_t* page = list_remove_head_type(&node, vm_page_t, queue_node);
  if (p) {
    *p = page;
  }
  if (pa) {
    *pa = page->paddr();
  }
  return ZX_OK;
}

static bool test_mapping_oom() {
  BEGIN_TEST;

  constexpr uint64_t kMappingPageCount = 8;
  constexpr uint64_t kMappingSize = kMappingPageCount * PAGE_SIZE;
  constexpr vaddr_t kMappingStart = (1UL << PGTABLE_L1_SHIFT) - kMappingSize / 2;

  // Allocate the pages which will be mapped into the test aspace.
  vm_page_t* mapping_pages[kMappingPageCount] = {};
  paddr_t mapping_paddrs[kMappingPageCount] = {};

  auto undo = fit::defer([&]() {
    for (vm_page_t* mapping_page : mapping_pages) {
      if (mapping_page) {
        pmm_free_page(mapping_page);
      }
    }
  });

  for (unsigned i = 0; i < kMappingPageCount; i++) {
    ASSERT_EQ(pmm_alloc_page(0, mapping_pages + i, mapping_paddrs + i), ZX_OK);
  }

  // Try to create the mapping with a limited number of pages available to
  // the aspace. Start with only 1 available and continue until the map operation
  // succeeds without running out of memory.
  bool map_success = false;
  uint64_t avail_mmu_pages = 1;
  while (!map_success) {
    for (unsigned i = 0; i < avail_mmu_pages; i++) {
      vm_page_t* page;
      ASSERT_EQ(pmm_alloc_page(0, &page), ZX_OK, "alloc fail");
      list_add_head(&node, &page->queue_node);
    }

    ArchVmAspace aspace(kAspaceBase, kAspaceSize, 0, test_page_alloc_fn);
    zx_status_t err = aspace.Init();
    ASSERT_EQ(err, ZX_OK, "init aspace");

    const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;

    size_t mapped;
    err = aspace.Map(kMappingStart, mapping_paddrs, kMappingPageCount, arch_rw_flags,
                     ArchVmAspace::ExistingEntryAction::Error, &mapped);
    if (err == ZX_OK) {
      map_success = true;
      size_t unmapped;
      EXPECT_EQ(aspace.Unmap(kMappingStart, kMappingPageCount, ArchVmAspace::EnlargeOperation::Yes,
                             &unmapped),
                ZX_OK);
      EXPECT_EQ(unmapped, kMappingPageCount);
    } else {
      EXPECT_EQ(err, ZX_ERR_NO_MEMORY);
      avail_mmu_pages++;
      // validate that all of the pages were consumed
      EXPECT_TRUE(list_is_empty(&node));
    }

    // Destroying the aspace verifies that everything was cleaned up
    // when the mapping failed part way through.
    err = aspace.Destroy();
    ASSERT_EQ(err, ZX_OK, "destroy aspace");
    ASSERT_TRUE(list_is_empty(&node));
  }

  END_TEST;
}

static bool test_skip_existing_mapping() {
  BEGIN_TEST;

  constexpr vaddr_t kMapBase = kAspaceBase;
  constexpr paddr_t kPhysBase = 0;
  constexpr size_t kNumPages = 8;
  constexpr size_t kMidPage = kNumPages / 2;

  ArchVmAspace aspace(kAspaceBase, kAspaceSize, 0);
  zx_status_t err = aspace.Init();
  EXPECT_EQ(err, ZX_OK);

  const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;

  paddr_t page_addresses[kNumPages];
  for (size_t i = 0; i < kNumPages; i++) {
    page_addresses[i] = kPhysBase + (PAGE_SIZE * i);
  }

  size_t mapped;

  // Map in the middle page by itself first, using the final settings.
  err = aspace.Map(kMapBase + kMidPage * PAGE_SIZE, &page_addresses[kMidPage], 1, arch_rw_flags,
                   ArchVmAspace::ExistingEntryAction::Error, &mapped);
  EXPECT_EQ(err, ZX_OK);

  // Now map in all the pages.
  err = aspace.Map(kMapBase, page_addresses, kNumPages, arch_rw_flags,
                   ArchVmAspace::ExistingEntryAction::Skip, &mapped);
  EXPECT_EQ(err, ZX_OK);

  // Validate all the pages.
  for (size_t i = 0; i < kNumPages; i++) {
    paddr_t paddr;
    uint flags;
    err = aspace.Query(kMapBase + i * PAGE_SIZE, &paddr, &flags);
    EXPECT_EQ(err, ZX_OK);
    EXPECT_EQ(paddr, page_addresses[i]);
    EXPECT_EQ(flags, arch_rw_flags);
  }
  err = aspace.Unmap(kMapBase, kNumPages, ArchVmAspace::EnlargeOperation::Yes, &mapped);
  EXPECT_EQ(err, ZX_OK);

  // Now try mapping in the midle page with different permissions.
  err = aspace.Map(kMapBase + kMidPage * PAGE_SIZE, &page_addresses[kMidPage], 1,
                   ARCH_MMU_FLAG_PERM_READ, ArchVmAspace::ExistingEntryAction::Error, &mapped);
  EXPECT_EQ(err, ZX_OK);
  err = aspace.Map(kMapBase, page_addresses, kNumPages, arch_rw_flags,
                   ArchVmAspace::ExistingEntryAction::Skip, &mapped);
  EXPECT_EQ(err, ZX_OK);
  for (size_t i = 0; i < kNumPages; i++) {
    paddr_t paddr;
    uint flags;
    err = aspace.Query(kMapBase + i * PAGE_SIZE, &paddr, &flags);
    EXPECT_EQ(err, ZX_OK);
    EXPECT_EQ(paddr, page_addresses[i]);
    if (i == kMidPage) {
      EXPECT_EQ(flags, ARCH_MMU_FLAG_PERM_READ);
    } else {
      EXPECT_EQ(flags, arch_rw_flags);
    }
  }
  err = aspace.Unmap(kMapBase, kNumPages, ArchVmAspace::EnlargeOperation::Yes, &mapped);
  EXPECT_EQ(err, ZX_OK);

  // Now map the middle page using a completely different physical address.
  paddr_t other_paddr = PAGE_SIZE * 42;
  err = aspace.Map(kMapBase + kMidPage * PAGE_SIZE, &other_paddr, 1, ARCH_MMU_FLAG_PERM_READ,
                   ArchVmAspace::ExistingEntryAction::Error, &mapped);
  EXPECT_EQ(err, ZX_OK);
  err = aspace.Map(kMapBase, page_addresses, kNumPages, arch_rw_flags,
                   ArchVmAspace::ExistingEntryAction::Skip, &mapped);
  EXPECT_EQ(err, ZX_OK);
  for (size_t i = 0; i < kNumPages; i++) {
    paddr_t paddr;
    uint flags;
    err = aspace.Query(kMapBase + i * PAGE_SIZE, &paddr, &flags);
    EXPECT_EQ(err, ZX_OK);
    if (i == kMidPage) {
      EXPECT_EQ(flags, ARCH_MMU_FLAG_PERM_READ);
      EXPECT_EQ(paddr, other_paddr);
    } else {
      EXPECT_EQ(flags, arch_rw_flags);
      EXPECT_EQ(paddr, page_addresses[i]);
    }
  }
  err = aspace.Unmap(kMapBase, kNumPages, ArchVmAspace::EnlargeOperation::Yes, &mapped);
  EXPECT_EQ(err, ZX_OK);

  err = aspace.Destroy();
  EXPECT_EQ(err, ZX_OK);

  END_TEST;
}

// Attempts to validate that unmapping part of a large page will not cause parallel threads
// accessing other parts of the page to fault. This test is only probabilistic and is heavily timing
// and micro architectural dependent, but could serve as a canary.
static bool test_large_region_atomic() {
  BEGIN_TEST;

  // Force a large page.
  static constexpr size_t alloc_size = 1UL << PGTABLE_L2_SHIFT;

  static constexpr size_t target_offsets[] = {
      0,
      PAGE_SIZE,
      2 * PAGE_SIZE,
      alloc_size - 3 * PAGE_SIZE,
      alloc_size - 2 * PAGE_SIZE,
      alloc_size - PAGE_SIZE,
  };

  for (unsigned i = 0; i < ktl::size(target_offsets); i++) {
    // Allocate a large page in the current kernel aspace. Need to allocate in the current aspace
    // and not a test aspace so that we can directly access the mappings.
    auto kaspace = VmAspace::kernel_aspace();
    void* ptr;
    const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;
    auto err =
        kaspace->Alloc("test", alloc_size, &ptr, 0, VmAspace::VMM_FLAG_COMMIT, arch_rw_flags);
    const vaddr_t va = reinterpret_cast<vaddr_t>(ptr);
    ASSERT_EQ(ZX_OK, err, "VmAspace::Alloc region of memory");

    auto cleanup_mapping = fit::defer([&] { kaspace->FreeRegion(va); });

    // Spin up a thread to start touching pages in the mapping.
    struct State {
      vaddr_t va;
      uint current_offset;
      ktl::atomic<bool> running;
    } state = {va, i, true};
    auto thread_body = [](void* arg) -> int {
      State* state = static_cast<State*>(arg);

      while (state->running) {
        for (unsigned i = 0; i < ktl::size(target_offsets); i++) {
          if (state->current_offset == i) {
            continue;
          }
          volatile uint64_t* addr = reinterpret_cast<uint64_t*>(state->va + target_offsets[i]);
          // Force read from the address
          asm volatile("" ::"r"(*addr));
        }
      }
      return 0;
    };

    Thread* thread = Thread::Create("test-thread", thread_body, &state, DEFAULT_PRIORITY);
    ASSERT_NONNULL(thread);
    thread->Resume();

    auto cleanup_thread = fit::defer([&]() {
      state.running = false;
      thread->Join(nullptr, ZX_TIME_INFINITE);
    });

    // Wait a moment to let the other thread start touching.
    Thread::Current::SleepRelative(ZX_MSEC(50));

    // Unmap a single page.
    err = kaspace->arch_aspace().Unmap(va + target_offsets[i], 1,
                                       ArchVmAspace::EnlargeOperation::No, nullptr);
    EXPECT_EQ(err, ZX_OK, "unmap single page");

    // If the other thread didn't cause a kernel panic by having a page fault, then success.
  }

  END_TEST;
}

UNITTEST_START_TESTCASE(mmu_tests)
UNITTEST("create large unaligned region and ensure it can be unmapped", test_large_unaligned_region)
UNITTEST("create large unaligned region without mapping and ensure it can be unmapped",
         test_large_unaligned_region_without_map)
UNITTEST("creating large vm region, and change permissions", test_large_region_protect)
UNITTEST("trigger oom failures when creating a mapping", test_mapping_oom)
UNITTEST("skip existing entry when mapping multiple pages", test_skip_existing_mapping)
UNITTEST("create large vm region and unmap single pages", test_large_region_unmap)
UNITTEST("splitting a large page is atomic", test_large_region_atomic)
UNITTEST_END_TESTCASE(mmu_tests, "mmu", "mmu tests")
