// Copyright (C) 2019 The Android Open Source Project
// Copyright (C) 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <linux/types.h>
#include <linux/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdlib>
#include <errno.h>
#include <memory>

#if PLATFORM_SDK_VERSION < 26
#include <cutils/log.h>
#else
#include <log/log.h>
#endif

#include "goldfish_address_space.h"

namespace {

struct goldfish_address_space_allocate_block {
    __u64 size;
    __u64 offset;
    __u64 phys_addr;
};

struct goldfish_address_space_claim_shared {
    __u64 offset;
    __u64 size;
};

#define GOLDFISH_ADDRESS_SPACE_IOCTL_MAGIC		'G'
#define GOLDFISH_ADDRESS_SPACE_IOCTL_OP(OP, T)		_IOWR(GOLDFISH_ADDRESS_SPACE_IOCTL_MAGIC, OP, T)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_ALLOCATE_BLOCK	GOLDFISH_ADDRESS_SPACE_IOCTL_OP(10, struct goldfish_address_space_allocate_block)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK	GOLDFISH_ADDRESS_SPACE_IOCTL_OP(11, __u64)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_PING		GOLDFISH_ADDRESS_SPACE_IOCTL_OP(12, struct goldfish_address_space_ping)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_CLAIM_SHARED		GOLDFISH_ADDRESS_SPACE_IOCTL_OP(13, struct goldfish_address_space_claim_shared)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_UNCLAIM_SHARED		GOLDFISH_ADDRESS_SPACE_IOCTL_OP(14, __u64)

const char GOLDFISH_ADDRESS_SPACE_DEVICE_NAME[] = "/dev/goldfish_address_space";

const int HOST_MEMORY_ALLOCATOR_COMMAND_ALLOCATE_ID = 1;
const int HOST_MEMORY_ALLOCATOR_COMMAND_UNALLOCATE_ID = 2;

int create_address_space_fd()
{
    return ::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR);
}

long ioctl_allocate(int fd, struct goldfish_address_space_allocate_block *request)
{
    return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_ALLOCATE_BLOCK, request);
}

long ioctl_deallocate(int fd, uint64_t offset)
{
    return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK, &offset);
}

long ioctl_ping(int fd, struct goldfish_address_space_ping *request)
{
    return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_PING, request);
}

long set_address_space_subdevice_type(int fd, uint64_t type)
{
    struct goldfish_address_space_ping request;
    ::memset(&request, 0, sizeof(request));
    request.version = sizeof(request);
    request.metadata = type;

    return ioctl_ping(fd, &request);
}

long ioctl_claim_shared(int fd, struct goldfish_address_space_claim_shared *request)
{
    return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_CLAIM_SHARED, request);
}

long ioctl_unclaim_shared(int fd, uint64_t offset)
{
    return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_UNCLAIM_SHARED, &offset);
}

}  // namespace

GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice)
  : m_handle(create_address_space_fd())
{
    if ((subdevice != GoldfishAddressSpaceSubdeviceType::NoSubdevice) && is_opened()) {
        const long ret = set_address_space_subdevice_type(m_handle, subdevice);
        if (ret) {
            ALOGE("%s: set_address_space_subdevice_type failed for device_type=%lu, ret=%ld",
                  __func__, static_cast<unsigned long>(subdevice), ret);
            close();
        }
    }
}

GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
{
    if (is_opened()) {
        ::close(m_handle);
    }
}

bool GoldfishAddressSpaceBlockProvider::is_opened() const
{
    return m_handle >= 0;
}

void GoldfishAddressSpaceBlockProvider::close()
{
    if (is_opened()) {
        ::close(m_handle);
        m_handle = -1;
    }
}

address_space_handle_t GoldfishAddressSpaceBlockProvider::release()
{
    address_space_handle_t handle = m_handle;
    m_handle = -1;
    return handle;
}

void GoldfishAddressSpaceBlockProvider::closeHandle(address_space_handle_t handle)
{
    ::close(handle);
}

GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock()
    : m_handle(-1)
    , m_mmaped_ptr(NULL)
    , m_phys_addr(0)
    , m_host_addr(0)
    , m_offset(0)
    , m_size(0) {}

GoldfishAddressSpaceBlock::~GoldfishAddressSpaceBlock()
{
    destroy();
}

GoldfishAddressSpaceBlock &GoldfishAddressSpaceBlock::operator=(const GoldfishAddressSpaceBlock &rhs)
{
    m_mmaped_ptr = rhs.m_mmaped_ptr;
    m_phys_addr = rhs.m_phys_addr;
    m_host_addr = rhs.m_host_addr;
    m_offset = rhs.m_offset;
    m_size = rhs.m_size;
    m_handle = rhs.m_handle;

    return *this;
}

