// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
// Copyright (c) 2015 Intel Corporation
//
// 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 <bits.h>
#include <debug.h>
#include <lib/counters.h>
#include <lib/crashlog.h>
#include <lib/fit/defer.h>
#include <lib/ktrace.h>
#include <platform.h>
#include <trace.h>
#include <zircon/boot/crash-reason.h>
#include <zircon/hw/debug/x86.h>
#include <zircon/syscalls/exception.h>
#include <zircon/types.h>

#include <arch/exception.h>
#include <arch/regs.h>
#include <arch/user_copy.h>
#include <arch/x86.h>
#include <arch/x86/apic.h>
#include <arch/x86/descriptor.h>
#include <arch/x86/feature.h>
#include <arch/x86/interrupts.h>
#include <arch/x86/perf_mon.h>
#include <arch/x86/registers.h>
#include <kernel/interrupt.h>
#include <kernel/thread.h>
#include <pretty/hexdump.h>
#include <vm/fault.h>
#include <vm/vm.h>

// Returns whether the register state indicates that the CPU was executing
// userland code.
static bool is_from_user(const iframe_t* frame) { return SELECTOR_PL(frame->cs) != 0; }

static void dump_fault_frame(iframe_t* frame) {
  dprintf(CRITICAL, " CS:  %#18" PRIx64 " RIP: %#18" PRIx64 " EFL: %#18" PRIx64 " CR2: %#18lx\n",
          frame->cs, frame->ip, frame->flags, x86_get_cr2());
  dprintf(CRITICAL,
          " RAX: %#18" PRIx64 " RBX: %#18" PRIx64 " RCX: %#18" PRIx64 " RDX: %#18" PRIx64 "\n",
          frame->rax, frame->rbx, frame->rcx, frame->rdx);
  dprintf(CRITICAL,
          " RSI: %#18" PRIx64 " RDI: %#18" PRIx64 " RBP: %#18" PRIx64 " RSP: %#18" PRIx64 "\n",
          frame->rsi, frame->rdi, frame->rbp, frame->user_sp);
  dprintf(CRITICAL,
          "  R8: %#18" PRIx64 "  R9: %#18" PRIx64 " R10: %#18" PRIx64 " R11: %#18" PRIx64 "\n",
          frame->r8, frame->r9, frame->r10, frame->r11);
  dprintf(CRITICAL,
          " R12: %#18" PRIx64 " R13: %#18" PRIx64 " R14: %#18" PRIx64 " R15: %#18" PRIx64 "\n",
          frame->r12, frame->r13, frame->r14, frame->r15);
  dprintf(CRITICAL, "errc: %#18" PRIx64 "\n", frame->err_code);

  // dump the bottom of the current stack
  void* stack = frame;

  if (frame->cs == CODE_64_SELECTOR) {
    dprintf(CRITICAL, "bottom of kernel stack at %p:\n", stack);
    hexdump(stack, 128);
  }
}

KCOUNTER(exceptions_debug, "exceptions.debug")
KCOUNTER(exceptions_nmi, "exceptions.nmi")
KCOUNTER(exceptions_brkpt, "exceptions.breakpoint")
KCOUNTER(exceptions_invop, "exceptions.inv_opcode")
KCOUNTER(exceptions_dev_na, "exceptions.dev_na")
KCOUNTER(exceptions_dfault, "exceptions.double_fault")
KCOUNTER(exceptions_fpu, "exceptions.fpu")
KCOUNTER(exceptions_simd, "exceptions.simd")
KCOUNTER(exceptions_gpf, "exceptions.gpf")
KCOUNTER(exceptions_page, "exceptions.page_fault")
KCOUNTER(exceptions_apic_err, "exceptions.apic_error")
KCOUNTER(exceptions_irq, "exceptions.irq")
KCOUNTER(exceptions_unhandled, "exceptions.unhandled")
KCOUNTER(exceptions_user, "exceptions.user")

