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

msm_debugfs.c (6855B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2013-2016 Red Hat
      4 * Author: Rob Clark <robdclark@gmail.com>
      5 */
      6
      7#ifdef CONFIG_DEBUG_FS
      8
      9#include <linux/debugfs.h>
     10
     11#include <drm/drm_debugfs.h>
     12#include <drm/drm_file.h>
     13
     14#include "msm_drv.h"
     15#include "msm_gpu.h"
     16#include "msm_kms.h"
     17#include "msm_debugfs.h"
     18#include "disp/msm_disp_snapshot.h"
     19
     20/*
     21 * GPU Snapshot:
     22 */
     23
     24struct msm_gpu_show_priv {
     25	struct msm_gpu_state *state;
     26	struct drm_device *dev;
     27};
     28
     29static int msm_gpu_show(struct seq_file *m, void *arg)
     30{
     31	struct drm_printer p = drm_seq_file_printer(m);
     32	struct msm_gpu_show_priv *show_priv = m->private;
     33	struct msm_drm_private *priv = show_priv->dev->dev_private;
     34	struct msm_gpu *gpu = priv->gpu;
     35	int ret;
     36
     37	ret = mutex_lock_interruptible(&gpu->lock);
     38	if (ret)
     39		return ret;
     40
     41	drm_printf(&p, "%s Status:\n", gpu->name);
     42	gpu->funcs->show(gpu, show_priv->state, &p);
     43
     44	mutex_unlock(&gpu->lock);
     45
     46	return 0;
     47}
     48
     49static int msm_gpu_release(struct inode *inode, struct file *file)
     50{
     51	struct seq_file *m = file->private_data;
     52	struct msm_gpu_show_priv *show_priv = m->private;
     53	struct msm_drm_private *priv = show_priv->dev->dev_private;
     54	struct msm_gpu *gpu = priv->gpu;
     55
     56	mutex_lock(&gpu->lock);
     57	gpu->funcs->gpu_state_put(show_priv->state);
     58	mutex_unlock(&gpu->lock);
     59
     60	kfree(show_priv);
     61
     62	return single_release(inode, file);
     63}
     64
     65static int msm_gpu_open(struct inode *inode, struct file *file)
     66{
     67	struct drm_device *dev = inode->i_private;
     68	struct msm_drm_private *priv = dev->dev_private;
     69	struct msm_gpu *gpu = priv->gpu;
     70	struct msm_gpu_show_priv *show_priv;
     71	int ret;
     72
     73	if (!gpu || !gpu->funcs->gpu_state_get)
     74		return -ENODEV;
     75
     76	show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL);
     77	if (!show_priv)
     78		return -ENOMEM;
     79
     80	ret = mutex_lock_interruptible(&gpu->lock);
     81	if (ret)
     82		goto free_priv;
     83
     84	pm_runtime_get_sync(&gpu->pdev->dev);
     85	msm_gpu_hw_init(gpu);
     86	show_priv->state = gpu->funcs->gpu_state_get(gpu);
     87	pm_runtime_put_sync(&gpu->pdev->dev);
     88
     89	mutex_unlock(&gpu->lock);
     90
     91	if (IS_ERR(show_priv->state)) {
     92		ret = PTR_ERR(show_priv->state);
     93		goto free_priv;
     94	}
     95
     96	show_priv->dev = dev;
     97
     98	ret = single_open(file, msm_gpu_show, show_priv);
     99	if (ret)
    100		goto free_priv;
    101
    102	return 0;
    103
    104free_priv:
    105	kfree(show_priv);
    106	return ret;
    107}
    108
    109static const struct file_operations msm_gpu_fops = {
    110	.owner = THIS_MODULE,
    111	.open = msm_gpu_open,
    112	.read = seq_read,
    113	.llseek = seq_lseek,
    114	.release = msm_gpu_release,
    115};
    116
    117/*
    118 * Display Snapshot:
    119 */
    120
    121static int msm_kms_show(struct seq_file *m, void *arg)
    122{
    123	struct drm_printer p = drm_seq_file_printer(m);
    124	struct msm_disp_state *state = m->private;
    125
    126	msm_disp_state_print(state, &p);
    127
    128	return 0;
    129}
    130
    131static int msm_kms_release(struct inode *inode, struct file *file)
    132{
    133	struct seq_file *m = file->private_data;
    134	struct msm_disp_state *state = m->private;
    135
    136	msm_disp_state_free(state);
    137
    138	return single_release(inode, file);
    139}
    140
    141static int msm_kms_open(struct inode *inode, struct file *file)
    142{
    143	struct drm_device *dev = inode->i_private;
    144	struct msm_drm_private *priv = dev->dev_private;
    145	struct msm_disp_state *state;
    146	int ret;
    147
    148	if (!priv->kms)
    149		return -ENODEV;
    150
    151	ret = mutex_lock_interruptible(&priv->kms->dump_mutex);
    152	if (ret)
    153		return ret;
    154
    155	state = msm_disp_snapshot_state_sync(priv->kms);
    156
    157	mutex_unlock(&priv->kms->dump_mutex);
    158
    159	if (IS_ERR(state)) {
    160		return PTR_ERR(state);
    161	}
    162
    163	ret = single_open(file, msm_kms_show, state);
    164	if (ret) {
    165		msm_disp_state_free(state);
    166		return ret;
    167	}
    168
    169	return 0;
    170}
    171
    172static const struct file_operations msm_kms_fops = {
    173	.owner = THIS_MODULE,
    174	.open = msm_kms_open,
    175	.read = seq_read,
    176	.llseek = seq_lseek,
    177	.release = msm_kms_release,
    178};
    179
    180/*
    181 * Other debugfs:
    182 */
    183
    184static unsigned long last_shrink_freed;
    185
    186static int
    187shrink_get(void *data, u64 *val)
    188{
    189	*val = last_shrink_freed;
    190
    191	return 0;
    192}
    193
    194static int
    195shrink_set(void *data, u64 val)
    196{
    197	struct drm_device *dev = data;
    198
    199	last_shrink_freed = msm_gem_shrinker_shrink(dev, val);
    200
    201	return 0;
    202}
    203
    204DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops,
    205			 shrink_get, shrink_set,
    206			 "0x%08llx\n");
    207
    208
    209static int msm_gem_show(struct seq_file *m, void *arg)
    210{
    211	struct drm_info_node *node = (struct drm_info_node *) m->private;
    212	struct drm_device *dev = node->minor->dev;
    213	struct msm_drm_private *priv = dev->dev_private;
    214	int ret;
    215
    216	ret = mutex_lock_interruptible(&priv->obj_lock);
    217	if (ret)
    218		return ret;
    219
    220	msm_gem_describe_objects(&priv->objects, m);
    221
    222	mutex_unlock(&priv->obj_lock);
    223
    224	return 0;
    225}
    226
    227static int msm_mm_show(struct seq_file *m, void *arg)
    228{
    229	struct drm_info_node *node = (struct drm_info_node *) m->private;
    230	struct drm_device *dev = node->minor->dev;
    231	struct drm_printer p = drm_seq_file_printer(m);
    232
    233	drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p);
    234
    235	return 0;
    236}
    237
    238static int msm_fb_show(struct seq_file *m, void *arg)
    239{
    240	struct drm_info_node *node = (struct drm_info_node *) m->private;
    241	struct drm_device *dev = node->minor->dev;
    242	struct msm_drm_private *priv = dev->dev_private;
    243	struct drm_framebuffer *fb, *fbdev_fb = NULL;
    244
    245	if (priv->fbdev) {
    246		seq_printf(m, "fbcon ");
    247		fbdev_fb = priv->fbdev->fb;
    248		msm_framebuffer_describe(fbdev_fb, m);
    249	}
    250
    251	mutex_lock(&dev->mode_config.fb_lock);
    252	list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
    253		if (fb == fbdev_fb)
    254			continue;
    255
    256		seq_printf(m, "user ");
    257		msm_framebuffer_describe(fb, m);
    258	}
    259	mutex_unlock(&dev->mode_config.fb_lock);
    260
    261	return 0;
    262}
    263
    264static struct drm_info_list msm_debugfs_list[] = {
    265		{"gem", msm_gem_show},
    266		{ "mm", msm_mm_show },
    267		{ "fb", msm_fb_show },
    268};
    269
    270static int late_init_minor(struct drm_minor *minor)
    271{
    272	int ret;
    273
    274	if (!minor)
    275		return 0;
    276
    277	ret = msm_rd_debugfs_init(minor);
    278	if (ret) {
    279		DRM_DEV_ERROR(minor->dev->dev, "could not install rd debugfs\n");
    280		return ret;
    281	}
    282
    283	ret = msm_perf_debugfs_init(minor);
    284	if (ret) {
    285		DRM_DEV_ERROR(minor->dev->dev, "could not install perf debugfs\n");
    286		return ret;
    287	}
    288
    289	return 0;
    290}
    291
    292int msm_debugfs_late_init(struct drm_device *dev)
    293{
    294	int ret;
    295	ret = late_init_minor(dev->primary);
    296	if (ret)
    297		return ret;
    298	ret = late_init_minor(dev->render);
    299	return ret;
    300}
    301
    302void msm_debugfs_init(struct drm_minor *minor)
    303{
    304	struct drm_device *dev = minor->dev;
    305	struct msm_drm_private *priv = dev->dev_private;
    306
    307	drm_debugfs_create_files(msm_debugfs_list,
    308				 ARRAY_SIZE(msm_debugfs_list),
    309				 minor->debugfs_root, minor);
    310
    311	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
    312		dev, &msm_gpu_fops);
    313
    314	debugfs_create_file("kms", S_IRUSR, minor->debugfs_root,
    315		dev, &msm_kms_fops);
    316
    317	debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root,
    318		&priv->hangcheck_period);
    319
    320	debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root,
    321		&priv->disable_err_irq);
    322
    323	debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root,
    324		dev, &shrink_fops);
    325
    326	if (priv->kms && priv->kms->funcs->debugfs_init)
    327		priv->kms->funcs->debugfs_init(priv->kms, minor);
    328}
    329#endif
    330