bool GoldfishAddressSpaceBlock::allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size)
{
    ALOGD("%s: Ask for block of size 0x%llx\n", __func__,
         (unsigned long long)size);

    destroy();

    if (!provider->is_opened()) {
        return false;
    }

    struct goldfish_address_space_allocate_block request;
    ::memset(&request, 0, sizeof(request));
    request.size = size;

    long res = ioctl_allocate(provider->m_handle, &request);
    if (res) {
        return false;
    } else {
        m_phys_addr = request.phys_addr;
        m_offset = request.offset;
        m_size = request.size;
        m_handle = provider->m_handle;
        m_is_shared_mapping = false;

        ALOGD("%s: ioctl allocate returned offset 0x%llx size 0x%llx\n", __func__,
                (unsigned long long)m_offset,
                (unsigned long long)m_size);

        return true;
    }
}

bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
{
    ALOGD("%s: Ask to claim region [0x%llx 0x%llx]\n", __func__,
         (unsigned long long)offset,
         (unsigned long long)offset + size);

    destroy();

    if (!provider->is_opened()) {
        return false;
    }

    struct goldfish_address_space_claim_shared request;
    request.offset = offset;
    request.size = size;
    long res = ioctl_claim_shared(provider->m_handle, &request);

    if (res) {
        return false;
    }

    m_offset = offset;
    m_size = size;
    m_handle = provider->m_handle;
    m_is_shared_mapping = true;

    return true;
}

uint64_t GoldfishAddressSpaceBlock::physAddr() const
{
    return m_phys_addr;
}

uint64_t GoldfishAddressSpaceBlock::hostAddr() const
{
    return m_host_addr;
}

void *GoldfishAddressSpaceBlock::mmap(uint64_t host_addr)
{
    if (m_size == 0) {
        ALOGE("%s: called with zero size\n", __func__);
        return NULL;
    }
    if (m_mmaped_ptr) {
        ALOGE("'mmap' called for an already mmaped address block");
        ::abort();
    }

    void *result;
    const int res = memoryMap(NULL, m_size, m_handle, m_offset, &result);
    if (res) {
        ALOGE("%s: host memory map failed with size 0x%llx "
              "off 0x%llx errno %d\n",
              __func__,
              (unsigned long long)m_size,
              (unsigned long long)m_offset, res);
        return NULL;
    } else {
        m_mmaped_ptr = result;
        m_host_addr = host_addr;
        return guestPtr();
    }
}

void *GoldfishAddressSpaceBlock::guestPtr() const
{
    return reinterpret_cast<char *>(m_mmaped_ptr) + (m_host_addr & (PAGE_SIZE - 1));
}

void GoldfishAddressSpaceBlock::destroy()
{
    if (m_mmaped_ptr && m_size) {
        memoryUnmap(m_mmaped_ptr, m_size);
        m_mmaped_ptr = NULL;
    }

    if (m_size) {
        long res = -EINVAL;

        if (m_is_shared_mapping) {
            res = ioctl_unclaim_shared(m_handle, m_offset);
            if (res) {
                ALOGE("ioctl_unclaim_shared failed, res=%ld", res);
                ::abort();
            }
        } else {
            res = ioctl_deallocate(m_handle, m_offset);
            if (res) {
                ALOGE("ioctl_deallocate failed, res=%ld", res);
                ::abort();
            }
        }

        m_is_shared_mapping = false;

        m_phys_addr = 0;
        m_host_addr = 0;
        m_offset = 0;
        m_size = 0;
    }
}

void GoldfishAddressSpaceBlock::release()
{
    m_handle = -1;
    m_mmaped_ptr = NULL;
    m_phys_addr = 0;
    m_host_addr = 0;
    m_offset = 0;
    m_size = 0;
}

int GoldfishAddressSpaceBlock::memoryMap(void *addr,
                                         size_t len,
                                         address_space_handle_t fd,
                                         uint64_t off,
                                         void** dst) {
    void* ptr = ::mmap64(addr, len, PROT_WRITE, MAP_SHARED, fd, off);
    if (MAP_FAILED == ptr) {
        return errno;
    } else {
        *dst = ptr;
        return 0;
    }
}

void GoldfishAddressSpaceBlock::memoryUnmap(void *ptr, size_t size)
{
    ::munmap(ptr, size);
}

GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
  : m_provider(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) {}

bool GoldfishAddressSpaceHostMemoryAllocator::is_opened() const { return m_provider.is_opened(); }

