// Copyright 2017 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 <assert.h>
#include <lib/unittest/unittest.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <hypervisor/guest_physical_address_space.h>
#include <hypervisor/interrupt_tracker.h>
#include <vm/pmm.h>
#include <vm/scanner.h>
#include <vm/vm.h>
#include <vm/vm_address_region.h>
#include <vm/vm_aspace.h>
#include <vm/vm_object.h>
#include <vm/vm_object_paged.h>

static constexpr uint kMmuFlags =
    ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE | ARCH_MMU_FLAG_PERM_EXECUTE;

static bool hypervisor_supported() {
#if ARCH_ARM64
  if (arm64_get_boot_el() < 2) {
    unittest_printf("Hypervisor not supported\n");
    return false;
  }
#endif
  return true;
}

static zx_status_t create_vmo(size_t vmo_size, fbl::RefPtr<VmObjectPaged>* vmo) {
  return VmObjectPaged::Create(PMM_ALLOC_FLAG_ANY, 0u, vmo_size, vmo);
}

static zx_status_t commit_vmo(fbl::RefPtr<VmObjectPaged> vmo) {
  zx_status_t status = vmo->CommitRange(0, vmo->size());
  if (status != ZX_OK) {
    return status;
  }
  return ZX_OK;
}

static zx_status_t create_gpas(ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace>* gpas) {
#if ARCH_ARM64
  return hypervisor::GuestPhysicalAddressSpace::Create(1 /* vmid */, gpas);
#elif ARCH_X86
  return hypervisor::GuestPhysicalAddressSpace::Create(gpas);
#endif
}

static zx_status_t create_mapping(fbl::RefPtr<VmAddressRegion> vmar, fbl::RefPtr<VmObjectPaged> vmo,
                                  zx_gpaddr_t addr, uint mmu_flags = kMmuFlags) {
  fbl::RefPtr<VmMapping> mapping;
  return vmar->CreateVmMapping(addr, vmo->size(), 0 /* align_pow2 */, VMAR_FLAG_SPECIFIC, vmo,
                               0 /* vmo_offset */, mmu_flags, "vmo", &mapping);
}

static zx_status_t create_sub_vmar(fbl::RefPtr<VmAddressRegion> vmar, size_t offset, size_t size,
                                   fbl::RefPtr<VmAddressRegion>* sub_vmar) {
  return vmar->CreateSubVmar(offset, size, 0 /* align_pow2 */, vmar->flags() | VMAR_FLAG_SPECIFIC,
                             "vmar", sub_vmar);
}

static bool guest_physical_address_space_unmap_range() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmObjectPaged> vmo;
  status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Unmap page.
  status = gpas->UnmapRange(0, PAGE_SIZE);
  EXPECT_EQ(ZX_OK, status, "Failed to unmap page from GuestPhysicalAddressSpace\n");

  // Verify GetPage for unmapped address fails.
  zx_paddr_t gpas_paddr;
  status = gpas->GetPage(0, &gpas_paddr);
  EXPECT_EQ(ZX_ERR_NOT_FOUND, status, "GetPage returning unexpected value for unmapped address\n");

  END_TEST;
}

static bool guest_physical_address_space_unmap_range_outside_of_mapping() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmObjectPaged> vmo;
  status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Unmap page.
  status = gpas->UnmapRange(PAGE_SIZE * 8, PAGE_SIZE);
  EXPECT_EQ(ZX_OK, status, "Failed to unmap page from GuestPhysicalAddressSpace\n");

  END_TEST;
}

static bool guest_physical_address_space_unmap_range_multiple_mappings() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");

  fbl::RefPtr<VmObjectPaged> vmo1;
  status = create_vmo(PAGE_SIZE * 2, &vmo1);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo1, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  fbl::RefPtr<VmObjectPaged> vmo2;
  status = create_vmo(PAGE_SIZE * 2, &vmo2);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo2, PAGE_SIZE * 3);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Unmap pages.
  status = gpas->UnmapRange(PAGE_SIZE, PAGE_SIZE * 3);
  EXPECT_EQ(ZX_OK, status, "Failed to multiple unmap pages from GuestPhysicalAddressSpace\n");

  // Verify GetPage for unmapped addresses fails.
  zx_paddr_t gpas_paddr = 0;
  for (zx_gpaddr_t addr = PAGE_SIZE; addr < PAGE_SIZE * 4; addr += PAGE_SIZE) {
    status = gpas->GetPage(addr, &gpas_paddr);
    EXPECT_EQ(ZX_ERR_NOT_FOUND, status,
              "GetPage returning unexpected value for unmapped address\n");
  }

  // Verify GetPage for mapped addresses succeeds.
  status = gpas->GetPage(0, &gpas_paddr);
  EXPECT_EQ(ZX_OK, status, "Failed to read page from GuestPhysicalAddressSpace\n");
  status = gpas->GetPage(PAGE_SIZE * 4, &gpas_paddr);
  EXPECT_EQ(ZX_OK, status, "Failed to read page from GuestPhysicalAddressSpace\n");

  END_TEST;
}

