Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/init.h>
  3#include <linux/seq_file.h>
  4#include <linux/fs.h>
  5#include <linux/mm.h>
  6#include <linux/proc_fs.h>
  7#include <linux/slab.h>
  8#include <xen/interface/platform.h>
  9#include <asm/xen/hypercall.h>
 10#include <xen/xen-ops.h>
 11#include "xenfs.h"
 12
 13
 14#define XEN_KSYM_NAME_LEN 127 /* Hypervisor may have different name length */
 15
 16struct xensyms {
 17	struct xen_platform_op op;
 18	char *name;
 19	uint32_t namelen;
 20};
 21
 22/* Grab next output page from the hypervisor */
 23static int xensyms_next_sym(struct xensyms *xs)
 24{
 25	int ret;
 26	struct xenpf_symdata *symdata = &xs->op.u.symdata;
 27	uint64_t symnum;
 28
 29	memset(xs->name, 0, xs->namelen);
 30	symdata->namelen = xs->namelen;
 31
 32	symnum = symdata->symnum;
 33
 34	ret = HYPERVISOR_platform_op(&xs->op);
 35	if (ret < 0)
 36		return ret;
 37
 38	/*
 39	 * If hypervisor's symbol didn't fit into the buffer then allocate
 40	 * a larger buffer and try again.
 41	 */
 42	if (unlikely(symdata->namelen > xs->namelen)) {
 43		kfree(xs->name);
 44
 45		xs->namelen = symdata->namelen;
 46		xs->name = kzalloc(xs->namelen, GFP_KERNEL);
 47		if (!xs->name)
 48			return -ENOMEM;
 49
 50		set_xen_guest_handle(symdata->name, xs->name);
 51		symdata->symnum--; /* Rewind */
 52
 53		ret = HYPERVISOR_platform_op(&xs->op);
 54		if (ret < 0)
 55			return ret;
 56	}
 57
 58	if (symdata->symnum == symnum)
 59		/* End of symbols */
 60		return 1;
 61
 62	return 0;
 63}
 64
 65static void *xensyms_start(struct seq_file *m, loff_t *pos)
 66{
 67	struct xensyms *xs = m->private;
 68
 69	xs->op.u.symdata.symnum = *pos;
 70
 71	if (xensyms_next_sym(xs))
 72		return NULL;
 73
 74	return m->private;
 75}
 76
 77static void *xensyms_next(struct seq_file *m, void *p, loff_t *pos)
 78{
 79	struct xensyms *xs = m->private;
 80
 81	xs->op.u.symdata.symnum = ++(*pos);
 82
 83	if (xensyms_next_sym(xs))
 84		return NULL;
 85
 86	return p;
 87}
 88
 89static int xensyms_show(struct seq_file *m, void *p)
 90{
 91	struct xensyms *xs = m->private;
 92	struct xenpf_symdata *symdata = &xs->op.u.symdata;
 93
 94	seq_printf(m, "%016llx %c %s\n", symdata->address,
 95		   symdata->type, xs->name);
 96
 97	return 0;
 98}
 99
