LCOV - code coverage report
Current view: top level - arch/x86/kernel - kdebugfs.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 4 4 100.0 %
Date: 2021-04-22 12:43:58 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * Architecture specific debugfs files
       4             :  *
       5             :  * Copyright (C) 2007, Intel Corp.
       6             :  *      Huang Ying <ying.huang@intel.com>
       7             :  */
       8             : #include <linux/debugfs.h>
       9             : #include <linux/uaccess.h>
      10             : #include <linux/export.h>
      11             : #include <linux/slab.h>
      12             : #include <linux/init.h>
      13             : #include <linux/stat.h>
      14             : #include <linux/io.h>
      15             : #include <linux/mm.h>
      16             : 
      17             : #include <asm/setup.h>
      18             : 
      19             : struct dentry *arch_debugfs_dir;
      20             : EXPORT_SYMBOL(arch_debugfs_dir);
      21             : 
      22             : #ifdef CONFIG_DEBUG_BOOT_PARAMS
      23             : struct setup_data_node {
      24             :         u64 paddr;
      25             :         u32 type;
      26             :         u32 len;
      27             : };
      28             : 
      29             : static ssize_t setup_data_read(struct file *file, char __user *user_buf,
      30             :                                size_t count, loff_t *ppos)
      31             : {
      32             :         struct setup_data_node *node = file->private_data;
      33             :         unsigned long remain;
      34             :         loff_t pos = *ppos;
      35             :         void *p;
      36             :         u64 pa;
      37             : 
      38             :         if (pos < 0)
      39             :                 return -EINVAL;
      40             : 
      41             :         if (pos >= node->len)
      42             :                 return 0;
      43             : 
      44             :         if (count > node->len - pos)
      45             :                 count = node->len - pos;
      46             : 
      47             :         pa = node->paddr + pos;
      48             : 
      49             :         /* Is it direct data or invalid indirect one? */
      50             :         if (!(node->type & SETUP_INDIRECT) || node->type == SETUP_INDIRECT)
      51             :                 pa += sizeof(struct setup_data);
      52             : 
      53             :         p = memremap(pa, count, MEMREMAP_WB);
      54             :         if (!p)
      55             :                 return -ENOMEM;
      56             : 
      57             :         remain = copy_to_user(user_buf, p, count);
      58             : 
      59             :         memunmap(p);
      60             : 
      61             :         if (remain)
      62             :                 return -EFAULT;
      63             : 
      64             :         *ppos = pos + count;
      65             : 
      66             :         return count;
      67             : }
      68             : 
      69             : static const struct file_operations fops_setup_data = {
      70             :         .read           = setup_data_read,
      71             :         .open           = simple_open,
      72             :         .llseek         = default_llseek,
      73             : };
      74             : 
      75             : static void __init
      76             : create_setup_data_node(struct dentry *parent, int no,
      77             :                        struct setup_data_node *node)
      78             : {
      79             :         struct dentry *d;
      80             :         char buf[16];
      81             : 
      82             :         sprintf(buf, "%d", no);
      83             :         d = debugfs_create_dir(buf, parent);
      84             : 
      85             :         debugfs_create_x32("type", S_IRUGO, d, &node->type);
      86             :         debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data);
      87             : }
      88             : 
      89             : static int __init create_setup_data_nodes(struct dentry *parent)
      90             : {
      91             :         struct setup_data_node *node;
      92             :         struct setup_data *data;
      93             :         int error;
      94             :         struct dentry *d;
      95             :         u64 pa_data;
      96             :         int no = 0;
      97             : 
      98             :         d = debugfs_create_dir("setup_data", parent);
      99             : 
     100             :         pa_data = boot_params.hdr.setup_data;
     101             : 
     102             :         while (pa_data) {
     103             :                 node = kmalloc(sizeof(*node), GFP_KERNEL);
     104             :                 if (!node) {
     105             :                         error = -ENOMEM;
     106             :                         goto err_dir;
     107             :                 }
     108             : 
     109             :                 data = memremap(pa_data, sizeof(*data), MEMREMAP_WB);
     110             :                 if (!data) {
     111             :                         kfree(node);
     112             :                         error = -ENOMEM;
     113             :                         goto err_dir;
     114             :                 }
     115             : 
     116             :                 if (data->type == SETUP_INDIRECT &&
     117             :                     ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
     118             :                         node->paddr = ((struct setup_indirect *)data->data)->addr;
     119             :                         node->type  = ((struct setup_indirect *)data->data)->type;
     120             :                         node->len   = ((struct setup_indirect *)data->data)->len;
     121             :                 } else {
     122             :                         node->paddr = pa_data;
     123             :                         node->type  = data->type;
     124             :                         node->len   = data->len;
     125             :                 }
     126             : 
     127             :                 create_setup_data_node(d, no, node);
     128             :                 pa_data = data->next;
     129             : 
     130             :                 memunmap(data);
     131             :                 no++;
     132             :         }
     133             : 
     134             :         return 0;
     135             : 
     136             : err_dir:
     137             :         debugfs_remove_recursive(d);
     138             :         return error;
     139             : }
     140             : 
     141             : static struct debugfs_blob_wrapper boot_params_blob = {
     142             :         .data           = &boot_params,
     143             :         .size           = sizeof(boot_params),
     144             : };
     145             : 
     146             : static int __init boot_params_kdebugfs_init(void)
     147             : {
     148             :         struct dentry *dbp;
     149             :         int error;
     150             : 
     151             :         dbp = debugfs_create_dir("boot_params", arch_debugfs_dir);
     152             : 
     153             :         debugfs_create_x16("version", S_IRUGO, dbp, &boot_params.hdr.version);
     154             :         debugfs_create_blob("data", S_IRUGO, dbp, &boot_params_blob);
     155             : 
     156             :         error = create_setup_data_nodes(dbp);
     157             :         if (error)
     158             :                 debugfs_remove_recursive(dbp);
     159             : 
     160             :         return error;
     161             : }
     162             : #endif /* CONFIG_DEBUG_BOOT_PARAMS */
     163             : 
     164           1 : static int __init arch_kdebugfs_init(void)
     165             : {
     166           1 :         int error = 0;
     167             : 
     168           1 :         arch_debugfs_dir = debugfs_create_dir("x86", NULL);
     169             : 
     170             : #ifdef CONFIG_DEBUG_BOOT_PARAMS
     171             :         error = boot_params_kdebugfs_init();
     172             : #endif
     173             : 
     174           1 :         return error;
     175             : }
     176             : arch_initcall(arch_kdebugfs_init);

Generated by: LCOV version 1.14