static bool guest_physical_address_space_unmap_range_sub_region() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmAddressRegion> root_vmar = gpas->RootVmar();
  // To test partial unmapping within sub-VMAR:
  // Sub-VMAR from [0, PAGE_SIZE * 2).
  // Map within sub-VMAR from [PAGE_SIZE, PAGE_SIZE * 2).
  fbl::RefPtr<VmAddressRegion> sub_vmar1;
  status = create_sub_vmar(root_vmar, 0, PAGE_SIZE * 2, &sub_vmar1);
  EXPECT_EQ(ZX_OK, status, "Failed to create sub-VMAR\n");
  EXPECT_TRUE(sub_vmar1->has_parent(), "Sub-VMAR does not have a parent");
  fbl::RefPtr<VmObjectPaged> vmo1;
  status = create_vmo(PAGE_SIZE, &vmo1);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(sub_vmar1, vmo1, PAGE_SIZE);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");
  // To test destroying of sub-VMAR:
  // Sub-VMAR from [PAGE_SIZE * 2, PAGE_SIZE * 3).
  // Map within sub-VMAR from [0, PAGE_SIZE).
  fbl::RefPtr<VmAddressRegion> sub_vmar2;
  status = create_sub_vmar(root_vmar, PAGE_SIZE * 2, PAGE_SIZE, &sub_vmar2);
  EXPECT_EQ(ZX_OK, status, "Failed to create sub-VMAR\n");
  EXPECT_TRUE(sub_vmar2->has_parent(), "Sub-VMAR does not have a parent");
  fbl::RefPtr<VmObjectPaged> vmo2;
  status = create_vmo(PAGE_SIZE, &vmo2);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(sub_vmar2, vmo2, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");
  // To test partial unmapping within root-VMAR:
  // Map within root-VMAR from [PAGE_SIZE * 3, PAGE_SIZE * 5).
  fbl::RefPtr<VmObjectPaged> vmo3;
  status = create_vmo(PAGE_SIZE * 2, &vmo3);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(root_vmar, vmo3, PAGE_SIZE * 3);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Unmap pages from [PAGE_SIZE, PAGE_SIZE * 4).
  status = gpas->UnmapRange(PAGE_SIZE, PAGE_SIZE * 3);
  EXPECT_EQ(ZX_OK, status, "Failed to multiple unmap pages from GuestPhysicalAddressSpace\n");

  // Verify GetPage for unmapped addresses fails.
  zx_paddr_t gpas_paddr = 0;
  for (zx_gpaddr_t addr = 0; addr < PAGE_SIZE * 4; addr += PAGE_SIZE) {
    status = gpas->GetPage(addr, &gpas_paddr);
    EXPECT_EQ(ZX_ERR_NOT_FOUND, status,
              "GetPage returning unexpected value for unmapped address\n");
  }

  // Verify GetPage for mapped addresses succeeds.
  status = gpas->GetPage(PAGE_SIZE * 4, &gpas_paddr);
  EXPECT_EQ(ZX_OK, status, "Failed to read page from GuestPhysicalAddressSpace\n");

  // Verify that sub-VMARs still have a parent.
  EXPECT_TRUE(sub_vmar1->has_parent(), "Sub-VMAR does not have a parent");
  EXPECT_TRUE(sub_vmar2->has_parent(), "Sub-VMAR does not have a parent");

  END_TEST;
}