__NO_RETURN static void exception_die(iframe_t* frame, const char* msg) {
  platform_panic_start();

  printf("vector %lu\n", (ulong)frame->vector);
  dprintf(CRITICAL, "%s", msg);
  dump_fault_frame(frame);
  crashlog.iframe = frame;

  // try to dump the user stack
  if (is_user_address(frame->user_sp)) {
    uint8_t buf[256];
    if (arch_copy_from_user(buf, (void*)frame->user_sp, sizeof(buf)) == ZX_OK) {
      printf("bottom of user stack at 0x%lx:\n", (vaddr_t)frame->user_sp);
      hexdump_ex(buf, sizeof(buf), frame->user_sp);
    }
  }

  platform_halt(HALT_ACTION_HALT, ZirconCrashReason::Panic);
}

static bool try_dispatch_user_exception(iframe_t* frame, uint exception_type) {
  if (is_from_user(frame)) {
    struct arch_exception_context context = {
        .frame = frame,
        .cr2 = 0,
        .user_synth_code = 0,
        .user_synth_data = 0,
        .is_page_fault = false,
    };
    PreemptionState& preemption_state = Thread::Current::preemption_state();
    preemption_state.PreemptReenableNoResched();
    arch_set_blocking_disallowed(false);
    arch_enable_ints();
    zx_status_t erc = dispatch_user_exception(exception_type, &context);
    arch_disable_ints();
    arch_set_blocking_disallowed(true);
    preemption_state.PreemptDisable();
    if (erc == ZX_OK)
      return true;
  }

  return false;
}

static void x86_debug_handler(iframe_t* frame) {
  // DR6 is the status register that explains what exception happened (single step, hardware
  // breakpoint, etc.).
  //
  // We only need to keep track of DR6 because the other state doesn't change and the only way
  // to actually change the debug registers for a thread is through the thread_write_state
  // syscall.

  Thread* thread = Thread::Current::Get();

  // We save the current state so that exception handlers can check what kind of exception it was.
  x86_read_debug_status(&thread->arch().debug_state.dr6);

  // NOTE: a HW breakpoint exception can also represent a single step.
  // TODO(fxbug.dev/32872): Is it worth separating this into two separate exceptions?
  if (try_dispatch_user_exception(frame, ZX_EXCP_HW_BREAKPOINT)) {
    // If the exception was successfully handled, we mask the debug the single step bit, as the cpu
    // doesn't automatically do it.
    //
    // After this point, any exception handler that reads DR6 won't see the single step bit active.
    X86_DBG_STATUS_BD_SET(&thread->arch().debug_state.dr6, 0);
    X86_DBG_STATUS_BS_SET(&thread->arch().debug_state.dr6, 0);
    X86_DBG_STATUS_BT_SET(&thread->arch().debug_state.dr6, 0);
    x86_write_debug_status(thread->arch().debug_state.dr6);

    return;
  }

  exception_die(frame, "unhandled hw breakpoint, halting\n");
}

static void x86_nmi_handler(iframe_t* frame) {}

static void x86_breakpoint_handler(iframe_t* frame) {
  if (try_dispatch_user_exception(frame, ZX_EXCP_SW_BREAKPOINT))
    return;

  exception_die(frame, "unhandled sw breakpoint, halting\n");
}

static void x86_gpf_handler(iframe_t* frame) {
  DEBUG_ASSERT(arch_ints_disabled());

  // Check if we were doing a GPF test, e.g. to check if an MSR exists.
  struct x86_percpu* percpu = x86_get_percpu();
  if (unlikely(percpu->gpf_return_target)) {
    ASSERT(!is_from_user(frame));

    // Set up return to new address
    frame->ip = percpu->gpf_return_target;
    percpu->gpf_return_target = 0;
    return;
  }

  if (try_dispatch_user_exception(frame, ZX_EXCP_GENERAL))
    return;

  exception_die(frame, "unhandled gpf, halting\n");
}

