// Copyright 2018 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/fzl/vmo-mapper.h>
#include <zircon/assert.h>

#include <utility>

namespace fzl {

zx_status_t VmoMapper::CreateAndMap(uint64_t size, zx_vm_option_t map_flags,
                                    fbl::RefPtr<VmarManager> vmar_manager, zx::vmo* vmo_out,
                                    zx_rights_t vmo_rights, uint32_t cache_policy,
                                    uint32_t vmo_options) {
  if (size == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t res = CheckReadyToMap(vmar_manager);
  if (res != ZX_OK) {
    return res;
  }

  zx::vmo vmo;
  zx_status_t ret = zx::vmo::create(size, vmo_options, &vmo);
  if (ret != ZX_OK) {
    return ret;
  }

  if (cache_policy != 0) {
    ret = vmo.set_cache_policy(cache_policy);
    if (ret != ZX_OK) {
      return ret;
    }
  }

  ret = InternalMap(vmo, 0, size, map_flags, std::move(vmar_manager));
  if (ret != ZX_OK) {
    return ret;
  }

  if (vmo_out) {
    if (vmo_rights != ZX_RIGHT_SAME_RIGHTS) {
      ret = vmo.replace(vmo_rights, &vmo);
      if (ret != ZX_OK) {
        Unmap();
        return ret;
      }
    }

    *vmo_out = std::move(vmo);
  }

  return ZX_OK;
}

zx_status_t VmoMapper::Map(const zx::vmo& vmo, uint64_t offset, uint64_t size,
                           zx_vm_option_t map_options, fbl::RefPtr<VmarManager> vmar_manager) {
  zx_status_t res;

  if (!vmo.is_valid()) {
    return ZX_ERR_INVALID_ARGS;
  }

  res = CheckReadyToMap(vmar_manager);
  if (res != ZX_OK) {
    return res;
  }

  uint64_t vmo_size;
  res = vmo.get_size(&vmo_size);
  if (res != ZX_OK) {
    return res;
  }

  uint64_t end_addr;
  if (add_overflow(size, offset, &end_addr) || end_addr > vmo_size) {
    return ZX_ERR_OUT_OF_RANGE;
  }

  if (!size) {
    size = vmo_size - offset;
  }

  return InternalMap(vmo, offset, size, map_options, vmar_manager);
}

void VmoMapper::Unmap() {
  if (start() != nullptr) {
    ZX_DEBUG_ASSERT(size_ != 0);
    zx_handle_t vmar_handle =
        (vmar_manager_ == nullptr) ? zx::vmar::root_self()->get() : vmar_manager_->vmar().get();

    [[maybe_unused]] zx_status_t res;
    res = zx_vmar_unmap(vmar_handle, start_, size_);
    ZX_DEBUG_ASSERT(res == ZX_OK);
  }

  vmar_manager_.reset();
  start_ = 0;
  size_ = 0;
}

zx_status_t VmoMapper::CheckReadyToMap(const fbl::RefPtr<VmarManager>& vmar_manager) {
  if (start_ != 0) {
    return ZX_ERR_BAD_STATE;
  }

  if ((vmar_manager != nullptr) && !vmar_manager->vmar().is_valid()) {
    return ZX_ERR_INVALID_ARGS;
  }

  return ZX_OK;
}

zx_status_t VmoMapper::InternalMap(const zx::vmo& vmo, uint64_t offset, uint64_t size,
                                   zx_vm_option_t map_options,
                                   fbl::RefPtr<VmarManager> vmar_manager) {
  ZX_DEBUG_ASSERT(vmo.is_valid());
  ZX_DEBUG_ASSERT(start() == nullptr);
  ZX_DEBUG_ASSERT(size_ == 0);
  ZX_DEBUG_ASSERT(vmar_manager_ == nullptr);

  zx_handle_t vmar_handle =
      (vmar_manager == nullptr) ? zx::vmar::root_self()->get() : vmar_manager->vmar().get();

  zx_status_t res = zx_vmar_map(vmar_handle, map_options, 0, vmo.get(), offset, size, &start_);
  if (res != ZX_OK) {
    return res;
  }

  size_ = size;
  vmar_manager_ = std::move(vmar_manager);

  return ZX_OK;
}

}  // namespace fzl