static bool guest_physical_address_space_get_page() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  AutoVmScannerDisable scanner_disable;

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmObjectPaged> vmo;
  status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Commit VMO.
  status = commit_vmo(vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to commit VMO\n");

  // Read expected physical address from the VMO.
  zx_paddr_t vmo_paddr = 0;
  status = vmo->Lookup(0, PAGE_SIZE, [&vmo_paddr](uint64_t offset, paddr_t pa) {
    vmo_paddr = pa;
    return ZX_ERR_STOP;
  });
  EXPECT_EQ(ZX_OK, status, "Failed to lookup physical address of VMO\n");
  EXPECT_NE(0u, vmo_paddr, "Failed to lookup physical address of VMO\n");

  // Read physical address from GPAS & compare with address read from VMO.
  zx_paddr_t gpas_paddr = 0;
  status = gpas->GetPage(0, &gpas_paddr);
  EXPECT_EQ(ZX_OK, status, "Failed to read page from GuestPhysicalAddressSpace\n");
  EXPECT_EQ(vmo_paddr, gpas_paddr,
            "Incorrect physical address returned from GuestPhysicalAddressSpace::GetPage\n");

  END_TEST;
}

static bool guest_physical_address_space_get_page_complex() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  AutoVmScannerDisable scanner_disable;

  // Test GetPage with a less trivial VMAR configuration.
  //
  //                  0 -->+--------+
  //                       |  Root  |
  //                       |  VMO   |
  //      ROOT_VMO_SIZE -->---------+ +--------+
  //                       |        | | Second |
  // ROOT_VMO_SIZE +       |        | | VMO    |
  //    SECOND_VMO_SIZE -->---------+ +--------+
  //                       |  Root  | | Shadow |
  //                       |  VMAR  | | VMAR   |
  //                        ~~~~~~~~   ~~~~~~~~
  //
  // The 'Root VMO/VMAR' is the default configuration when initializing
  // GuestPhysicalAddressSpace with a VMO size of 'PAGE_SIZE'. This test
  // allocates a second VMAR and VMO and attaches them both into the 'Root
  // VMAR' to ensure we correctly locate addresses in these structures.
  const uint ROOT_VMO_SIZE = PAGE_SIZE;
  const uint SECOND_VMO_SIZE = PAGE_SIZE;

  // Setup.
  fbl::RefPtr<VmObjectPaged> vmo1;
  zx_status_t status = create_vmo(ROOT_VMO_SIZE, &vmo1);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmAddressRegion> root_vmar = gpas->RootVmar();
  status = create_mapping(root_vmar, vmo1, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Commit first VMO.
  status = commit_vmo(vmo1);
  EXPECT_EQ(ZX_OK, status, "Failed to commit VMO\n");

  // Allocate second VMAR, offset one page into the root.
  fbl::RefPtr<VmAddressRegion> shadow_vmar;
  status =
      create_sub_vmar(root_vmar, ROOT_VMO_SIZE, root_vmar->size() - ROOT_VMO_SIZE, &shadow_vmar);
  EXPECT_EQ(ZX_OK, status, "Failed to create shadow VMAR\n");

  // Allocate second VMO; we'll map the original VMO on top of this one.
  fbl::RefPtr<VmObjectPaged> vmo2;
  status = create_vmo(SECOND_VMO_SIZE, &vmo2);
  EXPECT_EQ(ZX_OK, status, "Failed allocate second VMO\n");

  // Commit second VMO.
  status = commit_vmo(vmo2);
  EXPECT_EQ(ZX_OK, status, "Failed to commit second VMO\n");

  // Map second VMO into second VMAR.
  status = create_mapping(shadow_vmar, vmo2, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to map vmo into shadow vmar\n");

  // Read expected physical address from the VMO.
  zx_paddr_t vmo_paddr = 0;
  status = vmo2->Lookup(0, PAGE_SIZE, [&vmo_paddr](uint64_t offset, paddr_t pa) {
    vmo_paddr = pa;
    return ZX_ERR_STOP;
  });
  EXPECT_EQ(ZX_OK, status, "Failed to lookup physical address of VMO\n");
  EXPECT_NE(0u, vmo_paddr, "Failed to lookup physical address of VMO\n");

  // Read physical address from GPAS.
  zx_paddr_t gpas_paddr = 0;
  status = gpas->GetPage(ROOT_VMO_SIZE, &gpas_paddr);
  EXPECT_EQ(ZX_OK, status, "Failed to read page from GuestPhysicalAddressSpace\n");
  EXPECT_EQ(vmo_paddr, gpas_paddr,
            "Incorrect physical address returned from GuestPhysicalAddressSpace::GetPage\n");
  END_TEST;
}

static bool guest_physical_address_space_get_page_not_present() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  AutoVmScannerDisable scanner_disable;

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmObjectPaged> vmo;
  status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Commit VMO.
  status = commit_vmo(vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to commit VMO\n");

  // Query unmapped address.
  zx_paddr_t gpas_paddr = 0;
  status = gpas->GetPage(UINTPTR_MAX, &gpas_paddr);
  EXPECT_EQ(ZX_ERR_NOT_FOUND, status, "GetPage returning unexpected value for unmapped address\n");

  END_TEST;
}

static bool guest_physical_address_space_page_fault() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmObjectPaged> vmo;
  status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");
  status = create_mapping(gpas->RootVmar(), vmo, PAGE_SIZE, ARCH_MMU_FLAG_PERM_READ);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");
  status = create_mapping(gpas->RootVmar(), vmo, PAGE_SIZE * 2,
                          ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");
  status = create_mapping(gpas->RootVmar(), vmo, PAGE_SIZE * 3,
                          ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_EXECUTE);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Fault in each page.
  for (zx_gpaddr_t addr = 0; addr < PAGE_SIZE * 4; addr += PAGE_SIZE) {
    status = gpas->PageFault(addr);
    EXPECT_EQ(ZX_OK, status, "Failed to fault page\n");
  }

  END_TEST;
}

static bool guest_physical_address_space_map_interrupt_controller() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  zx_status_t status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  fbl::RefPtr<VmObjectPaged> vmo;
  status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  // Allocate a page to use as the interrupt controller.
  paddr_t paddr = 0;
  vm_page* vm_page;
  status = pmm_alloc_page(0, &vm_page, &paddr);
  EXPECT_EQ(ZX_OK, status, "Unable to allocate a page\n");

  // Map interrupt controller page in an arbitrary location.
  const vaddr_t APIC_ADDRESS = 0xffff0000;
  status = gpas->MapInterruptController(APIC_ADDRESS, paddr, PAGE_SIZE);
  EXPECT_EQ(ZX_OK, status, "Failed to map APIC page\n");

  // Cleanup
  pmm_free_page(vm_page);
  END_TEST;
}

