// Copyright 2016 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

// TODO(MG-992): Need to be able to r/w MSRs.
// The thought is to use resources (as in ResourceDispatcher), at which point
// this will all get rewritten. Until such time, the goal here is KISS.
// This file contains the lower part of Intel Processor Trace support that must
// be done in the kernel (so that we can read/write msrs).
// The userspace driver is in system/udev/intel-pt/intel-pt.c.
//
// We currently only support Table of Physical Addresses mode:
// it supports discontiguous buffers and supports stop-on-full behavior
// in addition to wrap-around.

#include <arch/arch_ops.h>
#include <arch/mmu.h>
#include <arch/x86.h>
#include <arch/x86/feature.h>
#include <arch/x86/mmu.h>
#include <arch/x86/proc_trace.h>
#include <err.h>
#include <kernel/mp.h>
#include <kernel/thread.h>
#include <kernel/vm.h>
#include <vm/vm_aspace.h>
#include <lib/ktrace.h>
#include <zircon/device/intel-pt.h>
#include <zircon/ktrace.h>
#include <zircon/mtrace.h>
#include <zircon/thread_annotations.h>
#include <fbl/auto_lock.h>
#include <fbl/macros.h>
#include <fbl/mutex.h>
#include <fbl/unique_ptr.h>
#include <pow2.h>
#include <string.h>
#include <trace.h>

using fbl::AutoLock;

#define LOCAL_TRACE 0

// Control MSRs
#define IA32_RTIT_OUTPUT_BASE 0x560
#define IA32_RTIT_OUTPUT_MASK_PTRS 0x561
#define IA32_RTIT_CTL 0x570
#define IA32_RTIT_STATUS 0x571
#define IA32_RTIT_CR3_MATCH 0x572
#define IA32_RTIT_ADDR0_A 0x580
#define IA32_RTIT_ADDR0_B 0x581
#define IA32_RTIT_ADDR1_A 0x582
#define IA32_RTIT_ADDR1_B 0x583
#define IA32_RTIT_ADDR2_A 0x584
#define IA32_RTIT_ADDR2_B 0x585
#define IA32_RTIT_ADDR3_A 0x586
#define IA32_RTIT_ADDR3_B 0x587

// We need bits[15:8] to get the "maximum non-turbo ratio".
// See libipt:intel-pt.h:pt_config, and Intel Vol. 3 chapter 35.5.
#define IA32_PLATFORM_INFO 0xce

// Our own copy of what h/w supports, mostly for sanity checking.
static bool supports_pt = false;
static bool supports_cr3_filtering = false;
static bool supports_psb = false;
static bool supports_ip_filtering = false;
static bool supports_mtc = false;
static bool supports_ptwrite = false;
static bool supports_power_events = false;
static bool supports_output_topa = false;
static bool supports_output_topa_multi = false;
static bool supports_output_single = false;
static bool supports_output_transport = false;

struct ipt_cpu_state_t {
    uint64_t ctl;
    uint64_t status;
    uint64_t output_base;
    uint64_t output_mask_ptrs;
    uint64_t cr3_match;
    struct {
        uint64_t a,b;
    } addr_ranges[IPT_MAX_NUM_ADDR_RANGES];
};

static fbl::Mutex ipt_lock;

static ipt_cpu_state_t* ipt_cpu_state TA_GUARDED(ipt_lock);

static bool active TA_GUARDED(ipt_lock) = false;

static ipt_trace_mode_t trace_mode TA_GUARDED(ipt_lock) = IPT_TRACE_CPUS;

void x86_processor_trace_init(void)
{
    if (!x86_feature_test(X86_FEATURE_PT)) {
        return;
    }

    struct cpuid_leaf leaf;
    if (!x86_get_cpuid_subleaf(X86_CPUID_PT, 0, &leaf)) {
        return;
    }

    supports_pt = true;

    // Keep our own copy of these flags, mostly for potential sanity checks.
    supports_cr3_filtering = !!(leaf.b & (1<<0));
    supports_psb = !!(leaf.b & (1<<1));
    supports_ip_filtering = !!(leaf.b & (1<<2));
    supports_mtc = !!(leaf.b & (1<<3));
    supports_ptwrite = !!(leaf.b & (1<<4));
    supports_power_events = !!(leaf.b & (1<<5));

    supports_output_topa = !!(leaf.c & (1<<0));
    supports_output_topa_multi = !!(leaf.c & (1<<1));
    supports_output_single = !!(leaf.c & (1<<2));
    supports_output_transport = !!(leaf.c & (1<<3));
}

