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

pci-stub.c (2404B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Simple stub driver to reserve a PCI device
      4 *
      5 * Copyright (C) 2008 Red Hat, Inc.
      6 * Author:
      7 *	Chris Wright
      8 *
      9 * Usage is simple, allocate a new id to the stub driver and bind the
     10 * device to it.  For example:
     11 *
     12 * # echo "8086 10f5" > /sys/bus/pci/drivers/pci-stub/new_id
     13 * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind
     14 * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/pci-stub/bind
     15 * # ls -l /sys/bus/pci/devices/0000:00:19.0/driver
     16 * .../0000:00:19.0/driver -> ../../../bus/pci/drivers/pci-stub
     17 */
     18
     19#include <linux/module.h>
     20#include <linux/pci.h>
     21
     22static char ids[1024] __initdata;
     23
     24module_param_string(ids, ids, sizeof(ids), 0);
     25MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the stub driver, format is "
     26		 "\"vendor:device[:subvendor[:subdevice[:class[:class_mask]]]]\""
     27		 " and multiple comma separated entries can be specified");
     28
     29static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id)
     30{
     31	pci_info(dev, "claimed by stub\n");
     32	return 0;
     33}
     34
     35static struct pci_driver stub_driver = {
     36	.name		= "pci-stub",
     37	.id_table	= NULL,	/* only dynamic id's */
     38	.probe		= pci_stub_probe,
     39	.driver_managed_dma = true,
     40};
     41
     42static int __init pci_stub_init(void)
     43{
     44	char *p, *id;
     45	int rc;
     46
     47	rc = pci_register_driver(&stub_driver);
     48	if (rc)
     49		return rc;
     50
     51	/* no ids passed actually */
     52	if (ids[0] == '\0')
     53		return 0;
     54
     55	/* add ids specified in the module parameter */
     56	p = ids;
     57	while ((id = strsep(&p, ","))) {
     58		unsigned int vendor, device, subvendor = PCI_ANY_ID,
     59			subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
     60		int fields;
     61
     62		if (!strlen(id))
     63			continue;
     64
     65		fields = sscanf(id, "%x:%x:%x:%x:%x:%x",
     66				&vendor, &device, &subvendor, &subdevice,
     67				&class, &class_mask);
     68
     69		if (fields < 2) {
     70			pr_warn("pci-stub: invalid ID string \"%s\"\n", id);
     71			continue;
     72		}
     73
     74		pr_info("pci-stub: add %04X:%04X sub=%04X:%04X cls=%08X/%08X\n",
     75		       vendor, device, subvendor, subdevice, class, class_mask);
     76
     77		rc = pci_add_dynid(&stub_driver, vendor, device,
     78				   subvendor, subdevice, class, class_mask, 0);
     79		if (rc)
     80			pr_warn("pci-stub: failed to add dynamic ID (%d)\n",
     81				rc);
     82	}
     83
     84	return 0;
     85}
     86
     87static void __exit pci_stub_exit(void)
     88{
     89	pci_unregister_driver(&stub_driver);
     90}
     91
     92module_init(pci_stub_init);
     93module_exit(pci_stub_exit);
     94
     95MODULE_LICENSE("GPL");
     96MODULE_AUTHOR("Chris Wright <chrisw@sous-sol.org>");