drivers/pci/syscall.c
Source file repositories/reference/linux-study-clean/drivers/pci/syscall.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pci/syscall.c- Extension
.c- Size
- 2688 bytes
- Lines
- 138
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: syscall or user/kernel boundary
- Status
- core implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/errno.hlinux/pci.hlinux/security.hlinux/syscalls.hlinux/uaccess.hpci.h
Detected Declarations
syscall pciconfig_readsyscall pciconfig_write
Annotated Snippet
SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn,
unsigned long, off, unsigned long, len, void __user *, buf)
{
struct pci_dev *dev;
u8 byte;
u16 word;
u32 dword;
int err, cfg_ret;
err = -EPERM;
dev = NULL;
if (!capable(CAP_SYS_ADMIN))
goto error;
err = -ENODEV;
dev = pci_get_domain_bus_and_slot(0, bus, dfn);
if (!dev)
goto error;
switch (len) {
case 1:
cfg_ret = pci_user_read_config_byte(dev, off, &byte);
break;
case 2:
cfg_ret = pci_user_read_config_word(dev, off, &word);
break;
case 4:
cfg_ret = pci_user_read_config_dword(dev, off, &dword);
break;
default:
err = -EINVAL;
goto error;
}
err = -EIO;
if (cfg_ret)
goto error;
switch (len) {
case 1:
err = put_user(byte, (u8 __user *)buf);
break;
case 2:
err = put_user(word, (u16 __user *)buf);
break;
case 4:
err = put_user(dword, (u32 __user *)buf);
break;
}
pci_dev_put(dev);
return err;
error:
/* ??? XFree86 doesn't even check the return value. They
just look for 0xffffffff in the output, since that's what
they get instead of a machine check on x86. */
switch (len) {
case 1:
put_user(-1, (u8 __user *)buf);
break;
case 2:
put_user(-1, (u16 __user *)buf);
break;
case 4:
put_user(-1, (u32 __user *)buf);
break;
}
pci_dev_put(dev);
return err;
}
SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
unsigned long, off, unsigned long, len, void __user *, buf)
{
struct pci_dev *dev;
u8 byte;
u16 word;
u32 dword;
int err = 0;
if (!capable(CAP_SYS_ADMIN) ||
security_locked_down(LOCKDOWN_PCI_ACCESS))
return -EPERM;
dev = pci_get_domain_bus_and_slot(0, bus, dfn);
if (!dev)
return -ENODEV;
switch (len) {
case 1:
Annotation
- Immediate include surface: `linux/errno.h`, `linux/pci.h`, `linux/security.h`, `linux/syscalls.h`, `linux/uaccess.h`, `pci.h`.
- Detected declarations: `syscall pciconfig_read`, `syscall pciconfig_write`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: core implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.