static bool guest_physical_address_space_uncached() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  fbl::RefPtr<VmObjectPaged> vmo;
  zx_status_t status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = vmo->SetMappingCachePolicy(ZX_CACHE_POLICY_UNCACHED);
  EXPECT_EQ(ZX_OK, status, "Failed to set cache policy\n");

  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  END_TEST;
}

static bool guest_physical_address_space_uncached_device() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  fbl::RefPtr<VmObjectPaged> vmo;
  zx_status_t status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = vmo->SetMappingCachePolicy(ZX_CACHE_POLICY_UNCACHED_DEVICE);
  EXPECT_EQ(ZX_OK, status, "Failed to set cache policy\n");

  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  END_TEST;
}

static bool guest_physical_address_space_write_combining() {
  BEGIN_TEST;

  if (!hypervisor_supported()) {
    return true;
  }

  // Setup.
  fbl::RefPtr<VmObjectPaged> vmo;
  zx_status_t status = create_vmo(PAGE_SIZE, &vmo);
  EXPECT_EQ(ZX_OK, status, "Failed to create VMO\n");
  status = vmo->SetMappingCachePolicy(ZX_CACHE_POLICY_WRITE_COMBINING);
  EXPECT_EQ(ZX_OK, status, "Failed to set cache policy\n");

  ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas;
  status = create_gpas(&gpas);
  EXPECT_EQ(ZX_OK, status, "Failed to create GuestPhysicalAddressSpace\n");
  status = create_mapping(gpas->RootVmar(), vmo, 0);
  EXPECT_EQ(ZX_OK, status, "Failed to create mapping\n");

  END_TEST;
}