static void x86_invop_handler(iframe_t* frame) {
  if (try_dispatch_user_exception(frame, ZX_EXCP_UNDEFINED_INSTRUCTION))
    return;

  exception_die(frame, "invalid opcode, halting\n");
}

static void x86_df_handler(iframe_t* frame) {
  // Do not give the user exception handler the opportunity to handle double
  // faults, since they indicate an unexpected system state and cannot be
  // recovered from.
  kcounter_add(exceptions_dfault, 1);
  exception_die(frame, "double fault, halting\n");
}

static void x86_unhandled_exception(iframe_t* frame) {
  if (try_dispatch_user_exception(frame, ZX_EXCP_GENERAL))
    return;

  exception_die(frame, "unhandled exception, halting\n");
}

static void x86_dump_pfe(iframe_t* frame, ulong cr2) {
  uint64_t error_code = frame->err_code;

  vaddr_t v_addr = cr2;
  vaddr_t ssp = frame->user_ss & X86_8BYTE_MASK;
  vaddr_t sp = frame->user_sp;
  vaddr_t cs = frame->cs & X86_8BYTE_MASK;
  vaddr_t ip = frame->ip;

  dprintf(CRITICAL, "<PAGE FAULT> Instruction Pointer   = 0x%lx:0x%lx\n", (ulong)cs, (ulong)ip);
  dprintf(CRITICAL, "<PAGE FAULT> Stack Pointer         = 0x%lx:0x%lx\n", (ulong)ssp, (ulong)sp);
  dprintf(CRITICAL, "<PAGE FAULT> Fault Linear Address  = 0x%lx\n", (ulong)v_addr);
  dprintf(CRITICAL, "<PAGE FAULT> Error Code Value      = 0x%lx\n", (ulong)error_code);
  dprintf(CRITICAL, "<PAGE FAULT> Error Code Type       = %s %s %s%s, %s\n",
          error_code & PFEX_U ? "user" : "supervisor", error_code & PFEX_W ? "write" : "read",
          error_code & PFEX_I ? "instruction" : "data", error_code & PFEX_RSV ? " rsv" : "",
          error_code & PFEX_P ? "protection violation" : "page not present");
}

__NO_RETURN static void x86_fatal_pfe_handler(iframe_t* frame, ulong cr2) {
  x86_dump_pfe(frame, cr2);

  uint64_t error_code = frame->err_code;

  dump_thread_during_panic(Thread::Current::Get(), true);

  if (error_code & PFEX_U) {
    // User mode page fault
    switch (error_code) {
      case 4:
      case 5:
      case 6:
      case 7:
        exception_die(frame, "User Page Fault exception, halting\n");
        break;
    }
  } else {
    // Supervisor mode page fault
    switch (error_code) {
      case 0:
      case 1:
      case 2:
      case 3:
        exception_die(frame, "Supervisor Page Fault exception, halting\n");
        break;
    }
  }

  exception_die(frame, "unhandled page fault, halting\n");
}

