arch/powerpc/platforms/powernv/pci-sriov.c
Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/pci-sriov.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/platforms/powernv/pci-sriov.c- Extension
.c- Size
- 22845 bytes
- Lines
- 761
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/ioport.hlinux/bitmap.hlinux/pci.hasm/opal.hpci.h
Detected Declarations
function finessefunction pnv_pci_ioda_fixup_iovfunction pnv_pci_iov_resource_alignmentfunction pnv_pci_vf_release_m64function for_each_set_bitfunction pnv_ioda_map_m64_segmentedfunction pnv_ioda_map_m64_singlefunction pnv_pci_alloc_m64_barfunction pnv_pci_vf_assign_m64function pnv_ioda_release_vf_PEfunction pnv_pci_vf_resource_shiftfunction pnv_pci_sriov_disablefunction pnv_ioda_setup_vf_PEfunction list_for_each_entryfunction pnv_pci_sriov_enablefunction pnv_pcibios_sriov_disablefunction pnv_pcibios_sriov_enable
Annotated Snippet
if (!pnv_pci_is_m64_flags(res->flags)) {
dev_warn(&pdev->dev, "Don't support SR-IOV with non M64 VF BAR%d: %pR. \n",
i, res);
goto disable_iov;
}
vf_bar_sz = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
/*
* Generally, one segmented M64 BAR maps one IOV BAR. However,
* if a VF BAR is too large we end up wasting a lot of space.
* If each VF needs more than 1/4 of the default m64 segment
* then each VF BAR should be mapped in single-PE mode to reduce
* the amount of space required. This does however limit the
* number of VFs we can support.
*
* The 1/4 limit is arbitrary and can be tweaked.
*/
if (vf_bar_sz > (phb->ioda.m64_segsize >> 2)) {
/*
* On PHB3, the minimum size alignment of M64 BAR in
* single mode is 32MB. If this VF BAR is smaller than
* 32MB, but still too large for a segmented window
* then we can't map it and need to disable SR-IOV for
* this device.
*/
if (vf_bar_sz < SZ_32M) {
pci_err(pdev, "VF BAR%d: %pR can't be mapped in single PE mode\n",
i, res);
goto disable_iov;
}
iov->m64_single_mode[i] = true;
continue;
}
/*
* This BAR can be mapped with one segmented window, so adjust
* te resource size to accommodate.
*/
pci_dbg(pdev, " Fixing VF BAR%d: %pR to\n", i, res);
res->end = res->start + vf_bar_sz * mul - 1;
pci_dbg(pdev, " %pR\n", res);
pci_info(pdev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
i, res, mul);
iov->need_shift = true;
}
return;
disable_iov:
/* Save ourselves some MMIO space by disabling the unusable BARs */
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
res = &pdev->resource[i + PCI_IOV_RESOURCES];
res->flags = 0;
res->end = res->start - 1;
}
pdev->dev.archdata.iov_data = NULL;
kfree(iov);
}
void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev)
{
if (pdev->is_virtfn) {
struct pnv_ioda_pe *pe = pnv_ioda_get_pe(pdev);
/*
* VF PEs are single-device PEs so their pdev pointer needs to
* be set. The pdev doesn't exist when the PE is allocated (in
* (pcibios_sriov_enable()) so we fix it up here.
*/
pe->pdev = pdev;
WARN_ON(!(pe->flags & PNV_IODA_PE_VF));
} else if (pdev->is_physfn) {
/*
* For PFs adjust their allocated IOV resources to match what
* the PHB can support using its M64 BAR table.
*/
pnv_pci_ioda_fixup_iov_resources(pdev);
}
}
resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev,
int resno)
{
resource_size_t align = pci_iov_resource_size(pdev, resno);
struct pnv_phb *phb = pci_bus_to_pnvhb(pdev->bus);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/ioport.h`, `linux/bitmap.h`, `linux/pci.h`, `asm/opal.h`, `pci.h`.
- Detected declarations: `function finesse`, `function pnv_pci_ioda_fixup_iov`, `function pnv_pci_iov_resource_alignment`, `function pnv_pci_vf_release_m64`, `function for_each_set_bit`, `function pnv_ioda_map_m64_segmented`, `function pnv_ioda_map_m64_single`, `function pnv_pci_alloc_m64_bar`, `function pnv_pci_vf_assign_m64`, `function pnv_ioda_release_vf_PE`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.