// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/zx/bti.h>
#include <lib/zx/iommu.h>
#include <lib/zx/process.h>
#include <zircon/syscalls/iommu.h>
#include <zircon/types.h>

#include <atomic>
#include <thread>
#include <vector>

#include <zxtest/zxtest.h>

extern "C" zx_handle_t get_root_resource(void);

namespace {

TEST(Bti, Create) {
  zx::iommu iommu;
  zx::bti bti;
  zx::pmt pmt;

  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;

  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);
}

TEST(Bti, NameSupport) {
  zx::iommu iommu;
  zx::bti bti;

  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;

  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  static char name_buffer[ZX_MAX_NAME_LEN];

  // Initially, there should be no name assigned to the BTI
  ASSERT_OK(bti.get_property(ZX_PROP_NAME, name_buffer, sizeof(name_buffer)));
  ASSERT_EQ(0, strlen(name_buffer));

  // Setting the name to normal name length should succeed.
  const char normal_name[] = "Core Test BTI";
  ASSERT_LE(strlen(normal_name), (ZX_MAX_NAME_LEN - 1), "normal_name would be truncated");
  ASSERT_OK(bti.set_property(ZX_PROP_NAME, normal_name, sizeof(normal_name)));
  ASSERT_OK(bti.get_property(ZX_PROP_NAME, name_buffer, sizeof(name_buffer)));
  ASSERT_STREQ(normal_name, name_buffer);

  // Setting the name to long_name should succeed, but the result will be truncated.
  const char long_name[] =
      "0123456789012345678901234567890123456789"
      "0123456789012345678901234567890123456789";
  ASSERT_GT(strlen(long_name), (ZX_MAX_NAME_LEN - 1), "long_name would not be truncated");
  ASSERT_OK(bti.set_property(ZX_PROP_NAME, long_name, sizeof(long_name)));
  ASSERT_OK(bti.get_property(ZX_PROP_NAME, name_buffer, sizeof(name_buffer)));
  ASSERT_EQ(0, name_buffer[sizeof(name_buffer) - 1]);
  ASSERT_BYTES_EQ(long_name, name_buffer, sizeof(name_buffer) - 1);

  // Setting the name to an empty string should be OK.
  const char empty_name[] = "";
  ASSERT_LE(strlen(empty_name), (ZX_MAX_NAME_LEN - 1), "empty_name would be truncated");
  ASSERT_OK(bti.set_property(ZX_PROP_NAME, empty_name, sizeof(empty_name)));
  ASSERT_OK(bti.get_property(ZX_PROP_NAME, name_buffer, sizeof(name_buffer)));
  ASSERT_STREQ(empty_name, name_buffer);
}

void bti_pin_test_helper(bool contiguous_vmo) {
  zx::iommu iommu;
  zx::bti bti;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  static constexpr uint64_t kPageCount = 256;
  const uint64_t kVmoSize = zx_system_get_page_size() * kPageCount;
  zx::vmo vmo;
  if (contiguous_vmo) {
    ASSERT_EQ(zx::vmo::create_contiguous(bti, kVmoSize, 0, &vmo), ZX_OK);
  } else {
    ASSERT_EQ(zx::vmo::create(kVmoSize, 0, &vmo), ZX_OK);
  }

  zx_paddr_t paddrs[kPageCount];
  zx::pmt pmt;
  ASSERT_EQ(bti.pin(ZX_BTI_PERM_READ, vmo, 0, kVmoSize, paddrs, kPageCount, &pmt), ZX_OK);

  ASSERT_EQ(pmt.unpin(), ZX_OK);

  if (contiguous_vmo) {
    for (unsigned i = 1; i < kPageCount; i++) {
      ASSERT_EQ(paddrs[i], paddrs[0] + i * zx_system_get_page_size());
    }
  }
}

TEST(Bti, Pin) { bti_pin_test_helper(false); }

TEST(Bti, PinContiguous) { bti_pin_test_helper(true); }

