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

core.c (8606B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2008  by Karsten Keil <kkeil@novell.com>
      4 */
      5
      6#include <linux/slab.h>
      7#include <linux/types.h>
      8#include <linux/stddef.h>
      9#include <linux/module.h>
     10#include <linux/spinlock.h>
     11#include <linux/mISDNif.h>
     12#include "core.h"
     13
     14static u_int debug;
     15
     16MODULE_AUTHOR("Karsten Keil");
     17MODULE_LICENSE("GPL");
     18module_param(debug, uint, S_IRUGO | S_IWUSR);
     19
     20static u64		device_ids;
     21#define MAX_DEVICE_ID	63
     22
     23static LIST_HEAD(Bprotocols);
     24static DEFINE_RWLOCK(bp_lock);
     25
     26static void mISDN_dev_release(struct device *dev)
     27{
     28	/* nothing to do: the device is part of its parent's data structure */
     29}
     30
     31static ssize_t id_show(struct device *dev,
     32		       struct device_attribute *attr, char *buf)
     33{
     34	struct mISDNdevice *mdev = dev_to_mISDN(dev);
     35
     36	if (!mdev)
     37		return -ENODEV;
     38	return sprintf(buf, "%d\n", mdev->id);
     39}
     40static DEVICE_ATTR_RO(id);
     41
     42static ssize_t nrbchan_show(struct device *dev,
     43			    struct device_attribute *attr, char *buf)
     44{
     45	struct mISDNdevice *mdev = dev_to_mISDN(dev);
     46
     47	if (!mdev)
     48		return -ENODEV;
     49	return sprintf(buf, "%d\n", mdev->nrbchan);
     50}
     51static DEVICE_ATTR_RO(nrbchan);
     52
     53static ssize_t d_protocols_show(struct device *dev,
     54				struct device_attribute *attr, char *buf)
     55{
     56	struct mISDNdevice *mdev = dev_to_mISDN(dev);
     57
     58	if (!mdev)
     59		return -ENODEV;
     60	return sprintf(buf, "%d\n", mdev->Dprotocols);
     61}
     62static DEVICE_ATTR_RO(d_protocols);
     63
     64static ssize_t b_protocols_show(struct device *dev,
     65				struct device_attribute *attr, char *buf)
     66{
     67	struct mISDNdevice *mdev = dev_to_mISDN(dev);
     68
     69	if (!mdev)
     70		return -ENODEV;
     71	return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols());
     72}
     73static DEVICE_ATTR_RO(b_protocols);
     74
     75static ssize_t protocol_show(struct device *dev,
     76			     struct device_attribute *attr, char *buf)
     77{
     78	struct mISDNdevice *mdev = dev_to_mISDN(dev);
     79
     80	if (!mdev)
     81		return -ENODEV;
     82	return sprintf(buf, "%d\n", mdev->D.protocol);
     83}
     84static DEVICE_ATTR_RO(protocol);
     85
     86static ssize_t name_show(struct device *dev,
     87			 struct device_attribute *attr, char *buf)
     88{
     89	strcpy(buf, dev_name(dev));
     90	return strlen(buf);
     91}
     92static DEVICE_ATTR_RO(name);
     93
     94#if 0 /* hangs */
     95static ssize_t name_set(struct device *dev, struct device_attribute *attr,
     96			const char *buf, size_t count)
     97{
     98	int err = 0;
     99	char *out = kmalloc(count + 1, GFP_KERNEL);
    100
    101	if (!out)
    102		return -ENOMEM;
    103
    104	memcpy(out, buf, count);
    105	if (count && out[count - 1] == '\n')
    106		out[--count] = 0;
    107	if (count)
    108		err = device_rename(dev, out);
    109	kfree(out);
    110
    111	return (err < 0) ? err : count;
    112}
    113static DEVICE_ATTR_RW(name);
    114#endif
    115
    116static ssize_t channelmap_show(struct device *dev,
    117			       struct device_attribute *attr, char *buf)
    118{
    119	struct mISDNdevice *mdev = dev_to_mISDN(dev);
    120	char *bp = buf;
    121	int i;
    122
    123	for (i = 0; i <= mdev->nrbchan; i++)
    124		*bp++ = test_channelmap(i, mdev->channelmap) ? '1' : '0';
    125
    126	return bp - buf;
    127}
    128static DEVICE_ATTR_RO(channelmap);
    129
    130static struct attribute *mISDN_attrs[] = {
    131	&dev_attr_id.attr,
    132	&dev_attr_d_protocols.attr,
    133	&dev_attr_b_protocols.attr,
    134	&dev_attr_protocol.attr,
    135	&dev_attr_channelmap.attr,
    136	&dev_attr_nrbchan.attr,
    137	&dev_attr_name.attr,
    138	NULL,
    139};
    140ATTRIBUTE_GROUPS(mISDN);
    141
    142static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env)
    143{
    144	struct mISDNdevice *mdev = dev_to_mISDN(dev);
    145
    146	if (!mdev)
    147		return 0;
    148
    149	if (add_uevent_var(env, "nchans=%d", mdev->nrbchan))
    150		return -ENOMEM;
    151
    152	return 0;
    153}
    154
    155static void mISDN_class_release(struct class *cls)
    156{
    157	/* do nothing, it's static */
    158}
    159
    160static struct class mISDN_class = {
    161	.name = "mISDN",
    162	.owner = THIS_MODULE,
    163	.dev_uevent = mISDN_uevent,
    164	.dev_groups = mISDN_groups,
    165	.dev_release = mISDN_dev_release,
    166	.class_release = mISDN_class_release,
    167};
    168
    169static int
    170_get_mdevice(struct device *dev, const void *id)
    171{
    172	struct mISDNdevice *mdev = dev_to_mISDN(dev);
    173
    174	if (!mdev)
    175		return 0;
    176	if (mdev->id != *(const u_int *)id)
    177		return 0;
    178	return 1;
    179}
    180
    181struct mISDNdevice
    182*get_mdevice(u_int id)
    183{
    184	return dev_to_mISDN(class_find_device(&mISDN_class, NULL, &id,
    185					      _get_mdevice));
    186}
    187
    188static int
    189_get_mdevice_count(struct device *dev, void *cnt)
    190{
    191	*(int *)cnt += 1;
    192	return 0;
    193}
    194
    195int
    196get_mdevice_count(void)
    197{
    198	int cnt = 0;
    199
    200	class_for_each_device(&mISDN_class, NULL, &cnt, _get_mdevice_count);
    201	return cnt;
    202}
    203
    204static int
    205get_free_devid(void)
    206{
    207	u_int	i;
    208
    209	for (i = 0; i <= MAX_DEVICE_ID; i++)
    210		if (!test_and_set_bit(i, (u_long *)&device_ids))
    211			break;
    212	if (i > MAX_DEVICE_ID)
    213		return -EBUSY;
    214	return i;
    215}
    216
    217int
    218mISDN_register_device(struct mISDNdevice *dev,
    219		      struct device *parent, char *name)
    220{
    221	int	err;
    222
    223	err = get_free_devid();
    224	if (err < 0)
    225		goto error1;
    226	dev->id = err;
    227
    228	device_initialize(&dev->dev);
    229	if (name && name[0])
    230		dev_set_name(&dev->dev, "%s", name);
    231	else
    232		dev_set_name(&dev->dev, "mISDN%d", dev->id);
    233	if (debug & DEBUG_CORE)
    234		printk(KERN_DEBUG "mISDN_register %s %d\n",
    235		       dev_name(&dev->dev), dev->id);
    236	err = create_stack(dev);
    237	if (err)
    238		goto error1;
    239
    240	dev->dev.class = &mISDN_class;
    241	dev->dev.platform_data = dev;
    242	dev->dev.parent = parent;
    243	dev_set_drvdata(&dev->dev, dev);
    244
    245	err = device_add(&dev->dev);
    246	if (err)
    247		goto error3;
    248	return 0;
    249
    250error3:
    251	delete_stack(dev);
    252	return err;
    253error1:
    254	return err;
    255
    256}
    257EXPORT_SYMBOL(mISDN_register_device);
    258
    259void
    260mISDN_unregister_device(struct mISDNdevice *dev) {
    261	if (debug & DEBUG_CORE)
    262		printk(KERN_DEBUG "mISDN_unregister %s %d\n",
    263		       dev_name(&dev->dev), dev->id);
    264	/* sysfs_remove_link(&dev->dev.kobj, "device"); */
    265	device_del(&dev->dev);
    266	dev_set_drvdata(&dev->dev, NULL);
    267
    268	test_and_clear_bit(dev->id, (u_long *)&device_ids);
    269	delete_stack(dev);
    270	put_device(&dev->dev);
    271}
    272EXPORT_SYMBOL(mISDN_unregister_device);
    273
    274u_int
    275get_all_Bprotocols(void)
    276{
    277	struct Bprotocol	*bp;
    278	u_int	m = 0;
    279
    280	read_lock(&bp_lock);
    281	list_for_each_entry(bp, &Bprotocols, list)
    282		m |= bp->Bprotocols;
    283	read_unlock(&bp_lock);
    284	return m;
    285}
    286
    287struct Bprotocol *
    288get_Bprotocol4mask(u_int m)
    289{
    290	struct Bprotocol	*bp;
    291
    292	read_lock(&bp_lock);
    293	list_for_each_entry(bp, &Bprotocols, list)
    294		if (bp->Bprotocols & m) {
    295			read_unlock(&bp_lock);
    296			return bp;
    297		}
    298	read_unlock(&bp_lock);
    299	return NULL;
    300}
    301
    302struct Bprotocol *
    303get_Bprotocol4id(u_int id)
    304{
    305	u_int	m;
    306
    307	if (id < ISDN_P_B_START || id > 63) {
    308		printk(KERN_WARNING "%s id not in range  %d\n",
    309		       __func__, id);
    310		return NULL;
    311	}
    312	m = 1 << (id & ISDN_P_B_MASK);
    313	return get_Bprotocol4mask(m);
    314}
    315
    316int
    317mISDN_register_Bprotocol(struct Bprotocol *bp)
    318{
    319	u_long			flags;
    320	struct Bprotocol	*old;
    321
    322	if (debug & DEBUG_CORE)
    323		printk(KERN_DEBUG "%s: %s/%x\n", __func__,
    324		       bp->name, bp->Bprotocols);
    325	old = get_Bprotocol4mask(bp->Bprotocols);
    326	if (old) {
    327		printk(KERN_WARNING
    328		       "register duplicate protocol old %s/%x new %s/%x\n",
    329		       old->name, old->Bprotocols, bp->name, bp->Bprotocols);
    330		return -EBUSY;
    331	}
    332	write_lock_irqsave(&bp_lock, flags);
    333	list_add_tail(&bp->list, &Bprotocols);
    334	write_unlock_irqrestore(&bp_lock, flags);
    335	return 0;
    336}
    337EXPORT_SYMBOL(mISDN_register_Bprotocol);
    338
    339void
    340mISDN_unregister_Bprotocol(struct Bprotocol *bp)
    341{
    342	u_long	flags;
    343
    344	if (debug & DEBUG_CORE)
    345		printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name,
    346		       bp->Bprotocols);
    347	write_lock_irqsave(&bp_lock, flags);
    348	list_del(&bp->list);
    349	write_unlock_irqrestore(&bp_lock, flags);
    350}
    351EXPORT_SYMBOL(mISDN_unregister_Bprotocol);
    352
    353static const char *msg_no_channel = "<no channel>";
    354static const char *msg_no_stack = "<no stack>";
    355static const char *msg_no_stackdev = "<no stack device>";
    356
    357const char *mISDNDevName4ch(struct mISDNchannel *ch)
    358{
    359	if (!ch)
    360		return msg_no_channel;
    361	if (!ch->st)
    362		return msg_no_stack;
    363	if (!ch->st->dev)
    364		return msg_no_stackdev;
    365	return dev_name(&ch->st->dev->dev);
    366};
    367EXPORT_SYMBOL(mISDNDevName4ch);
    368
    369static int
    370mISDNInit(void)
    371{
    372	int	err;
    373
    374	printk(KERN_INFO "Modular ISDN core version %d.%d.%d\n",
    375	       MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE);
    376	mISDN_init_clock(&debug);
    377	mISDN_initstack(&debug);
    378	err = class_register(&mISDN_class);
    379	if (err)
    380		goto error1;
    381	err = mISDN_inittimer(&debug);
    382	if (err)
    383		goto error2;
    384	err = Isdnl1_Init(&debug);
    385	if (err)
    386		goto error3;
    387	err = Isdnl2_Init(&debug);
    388	if (err)
    389		goto error4;
    390	err = misdn_sock_init(&debug);
    391	if (err)
    392		goto error5;
    393	return 0;
    394
    395error5:
    396	Isdnl2_cleanup();
    397error4:
    398	Isdnl1_cleanup();
    399error3:
    400	mISDN_timer_cleanup();
    401error2:
    402	class_unregister(&mISDN_class);
    403error1:
    404	return err;
    405}
    406
    407static void mISDN_cleanup(void)
    408{
    409	misdn_sock_cleanup();
    410	Isdnl2_cleanup();
    411	Isdnl1_cleanup();
    412	mISDN_timer_cleanup();
    413	class_unregister(&mISDN_class);
    414
    415	printk(KERN_DEBUG "mISDNcore unloaded\n");
    416}
    417
    418module_init(mISDNInit);
    419module_exit(mISDN_cleanup);