static zx_status_t x86_pfe_handler(iframe_t* frame) {
  /* Handle a page fault exception */
  uint64_t error_code = frame->err_code;
  vaddr_t va = x86_get_cr2();

  /* reenable interrupts */
  PreemptionState& preemption_state = Thread::Current::preemption_state();
  preemption_state.PreemptReenableNoResched();
  arch_set_blocking_disallowed(false);
  arch_enable_ints();

  /* make sure we put interrupts back as we exit */
  auto cleanup = fit::defer([&preemption_state]() {
    arch_disable_ints();
    arch_set_blocking_disallowed(true);
    preemption_state.PreemptDisable();
  });

  /* check for flags we're not prepared to handle */
  if (unlikely(error_code & ~(PFEX_I | PFEX_U | PFEX_W | PFEX_P))) {
    printf("x86_pfe_handler: unhandled error code bits set, error code %#" PRIx64 "\n", error_code);
    return ZX_ERR_NOT_SUPPORTED;
  }

  // Check for an SMAP violation.
  //
  // By policy, the kernel is not allowed to access user memory except when performing a
  // user_copy. SMAP is used to enforce the policy.
  if (unlikely(!(error_code & PFEX_U) &&          // fault taken in kernel mode
               g_x86_feature_has_smap &&          // CPU supports SMAP
               !(frame->flags & X86_FLAGS_AC) &&  // SMAP was enabled at time of fault
               is_user_address(va))) {            // faulting address is a user address
    printf("x86_pfe_handler: potential SMAP failure, supervisor access at address %#" PRIxPTR "\n",
           va);
    return ZX_ERR_ACCESS_DENIED;
  }

  /* convert the PF error codes to page fault flags */
  uint flags = 0;
  flags |= (error_code & PFEX_W) ? VMM_PF_FLAG_WRITE : 0;
  flags |= (error_code & PFEX_U) ? VMM_PF_FLAG_USER : 0;
  flags |= (error_code & PFEX_I) ? VMM_PF_FLAG_INSTRUCTION : 0;
  flags |= (error_code & PFEX_P) ? 0 : VMM_PF_FLAG_NOT_PRESENT;

  /* Check if the page fault handler should be skipped. It is skipped if there's a page_fault_resume
   * address and the highest bit is 0. */
  uint64_t pfr = Thread::Current::Get()->arch().page_fault_resume;
  if (unlikely(pfr && !BIT_SET(pfr, X86_PFR_RUN_FAULT_HANDLER_BIT))) {
    // Need to reconstruct the canonical resume address by ensuring it is correctly sign extended.
    // Double check the bit before X86_PFR_RUN_FAULT_HANDLER_BIT was set (indicating kernel
    // address) and fill it in.
    DEBUG_ASSERT(BIT_SET(pfr, X86_PFR_RUN_FAULT_HANDLER_BIT - 1));
    frame->ip = pfr | (1ull << X86_PFR_RUN_FAULT_HANDLER_BIT);
    frame->rdx = va;
    frame->rcx = flags;
    return ZX_OK;
  }

  /* call the high level page fault handler */
  zx_status_t pf_err = vmm_page_fault_handler(va, flags);
  if (likely(pf_err == ZX_OK))
    return ZX_OK;

  /* if the high level page fault handler can't deal with it,
   * resort to trying to recover first, before bailing */

  /* Check if a resume address is specified, and just return to it if so */
  if (unlikely(pfr)) {
    // Having the X86_PFR_RUN_FAULT_HANDLER_BIT set should have already resulted in a valid
    // sign extended canonical address. Double check the bit before, which should be a one.
    DEBUG_ASSERT(BIT_SET(pfr, X86_PFR_RUN_FAULT_HANDLER_BIT - 1));
    frame->ip = pfr;
    return ZX_OK;
  }

  /* let high level code deal with this */
  if (is_from_user(frame)) {
    kcounter_add(exceptions_user, 1);
    struct arch_exception_context context = {
        .frame = frame,
        .cr2 = va,
        .user_synth_code = 0,
        .user_synth_data = 0,
        .is_page_fault = true,
    };
    return dispatch_user_exception(ZX_EXCP_FATAL_PAGE_FAULT, &context);
  }

  /* fall through to fatal path */
  return ZX_ERR_NOT_SUPPORTED;
}