TEST(Bti, PinContigFlag) {
  zx::iommu iommu;
  zx::bti bti;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  static constexpr uint64_t kPageCount = 256;
  const uint64_t kVmoSize = zx_system_get_page_size() * kPageCount;
  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create_contiguous(bti, kVmoSize, 0, &vmo), ZX_OK);

  zx_paddr_t paddr;
  zx::pmt pmt;
  ASSERT_EQ(bti.pin(ZX_BTI_PERM_READ | ZX_BTI_CONTIGUOUS, vmo, 0, kVmoSize, &paddr, 1, &pmt),
            ZX_OK);

  ASSERT_EQ(pmt.unpin(), ZX_OK);
}

TEST(Bti, Resize) {
  zx::iommu iommu;
  zx::bti bti;
  zx::pmt pmt;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(zx_system_get_page_size(), ZX_VMO_RESIZABLE, &vmo), ZX_OK);

  zx_paddr_t paddrs;
  ASSERT_EQ(bti.pin(ZX_BTI_PERM_READ, vmo, 0, zx_system_get_page_size(), &paddrs, 1, &pmt), ZX_OK);

  EXPECT_EQ(vmo.set_size(0), ZX_ERR_BAD_STATE);

  pmt.unpin();
}

TEST(Bti, Clone) {
  zx::iommu iommu;
  zx::bti bti;
  zx::pmt pmt;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  zx::vmo vmo, clone;
  ASSERT_EQ(zx::vmo::create(zx_system_get_page_size(), ZX_VMO_RESIZABLE, &vmo), ZX_OK);
  ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_SNAPSHOT, 0, zx_system_get_page_size(), &clone), ZX_OK);

  zx_paddr_t paddrs;
  ASSERT_EQ(bti.pin(ZX_BTI_PERM_READ, clone, 0, zx_system_get_page_size(), &paddrs, 1, &pmt),
            ZX_OK);

  clone.reset();

  zx_signals_t o;
  EXPECT_EQ(vmo.wait_one(ZX_VMO_ZERO_CHILDREN, zx::time::infinite_past(), &o), ZX_ERR_TIMED_OUT);

  pmt.unpin();

  EXPECT_EQ(vmo.wait_one(ZX_VMO_ZERO_CHILDREN, zx::time::infinite_past(), &o), ZX_OK);
}

TEST(Bti, GetInfoTest) {
  zx::iommu iommu;
  zx::bti bti;
  zx::pmt pmt;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);
  // Query the info on the bti. It should have no pmos, and no quarantines:
  zx_info_bti_t bti_info;
  EXPECT_EQ(bti.get_info(ZX_INFO_BTI, &bti_info, sizeof(bti_info), nullptr, nullptr), ZX_OK);
  EXPECT_EQ(bti_info.pmo_count, 0);
  EXPECT_EQ(bti_info.quarantine_count, 0);

  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(zx_system_get_page_size(), ZX_VMO_RESIZABLE, &vmo), ZX_OK);

  zx_paddr_t paddrs;
  ASSERT_EQ(bti.pin(ZX_BTI_PERM_READ, vmo, 0, zx_system_get_page_size(), &paddrs, 1, &pmt), ZX_OK);

  // Now our bti should have one pmo, and no quarantines:
  EXPECT_EQ(bti.get_info(ZX_INFO_BTI, &bti_info, sizeof(bti_info), nullptr, nullptr), ZX_OK);
  EXPECT_EQ(bti_info.pmo_count, 1);
  EXPECT_EQ(bti_info.quarantine_count, 0);

  // Delete pmt without unpinning. This should trigger a quarantine.
  pmt.reset();

  // Now our bti should have one pmo, and one quarantines:
  EXPECT_EQ(bti.get_info(ZX_INFO_BTI, &bti_info, sizeof(bti_info), nullptr, nullptr), ZX_OK);
  EXPECT_EQ(bti_info.pmo_count, 1);
  EXPECT_EQ(bti_info.quarantine_count, 1);

  EXPECT_EQ(bti.release_quarantine(), ZX_OK);
  // Now our bti should have no pmo, and no quarantines:
  EXPECT_EQ(bti.get_info(ZX_INFO_BTI, &bti_info, sizeof(bti_info), nullptr, nullptr), ZX_OK);
  EXPECT_EQ(bti_info.pmo_count, 0);
  EXPECT_EQ(bti_info.quarantine_count, 0);
}

