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 (7836B)


      1/*
      2 * This file is provided under a dual BSD/GPLv2 license.  When using or
      3 *   redistributing this file, you may do so under either license.
      4 *
      5 *   GPL LICENSE SUMMARY
      6 *
      7 *   Copyright (C) 2015 EMC Corporation. All Rights Reserved.
      8 *   Copyright (C) 2016 T-Platforms. All Rights Reserved.
      9 *
     10 *   This program is free software; you can redistribute it and/or modify
     11 *   it under the terms of version 2 of the GNU General Public License as
     12 *   published by the Free Software Foundation.
     13 *
     14 *   This program is distributed in the hope that it will be useful, but
     15 *   WITHOUT ANY WARRANTY; without even the implied warranty of
     16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17 *   General Public License for more details.
     18 *
     19 *   BSD LICENSE
     20 *
     21 *   Copyright (C) 2015 EMC Corporation. All Rights Reserved.
     22 *   Copyright (C) 2016 T-Platforms. All Rights Reserved.
     23 *
     24 *   Redistribution and use in source and binary forms, with or without
     25 *   modification, are permitted provided that the following conditions
     26 *   are met:
     27 *
     28 *     * Redistributions of source code must retain the above copyright
     29 *       notice, this list of conditions and the following disclaimer.
     30 *     * Redistributions in binary form must reproduce the above copy
     31 *       notice, this list of conditions and the following disclaimer in
     32 *       the documentation and/or other materials provided with the
     33 *       distribution.
     34 *     * Neither the name of Intel Corporation nor the names of its
     35 *       contributors may be used to endorse or promote products derived
     36 *       from this software without specific prior written permission.
     37 *
     38 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     39 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     40 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     41 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     42 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     43 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     44 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     45 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     46 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     47 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     48 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     49 *
     50 * PCIe NTB Linux driver
     51 *
     52 * Contact Information:
     53 * Allen Hubbe <Allen.Hubbe@emc.com>
     54 */
     55
     56#include <linux/device.h>
     57#include <linux/kernel.h>
     58#include <linux/module.h>
     59
     60#include <linux/ntb.h>
     61#include <linux/pci.h>
     62
     63#define DRIVER_NAME			"ntb"
     64#define DRIVER_DESCRIPTION		"PCIe NTB Driver Framework"
     65
     66#define DRIVER_VERSION			"1.0"
     67#define DRIVER_RELDATE			"24 March 2015"
     68#define DRIVER_AUTHOR			"Allen Hubbe <Allen.Hubbe@emc.com>"
     69
     70MODULE_LICENSE("Dual BSD/GPL");
     71MODULE_VERSION(DRIVER_VERSION);
     72MODULE_AUTHOR(DRIVER_AUTHOR);
     73MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
     74
     75static struct bus_type ntb_bus;
     76static void ntb_dev_release(struct device *dev);
     77
     78int __ntb_register_client(struct ntb_client *client, struct module *mod,
     79			  const char *mod_name)
     80{
     81	if (!client)
     82		return -EINVAL;
     83	if (!ntb_client_ops_is_valid(&client->ops))
     84		return -EINVAL;
     85
     86	memset(&client->drv, 0, sizeof(client->drv));
     87	client->drv.bus = &ntb_bus;
     88	client->drv.name = mod_name;
     89	client->drv.owner = mod;
     90
     91	return driver_register(&client->drv);
     92}
     93EXPORT_SYMBOL(__ntb_register_client);
     94
     95void ntb_unregister_client(struct ntb_client *client)
     96{
     97	driver_unregister(&client->drv);
     98}
     99EXPORT_SYMBOL(ntb_unregister_client);
    100
    101int ntb_register_device(struct ntb_dev *ntb)
    102{
    103	if (!ntb)
    104		return -EINVAL;
    105	if (!ntb->pdev)
    106		return -EINVAL;
    107	if (!ntb->ops)
    108		return -EINVAL;
    109	if (!ntb_dev_ops_is_valid(ntb->ops))
    110		return -EINVAL;
    111
    112	init_completion(&ntb->released);
    113
    114	ntb->dev.bus = &ntb_bus;
    115	ntb->dev.parent = &ntb->pdev->dev;
    116	ntb->dev.release = ntb_dev_release;
    117	dev_set_name(&ntb->dev, "%s", pci_name(ntb->pdev));
    118
    119	ntb->ctx = NULL;
    120	ntb->ctx_ops = NULL;
    121	spin_lock_init(&ntb->ctx_lock);
    122
    123	return device_register(&ntb->dev);
    124}
    125EXPORT_SYMBOL(ntb_register_device);
    126
    127void ntb_unregister_device(struct ntb_dev *ntb)
    128{
    129	device_unregister(&ntb->dev);
    130	wait_for_completion(&ntb->released);
    131}
    132EXPORT_SYMBOL(ntb_unregister_device);
    133
    134int ntb_set_ctx(struct ntb_dev *ntb, void *ctx,
    135		const struct ntb_ctx_ops *ctx_ops)
    136{
    137	unsigned long irqflags;
    138
    139	if (!ntb_ctx_ops_is_valid(ctx_ops))
    140		return -EINVAL;
    141	if (ntb->ctx_ops)
    142		return -EINVAL;
    143
    144	spin_lock_irqsave(&ntb->ctx_lock, irqflags);
    145	{
    146		ntb->ctx = ctx;
    147		ntb->ctx_ops = ctx_ops;
    148	}
    149	spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
    150
    151	return 0;
    152}
    153EXPORT_SYMBOL(ntb_set_ctx);
    154
    155void ntb_clear_ctx(struct ntb_dev *ntb)
    156{
    157	unsigned long irqflags;
    158
    159	spin_lock_irqsave(&ntb->ctx_lock, irqflags);
    160	{
    161		ntb->ctx_ops = NULL;
    162		ntb->ctx = NULL;
    163	}
    164	spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
    165}
    166EXPORT_SYMBOL(ntb_clear_ctx);
    167
    168void ntb_link_event(struct ntb_dev *ntb)
    169{
    170	unsigned long irqflags;
    171
    172	spin_lock_irqsave(&ntb->ctx_lock, irqflags);
    173	{
    174		if (ntb->ctx_ops && ntb->ctx_ops->link_event)
    175			ntb->ctx_ops->link_event(ntb->ctx);
    176	}
    177	spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
    178}
    179EXPORT_SYMBOL(ntb_link_event);
    180
    181void ntb_db_event(struct ntb_dev *ntb, int vector)
    182{
    183	unsigned long irqflags;
    184
    185	spin_lock_irqsave(&ntb->ctx_lock, irqflags);
    186	{
    187		if (ntb->ctx_ops && ntb->ctx_ops->db_event)
    188			ntb->ctx_ops->db_event(ntb->ctx, vector);
    189	}
    190	spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
    191}
    192EXPORT_SYMBOL(ntb_db_event);
    193
    194void ntb_msg_event(struct ntb_dev *ntb)
    195{
    196	unsigned long irqflags;
    197
    198	spin_lock_irqsave(&ntb->ctx_lock, irqflags);
    199	{
    200		if (ntb->ctx_ops && ntb->ctx_ops->msg_event)
    201			ntb->ctx_ops->msg_event(ntb->ctx);
    202	}
    203	spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
    204}
    205EXPORT_SYMBOL(ntb_msg_event);
    206
    207int ntb_default_port_number(struct ntb_dev *ntb)
    208{
    209	switch (ntb->topo) {
    210	case NTB_TOPO_PRI:
    211	case NTB_TOPO_B2B_USD:
    212		return NTB_PORT_PRI_USD;
    213	case NTB_TOPO_SEC:
    214	case NTB_TOPO_B2B_DSD:
    215		return NTB_PORT_SEC_DSD;
    216	default:
    217		return 0;
    218	}
    219}
    220EXPORT_SYMBOL(ntb_default_port_number);
    221
    222int ntb_default_peer_port_count(struct ntb_dev *ntb)
    223{
    224	return NTB_DEF_PEER_CNT;
    225}
    226EXPORT_SYMBOL(ntb_default_peer_port_count);
    227
    228int ntb_default_peer_port_number(struct ntb_dev *ntb, int pidx)
    229{
    230	if (pidx != NTB_DEF_PEER_IDX)
    231		return -EINVAL;
    232
    233	switch (ntb->topo) {
    234	case NTB_TOPO_PRI:
    235	case NTB_TOPO_B2B_USD:
    236		return NTB_PORT_SEC_DSD;
    237	case NTB_TOPO_SEC:
    238	case NTB_TOPO_B2B_DSD:
    239		return NTB_PORT_PRI_USD;
    240	default:
    241		return 0;
    242	}
    243}
    244EXPORT_SYMBOL(ntb_default_peer_port_number);
    245
    246int ntb_default_peer_port_idx(struct ntb_dev *ntb, int port)
    247{
    248	int peer_port = ntb_default_peer_port_number(ntb, NTB_DEF_PEER_IDX);
    249
    250	if (peer_port == -EINVAL || port != peer_port)
    251		return -EINVAL;
    252
    253	return 0;
    254}
    255EXPORT_SYMBOL(ntb_default_peer_port_idx);
    256
    257static int ntb_probe(struct device *dev)
    258{
    259	struct ntb_dev *ntb;
    260	struct ntb_client *client;
    261	int rc;
    262
    263	get_device(dev);
    264	ntb = dev_ntb(dev);
    265	client = drv_ntb_client(dev->driver);
    266
    267	rc = client->ops.probe(client, ntb);
    268	if (rc)
    269		put_device(dev);
    270
    271	return rc;
    272}
    273
    274static void ntb_remove(struct device *dev)
    275{
    276	struct ntb_dev *ntb;
    277	struct ntb_client *client;
    278
    279	if (dev->driver) {
    280		ntb = dev_ntb(dev);
    281		client = drv_ntb_client(dev->driver);
    282
    283		client->ops.remove(client, ntb);
    284		put_device(dev);
    285	}
    286}
    287
    288static void ntb_dev_release(struct device *dev)
    289{
    290	struct ntb_dev *ntb = dev_ntb(dev);
    291
    292	complete(&ntb->released);
    293}
    294
    295static struct bus_type ntb_bus = {
    296	.name = "ntb",
    297	.probe = ntb_probe,
    298	.remove = ntb_remove,
    299};
    300
    301static int __init ntb_driver_init(void)
    302{
    303	return bus_register(&ntb_bus);
    304}
    305module_init(ntb_driver_init);
    306
    307static void __exit ntb_driver_exit(void)
    308{
    309	bus_unregister(&ntb_bus);
    310}
    311module_exit(ntb_driver_exit);