static void handle_exception_types(iframe_t* frame) {
  switch (frame->vector) {
    case X86_INT_DEBUG:
      kcounter_add(exceptions_debug, 1);
      x86_debug_handler(frame);
      break;
    case X86_INT_NMI:
      kcounter_add(exceptions_nmi, 1);
      x86_nmi_handler(frame);
      break;
    case X86_INT_BREAKPOINT:
      kcounter_add(exceptions_brkpt, 1);
      x86_breakpoint_handler(frame);
      break;

    case X86_INT_INVALID_OP:
      kcounter_add(exceptions_invop, 1);
      x86_invop_handler(frame);
      break;

    case X86_INT_DEVICE_NA:
      kcounter_add(exceptions_dev_na, 1);
      exception_die(frame, "device na fault\n");
      break;

    case X86_INT_DOUBLE_FAULT:
      x86_df_handler(frame);
      break;
    case X86_INT_FPU_FP_ERROR:
      kcounter_add(exceptions_fpu, 1);
      x86_unhandled_exception(frame);
      break;
    case X86_INT_SIMD_FP_ERROR:
      kcounter_add(exceptions_simd, 1);
      x86_unhandled_exception(frame);
      break;
    case X86_INT_GP_FAULT:
      kcounter_add(exceptions_gpf, 1);
      x86_gpf_handler(frame);
      break;

    case X86_INT_PAGE_FAULT:
      kcounter_add(exceptions_page, 1);
      CPU_STATS_INC(page_faults);
      if (x86_pfe_handler(frame) != ZX_OK)
        x86_fatal_pfe_handler(frame, x86_get_cr2());
      break;

    /* ignore spurious APIC irqs */
    case X86_INT_APIC_SPURIOUS:
      break;
    case X86_INT_APIC_ERROR: {
      kcounter_add(exceptions_apic_err, 1);
      apic_error_interrupt_handler();
      apic_issue_eoi();
      break;
    }
    case X86_INT_APIC_TIMER: {
      apic_timer_interrupt_handler();
      apic_issue_eoi();
      break;
    }
    case X86_INT_IPI_GENERIC: {
      mp_mbx_generic_irq(nullptr);
      apic_issue_eoi();
      break;
    }
    case X86_INT_IPI_RESCHEDULE: {
      mp_mbx_reschedule_irq(nullptr);
      apic_issue_eoi();
      break;
    }
    case X86_INT_IPI_INTERRUPT: {
      mp_mbx_interrupt_irq(nullptr);
      apic_issue_eoi();
      break;
    }
    case X86_INT_IPI_HALT: {
      x86_ipi_halt_handler(nullptr);
      /* no return */
      break;
    }
    case X86_INT_APIC_PMI: {
      apic_pmi_interrupt_handler(frame);
      // Note: apic_pmi_interrupt_handler calls apic_issue_eoi().
      break;
    }
    /* pass all other non-Intel defined irq vectors to the platform */
    case X86_INT_PLATFORM_BASE ... X86_INT_PLATFORM_MAX: {
      kcounter_add(exceptions_irq, 1);
      platform_irq(frame);
      break;
    }

    /* Integer division-by-zero */
    case X86_INT_DIVIDE_0:
    /* Overflow for INTO instruction (should be x86-32-only) */
    case X86_INT_OVERFLOW:
    /* Bound range exceeded for BOUND instruction (should be x86-32-only) */
    case X86_INT_BOUND_RANGE:
    /* Loading segment with "not present" bit set */
    case X86_INT_SEGMENT_NOT_PRESENT:
    /* Stack segment fault (should be x86-32-only) */
    case X86_INT_STACK_FAULT:
    /* Misaligned memory access when AC=1 in flags */
    case X86_INT_ALIGNMENT_CHECK:
      kcounter_add(exceptions_unhandled, 1);
      x86_unhandled_exception(frame);
      break;

    default:
      exception_die(frame, "unhandled exception type, halting\n");
      break;
  }
}