long GoldfishAddressSpaceHostMemoryAllocator::hostMalloc(GoldfishAddressSpaceBlock *block, size_t size)
{
    if (size == 0) {
        return -EINVAL;
    }
    if (block->size() > 0) {
        return -EINVAL;
    }
    if (!m_provider.is_opened()) {
        return -ENODEV;
    }
    if (!block->allocate(&m_provider, size)) {
        return -ENOMEM;
    }

    struct goldfish_address_space_ping request;
    ::memset(&request, 0, sizeof(request));
    request.version = sizeof(request);
    request.offset = block->offset();
    request.size = block->size();
    request.metadata = HOST_MEMORY_ALLOCATOR_COMMAND_ALLOCATE_ID;

    long ret = ioctl_ping(m_provider.m_handle, &request);
    if (ret) {
        return ret;
    }
    ret = static_cast<long>(request.metadata);
    if (ret) {
        return ret;
    }

    block->mmap(0);
    return 0;
}

void GoldfishAddressSpaceHostMemoryAllocator::hostFree(GoldfishAddressSpaceBlock *block)
{
    if (block->size() == 0) {
        return;
    }

    if (!m_provider.is_opened()) {
        ALOGE("%s: device is not available", __func__);
        ::abort();
    }

    if (block->guestPtr()) {
        struct goldfish_address_space_ping request;
        ::memset(&request, 0, sizeof(request));
        request.version = sizeof(request);
        request.offset = block->offset();
        request.metadata = HOST_MEMORY_ALLOCATOR_COMMAND_UNALLOCATE_ID;

        const long ret = ioctl_ping(m_provider.m_handle, &request);
        if (ret) {
            ALOGE("%s: ioctl_ping failed, ret=%ld", __func__, ret);
            ::abort();
        }
    }

    block->replace(NULL);
}

address_space_handle_t goldfish_address_space_open() {
    return ::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR);
}

void goldfish_address_space_close(address_space_handle_t handle) {
    ::close(handle);
}

bool goldfish_address_space_allocate(
    address_space_handle_t handle,
    size_t size, uint64_t* phys_addr, uint64_t* offset) {

    struct goldfish_address_space_allocate_block request;
    ::memset(&request, 0, sizeof(request));
    request.size = size;

    long res = ioctl_allocate(handle, &request);

    if (res) return false;

    *phys_addr = request.phys_addr;
    *offset = request.offset;
    return true;
}

bool goldfish_address_space_free(
    address_space_handle_t handle, uint64_t offset) {

    long res = ioctl_deallocate(handle, offset);

    if (res) {
        ALOGE("ioctl_deallocate failed, res=%ld", res);
        ::abort();
    }

    return true;
}

bool goldfish_address_space_claim_shared(
    address_space_handle_t handle, uint64_t offset, uint64_t size) {

    struct goldfish_address_space_claim_shared request;
    request.offset = offset;
    request.size = size;
    long res = ioctl_claim_shared(handle, &request);

    if (res) return false;

    return true;
}

bool goldfish_address_space_unclaim_shared(
        address_space_handle_t handle, uint64_t offset) {
    long res = ioctl_unclaim_shared(handle, offset);
    if (res) {
        ALOGE("ioctl_unclaim_shared failed, res=%ld", res);
        ::abort();
    }

    return true;
}

// pgoff is the offset into the page to return in the result
void* goldfish_address_space_map(
    address_space_handle_t handle,
    uint64_t offset, uint64_t size,
    uint64_t pgoff) {

    void* res = ::mmap64(0, size, PROT_WRITE, MAP_SHARED, handle, offset);

    if (res == MAP_FAILED) {
        ALOGE("%s: failed to map. errno: %d\n", __func__, errno);
        return 0;
    }

    return (void*)(((char*)res) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
}

void goldfish_address_space_unmap(void* ptr, uint64_t size) {
    void* pagePtr = (void*)(((uintptr_t)ptr) & ~(PAGE_SIZE - 1));
    ::munmap(pagePtr, size);
}

bool goldfish_address_space_set_subdevice_type(
    address_space_handle_t handle, GoldfishAddressSpaceSubdeviceType type,
    address_space_handle_t* handle_out) {
    struct goldfish_address_space_ping request;
    request.metadata = (uint64_t)type;
    *handle_out = handle;
    return goldfish_address_space_ping(handle, &request);
}

bool goldfish_address_space_ping(
    address_space_handle_t handle,
    struct goldfish_address_space_ping* ping) {
    long res = ioctl_ping(handle, ping);

    if (res) {
        ALOGE("%s: ping failed: errno: %d\n", __func__, errno);
        return false;
    }

    return true;
}
