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