/* top level x86 exception handler for most exceptions and irqs */
void x86_exception_handler(iframe_t* frame) {
  // are we recursing?
  if (unlikely(arch_blocking_disallowed()) && frame->vector != X86_INT_NMI) {
    exception_die(frame, "recursion in interrupt handler\n");
  }

  int_handler_saved_state_t state;
  int_handler_start(&state);

  // did we come from user or kernel space?
  bool from_user = is_from_user(frame);

  const auto entry_vector = frame->vector;
  if (entry_vector != X86_INT_PAGE_FAULT) {
    // For page faults, the cpu number for the IRQ_ENTER event might be different from the IRQ_EXIT
    // event. A context switch can occur if the page fault is fulfilled asynchronously by a pager.
    // Hence page fault events are emitted in the thread context, not the cpu context like other
    // irq's. See TAG_PAGE_FAULT in vmm_page_fault_handler().
    ktrace_tiny(TAG_IRQ_ENTER, (static_cast<uint32_t>(entry_vector) << 8) | arch_curr_cpu_num());
  }

  // deliver the interrupt
  handle_exception_types(frame);

  if (entry_vector != X86_INT_PAGE_FAULT) {
    ktrace_tiny(TAG_IRQ_EXIT, (static_cast<uint32_t>(entry_vector) << 8) | arch_curr_cpu_num());
  }

  bool do_preempt = int_handler_finish(&state);

  /* if we came from user space, check to see if we have any signals to handle */
  if (unlikely(from_user)) {
    /* in the case of receiving a kill signal, this function may not return,
     * but the scheduler would have been invoked so it's fine.
     */
    arch_iframe_process_pending_signals(frame);
  }

  if (do_preempt)
    Thread::Current::Preempt();

  DEBUG_ASSERT_MSG(arch_ints_disabled(),
                   "ints disabled on way out of exception, vector %" PRIu64 " IP %#" PRIx64 "\n",
                   frame->vector, frame->ip);
}

void x86_syscall_process_pending_signals(syscall_regs_t* gregs) {
  Thread::Current::ProcessPendingSignals(GeneralRegsSource::Syscall, gregs);
}

void arch_iframe_process_pending_signals(iframe_t* iframe) {
  DEBUG_ASSERT(iframe != nullptr);
  Thread::Current::ProcessPendingSignals(GeneralRegsSource::Iframe, iframe);
}

void arch_dump_exception_context(const arch_exception_context_t* context) {
  // If we don't have a frame, there's nothing more we can print.
  if (context->frame == nullptr) {
    printf("no frame to dump\n");
    return;
  }

  if (context->is_page_fault) {
    x86_dump_pfe(context->frame, context->cr2);
  }

  dump_fault_frame(context->frame);

  // try to dump the user stack
  if (context->frame->cs != CODE_64_SELECTOR && is_user_address(context->frame->user_sp)) {
    uint8_t buf[256];
    if (arch_copy_from_user(buf, (void*)context->frame->user_sp, sizeof(buf)) == ZX_OK) {
      printf("bottom of user stack at 0x%lx:\n", (vaddr_t)context->frame->user_sp);
      hexdump_ex(buf, sizeof(buf), context->frame->user_sp);
    }
  }
}

void arch_fill_in_exception_context(const arch_exception_context_t* arch_context,
                                    zx_exception_report_t* report) {
  zx_exception_context_t* zx_context = &report->context;

  zx_context->synth_code = arch_context->user_synth_code;
  zx_context->synth_data = arch_context->user_synth_data;

  // TODO(fxbug.dev/30521): |frame| will be nullptr for synthetic exceptions that
  // don't provide general register values yet.
  if (arch_context->frame) {
    zx_context->arch.u.x86_64.vector = arch_context->frame->vector;
    zx_context->arch.u.x86_64.err_code = arch_context->frame->err_code;
  }
  zx_context->arch.u.x86_64.cr2 = arch_context->cr2;
}

zx_status_t arch_dispatch_user_policy_exception(uint32_t policy_exception_code,
                                                uint32_t policy_exception_data) {
  arch_exception_context_t context = {};
  context.user_synth_code = policy_exception_code;
  context.user_synth_data = policy_exception_data;
  return dispatch_user_exception(ZX_EXCP_POLICY_ERROR, &context);
}

bool arch_install_exception_context(Thread* thread, const arch_exception_context_t* context) {
  if (!context->frame) {
    // TODO(fxbug.dev/30521): Must be a synthetic exception as they don't (yet) provide the
    // registers.
    return false;
  }

  arch_set_suspended_general_regs(thread, GeneralRegsSource::Iframe, context->frame);
  return true;
}

void arch_remove_exception_context(Thread* thread) { arch_reset_suspended_general_regs(thread); }
