LCOV - code coverage report
Current view: top level - arch/x86/kernel - kdebugfs.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 24 76 31.6 %
Date: 2022-04-01 14:35:51 Functions: 3 5 60.0 %
Branches: 2 24 8.3 %

           Branch data     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                 :          0 : static ssize_t setup_data_read(struct file *file, char __user *user_buf,
      30                 :            :                                size_t count, loff_t *ppos)
      31                 :            : {
      32                 :          0 :         struct setup_data_node *node = file->private_data;
      33                 :          0 :         unsigned long remain;
      34                 :          0 :         loff_t pos = *ppos;
      35                 :          0 :         void *p;
      36                 :          0 :         u64 pa;
      37                 :            : 
      38         [ #  # ]:          0 :         if (pos < 0)
      39                 :            :                 return -EINVAL;
      40                 :            : 
      41         [ #  # ]:          0 :         if (pos >= node->len)
      42                 :            :                 return 0;
      43                 :            : 
      44                 :          0 :         if (count > node->len - pos)
      45                 :            :                 count = node->len - pos;
      46                 :            : 
      47                 :          0 :         pa = node->paddr + pos;
      48                 :            : 
      49                 :            :         /* Is it direct data or invalid indirect one? */
      50         [ #  # ]:          0 :         if (!(node->type & SETUP_INDIRECT) || node->type == SETUP_INDIRECT)
      51                 :          0 :                 pa += sizeof(struct setup_data);
      52                 :            : 
      53                 :          0 :         p = memremap(pa, count, MEMREMAP_WB);
      54         [ #  # ]:          0 :         if (!p)
      55                 :            :                 return -ENOMEM;
      56                 :            : 
      57         [ #  # ]:          0 :         remain = copy_to_user(user_buf, p, count);
      58                 :            : 
      59                 :          0 :         memunmap(p);
      60                 :            : 
      61         [ #  # ]:          0 :         if (remain)
      62                 :            :                 return -EFAULT;
      63                 :            : 
      64                 :          0 :         *ppos = pos + count;
      65                 :            : 
      66                 :          0 :         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                 :          0 : create_setup_data_node(struct dentry *parent, int no,
      77                 :            :                        struct setup_data_node *node)
      78                 :            : {
      79                 :          0 :         struct dentry *d;
      80                 :          0 :         char buf[16];
      81                 :            : 
      82                 :          0 :         sprintf(buf, "%d", no);
      83                 :          0 :         d = debugfs_create_dir(buf, parent);
      84                 :            : 
      85                 :          0 :         debugfs_create_x32("type", S_IRUGO, d, &node->type);
      86                 :          0 :         debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data);
      87                 :          0 : }
      88                 :            : 
      89                 :         21 : static int __init create_setup_data_nodes(struct dentry *parent)
      90                 :            : {
      91                 :         21 :         struct setup_data_node *node;
      92                 :         21 :         struct setup_data *data;
      93                 :         21 :         int error;
      94                 :         21 :         struct dentry *d;
      95                 :         21 :         u64 pa_data;
      96                 :         21 :         int no = 0;
      97                 :            : 
      98                 :         21 :         d = debugfs_create_dir("setup_data", parent);
      99                 :            : 
     100                 :         21 :         pa_data = boot_params.hdr.setup_data;
     101                 :            : 
     102         [ -  + ]:         21 :         while (pa_data) {
     103                 :          0 :                 node = kmalloc(sizeof(*node), GFP_KERNEL);
     104         [ #  # ]:          0 :                 if (!node) {
     105                 :          0 :                         error = -ENOMEM;
     106                 :          0 :                         goto err_dir;
     107                 :            :                 }
     108                 :            : 
     109                 :          0 :                 data = memremap(pa_data, sizeof(*data), MEMREMAP_WB);
     110         [ #  # ]:          0 :                 if (!data) {
     111                 :          0 :                         kfree(node);
     112                 :          0 :                         error = -ENOMEM;
     113                 :          0 :                         goto err_dir;
     114                 :            :                 }
     115                 :            : 
     116         [ #  # ]:          0 :                 if (data->type == SETUP_INDIRECT &&
     117         [ #  # ]:          0 :                     ((struct setup_indirect *)data->data)->type != SETUP_INDIRECT) {
     118                 :          0 :                         node->paddr = ((struct setup_indirect *)data->data)->addr;
     119                 :          0 :                         node->type  = ((struct setup_indirect *)data->data)->type;
     120                 :          0 :                         node->len   = ((struct setup_indirect *)data->data)->len;
     121                 :            :                 } else {
     122                 :          0 :                         node->paddr = pa_data;
     123                 :          0 :                         node->type  = data->type;
     124                 :          0 :                         node->len   = data->len;
     125                 :            :                 }
     126                 :            : 
     127                 :          0 :                 create_setup_data_node(d, no, node);
     128                 :          0 :                 pa_data = data->next;
     129                 :            : 
     130                 :          0 :                 memunmap(data);
     131                 :          0 :                 no++;
     132                 :            :         }
     133                 :            : 
     134                 :            :         return 0;
     135                 :            : 
     136                 :          0 : err_dir:
     137                 :          0 :         debugfs_remove_recursive(d);
     138                 :          0 :         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                 :         21 : static int __init boot_params_kdebugfs_init(void)
     147                 :            : {
     148                 :         21 :         struct dentry *dbp;
     149                 :         21 :         int error;
     150                 :            : 
     151                 :         21 :         dbp = debugfs_create_dir("boot_params", arch_debugfs_dir);
     152                 :            : 
     153                 :         21 :         debugfs_create_x16("version", S_IRUGO, dbp, &boot_params.hdr.version);
     154                 :         21 :         debugfs_create_blob("data", S_IRUGO, dbp, &boot_params_blob);
     155                 :            : 
     156                 :         21 :         error = create_setup_data_nodes(dbp);
     157         [ -  + ]:         21 :         if (error)
     158                 :          0 :                 debugfs_remove_recursive(dbp);
     159                 :            : 
     160                 :         21 :         return error;
     161                 :            : }
     162                 :            : #endif /* CONFIG_DEBUG_BOOT_PARAMS */
     163                 :            : 
     164                 :         21 : static int __init arch_kdebugfs_init(void)
     165                 :            : {
     166                 :         21 :         int error = 0;
     167                 :            : 
     168                 :         21 :         arch_debugfs_dir = debugfs_create_dir("x86", NULL);
     169                 :            : 
     170                 :            : #ifdef CONFIG_DEBUG_BOOT_PARAMS
     171                 :         21 :         error = boot_params_kdebugfs_init();
     172                 :            : #endif
     173                 :            : 
     174                 :         21 :         return error;
     175                 :            : }
     176                 :            : arch_initcall(arch_kdebugfs_init);

Generated by: LCOV version 1.14