// Intel Processor Trace support needs to be able to map cr3 values that
// appear in the trace to pids that ld.so uses to dump memory maps.
void arch_trace_process_create(uint64_t pid, paddr_t pt_phys) {
    // The cr3 value that appears in Intel PT h/w tracing.
    uint64_t cr3 = pt_phys;
    ktrace(TAG_IPT_PROCESS_CREATE, (uint32_t)pid, (uint32_t)(pid >> 32),
           (uint32_t)cr3, (uint32_t)(cr3 >> 32));
}

// IPT tracing has two "modes":
// - per-cpu tracing
// - thread-specific tracing
// Tracing can only be done in one mode at a time. This is because saving/
// restoring thread PT state via the xsaves/xrstors instructions is a global
// flag in the XSS msr.

// Worker for x86_ipt_set_mode to be executed on all cpus.
// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
static void x86_ipt_set_mode_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
    DEBUG_ASSERT(arch_ints_disabled());
    DEBUG_ASSERT(!active);

    // When changing modes make sure all PT MSRs are in the init state.
    // We don't want a value to appear in the xsave buffer and have xrstors
    // #gp because XCOMP_BV has the PT bit set that's not set in XSS.
    // We still need to do this, even with MG-892, when transitioning
    // from IPT_TRACE_CPUS to IPT_TRACE_THREADS.
    write_msr(IA32_RTIT_CTL, 0);
    write_msr(IA32_RTIT_STATUS, 0);
    write_msr(IA32_RTIT_OUTPUT_BASE, 0);
    write_msr(IA32_RTIT_OUTPUT_MASK_PTRS, 0);
    if (supports_cr3_filtering)
        write_msr(IA32_RTIT_CR3_MATCH, 0);
    // TODO(dje): addr range msrs

    ipt_trace_mode_t new_mode = static_cast<ipt_trace_mode_t>(reinterpret_cast<uintptr_t>(raw_context));

    // PT state saving, if supported, was enabled during boot so there's no
    // need to recalculate the xsave space needed.
    x86_set_extended_register_pt_state(new_mode == IPT_TRACE_THREADS);
}

status_t x86_ipt_set_mode(ipt_trace_mode_t mode) {
    AutoLock al(&ipt_lock);

    if (!supports_pt)
        return ZX_ERR_NOT_SUPPORTED;
    if (active)
        return ZX_ERR_BAD_STATE;
    if (ipt_cpu_state)
        return ZX_ERR_BAD_STATE;
    // Changing to the same mode is a no-op.
    // This check is still done after the above checks. E.g., it doesn't make
    // sense to call this function if tracing is active.
    if (mode == trace_mode)
        return ZX_OK;

    // MG-892: We don't support changing the mode from IPT_TRACE_THREADS to
    // IPT_TRACE_CPUS: We can't turn off XSS.PT until we're sure all threads
    // have no PT state, and that's too tricky to do right now. Instead,
    // require the developer to reboot (the default is IPT_TRACE_CPUS).
    if (trace_mode == IPT_TRACE_THREADS && mode == IPT_TRACE_CPUS)
        return ZX_ERR_NOT_SUPPORTED;

    mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_ipt_set_mode_task,
                 reinterpret_cast<void*>(static_cast<uintptr_t>(mode)));
    trace_mode = mode;

    return ZX_OK;
}

// Allocate all needed state for tracing.

status_t x86_ipt_cpu_mode_alloc() {
    AutoLock al(&ipt_lock);

    if (!supports_pt)
        return ZX_ERR_NOT_SUPPORTED;
    if (trace_mode == IPT_TRACE_THREADS)
        return ZX_ERR_BAD_STATE;
    if (active)
        return ZX_ERR_BAD_STATE;
    if (ipt_cpu_state)
        return ZX_ERR_BAD_STATE;

    uint32_t num_cpus = arch_max_num_cpus();
    ipt_cpu_state =
        reinterpret_cast<ipt_cpu_state_t*>(calloc(num_cpus,
                                                  sizeof(*ipt_cpu_state)));
    if (!ipt_cpu_state)
        return ZX_ERR_NO_MEMORY;
    return ZX_OK;
}

