blob: 25561890cfaebc590e3c0df4992b9b9fbac87dd9 [file] [log] [blame]
// 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/fake-bti/bti.h>
#include <lib/fzl/pinned-vmo.h>
#include <lib/zx/vmo.h>
#include <zircon/rights.h>
#include <zxtest/zxtest.h>
#include <utility>
namespace {
static constexpr size_t kVmoTestSize = 512 << 10; // 512KB
class PinnedVmoTester : public zxtest::Test {
public:
void Init() {
ASSERT_EQ(zx::vmo::create(kVmoTestSize, 0, &vmo_), ZX_OK);
}
void InitContiguous() {
ASSERT_EQ(zx::vmo::create_contiguous(*zx::unowned_bti(bti_handle_),
kVmoTestSize, 0, &vmo_),
ZX_OK);
}
void Pin(uint32_t rights) {
// Make sure our handles are valid:
EXPECT_TRUE(vmo_.is_valid());
EXPECT_EQ(pinned_vmo_.Pin(vmo_, *zx::unowned_bti(bti_handle_), rights), ZX_OK);
}
// Check that the PinnedVmo is pinned; that it has regions
// and the regions are of non-zero size
void CheckPinned() {
uint32_t region_count = pinned_vmo_.region_count();
ASSERT_GT(region_count, 0);
for (uint32_t i = 0; i < region_count; ++i) {
fzl::PinnedVmo::Region r = pinned_vmo_.region(i);
EXPECT_GT(r.size, 0);
// We would check that phys_addr != 0, but fake-bti sets all the
// addresses to zero.
}
}
// Check that the PinnedVmo is pinned; that it has only one region
// and the region is of non-zero size
void CheckContiguousPinned() {
ASSERT_EQ(pinned_vmo_.region_count(), 1);
CheckPinned();
}
void CheckUnpinned() {
ASSERT_EQ(pinned_vmo_.region_count(), 0);
}
void SetUp() override;
~PinnedVmoTester() {
if (bti_handle_ != ZX_HANDLE_INVALID) {
fake_bti_destroy(bti_handle_);
}
pinned_vmo_.Unpin();
}
zx::vmo vmo_;
fzl::PinnedVmo pinned_vmo_;
zx_handle_t bti_handle_ = ZX_HANDLE_INVALID;
};
void PinnedVmoTester::SetUp() {
ASSERT_EQ(fake_bti_create(&bti_handle_), ZX_OK);
EXPECT_NE(bti_handle_, ZX_HANDLE_INVALID);
}
TEST_F(PinnedVmoTester, CreateAndPinTest) {
CheckUnpinned();
Init();
Pin(ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE);
CheckPinned();
}
TEST_F(PinnedVmoTester, CreateContiguousTest) {
CheckUnpinned();
InitContiguous();
Pin(ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE | ZX_BTI_CONTIGUOUS);
CheckContiguousPinned();
}
TEST_F(PinnedVmoTester, FailPinTwiceTest) {
Init();
Pin(ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE);
EXPECT_EQ(pinned_vmo_.Pin(vmo_, *zx::unowned_bti(bti_handle_),
ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE),
ZX_ERR_BAD_STATE);
}
TEST(PinnedVmoTests, FailPinArgsTest) {
fzl::PinnedVmo pinned_vmo;
zx::vmo vmo;
zx::bti bti;
EXPECT_EQ(pinned_vmo.Pin(vmo, bti, ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE), ZX_ERR_INVALID_ARGS);
ASSERT_EQ(zx::vmo::create(kVmoTestSize, 0, &vmo), ZX_OK);
EXPECT_EQ(pinned_vmo.Pin(vmo, bti, ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE), ZX_ERR_INVALID_ARGS);
}
} // namespace