// Copyright 2020 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 "vm/pmm_checker.h"

#include <assert.h>
#include <lib/counters.h>
#include <lib/instrumentation/asan.h>
#include <platform.h>
#include <string.h>
#include <sys/types.h>

#include <pretty/hexdump.h>
#include <vm/physmap.h>

#include "debug.h"

namespace {

// The number of times the pmm checker has detected corruption.
KCOUNTER(counter_pattern_validation_failed, "vm.pmm.checker.validation_failed")

// The value 0x43 was chosen because it stands out when interpreted as ASCII ('C') and is an odd
// value that is less likely to occur natually (e.g. arm64 instructions are 4-byte aligned).
constexpr uint8_t kPatternOneByte = 0x43u;
constexpr uint64_t kPattern = 0x4343434343434343ull;

// This is a macro because it's passed to KERNEL_OOPS and KERNEL_OOPS requires a literal.
#define FORMAT_MESSAGE "pmm checker found unexpected pattern in page at %p; fill size is %lu\n"

void DumpPage(size_t fill_size, void* kvaddr) {
  printf("dump of page follows\n");
  hexdump8(kvaddr, PAGE_SIZE);
}

void DumpPageAndOops(vm_page_t* page, size_t fill_size, void* kvaddr) {
  KERNEL_OOPS(FORMAT_MESSAGE, kvaddr, fill_size);
  DumpPage(fill_size, kvaddr);
}

void DumpPageAndPanic(vm_page_t* page, size_t fill_size, void* kvaddr) {
  platform_panic_start();
  printf(FORMAT_MESSAGE, kvaddr, fill_size);
  DumpPage(fill_size, kvaddr);
  panic("pmm free list corruption suspected\n");
}

}  // namespace

// static
ktl::optional<PmmChecker::Action> PmmChecker::ActionFromString(const char* action_string) {
  if (!strcmp(action_string, "oops")) {
    return PmmChecker::Action::OOPS;
  }
  if (!strcmp(action_string, "panic")) {
    return PmmChecker::Action::PANIC;
  }
  return ktl::nullopt;
}

// static
const char* PmmChecker::ActionToString(Action action) {
  switch (action) {
    case PmmChecker::Action::OOPS:
      return "oops";
    case PmmChecker::Action::PANIC:
      return "panic";
  };
  __UNREACHABLE;
}

// static
bool PmmChecker::IsValidFillSize(size_t fill_size) {
  return fill_size >= 8 && fill_size <= PAGE_SIZE && (fill_size % 8 == 0);
}

void PmmChecker::SetFillSize(size_t fill_size) {
  DEBUG_ASSERT(IsValidFillSize(fill_size));
  DEBUG_ASSERT(!armed_);
  fill_size_ = fill_size;
}

void PmmChecker::Arm() { armed_ = true; }

void PmmChecker::Disarm() { armed_ = false; }

void PmmChecker::FillPattern(vm_page_t* page) {
  DEBUG_ASSERT(page->is_free());
  void* kvaddr = paddr_to_physmap(page->paddr());
  DEBUG_ASSERT(is_kernel_address(reinterpret_cast<vaddr_t>(kvaddr)));
  __unsanitized_memset(kvaddr, kPatternOneByte, fill_size_);
}

NO_ASAN bool PmmChecker::ValidatePattern(vm_page_t* page) {
  if (!armed_) {
    return true;
  }

  // Validate the pattern.  There's a decent chance that, on arm64, checking 8 bytes at a time will
  // be faster than 1 byte at time.
  auto kvaddr = static_cast<uint64_t*>(paddr_to_physmap(page->paddr()));
  for (size_t j = 0; j < fill_size_ / 8; ++j) {
    if (kvaddr[j] != kPattern) {
      return false;
    }
  }
  return true;
}

void PmmChecker::AssertPattern(vm_page_t* page) {
  if (!ValidatePattern(page)) {
    kcounter_add(counter_pattern_validation_failed, 1);
    auto kvaddr = static_cast<void*>(paddr_to_physmap(page->paddr()));
    switch (action_) {
      case Action::OOPS:
        DumpPageAndOops(page, fill_size_, kvaddr);
        break;
      case Action::PANIC:
        DumpPageAndPanic(page, fill_size_, kvaddr);
        break;
    }
  }
}

void PmmChecker::PrintStatus(FILE* f) const {
  fprintf(f, "PMM: pmm checker %s, fill size is %lu, action is %s\n",
          armed_ ? "enabled" : "disabled", fill_size_, ActionToString(action_));
}

int64_t PmmChecker::get_validation_failed_count() {
  return counter_pattern_validation_failed.SumAcrossAllCpus();
}