static bool interrupt_bitmap() {
  BEGIN_TEST;

  hypervisor::InterruptBitmap<8> bitmap;

  uint32_t vector = UINT32_MAX;
  ASSERT_EQ(ZX_OK, bitmap.Init());
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(0));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(1));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Scan(&vector));
  EXPECT_EQ(UINT32_MAX, vector);

  // Index 0.
  vector = UINT32_MAX;
  bitmap.Set(0u, hypervisor::InterruptType::VIRTUAL);
  EXPECT_EQ(hypervisor::InterruptType::VIRTUAL, bitmap.Get(0));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(1));
  EXPECT_EQ(hypervisor::InterruptType::VIRTUAL, bitmap.Scan(&vector));
  EXPECT_EQ(0u, vector);

  vector = UINT32_MAX;
  bitmap.Set(0u, hypervisor::InterruptType::PHYSICAL);
  EXPECT_EQ(hypervisor::InterruptType::PHYSICAL, bitmap.Get(0u));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(1u));
  EXPECT_EQ(hypervisor::InterruptType::PHYSICAL, bitmap.Scan(&vector));
  EXPECT_EQ(0u, vector);

  vector = UINT32_MAX;
  bitmap.Set(0u, hypervisor::InterruptType::INACTIVE);
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(0u));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(1u));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Scan(&vector));
  EXPECT_EQ(UINT32_MAX, vector);

  // Index 1.
  vector = UINT32_MAX;
  bitmap.Set(1u, hypervisor::InterruptType::VIRTUAL);
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(0u));
  EXPECT_EQ(hypervisor::InterruptType::VIRTUAL, bitmap.Get(1u));
  EXPECT_EQ(hypervisor::InterruptType::VIRTUAL, bitmap.Scan(&vector));
  EXPECT_EQ(1u, vector);

  vector = UINT32_MAX;
  bitmap.Set(1u, hypervisor::InterruptType::PHYSICAL);
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(0u));
  EXPECT_EQ(hypervisor::InterruptType::PHYSICAL, bitmap.Get(1u));
  EXPECT_EQ(hypervisor::InterruptType::PHYSICAL, bitmap.Scan(&vector));
  EXPECT_EQ(1u, vector);

  vector = UINT32_MAX;
  bitmap.Set(1u, hypervisor::InterruptType::INACTIVE);
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(0u));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(1u));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Scan(&vector));
  EXPECT_EQ(UINT32_MAX, vector);

  // Clear
  bitmap.Set(0u, hypervisor::InterruptType::VIRTUAL);
  bitmap.Set(1u, hypervisor::InterruptType::VIRTUAL);
  bitmap.Set(2u, hypervisor::InterruptType::PHYSICAL);
  bitmap.Set(3u, hypervisor::InterruptType::PHYSICAL);
  bitmap.Clear(1u, 3u);
  EXPECT_EQ(hypervisor::InterruptType::VIRTUAL, bitmap.Get(0u));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(1u));
  EXPECT_EQ(hypervisor::InterruptType::INACTIVE, bitmap.Get(2u));
  EXPECT_EQ(hypervisor::InterruptType::PHYSICAL, bitmap.Get(3u));

  END_TEST;
}

// Use the function name as the test name
#define HYPERVISOR_UNITTEST(fname) UNITTEST(#fname, fname)

UNITTEST_START_TESTCASE(hypervisor)
HYPERVISOR_UNITTEST(guest_physical_address_space_unmap_range)
HYPERVISOR_UNITTEST(guest_physical_address_space_unmap_range_outside_of_mapping)
HYPERVISOR_UNITTEST(guest_physical_address_space_unmap_range_multiple_mappings)
HYPERVISOR_UNITTEST(guest_physical_address_space_unmap_range_sub_region)
HYPERVISOR_UNITTEST(guest_physical_address_space_get_page)
HYPERVISOR_UNITTEST(guest_physical_address_space_get_page_complex)
HYPERVISOR_UNITTEST(guest_physical_address_space_get_page_not_present)
HYPERVISOR_UNITTEST(guest_physical_address_space_page_fault)
HYPERVISOR_UNITTEST(guest_physical_address_space_map_interrupt_controller)
HYPERVISOR_UNITTEST(guest_physical_address_space_uncached)
HYPERVISOR_UNITTEST(guest_physical_address_space_uncached_device)
HYPERVISOR_UNITTEST(guest_physical_address_space_write_combining)
HYPERVISOR_UNITTEST(interrupt_bitmap)
UNITTEST_END_TESTCASE(hypervisor, "hypervisor", "Hypervisor unit tests.")
