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

proc.c (9957B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Procfs interface for the PCI bus
      4 *
      5 * Copyright (c) 1997--1999 Martin Mares <mj@ucw.cz>
      6 */
      7
      8#include <linux/init.h>
      9#include <linux/pci.h>
     10#include <linux/slab.h>
     11#include <linux/module.h>
     12#include <linux/proc_fs.h>
     13#include <linux/seq_file.h>
     14#include <linux/capability.h>
     15#include <linux/uaccess.h>
     16#include <linux/security.h>
     17#include <asm/byteorder.h>
     18#include "pci.h"
     19
     20static int proc_initialized;	/* = 0 */
     21
     22static loff_t proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
     23{
     24	struct pci_dev *dev = pde_data(file_inode(file));
     25	return fixed_size_llseek(file, off, whence, dev->cfg_size);
     26}
     27
     28static ssize_t proc_bus_pci_read(struct file *file, char __user *buf,
     29				 size_t nbytes, loff_t *ppos)
     30{
     31	struct pci_dev *dev = pde_data(file_inode(file));
     32	unsigned int pos = *ppos;
     33	unsigned int cnt, size;
     34
     35	/*
     36	 * Normal users can read only the standardized portion of the
     37	 * configuration space as several chips lock up when trying to read
     38	 * undefined locations (think of Intel PIIX4 as a typical example).
     39	 */
     40
     41	if (capable(CAP_SYS_ADMIN))
     42		size = dev->cfg_size;
     43	else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
     44		size = 128;
     45	else
     46		size = 64;
     47
     48	if (pos >= size)
     49		return 0;
     50	if (nbytes >= size)
     51		nbytes = size;
     52	if (pos + nbytes > size)
     53		nbytes = size - pos;
     54	cnt = nbytes;
     55
     56	if (!access_ok(buf, cnt))
     57		return -EINVAL;
     58
     59	pci_config_pm_runtime_get(dev);
     60
     61	if ((pos & 1) && cnt) {
     62		unsigned char val;
     63		pci_user_read_config_byte(dev, pos, &val);
     64		__put_user(val, buf);
     65		buf++;
     66		pos++;
     67		cnt--;
     68	}
     69
     70	if ((pos & 3) && cnt > 2) {
     71		unsigned short val;
     72		pci_user_read_config_word(dev, pos, &val);
     73		__put_user(cpu_to_le16(val), (__le16 __user *) buf);
     74		buf += 2;
     75		pos += 2;
     76		cnt -= 2;
     77	}
     78
     79	while (cnt >= 4) {
     80		unsigned int val;
     81		pci_user_read_config_dword(dev, pos, &val);
     82		__put_user(cpu_to_le32(val), (__le32 __user *) buf);
     83		buf += 4;
     84		pos += 4;
     85		cnt -= 4;
     86		cond_resched();
     87	}
     88
     89	if (cnt >= 2) {
     90		unsigned short val;
     91		pci_user_read_config_word(dev, pos, &val);
     92		__put_user(cpu_to_le16(val), (__le16 __user *) buf);
     93		buf += 2;
     94		pos += 2;
     95		cnt -= 2;
     96	}
     97
     98	if (cnt) {
     99		unsigned char val;
    100		pci_user_read_config_byte(dev, pos, &val);
    101		__put_user(val, buf);
    102		pos++;
    103	}
    104
    105	pci_config_pm_runtime_put(dev);
    106
    107	*ppos = pos;
    108	return nbytes;
    109}
    110
    111static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
    112				  size_t nbytes, loff_t *ppos)
    113{
    114	struct inode *ino = file_inode(file);
    115	struct pci_dev *dev = pde_data(ino);
    116	int pos = *ppos;
    117	int size = dev->cfg_size;
    118	int cnt, ret;
    119
    120	ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
    121	if (ret)
    122		return ret;
    123
    124	if (pos >= size)
    125		return 0;
    126	if (nbytes >= size)
    127		nbytes = size;
    128	if (pos + nbytes > size)
    129		nbytes = size - pos;
    130	cnt = nbytes;
    131
    132	if (!access_ok(buf, cnt))
    133		return -EINVAL;
    134
    135	pci_config_pm_runtime_get(dev);
    136
    137	if ((pos & 1) && cnt) {
    138		unsigned char val;
    139		__get_user(val, buf);
    140		pci_user_write_config_byte(dev, pos, val);
    141		buf++;
    142		pos++;
    143		cnt--;
    144	}
    145
    146	if ((pos & 3) && cnt > 2) {
    147		__le16 val;
    148		__get_user(val, (__le16 __user *) buf);
    149		pci_user_write_config_word(dev, pos, le16_to_cpu(val));
    150		buf += 2;
    151		pos += 2;
    152		cnt -= 2;
    153	}
    154
    155	while (cnt >= 4) {
    156		__le32 val;
    157		__get_user(val, (__le32 __user *) buf);
    158		pci_user_write_config_dword(dev, pos, le32_to_cpu(val));
    159		buf += 4;
    160		pos += 4;
    161		cnt -= 4;
    162	}
    163
    164	if (cnt >= 2) {
    165		__le16 val;
    166		__get_user(val, (__le16 __user *) buf);
    167		pci_user_write_config_word(dev, pos, le16_to_cpu(val));
    168		buf += 2;
    169		pos += 2;
    170		cnt -= 2;
    171	}
    172
    173	if (cnt) {
    174		unsigned char val;
    175		__get_user(val, buf);
    176		pci_user_write_config_byte(dev, pos, val);
    177		pos++;
    178	}
    179
    180	pci_config_pm_runtime_put(dev);
    181
    182	*ppos = pos;
    183	i_size_write(ino, dev->cfg_size);
    184	return nbytes;
    185}
    186
    187#ifdef HAVE_PCI_MMAP
    188struct pci_filp_private {
    189	enum pci_mmap_state mmap_state;
    190	int write_combine;
    191};
    192#endif /* HAVE_PCI_MMAP */
    193
    194static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
    195			       unsigned long arg)
    196{
    197	struct pci_dev *dev = pde_data(file_inode(file));
    198#ifdef HAVE_PCI_MMAP
    199	struct pci_filp_private *fpriv = file->private_data;
    200#endif /* HAVE_PCI_MMAP */
    201	int ret = 0;
    202
    203	ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
    204	if (ret)
    205		return ret;
    206
    207	switch (cmd) {
    208	case PCIIOC_CONTROLLER:
    209		ret = pci_domain_nr(dev->bus);
    210		break;
    211
    212#ifdef HAVE_PCI_MMAP
    213	case PCIIOC_MMAP_IS_IO:
    214		if (!arch_can_pci_mmap_io())
    215			return -EINVAL;
    216		fpriv->mmap_state = pci_mmap_io;
    217		break;
    218
    219	case PCIIOC_MMAP_IS_MEM:
    220		fpriv->mmap_state = pci_mmap_mem;
    221		break;
    222
    223	case PCIIOC_WRITE_COMBINE:
    224		if (arch_can_pci_mmap_wc()) {
    225			if (arg)
    226				fpriv->write_combine = 1;
    227			else
    228				fpriv->write_combine = 0;
    229			break;
    230		}
    231		/* If arch decided it can't, fall through... */
    232		fallthrough;
    233#endif /* HAVE_PCI_MMAP */
    234	default:
    235		ret = -EINVAL;
    236		break;
    237	}
    238
    239	return ret;
    240}
    241
    242#ifdef HAVE_PCI_MMAP
    243static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
    244{
    245	struct pci_dev *dev = pde_data(file_inode(file));
    246	struct pci_filp_private *fpriv = file->private_data;
    247	int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM;
    248
    249	if (!capable(CAP_SYS_RAWIO) ||
    250	    security_locked_down(LOCKDOWN_PCI_ACCESS))
    251		return -EPERM;
    252
    253	if (fpriv->mmap_state == pci_mmap_io) {
    254		if (!arch_can_pci_mmap_io())
    255			return -EINVAL;
    256		res_bit = IORESOURCE_IO;
    257	}
    258
    259	/* Make sure the caller is mapping a real resource for this device */
    260	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
    261		if (dev->resource[i].flags & res_bit &&
    262		    pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
    263			break;
    264	}
    265
    266	if (i >= PCI_STD_NUM_BARS)
    267		return -ENODEV;
    268
    269	if (fpriv->mmap_state == pci_mmap_mem &&
    270	    fpriv->write_combine) {
    271		if (dev->resource[i].flags & IORESOURCE_PREFETCH)
    272			write_combine = 1;
    273		else
    274			return -EINVAL;
    275	}
    276
    277	if (dev->resource[i].flags & IORESOURCE_MEM &&
    278	    iomem_is_exclusive(dev->resource[i].start))
    279		return -EINVAL;
    280
    281	ret = pci_mmap_page_range(dev, i, vma,
    282				  fpriv->mmap_state, write_combine);
    283	if (ret < 0)
    284		return ret;
    285
    286	return 0;
    287}
    288
    289static int proc_bus_pci_open(struct inode *inode, struct file *file)
    290{
    291	struct pci_filp_private *fpriv = kmalloc(sizeof(*fpriv), GFP_KERNEL);
    292
    293	if (!fpriv)
    294		return -ENOMEM;
    295
    296	fpriv->mmap_state = pci_mmap_io;
    297	fpriv->write_combine = 0;
    298
    299	file->private_data = fpriv;
    300	file->f_mapping = iomem_get_mapping();
    301
    302	return 0;
    303}
    304
    305static int proc_bus_pci_release(struct inode *inode, struct file *file)
    306{
    307	kfree(file->private_data);
    308	file->private_data = NULL;
    309
    310	return 0;
    311}
    312#endif /* HAVE_PCI_MMAP */
    313
    314static const struct proc_ops proc_bus_pci_ops = {
    315	.proc_lseek	= proc_bus_pci_lseek,
    316	.proc_read	= proc_bus_pci_read,
    317	.proc_write	= proc_bus_pci_write,
    318	.proc_ioctl	= proc_bus_pci_ioctl,
    319#ifdef CONFIG_COMPAT
    320	.proc_compat_ioctl = proc_bus_pci_ioctl,
    321#endif
    322#ifdef HAVE_PCI_MMAP
    323	.proc_open	= proc_bus_pci_open,
    324	.proc_release	= proc_bus_pci_release,
    325	.proc_mmap	= proc_bus_pci_mmap,
    326#ifdef HAVE_ARCH_PCI_GET_UNMAPPED_AREA
    327	.proc_get_unmapped_area = get_pci_unmapped_area,
    328#endif /* HAVE_ARCH_PCI_GET_UNMAPPED_AREA */
    329#endif /* HAVE_PCI_MMAP */
    330};
    331
    332/* iterator */
    333static void *pci_seq_start(struct seq_file *m, loff_t *pos)
    334{
    335	struct pci_dev *dev = NULL;
    336	loff_t n = *pos;
    337
    338	for_each_pci_dev(dev) {
    339		if (!n--)
    340			break;
    341	}
    342	return dev;
    343}
    344
    345static void *pci_seq_next(struct seq_file *m, void *v, loff_t *pos)
    346{
    347	struct pci_dev *dev = v;
    348
    349	(*pos)++;
    350	dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
    351	return dev;
    352}
    353
    354static void pci_seq_stop(struct seq_file *m, void *v)
    355{
    356	if (v) {
    357		struct pci_dev *dev = v;
    358		pci_dev_put(dev);
    359	}
    360}
    361
    362static int show_device(struct seq_file *m, void *v)
    363{
    364	const struct pci_dev *dev = v;
    365	const struct pci_driver *drv;
    366	int i;
    367
    368	if (dev == NULL)
    369		return 0;
    370
    371	drv = pci_dev_driver(dev);
    372	seq_printf(m, "%02x%02x\t%04x%04x\t%x",
    373			dev->bus->number,
    374			dev->devfn,
    375			dev->vendor,
    376			dev->device,
    377			dev->irq);
    378
    379	/* only print standard and ROM resources to preserve compatibility */
    380	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
    381		resource_size_t start, end;
    382		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
    383		seq_printf(m, "\t%16llx",
    384			(unsigned long long)(start |
    385			(dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
    386	}
    387	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
    388		resource_size_t start, end;
    389		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
    390		seq_printf(m, "\t%16llx",
    391			dev->resource[i].start < dev->resource[i].end ?
    392			(unsigned long long)(end - start) + 1 : 0);
    393	}
    394	seq_putc(m, '\t');
    395	if (drv)
    396		seq_puts(m, drv->name);
    397	seq_putc(m, '\n');
    398	return 0;
    399}
    400
    401static const struct seq_operations proc_bus_pci_devices_op = {
    402	.start	= pci_seq_start,
    403	.next	= pci_seq_next,
    404	.stop	= pci_seq_stop,
    405	.show	= show_device
    406};
    407
    408static struct proc_dir_entry *proc_bus_pci_dir;
    409
    410int pci_proc_attach_device(struct pci_dev *dev)
    411{
    412	struct pci_bus *bus = dev->bus;
    413	struct proc_dir_entry *e;
    414	char name[16];
    415
    416	if (!proc_initialized)
    417		return -EACCES;
    418
    419	if (!bus->procdir) {
    420		if (pci_proc_domain(bus)) {
    421			sprintf(name, "%04x:%02x", pci_domain_nr(bus),
    422					bus->number);
    423		} else {
    424			sprintf(name, "%02x", bus->number);
    425		}
    426		bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
    427		if (!bus->procdir)
    428			return -ENOMEM;
    429	}
    430
    431	sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
    432	e = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, bus->procdir,
    433			     &proc_bus_pci_ops, dev);
    434	if (!e)
    435		return -ENOMEM;
    436	proc_set_size(e, dev->cfg_size);
    437	dev->procent = e;
    438
    439	return 0;
    440}
    441
    442int pci_proc_detach_device(struct pci_dev *dev)
    443{
    444	proc_remove(dev->procent);
    445	dev->procent = NULL;
    446	return 0;
    447}
    448
    449int pci_proc_detach_bus(struct pci_bus *bus)
    450{
    451	proc_remove(bus->procdir);
    452	return 0;
    453}
    454
    455static int __init pci_proc_init(void)
    456{
    457	struct pci_dev *dev = NULL;
    458	proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
    459	proc_create_seq("devices", 0, proc_bus_pci_dir,
    460		    &proc_bus_pci_devices_op);
    461	proc_initialized = 1;
    462	for_each_pci_dev(dev)
    463		pci_proc_attach_device(dev);
    464
    465	return 0;
    466}
    467device_initcall(pci_proc_init);