TEST(Bti, NoDelayedUnpin) {
  zx::iommu iommu;
  zx::bti bti;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  zx::unowned_resource root_res(get_root_resource());
  zx_iommu_desc_dummy_t desc;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  // Create the VMO we will pin+unpin
  static constexpr uint64_t kPageCount = 4;
  const uint64_t kVmoSize = zx_system_get_page_size() * kPageCount;
  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(kVmoSize, 0, &vmo), ZX_OK);

  // Spin up a helper that will query handle information of the process. This helper should not
  // cause our unpins to be delayed.
  std::atomic<bool> running = true;

  std::thread thread = std::thread([&running] {
    // Create a vmo and clone it a few times with a semi random hierarchy. Vmo shall have a lot of
    // pages so that we can do long running writes to it.
    static constexpr uint64_t kPageCount = 4096;
    const uint64_t kVmoSize = zx_system_get_page_size() * kPageCount;
    zx::vmo vmo;
    zx::vmo::create(kVmoSize, 0, &vmo);

    // Size clones so that our get_info call takes longer, but not too many as only the clone
    // handles that fall into the same batch (batches are currently 32 handles) as our pmt will
    // actually be useful.
    static constexpr int kClones = 16;
    zx::vmo clones[kClones];
    vmo.create_child(ZX_VMO_CHILD_SNAPSHOT, 0, kVmoSize, &clones[0]);
    for (int i = 1; i < kClones; i++) {
      clones[rand() % i].create_child(ZX_VMO_CHILD_SNAPSHOT, 0, kVmoSize, &clones[i]);
    }
    // To ensure our info querying is slow, spin up another thread to do long running operations on
    // our vmo chain. When tested this made the get_info call take around 500ms.
    std::thread thread = std::thread([&running, &vmo, kVmoSize] {
      std::vector<uint8_t> buffer(kVmoSize);
      while (running) {
        vmo.write(buffer.data(), 0, kVmoSize);
      }
    });

    zx::unowned_process self_process{zx::process::self()};
    static constexpr int kMaxInfo = 1024;
    std::vector<zx_info_vmo_t> vmo_info(kMaxInfo);
    while (running) {
      size_t actual, avail;
      self_process->get_info(ZX_INFO_PROCESS_VMOS, vmo_info.data(),
                             kMaxInfo * sizeof(zx_info_vmo_t), &actual, &avail);
    }

    thread.join();
  });

  zx_paddr_t paddrs[kPageCount];

  // Perform pin+unpin+clone some arbitrary number of times to see if we hit the race condition.
  // This part of the test could spuriously succeed, but in my testing that never happened and
  // would typically fail around 1000 iterations in. Do 20000 iterations anyway since these
  // iterations are very fast and do not make the test take any noticeable time.
  for (int i = 0; i < 20000; i++) {
    zx::pmt pmt;
    ASSERT_EQ(bti.pin(ZX_BTI_PERM_READ, vmo, 0, kVmoSize, paddrs, kPageCount, &pmt), ZX_OK);
    ASSERT_EQ(pmt.unpin(), ZX_OK);

    // After unpinning we should be able to make a clone.
    zx::vmo clone;
    ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_SNAPSHOT, 0, kVmoSize, &clone), ZX_OK);
  }

  running = false;
  thread.join();
}