// Free resources obtained by x86_ipt_cpu_mode_alloc().
// This doesn't care if resources have already been freed to save callers
// from having to care during any cleanup.

status_t x86_ipt_cpu_mode_free() {
    AutoLock al(&ipt_lock);

    if (!supports_pt)
        return ZX_ERR_NOT_SUPPORTED;
    if (trace_mode == IPT_TRACE_THREADS)
        return ZX_ERR_BAD_STATE;
    if (active)
        return ZX_ERR_BAD_STATE;

    free(ipt_cpu_state);
    ipt_cpu_state = nullptr;
    return ZX_OK;
}

// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
static void x86_ipt_start_cpu_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
    DEBUG_ASSERT(arch_ints_disabled());
    DEBUG_ASSERT(active && raw_context);

    ipt_cpu_state_t* context = reinterpret_cast<ipt_cpu_state_t*>(raw_context);
    uint32_t cpu = arch_curr_cpu_num();
    ipt_cpu_state_t* state = &context[cpu];

    DEBUG_ASSERT(!(read_msr(IA32_RTIT_CTL) & IPT_CTL_TRACE_EN_MASK));

    // Load the ToPA configuration
    write_msr(IA32_RTIT_OUTPUT_BASE, state->output_base);
    write_msr(IA32_RTIT_OUTPUT_MASK_PTRS, state->output_mask_ptrs);

    // Load all other msrs, prior to enabling tracing.
    write_msr(IA32_RTIT_STATUS, state->status);
    if (supports_cr3_filtering)
        write_msr(IA32_RTIT_CR3_MATCH, state->cr3_match);

    // Enable the trace
    write_msr(IA32_RTIT_CTL, state->ctl);
}

// Begin the trace.

status_t x86_ipt_cpu_mode_start() {
    AutoLock al(&ipt_lock);

    if (!supports_pt)
        return ZX_ERR_NOT_SUPPORTED;
    if (trace_mode == IPT_TRACE_THREADS)
        return ZX_ERR_BAD_STATE;
    if (active)
        return ZX_ERR_BAD_STATE;
    if (!ipt_cpu_state)
        return ZX_ERR_BAD_STATE;

    uint64_t kernel_cr3 = x86_kernel_cr3();
    TRACEF("Enabling processor trace, kernel cr3: 0x%" PRIxPTR "\n",
           kernel_cr3);

    active = true;

    uint64_t platform_msr = read_msr(IA32_PLATFORM_INFO);
    unsigned nom_freq = (platform_msr >> 8) & 0xff;
    ktrace(TAG_IPT_START, (uint32_t)nom_freq, 0,
           (uint32_t)kernel_cr3, (uint32_t)(kernel_cr3 >> 32));

    // Emit other sideband info needed by the trace reader.
    const struct x86_model_info* model_info = x86_get_model();
    ktrace(TAG_IPT_CPU_INFO, model_info->processor_type,
           model_info->display_family, model_info->display_model,
           model_info->stepping);

    mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_ipt_start_cpu_task, ipt_cpu_state);
    return ZX_OK;
}

// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
static void x86_ipt_stop_cpu_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
    DEBUG_ASSERT(arch_ints_disabled());
    DEBUG_ASSERT(raw_context);

    ipt_cpu_state_t* context = reinterpret_cast<ipt_cpu_state_t*>(raw_context);
    uint32_t cpu = arch_curr_cpu_num();
    ipt_cpu_state_t* state = &context[cpu];

    // Disable the trace
    write_msr(IA32_RTIT_CTL, 0);

    // Retrieve msr values for later providing to userspace
    state->ctl = 0;
    state->status = read_msr(IA32_RTIT_STATUS);
    state->output_base = read_msr(IA32_RTIT_OUTPUT_BASE);
    state->output_mask_ptrs = read_msr(IA32_RTIT_OUTPUT_MASK_PTRS);

    // Zero all MSRs so that we are in the XSAVE initial configuration.
    // This allows h/w to do some optimizations regarding the state.
    write_msr(IA32_RTIT_STATUS, 0);
    write_msr(IA32_RTIT_OUTPUT_BASE, 0);
    write_msr(IA32_RTIT_OUTPUT_MASK_PTRS, 0);
    if (supports_cr3_filtering)
        write_msr(IA32_RTIT_CR3_MATCH, 0);

    // TODO(dje): Make it explicit that packets have been completely written.
    // See Intel Vol 3 chapter 36.2.4.

    // TODO(teisenbe): Clear ADDR* MSRs depending on leaf 1
}

// This can be called while not active, so the caller doesn't have to care
// during any cleanup.

status_t x86_ipt_cpu_mode_stop() {
    AutoLock al(&ipt_lock);

    if (!supports_pt)
        return ZX_ERR_NOT_SUPPORTED;
    if (trace_mode == IPT_TRACE_THREADS)
        return ZX_ERR_BAD_STATE;
    if (!ipt_cpu_state)
        return ZX_ERR_BAD_STATE;

    TRACEF("Disabling processor trace\n");

    mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_ipt_stop_cpu_task, ipt_cpu_state);
    ktrace(TAG_IPT_STOP, 0, 0, 0, 0);
    active = false;
    return ZX_OK;
}

status_t x86_ipt_stage_cpu_data(uint32_t cpu, const zx_x86_pt_regs_t* regs) {
    AutoLock al(&ipt_lock);

    if (!supports_pt)
        return ZX_ERR_NOT_SUPPORTED;
    if (trace_mode == IPT_TRACE_THREADS)
        return ZX_ERR_BAD_STATE;
    if (active)
        return ZX_ERR_BAD_STATE;
    if (!ipt_cpu_state)
            return ZX_ERR_BAD_STATE;
    uint32_t num_cpus = arch_max_num_cpus();
    if (cpu >= num_cpus)
        return ZX_ERR_INVALID_ARGS;

    ipt_cpu_state[cpu].ctl = regs->ctl;
    ipt_cpu_state[cpu].status = regs->status;
    ipt_cpu_state[cpu].output_base = regs->output_base;
    ipt_cpu_state[cpu].output_mask_ptrs = regs->output_mask_ptrs;
    ipt_cpu_state[cpu].cr3_match = regs->cr3_match;
    static_assert(sizeof(ipt_cpu_state[cpu].addr_ranges) == sizeof(regs->addr_ranges), "addr_ranges size mismatch");
    memcpy(ipt_cpu_state[cpu].addr_ranges, regs->addr_ranges, sizeof(regs->addr_ranges));

    return ZX_OK;
}

status_t x86_ipt_get_cpu_data(uint32_t cpu, zx_x86_pt_regs_t* regs) {
    AutoLock al(&ipt_lock);

    if (!supports_pt)
        return ZX_ERR_NOT_SUPPORTED;
    if (trace_mode == IPT_TRACE_THREADS)
        return ZX_ERR_BAD_STATE;
    if (active)
        return ZX_ERR_BAD_STATE;
    if (!ipt_cpu_state)
        return ZX_ERR_BAD_STATE;
    uint32_t num_cpus = arch_max_num_cpus();
    if (cpu >= num_cpus)
        return ZX_ERR_INVALID_ARGS;

    regs->ctl = ipt_cpu_state[cpu].ctl;
    regs->status = ipt_cpu_state[cpu].status;
    regs->output_base = ipt_cpu_state[cpu].output_base;
    regs->output_mask_ptrs = ipt_cpu_state[cpu].output_mask_ptrs;
    regs->cr3_match = ipt_cpu_state[cpu].cr3_match;
    static_assert(sizeof(regs->addr_ranges) == sizeof(ipt_cpu_state[cpu].addr_ranges), "addr_ranges size mismatch");
    memcpy(regs->addr_ranges, ipt_cpu_state[cpu].addr_ranges, sizeof(regs->addr_ranges));

    return ZX_OK;
}