100static void xensyms_stop(struct seq_file *m, void *p)
101{
102}
103
104static const struct seq_operations xensyms_seq_ops = {
105	.start = xensyms_start,
106	.next = xensyms_next,
107	.show = xensyms_show,
108	.stop = xensyms_stop,
109};
110
111static int xensyms_open(struct inode *inode, struct file *file)
112{
113	struct seq_file *m;
114	struct xensyms *xs;
115	int ret;
116
117	ret = seq_open_private(file, &xensyms_seq_ops,
118			       sizeof(struct xensyms));
119	if (ret)
120		return ret;
121
122	m = file->private_data;
123	xs = m->private;
124
125	xs->namelen = XEN_KSYM_NAME_LEN + 1;
126	xs->name = kzalloc(xs->namelen, GFP_KERNEL);
127	if (!xs->name) {
128		seq_release_private(inode, file);
129		return -ENOMEM;
130	}
131	set_xen_guest_handle(xs->op.u.symdata.name, xs->name);
132	xs->op.cmd = XENPF_get_symbol;
133	xs->op.u.symdata.namelen = xs->namelen;
134
135	return 0;
136}
137
138static int xensyms_release(struct inode *inode, struct file *file)
139{
140	struct seq_file *m = file->private_data;
141	struct xensyms *xs = m->private;
142
143	kfree(xs->name);
144	return seq_release_private(inode, file);
145}
146
147const struct file_operations xensyms_ops = {
148	.open = xensyms_open,
149	.read = seq_read,
150	.llseek = seq_lseek,
151	.release = xensyms_release
152};
v4.10.11
 
  1#include <linux/init.h>
  2#include <linux/seq_file.h>
  3#include <linux/fs.h>
  4#include <linux/mm.h>
  5#include <linux/proc_fs.h>
  6#include <linux/slab.h>
  7#include <xen/interface/platform.h>
  8#include <asm/xen/hypercall.h>
  9#include <xen/xen-ops.h>
 10#include "xenfs.h"
 11
 12
 13#define XEN_KSYM_NAME_LEN 127 /* Hypervisor may have different name length */
 14
 15struct xensyms {
 16	struct xen_platform_op op;
 17	char *name;
 18	uint32_t namelen;
 19};
 20
 21/* Grab next output page from the hypervisor */
 22static int xensyms_next_sym(struct xensyms *xs)
 23{
 24	int ret;
 25	struct xenpf_symdata *symdata = &xs->op.u.symdata;
 26	uint64_t symnum;
 27
 28	memset(xs->name, 0, xs->namelen);
 29	symdata->namelen = xs->namelen;
 30
 31	symnum = symdata->symnum;
 32
 33	ret = HYPERVISOR_platform_op(&xs->op);
 34	if (ret < 0)
 35		return ret;
 36
 37	/*
 38	 * If hypervisor's symbol didn't fit into the buffer then allocate
 39	 * a larger buffer and try again.
 40	 */
 41	if (unlikely(symdata->namelen > xs->namelen)) {
 42		kfree(xs->name);
 43
 44		xs->namelen = symdata->namelen;
 45		xs->name = kzalloc(xs->namelen, GFP_KERNEL);
 46		if (!xs->name)
 47			return -ENOMEM;
 48
 49		set_xen_guest_handle(symdata->name, xs->name);
 50		symdata->symnum--; /* Rewind */
 51
 52		ret = HYPERVISOR_platform_op(&xs->op);
 53		if (ret < 0)
 54			return ret;
 55	}
 56
 57	if (symdata->symnum == symnum)
 58		/* End of symbols */
 59		return 1;
 60
 61	return 0;
 62}
 63
 64static void *xensyms_start(struct seq_file *m, loff_t *pos)
 65{
 66	struct xensyms *xs = (struct xensyms *)m->private;
 67
 68	xs->op.u.symdata.symnum = *pos;
 69
 70	if (xensyms_next_sym(xs))
 71		return NULL;
 72
 73	return m->private;
 74}
 75
 76static void *xensyms_next(struct seq_file *m, void *p, loff_t *pos)
 77{
 78	struct xensyms *xs = (struct xensyms *)m->private;
 79
 80	xs->op.u.symdata.symnum = ++(*pos);
 81
 82	if (xensyms_next_sym(xs))
 83		return NULL;
 84
 85	return p;
 86}
 87
 88static int xensyms_show(struct seq_file *m, void *p)
 89{
 90	struct xensyms *xs = (struct xensyms *)m->private;
 91	struct xenpf_symdata *symdata = &xs->op.u.symdata;
 92
 93	seq_printf(m, "%016llx %c %s\n", symdata->address,
 94		   symdata->type, xs->name);
 95
 96	return 0;
 97}
 98
 99static void xensyms_stop(struct seq_file *m, void *p)
100{
101}
102
103static const struct seq_operations xensyms_seq_ops = {
104	.start = xensyms_start,
105	.next = xensyms_next,
106	.show = xensyms_show,
107	.stop = xensyms_stop,
108};
109
110static int xensyms_open(struct inode *inode, struct file *file)
111{
112	struct seq_file *m;
113	struct xensyms *xs;
114	int ret;
115
116	ret = seq_open_private(file, &xensyms_seq_ops,
117			       sizeof(struct xensyms));
118	if (ret)
119		return ret;
120
121	m = file->private_data;
122	xs = (struct xensyms *)m->private;
123
124	xs->namelen = XEN_KSYM_NAME_LEN + 1;
125	xs->name = kzalloc(xs->namelen, GFP_KERNEL);
126	if (!xs->name) {
127		seq_release_private(inode, file);
128		return -ENOMEM;
129	}
130	set_xen_guest_handle(xs->op.u.symdata.name, xs->name);
131	xs->op.cmd = XENPF_get_symbol;
132	xs->op.u.symdata.namelen = xs->namelen;
133
134	return 0;
135}
136
137static int xensyms_release(struct inode *inode, struct file *file)
138{
139	struct seq_file *m = file->private_data;
140	struct xensyms *xs = (struct xensyms *)m->private;
141
142	kfree(xs->name);
143	return seq_release_private(inode, file);
144}
145
146const struct file_operations xensyms_ops = {
147	.open = xensyms_open,
148	.read = seq_read,
149	.llseek = seq_lseek,
150	.release = xensyms_release
151};