TEST(Bti, DecommitRace) {
  zx::iommu iommu;
  zx::bti bti;
  zx_iommu_desc_dummy_t desc;
  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  // Create the VMO we will pin/decommit.
  constexpr uint64_t kPageCount = 64;
  const uint64_t kVmoSize = zx_system_get_page_size() * kPageCount;
  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(kVmoSize, 0, &vmo), ZX_OK);

  // Spin up a helper that will perform the decommits.
  std::atomic<bool> running = true;

  // Flag that indicates the helper thread is up and running in case it takes a bit.
  std::atomic<bool> done_one_iteration = false;
  std::thread thread = std::thread([&running, &done_one_iteration, &vmo, kVmoSize] {
    while (running) {
      vmo.op_range(ZX_VMO_OP_DECOMMIT, 0, kVmoSize, nullptr, 0);
      done_one_iteration = true;
    }
  });

  zx_paddr_t paddrs[kPageCount];

  // Wait until at least one iteration of the helper thread is done. Shouldn't take long so no need
  // to yield or sleep.
  while (!done_one_iteration)
    ;

  // Perform pin+unpin some arbitrary number of times to see if we hit the race condition.
  for (int i = 0; i < 20000; i++) {
    zx::pmt pmt;
    ASSERT_EQ(bti.pin(ZX_BTI_PERM_READ, vmo, 0, kVmoSize, paddrs, kPageCount, &pmt), ZX_OK);
    ASSERT_EQ(pmt.unpin(), ZX_OK);
  }

  running = false;
  thread.join();
}

// TODO(fxbug.dev/56205): Re-enable this test when enforcement of the "no pinning
// while there are quarantined pages" rule has been turned on in the kernel.
#if 0
TEST(Bti, QuarantineDisallowsPin) {
  zx::iommu iommu;
  zx::bti bti;
  zx_iommu_desc_dummy_t desc;

  // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
  ASSERT_EQ(zx_iommu_create(get_root_resource(), ZX_IOMMU_TYPE_DUMMY, &desc, sizeof(desc),
                            iommu.reset_and_get_address()),
            ZX_OK);
  ASSERT_EQ(zx::bti::create(iommu, 0, 0xdeadbeef, &bti), ZX_OK);

  // Create and pin a VMO, then allow the pinned VMO to leak while still pinned.
  // Its pages will be added to the quarantine list for the BTI.
  constexpr uint64_t kPageCount = 4;
  constexpr uint64_t kVmoSize = zx_system_get_page_size() * kPageCount;
  zx_paddr_t paddrs[kPageCount];
  {
    zx::vmo vmo;
    zx::pmt pmt;
    EXPECT_OK(zx::vmo::create(kVmoSize, 0, &vmo));
    EXPECT_OK(bti.pin(ZX_BTI_PERM_READ, vmo, 0, kVmoSize, paddrs, kPageCount, &pmt));
  }

  // Now that our BTI has a non-empty quarantine list, new pin operations should
  // fail with ZX_ERR_BAD_STATE.
  {
    zx::vmo vmo;
    zx::pmt pmt;
    EXPECT_OK(zx::vmo::create(kVmoSize, 0, &vmo));
    EXPECT_STATUS(ZX_ERR_BAD_STATE,
                  bti.pin(ZX_BTI_PERM_READ, vmo, 0, kVmoSize, paddrs, kPageCount, &pmt));
  }

  // Release the quarantine on our BTI, sending the quarantined pages back to
  // the page pool
  EXPECT_OK(bti.release_quarantine());

  // Try to pin some pages again.  Now that the quarantine list is clear, this
  // should be allowed again.  Don't forget to unpin the pages we had pinned.
  {
    zx::vmo vmo;
    zx::pmt pmt;
    EXPECT_OK(zx::vmo::create(kVmoSize, 0, &vmo));
    EXPECT_OK(bti.pin(ZX_BTI_PERM_READ, vmo, 0, kVmoSize, paddrs, kPageCount, &pmt));
    EXPECT_OK(pmt.unpin());
  }
}
#endif

}  // namespace
