cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel_guc_log_debugfs.c (4041B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright © 2020 Intel Corporation
      4 */
      5
      6#include <linux/fs.h>
      7#include <drm/drm_print.h>
      8
      9#include "gt/intel_gt_debugfs.h"
     10#include "intel_guc.h"
     11#include "intel_guc_log.h"
     12#include "intel_guc_log_debugfs.h"
     13#include "intel_uc.h"
     14
     15static u32 obj_to_guc_log_dump_size(struct drm_i915_gem_object *obj)
     16{
     17	u32 size;
     18
     19	if (!obj)
     20		return PAGE_SIZE;
     21
     22	/* "0x%08x 0x%08x 0x%08x 0x%08x\n" => 16 bytes -> 44 chars => x2.75 */
     23	size = ((obj->base.size * 11) + 3) / 4;
     24
     25	/* Add padding for final blank line, any extra header info, etc. */
     26	size = PAGE_ALIGN(size + PAGE_SIZE);
     27
     28	return size;
     29}
     30
     31static u32 guc_log_dump_size(struct intel_guc_log *log)
     32{
     33	struct intel_guc *guc = log_to_guc(log);
     34
     35	if (!intel_guc_is_supported(guc))
     36		return PAGE_SIZE;
     37
     38	if (!log->vma)
     39		return PAGE_SIZE;
     40
     41	return obj_to_guc_log_dump_size(log->vma->obj);
     42}
     43
     44static int guc_log_dump_show(struct seq_file *m, void *data)
     45{
     46	struct drm_printer p = drm_seq_file_printer(m);
     47	int ret;
     48
     49	ret = intel_guc_log_dump(m->private, &p, false);
     50
     51	if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
     52		pr_warn_once("preallocated size:%zx for %s exceeded\n",
     53			     m->size, __func__);
     54
     55	return ret;
     56}
     57DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_log_dump, guc_log_dump_size);
     58
     59static u32 guc_load_err_dump_size(struct intel_guc_log *log)
     60{
     61	struct intel_guc *guc = log_to_guc(log);
     62	struct intel_uc *uc = container_of(guc, struct intel_uc, guc);
     63
     64	if (!intel_guc_is_supported(guc))
     65		return PAGE_SIZE;
     66
     67	return obj_to_guc_log_dump_size(uc->load_err_log);
     68}
     69
     70static int guc_load_err_log_dump_show(struct seq_file *m, void *data)
     71{
     72	struct drm_printer p = drm_seq_file_printer(m);
     73
     74	if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && seq_has_overflowed(m))
     75		pr_warn_once("preallocated size:%zx for %s exceeded\n",
     76			     m->size, __func__);
     77
     78	return intel_guc_log_dump(m->private, &p, true);
     79}
     80DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE_WITH_SIZE(guc_load_err_log_dump, guc_load_err_dump_size);
     81
     82static int guc_log_level_get(void *data, u64 *val)
     83{
     84	struct intel_guc_log *log = data;
     85
     86	if (!log->vma)
     87		return -ENODEV;
     88
     89	*val = intel_guc_log_get_level(log);
     90
     91	return 0;
     92}
     93
     94static int guc_log_level_set(void *data, u64 val)
     95{
     96	struct intel_guc_log *log = data;
     97
     98	if (!log->vma)
     99		return -ENODEV;
    100
    101	return intel_guc_log_set_level(log, val);
    102}
    103
    104DEFINE_SIMPLE_ATTRIBUTE(guc_log_level_fops,
    105			guc_log_level_get, guc_log_level_set,
    106			"%lld\n");
    107
    108static int guc_log_relay_open(struct inode *inode, struct file *file)
    109{
    110	struct intel_guc_log *log = inode->i_private;
    111
    112	if (!intel_guc_is_ready(log_to_guc(log)))
    113		return -ENODEV;
    114
    115	file->private_data = log;
    116
    117	return intel_guc_log_relay_open(log);
    118}
    119
    120static ssize_t
    121guc_log_relay_write(struct file *filp,
    122		    const char __user *ubuf,
    123		    size_t cnt,
    124		    loff_t *ppos)
    125{
    126	struct intel_guc_log *log = filp->private_data;
    127	int val;
    128	int ret;
    129
    130	ret = kstrtoint_from_user(ubuf, cnt, 0, &val);
    131	if (ret < 0)
    132		return ret;
    133
    134	/*
    135	 * Enable and start the guc log relay on value of 1.
    136	 * Flush log relay for any other value.
    137	 */
    138	if (val == 1)
    139		ret = intel_guc_log_relay_start(log);
    140	else
    141		intel_guc_log_relay_flush(log);
    142
    143	return ret ?: cnt;
    144}
    145
    146static int guc_log_relay_release(struct inode *inode, struct file *file)
    147{
    148	struct intel_guc_log *log = inode->i_private;
    149
    150	intel_guc_log_relay_close(log);
    151	return 0;
    152}
    153
    154static const struct file_operations guc_log_relay_fops = {
    155	.owner = THIS_MODULE,
    156	.open = guc_log_relay_open,
    157	.write = guc_log_relay_write,
    158	.release = guc_log_relay_release,
    159};
    160
    161void intel_guc_log_debugfs_register(struct intel_guc_log *log,
    162				    struct dentry *root)
    163{
    164	static const struct intel_gt_debugfs_file files[] = {
    165		{ "guc_log_dump", &guc_log_dump_fops, NULL },
    166		{ "guc_load_err_log_dump", &guc_load_err_log_dump_fops, NULL },
    167		{ "guc_log_level", &guc_log_level_fops, NULL },
    168		{ "guc_log_relay", &guc_log_relay_fops, NULL },
    169	};
    170
    171	if (!intel_guc_is_supported(log_to_guc(log)))
    172		return;
    173
    174	intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log);
    175}