x86_64 boot -v2: export linked list of struct setup_data via debugfs
PATCH 3/4 x86_64 boot -v2: export linked list of struct setup_data via debugfs
Export linked list of struct setup_data via debugfs.
Signed-off-by Huang Ying <[email protected]>
--- arch/x86/kernel/kdebugfs.c | 139 +++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup_64.c | 2 2 files changed, 141 insertions(+)
arch/x86/kernel/kdebugfs.c +139 -0
@@ -10,10 +10,144 @@#include <linux/debugfs.h> #include <linux/stat.h> #include <linux/init.h> +#include <linux/io.h> +#include <linux/mm.h> +#include <linux/uaccess.h> #include <asm/setup.h> #ifdef CONFIG_DEBUG_BOOT_PARAMS +struct setup_data_node { +u64 paddr; +u32 type; +u32 len; +}; + +static ssize_t setup_data_read (struct file *file,char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct setup_data_node *node = file->private_data; +loff_t pos = *ppos; +unsigned long remain; +struct page *pg; +void *p; +u64 pa; + +if (pos <0 ) +return -EINVAL ; +if (pos >= node->len) +return 0 ; +if (count > node->len - pos) + count = node->len - pos; + pa = node->paddr +sizeof (struct setup_data ) + pos; + pg =pfn_to_page ((pa + count -1 ) >>PAGE_SHIFT ); +if (PageHighMem (pg)) { + p =ioremap_cache (pa, count); +if (!p) +return -ENXIO ; + }else + p =__va (pa); + remain =copy_to_user (user_buf, p, count); +if (PageHighMem (pg)) +iounmap (p); +if (remain) +return -EFAULT ; + *ppos = pos + count; +return count; +} + +static int setup_data_open (struct inode *inode,struct file *file) +{ + file->private_data = inode->i_private; +return 0 ; +} + +static const struct file_operations fops_setup_data = { + .read = setup_data_read, + .open = setup_data_open, +}; + +static int __init create_setup_data_node (struct dentry *parent, +int no, +struct setup_data_node *node) +{ +int error; +struct dentry *d, *type, *data; +char buf[16 ]; + +sprintf (buf,"%d" , no); + d =debugfs_create_dir (buf, parent); +if (!d) { + error = -ENOMEM ; + goto err_return; + } + type =debugfs_create_x32 ("type" ,S_IRUGO , d, &node->type); +if (!type) { + error = -ENOMEM ; + goto err_dir; + } + data =debugfs_create_file ("data" ,S_IRUGO , d, node, &fops_setup_data); +if (!data) { + error = -ENOMEM ; + goto err_type; + } +return 0 ; +err_type: +debugfs_remove (type); +err_dir: +debugfs_remove (d); +err_return: +return error; +} + +static int __init create_setup_data_nodes (struct dentry *parent) +{ +int error, no =0 ; +struct dentry *d; +struct setup_data *data; +u64 pa_data; +struct page *pg; +struct setup_data_node *node; + + d =debugfs_create_dir ("setup_data" , parent); +if (!d) { + error = -ENOMEM ; + goto err_return; + } + pa_data = boot_params.hdr.setup_data; +while (pa_data) { + node =kmalloc (sizeof (*node),GFP_KERNEL ); +if (!node) { + error = -ENOMEM ; + goto err_dir; + } + pg =pfn_to_page ((pa_data+sizeof (*data)-1 ) >>PAGE_SHIFT ); +if (PageHighMem (pg)) { + data =ioremap_cache (pa_data,sizeof (*data)); +if (!data) { + error = -ENXIO ; + goto err_dir; + } + }else + data =__va (pa_data); + node->paddr = pa_data; + node->type = data->type; + node->len = data->len; + error =create_setup_data_node (d, no, node); + pa_data = data->next; +if (PageHighMem (pg)) +iounmap (data); +if (error) + goto err_dir; + no++; + } +return 0 ; +err_dir: +debugfs_remove (d); +err_return: +return error; +} +static struct debugfs_blob_wrapper boot_params_blob = { .data = &boot_params, .size = sizeof(boot_params),
@@ -41,7 +175,12 @@ static int __init boot_params_kdebugfs_i error = -ENOMEM ; goto err_version; } + error =create_setup_data_nodes (dbp); +if (error) + goto err_data;return 0 ; +err_data: +debugfs_remove (data); err_version:debugfs_remove (version); err_dir:
arch/x86/kernel/setup_64.c +2 -0
@@ -279,7 +279,9 @@ static void __init parse_setup_data(voiddefault :break ; } +#ifndef CONFIG_DEBUG_BOOT_PARAMS free_early (pa_data, pa_data+sizeof (*data)+data->len); +#endif pa_data = data->next;early_iounmap (data,PAGE_SIZE ); }