// SPDX-License-Identifier: GPL-2.0-only /* * VFIO PCI config space virtualization * * Copyright (C) 2012 Red Hat, Inc. All rights reserved. * Author: Alex Williamson <alex.williamson@redhat.com> * * Derived from original vfio: * Copyright 2010 Cisco Systems, Inc. All rights reserved. * Author: Tom Lyon, pugs@cisco.com
*/
/* * This code handles reading and writing of PCI configuration registers. * This is hairy because we want to allow a lot of flexibility to the * user driver, but cannot trust it with all of the config fields. * Tables determine which fields can be read and written, as well as * which fields are 'virtualized' - special actions and translations to * make it appear to the user that he has control, when in fact things * must be negotiated with the underlying OS.
*/
/* * Lengths of PCIe/PCI-X Extended Config Capabilities * 0: Removed or masked from the user visible capability list * FF: Variable length
*/ staticconst u16 pci_ext_cap_length[PCI_EXT_CAP_ID_MAX + 1] = {
[PCI_EXT_CAP_ID_ERR] = PCI_ERR_ROOT_COMMAND,
[PCI_EXT_CAP_ID_VC] = 0xFF,
[PCI_EXT_CAP_ID_DSN] = PCI_EXT_CAP_DSN_SIZEOF,
[PCI_EXT_CAP_ID_PWR] = PCI_EXT_CAP_PWR_SIZEOF,
[PCI_EXT_CAP_ID_RCLD] = 0, /* root only - don't care */
[PCI_EXT_CAP_ID_RCILC] = 0, /* root only - don't care */
[PCI_EXT_CAP_ID_RCEC] = 0, /* root only - don't care */
[PCI_EXT_CAP_ID_MFVC] = 0xFF,
[PCI_EXT_CAP_ID_VC9] = 0xFF, /* same as CAP_ID_VC */
[PCI_EXT_CAP_ID_RCRB] = 0, /* root only - don't care */
[PCI_EXT_CAP_ID_VNDR] = 0xFF,
[PCI_EXT_CAP_ID_CAC] = 0, /* obsolete */
[PCI_EXT_CAP_ID_ACS] = 0xFF,
[PCI_EXT_CAP_ID_ARI] = PCI_EXT_CAP_ARI_SIZEOF,
[PCI_EXT_CAP_ID_ATS] = PCI_EXT_CAP_ATS_SIZEOF,
[PCI_EXT_CAP_ID_SRIOV] = PCI_EXT_CAP_SRIOV_SIZEOF,
[PCI_EXT_CAP_ID_MRIOV] = 0, /* not yet */
[PCI_EXT_CAP_ID_MCAST] = PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF,
[PCI_EXT_CAP_ID_PRI] = PCI_EXT_CAP_PRI_SIZEOF,
[PCI_EXT_CAP_ID_AMD_XXX] = 0, /* not yet */
[PCI_EXT_CAP_ID_REBAR] = 0xFF,
[PCI_EXT_CAP_ID_DPA] = 0xFF,
[PCI_EXT_CAP_ID_TPH] = 0xFF,
[PCI_EXT_CAP_ID_LTR] = PCI_EXT_CAP_LTR_SIZEOF,
[PCI_EXT_CAP_ID_SECPCI] = 0, /* not yet */
[PCI_EXT_CAP_ID_PMUX] = 0, /* not yet */
[PCI_EXT_CAP_ID_PASID] = 0, /* not yet */
[PCI_EXT_CAP_ID_DVSEC] = 0xFF,
};
/* * Read/Write Permission Bits - one bit for each bit in capability * Any field can be read if it exists, but what is read depends on * whether the field is 'virtualized', or just pass through to the * hardware. Any virtualized field is also virtualized for writes. * Writes are only permitted if they have a 1 bit here.
*/ struct perm_bits {
u8 *virt; /* read/write virtual data, not hw */
u8 *write; /* writeable bits */ int (*readfn)(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 *val); int (*writefn)(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val);
};
staticint vfio_user_config_read(struct pci_dev *pdev, int offset,
__le32 *val, int count)
{ int ret = -EINVAL;
u32 tmp_val = 0;
switch (count) { case 1:
{
u8 tmp;
ret = pci_user_read_config_byte(pdev, offset, &tmp);
tmp_val = tmp; break;
} case 2:
{
u16 tmp;
ret = pci_user_read_config_word(pdev, offset, &tmp);
tmp_val = tmp; break;
} case 4:
ret = pci_user_read_config_dword(pdev, offset, &tmp_val); break;
}
*val = cpu_to_le32(tmp_val);
return ret;
}
staticint vfio_user_config_write(struct pci_dev *pdev, int offset,
__le32 val, int count)
{ int ret = -EINVAL;
u32 tmp_val = le32_to_cpu(val);
switch (count) { case 1:
ret = pci_user_write_config_byte(pdev, offset, tmp_val); break; case 2:
ret = pci_user_write_config_word(pdev, offset, tmp_val); break; case 4:
ret = pci_user_write_config_dword(pdev, offset, tmp_val); break;
}
return ret;
}
staticint vfio_default_config_read(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 *val)
{
__le32 virt = 0;
memcpy(val, vdev->vconfig + pos, count);
memcpy(&virt, perm->virt + offset, count);
/* Any non-virtualized bits? */ if (cpu_to_le32(~0U >> (32 - (count * 8))) != virt) { struct pci_dev *pdev = vdev->pdev;
__le32 phys_val = 0; int ret;
ret = vfio_user_config_read(pdev, pos, &phys_val, count); if (ret) return ret;
*val = (phys_val & ~virt) | (*val & virt);
}
return count;
}
staticint vfio_default_config_write(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val)
{
__le32 virt = 0, write = 0;
memcpy(&write, perm->write + offset, count);
if (!write) return count; /* drop, no writable bits */
memcpy(&virt, perm->virt + offset, count);
/* Virtualized and writable bits go to vconfig */ if (write & virt) {
__le32 virt_val = 0;
ret = vfio_user_config_write(pdev, pos, phys_val, count); if (ret) return ret;
}
return count;
}
/* Allow direct read from hardware, except for capability next pointer */ staticint vfio_direct_config_read(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 *val)
{ int ret;
ret = vfio_user_config_read(vdev->pdev, pos, val, count); if (ret) return ret;
/* Raw access skips any kind of virtualization */ staticint vfio_raw_config_write(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val)
{ int ret;
ret = vfio_user_config_write(vdev->pdev, pos, val, count); if (ret) return ret;
return count;
}
staticint vfio_raw_config_read(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 *val)
{ int ret;
ret = vfio_user_config_read(vdev->pdev, pos, val, count); if (ret) return ret;
return count;
}
/* Virt access uses only virtualization */ staticint vfio_virt_config_write(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val)
{
memcpy(vdev->vconfig + pos, &val, count); return count;
}
staticint vfio_virt_config_read(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 *val)
{
memcpy(val, vdev->vconfig + pos, count); return count;
}
/* Default capability regions to read-only, no-virtualization */ staticstruct perm_bits cap_perms[PCI_CAP_ID_MAX + 1] = {
[0 ... PCI_CAP_ID_MAX] = { .readfn = vfio_direct_config_read }
}; staticstruct perm_bits ecap_perms[PCI_EXT_CAP_ID_MAX + 1] = {
[0 ... PCI_EXT_CAP_ID_MAX] = { .readfn = vfio_direct_config_read }
}; /* * Default unassigned regions to raw read-write access. Some devices * require this to function as they hide registers between the gaps in * config space (be2net). Like MMIO and I/O port registers, we have * to trust the hardware isolation.
*/ staticstruct perm_bits unassigned_perms = {
.readfn = vfio_raw_config_read,
.writefn = vfio_raw_config_write
};
staticint alloc_perm_bits(struct perm_bits *perm, int size)
{ /* * Round up all permission bits to the next dword, this lets us * ignore whether a read/write exceeds the defined capability * structure. We can do this because: * - Standard config space is already dword aligned * - Capabilities are all dword aligned (bits 0:1 of next reserved) * - Express capabilities defined as dword aligned
*/
size = round_up(size, 4);
/* * Zero state is * - All Readable, None Writeable, None Virtualized
*/
perm->virt = kzalloc(size, GFP_KERNEL);
perm->write = kzalloc(size, GFP_KERNEL); if (!perm->virt || !perm->write) {
free_perm_bits(perm); return -ENOMEM;
}
/* * Memory region cannot be accessed if device power state is D3. * * SR-IOV VF memory enable is handled by the MSE bit in the * PF SR-IOV capability, there's therefore no need to trigger * faults based on the virtual value.
*/ return pdev->current_state < PCI_D3hot &&
(pdev->no_command_memory || (cmd & PCI_COMMAND_MEMORY));
}
/* * Restore the *real* BARs after we detect a FLR or backdoor reset. * (backdoor = some device specific technique that we didn't catch)
*/ staticvoid vfio_bar_restore(struct vfio_pci_core_device *vdev)
{ struct pci_dev *pdev = vdev->pdev;
u32 *rbar = vdev->rbar;
u16 cmd; int i;
if (flags & IORESOURCE_IO) return cpu_to_le32(PCI_BASE_ADDRESS_SPACE_IO);
val = PCI_BASE_ADDRESS_SPACE_MEMORY;
if (flags & IORESOURCE_PREFETCH)
val |= PCI_BASE_ADDRESS_MEM_PREFETCH;
if (flags & IORESOURCE_MEM_64)
val |= PCI_BASE_ADDRESS_MEM_TYPE_64;
return cpu_to_le32(val);
}
/* * Pretend we're hardware and tweak the values of the *virtual* PCI BARs * to reflect the hardware capabilities. This implements BAR sizing.
*/ staticvoid vfio_bar_fixup(struct vfio_pci_core_device *vdev)
{ struct pci_dev *pdev = vdev->pdev; int i;
__le32 *vbar;
u64 mask;
/* * NB. REGION_INFO will have reported zero size if we weren't able * to read the ROM, but we still return the actual BAR size here if * it exists (or the shadow ROM space).
*/ if (pci_resource_start(pdev, PCI_ROM_RESOURCE)) {
mask = ~(pci_resource_len(pdev, PCI_ROM_RESOURCE) - 1);
mask |= PCI_ROM_ADDRESS_ENABLE;
*vbar &= cpu_to_le32((u32)mask);
} elseif (pdev->rom && pdev->romlen) {
mask = ~(roundup_pow_of_two(pdev->romlen) - 1);
mask |= PCI_ROM_ADDRESS_ENABLE;
*vbar &= cpu_to_le32((u32)mask);
} else {
*vbar = 0;
}
vdev->bardirty = false;
}
staticint vfio_basic_config_read(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 *val)
{ if (is_bar(offset)) /* pos == offset for basic config */
vfio_bar_fixup(vdev);
/* Test whether BARs match the value we think they should contain */ staticbool vfio_need_bar_restore(struct vfio_pci_core_device *vdev)
{ int i = 0, pos = PCI_BASE_ADDRESS_0, ret;
u32 bar;
for (; pos <= PCI_BASE_ADDRESS_5; i++, pos += 4) { if (vdev->rbar[i]) {
ret = pci_user_read_config_dword(vdev->pdev, pos, &bar); if (ret || vdev->rbar[i] != bar) returntrue;
}
}
returnfalse;
}
staticint vfio_basic_config_write(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val)
{ struct pci_dev *pdev = vdev->pdev;
__le16 *virt_cmd;
u16 new_cmd = 0; int ret;
if (!new_mem)
vfio_pci_zap_and_down_write_memory_lock(vdev); else
down_write(&vdev->memory_lock);
/* * If the user is writing mem/io enable (new_mem/io) and we * think it's already enabled (virt_mem/io), but the hardware * shows it disabled (phys_mem/io, then the device has * undergone some kind of backdoor reset and needs to be * restored before we allow it to enable the bars. * SR-IOV devices will trigger this - for mem enable let's * catch this now and for io enable it will be caught later
*/ if ((new_mem && virt_mem && !phys_mem &&
!pdev->no_command_memory) ||
(new_io && virt_io && !phys_io) ||
vfio_need_bar_restore(vdev))
vfio_bar_restore(vdev);
}
/* * Save current memory/io enable bits in vconfig to allow for * the test above next time.
*/ if (offset == PCI_COMMAND) {
u16 mask = PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
/* Virtualized for SR-IOV functions, which just have FFFF */
p_setw(perm, PCI_VENDOR_ID, (u16)ALL_VIRT, NO_WRITE);
p_setw(perm, PCI_DEVICE_ID, (u16)ALL_VIRT, NO_WRITE);
/* * Virtualize INTx disable, we use it internally for interrupt * control and can emulate it for non-PCI 2.3 devices.
*/
p_setw(perm, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE, (u16)ALL_WRITE);
/* Virtualize capability list, we might want to skip/disable */
p_setw(perm, PCI_STATUS, PCI_STATUS_CAP_LIST, NO_WRITE);
/* No harm to write */
p_setb(perm, PCI_CACHE_LINE_SIZE, NO_VIRT, (u8)ALL_WRITE);
p_setb(perm, PCI_LATENCY_TIMER, NO_VIRT, (u8)ALL_WRITE);
p_setb(perm, PCI_BIST, NO_VIRT, (u8)ALL_WRITE);
/* * It takes all the required locks to protect the access of power related * variables and then invokes vfio_pci_set_power_state().
*/ staticvoid vfio_lock_and_set_power_state(struct vfio_pci_core_device *vdev,
pci_power_t state)
{ if (state >= PCI_D3hot)
vfio_pci_zap_and_down_write_memory_lock(vdev); else
down_write(&vdev->memory_lock);
staticint vfio_pm_config_write(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val)
{
count = vfio_default_config_write(vdev, pos, count, perm, offset, val); if (count < 0) return count;
if (offset == PCI_PM_CTRL) {
pci_power_t state;
switch (le32_to_cpu(val) & PCI_PM_CTRL_STATE_MASK) { case 0:
state = PCI_D0; break; case 1:
state = PCI_D1; break; case 2:
state = PCI_D2; break; case 3:
state = PCI_D3hot; break;
}
vfio_lock_and_set_power_state(vdev, state);
}
return count;
}
/* Permissions for the Power Management capability */ staticint __init init_pci_cap_pm_perm(struct perm_bits *perm)
{ if (alloc_perm_bits(perm, pci_cap_length[PCI_CAP_ID_PM])) return -ENOMEM;
perm->writefn = vfio_pm_config_write;
/* * We always virtualize the next field so we can remove * capabilities from the chain if we want to.
*/
p_setb(perm, PCI_CAP_LIST_NEXT, (u8)ALL_VIRT, NO_WRITE);
/* * The guests can't process PME events. If any PME event will be * generated, then it will be mostly handled in the host and the * host will clear the PME_STATUS. So virtualize PME_Support bits. * The vconfig bits will be cleared during device capability * initialization.
*/
p_setw(perm, PCI_PM_PMC, PCI_PM_CAP_PME_MASK, NO_WRITE);
/* * Power management is defined *per function*, so we can let * the user change power state, but we trap and initiate the * change ourselves, so the state bits are read-only. * * The guest can't process PME from D3cold so virtualize PME_Status * and PME_En bits. The vconfig bits will be cleared during device * capability initialization.
*/
p_setd(perm, PCI_PM_CTRL,
PCI_PM_CTRL_PME_ENABLE | PCI_PM_CTRL_PME_STATUS,
~(PCI_PM_CTRL_PME_ENABLE | PCI_PM_CTRL_PME_STATUS |
PCI_PM_CTRL_STATE_MASK));
/* * Write through to emulation. If the write includes the upper byte * of PCI_VPD_ADDR, then the PCI_VPD_ADDR_F bit is written and we * have work to do.
*/
count = vfio_default_config_write(vdev, pos, count, perm, offset, val); if (count < 0 || offset > PCI_VPD_ADDR + 1 ||
offset + count <= PCI_VPD_ADDR + 1) return count;
addr = le16_to_cpu(*paddr);
if (addr & PCI_VPD_ADDR_F) {
data = le32_to_cpu(*pdata); if (pci_write_vpd(pdev, addr & ~PCI_VPD_ADDR_F, 4, &data) != 4) return count;
} else {
data = 0; if (pci_read_vpd(pdev, addr, 4, &data) < 0) return count;
*pdata = cpu_to_le32(data);
}
/* * Toggle PCI_VPD_ADDR_F in the emulated PCI_VPD_ADDR register to * signal completion. If an error occurs above, we assume that not * toggling this bit will induce a driver timeout.
*/
addr ^= PCI_VPD_ADDR_F;
*paddr = cpu_to_le16(addr);
return count;
}
/* Permissions for Vital Product Data capability */ staticint __init init_pci_cap_vpd_perm(struct perm_bits *perm)
{ if (alloc_perm_bits(perm, pci_cap_length[PCI_CAP_ID_VPD])) return -ENOMEM;
perm->writefn = vfio_vpd_config_write;
/* * We always virtualize the next field so we can remove * capabilities from the chain if we want to.
*/
p_setb(perm, PCI_CAP_LIST_NEXT, (u8)ALL_VIRT, NO_WRITE);
/* * Both the address and data registers are virtualized to * enable access through the pci_vpd_read/write functions
*/
p_setw(perm, PCI_VPD_ADDR, (u16)ALL_VIRT, (u16)ALL_WRITE);
p_setd(perm, PCI_VPD_DATA, ALL_VIRT, ALL_WRITE);
return 0;
}
/* Permissions for PCI-X capability */ staticint __init init_pci_cap_pcix_perm(struct perm_bits *perm)
{ /* Alloc 24, but only 8 are used in v0 */ if (alloc_perm_bits(perm, PCI_CAP_PCIX_SIZEOF_V2)) return -ENOMEM;
/* * The FLR bit is virtualized, if set and the device supports PCIe * FLR, issue a reset_function. Regardless, clear the bit, the spec * requires it to be always read as zero. NB, reset_function might * not use a PCIe FLR, we don't have that level of granularity.
*/ if (*ctrl & cpu_to_le16(PCI_EXP_DEVCTL_BCR_FLR)) {
u32 cap; int ret;
*ctrl &= ~cpu_to_le16(PCI_EXP_DEVCTL_BCR_FLR);
ret = pci_user_read_config_dword(vdev->pdev,
pos - offset + PCI_EXP_DEVCAP,
&cap);
/* * MPS is virtualized to the user, writes do not change the physical * register since determining a proper MPS value requires a system wide * device view. The MRRS is largely independent of MPS, but since the * user does not have that system-wide view, they might set a safe, but * inefficiently low value. Here we allow writes through to hardware, * but we set the floor to the physical device MPS setting, so that * we can at least use full TLPs, as defined by the MPS value. * * NB, if any devices actually depend on an artificially low MRRS * setting, this will need to be revisited, perhaps with a quirk * though pcie_set_readrq().
*/ if (readrq != (le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ)) {
readrq = 128 <<
((le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ) >> 12);
readrq = max(readrq, pcie_get_mps(vdev->pdev));
pcie_set_readrq(vdev->pdev, readrq);
}
return count;
}
/* Permissions for PCI Express capability */ staticint __init init_pci_cap_exp_perm(struct perm_bits *perm)
{ /* Alloc largest of possible sizes */ if (alloc_perm_bits(perm, PCI_CAP_EXP_ENDPOINT_SIZEOF_V2)) return -ENOMEM;
/* * Allow writes to device control fields, except devctl_phantom, * which could confuse IOMMU, MPS, which can break communication * with other physical devices, and the ARI bit in devctl2, which * is set at probe time. FLR and MRRS get virtualized via our * writefn.
*/
p_setw(perm, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_PAYLOAD |
PCI_EXP_DEVCTL_READRQ, ~PCI_EXP_DEVCTL_PHANTOM);
p_setw(perm, PCI_EXP_DEVCTL2, NO_VIRT, ~PCI_EXP_DEVCTL2_ARI); return 0;
}
staticint vfio_af_config_write(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val)
{
u8 *ctrl = vdev->vconfig + pos - offset + PCI_AF_CTRL;
/* * The FLR bit is virtualized, if set and the device supports AF * FLR, issue a reset_function. Regardless, clear the bit, the spec * requires it to be always read as zero. NB, reset_function might * not use an AF FLR, we don't have that level of granularity.
*/ if (*ctrl & PCI_AF_CTRL_FLR) {
u8 cap; int ret;
*ctrl &= ~PCI_AF_CTRL_FLR;
ret = pci_user_read_config_byte(vdev->pdev,
pos - offset + PCI_AF_CAP,
&cap);
if (alloc_perm_bits(perm, pci_ext_cap_length[PCI_EXT_CAP_ID_ERR])) return -ENOMEM;
/* * Virtualize the first dword of all express capabilities * because it includes the next pointer. This lets us later * remove capabilities from the chain if we need to.
*/
p_setd(perm, 0, ALL_VIRT, NO_WRITE);
int __init vfio_pci_init_perm_bits(void)
{ int ret;
/* Basic config space */
ret = init_pci_cap_basic_perm(&cap_perms[PCI_CAP_ID_BASIC]);
/* Capabilities */
ret |= init_pci_cap_pm_perm(&cap_perms[PCI_CAP_ID_PM]);
ret |= init_pci_cap_vpd_perm(&cap_perms[PCI_CAP_ID_VPD]);
ret |= init_pci_cap_pcix_perm(&cap_perms[PCI_CAP_ID_PCIX]);
cap_perms[PCI_CAP_ID_VNDR].writefn = vfio_raw_config_write;
ret |= init_pci_cap_exp_perm(&cap_perms[PCI_CAP_ID_EXP]);
ret |= init_pci_cap_af_perm(&cap_perms[PCI_CAP_ID_AF]);
/* Extended capabilities */
ret |= init_pci_ext_cap_err_perm(&ecap_perms[PCI_EXT_CAP_ID_ERR]);
ret |= init_pci_ext_cap_pwr_perm(&ecap_perms[PCI_EXT_CAP_ID_PWR]);
ecap_perms[PCI_EXT_CAP_ID_VNDR].writefn = vfio_raw_config_write;
ecap_perms[PCI_EXT_CAP_ID_DVSEC].writefn = vfio_raw_config_write;
if (ret)
vfio_pci_uninit_perm_bits();
return ret;
}
staticint vfio_find_cap_start(struct vfio_pci_core_device *vdev, int pos)
{
u8 cap; int base = (pos >= PCI_CFG_SPACE_SIZE) ? PCI_CFG_SPACE_SIZE :
PCI_STD_HEADER_SIZEOF;
cap = vdev->pci_config_map[pos];
if (cap == PCI_CAP_ID_BASIC) return 0;
/* XXX Can we have to abutting capabilities of the same type? */ while (pos - 1 >= base && vdev->pci_config_map[pos - 1] == cap)
pos--;
return pos;
}
staticint vfio_msi_config_read(struct vfio_pci_core_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 *val)
{ /* Update max available queue size from msi_qmax */ if (offset <= PCI_MSI_FLAGS && offset + count >= PCI_MSI_FLAGS) {
__le16 *flags; int start;
/* Write back to virt and to hardware */
*pflags = cpu_to_le16(flags);
ret = pci_user_write_config_word(vdev->pdev,
start + PCI_MSI_FLAGS,
flags); if (ret) return ret;
}
return count;
}
/* * MSI determination is per-device, so this routine gets used beyond * initialization time. Don't add __init
*/ staticint init_pci_cap_msi_perm(struct perm_bits *perm, int len, u16 flags)
{ if (alloc_perm_bits(perm, len)) return -ENOMEM;
/* * Port arbitration tables are root & switch only; * function arbitration tables are function 0 only. * In either case, we'll never let user write them so * we don't care how big they are
*/
len += (1 + evcc) * PCI_CAP_VC_PER_VC_SIZEOF; if (vc_arb) {
len = round_up(len, 16);
len += vc_arb / 8;
} return len;
}
switch (cap) { case PCI_CAP_ID_MSI: return vfio_msi_cap_len(vdev, pos); case PCI_CAP_ID_PCIX:
ret = pci_read_config_word(pdev, pos + PCI_X_CMD, &word); if (ret) return pcibios_err_to_errno(ret);
if (PCI_X_CMD_VERSION(word)) { if (pdev->cfg_size > PCI_CFG_SPACE_SIZE) { /* Test for extended capabilities */
pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE,
&dword);
vdev->extended_caps = (dword != 0);
} return PCI_CAP_PCIX_SIZEOF_V2;
} else return PCI_CAP_PCIX_SIZEOF_V0; case PCI_CAP_ID_VNDR: /* length follows next field */
ret = pci_read_config_byte(pdev, pos + PCI_CAP_FLAGS, &byte); if (ret) return pcibios_err_to_errno(ret);
return byte; case PCI_CAP_ID_EXP: if (pdev->cfg_size > PCI_CFG_SPACE_SIZE) { /* Test for extended capabilities */
pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &dword);
vdev->extended_caps = (dword != 0);
}
/* length based on version and type */ if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1) { if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END) return 0xc; /* "All Devices" only, no link */ return PCI_CAP_EXP_ENDPOINT_SIZEOF_V1;
} else { if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END) return 0x2c; /* No link */ return PCI_CAP_EXP_ENDPOINT_SIZEOF_V2;
} case PCI_CAP_ID_HT:
ret = pci_read_config_byte(pdev, pos + 3, &byte); if (ret) return pcibios_err_to_errno(ret);
return (byte & HT_3BIT_CAP_MASK) ?
HT_CAP_SIZEOF_SHORT : HT_CAP_SIZEOF_LONG; case PCI_CAP_ID_SATA:
ret = pci_read_config_byte(pdev, pos + PCI_SATA_REGS, &byte); if (ret) return pcibios_err_to_errno(ret);
byte &= PCI_SATA_REGS_MASK; if (byte == PCI_SATA_REGS_INLINE) return PCI_SATA_SIZEOF_LONG; else return PCI_SATA_SIZEOF_SHORT; default:
pci_warn(pdev, "%s: unknown length for PCI cap %#x@%#x\n",
__func__, cap, pos);
}
switch (ecap) { case PCI_EXT_CAP_ID_VNDR:
ret = pci_read_config_dword(pdev, epos + PCI_VNDR_HEADER,
&dword); if (ret) return pcibios_err_to_errno(ret);
return PCI_VNDR_HEADER_LEN(dword); case PCI_EXT_CAP_ID_VC: case PCI_EXT_CAP_ID_VC9: case PCI_EXT_CAP_ID_MFVC: return vfio_vc_cap_len(vdev, epos); case PCI_EXT_CAP_ID_ACS:
ret = pci_read_config_byte(pdev, epos + PCI_ACS_CAP, &byte); if (ret) return pcibios_err_to_errno(ret);
if (byte & PCI_ACS_EC) { int bits;
ret = pci_read_config_byte(pdev,
epos + PCI_ACS_EGRESS_BITS,
&byte); if (ret) return pcibios_err_to_errno(ret);
staticint vfio_fill_vconfig_bytes(struct vfio_pci_core_device *vdev, int offset, int size)
{ struct pci_dev *pdev = vdev->pdev; int ret = 0;
/* * We try to read physical config space in the largest chunks * we can, assuming that all of the fields support dword access. * pci_save_state() makes this same assumption and seems to do ok.
*/ while (size) { int filled;
/* Any capabilities? */
ret = pci_read_config_word(pdev, PCI_STATUS, &status); if (ret) return ret;
if (!(status & PCI_STATUS_CAP_LIST)) return 0; /* Done */
ret = pci_read_config_byte(pdev, PCI_CAPABILITY_LIST, &pos); if (ret) return ret;
/* Mark the previous position in case we want to skip a capability */
prev = &vdev->vconfig[PCI_CAPABILITY_LIST];
/* We can bound our loop, capabilities are dword aligned */
loops = (PCI_CFG_SPACE_SIZE - PCI_STD_HEADER_SIZEOF) / PCI_CAP_SIZEOF; while (pos && loops--) {
u8 next; int i, len = 0;
ret = pci_read_config_byte(pdev, pos, &cap); if (ret) return ret;
ret = pci_read_config_byte(pdev,
pos + PCI_CAP_LIST_NEXT, &next); if (ret) return ret;
/* * ID 0 is a NULL capability, conflicting with our fake * PCI_CAP_ID_BASIC. As it has no content, consider it * hidden for now.
*/ if (cap && cap <= PCI_CAP_ID_MAX) {
len = pci_cap_length[cap]; if (len == 0xFF) { /* Variable length */
len = vfio_cap_len(vdev, cap, pos); if (len < 0) return len;
}
}
if (!len) {
pci_dbg(pdev, "%s: hiding cap %#x@%#x\n", __func__,
cap, pos);
*prev = next;
pos = next; continue;
}
/* Sanity check, do we overlap other capabilities? */ for (i = 0; i < len; i++) { if (likely(map[pos + i] == PCI_CAP_ID_INVALID)) continue;
pci_warn(pdev, "%s: PCI config conflict @%#x, was cap %#x now cap %#x\n",
__func__, pos + i, map[pos + i], cap);
}
/* If we didn't fill any capabilities, clear the status flag */ if (!caps) {
__le16 *vstatus = (__le16 *)&vdev->vconfig[PCI_STATUS];
*vstatus &= ~cpu_to_le16(PCI_STATUS_CAP_LIST);
}
/* If not the first in the chain, we can skip over it */ if (prev) {
u32 val = epos = PCI_EXT_CAP_NEXT(header);
*prev &= cpu_to_le32(~(0xffcU << 20));
*prev |= cpu_to_le32(val << 20); continue;
}
/* * Otherwise, fill in a placeholder, the direct * readfn will virtualize this automatically
*/
len = PCI_CAP_SIZEOF;
hidden = true;
}
for (i = 0; i < len; i++) { if (likely(map[epos + i] == PCI_CAP_ID_INVALID)) continue;
pci_warn(pdev, "%s: PCI config conflict @%#x, was ecap %#x now ecap %#x\n",
__func__, epos + i, map[epos + i], ecap);
}
/* * Even though ecap is 2 bytes, we're currently a long way * from exceeding 1 byte capabilities. If we ever make it * up to 0xFE we'll need to up this to a two-byte, byte map.
*/
BUILD_BUG_ON(PCI_EXT_CAP_ID_MAX >= PCI_CAP_ID_INVALID_VIRT);
memset(map + epos, ecap, len);
ret = vfio_fill_vconfig_bytes(vdev, epos, len); if (ret) return ret;
/* * If we're just using this capability to anchor the list, * hide the real ID. Only count real ecaps. XXX PCI spec * indicates to use cap id = 0, version = 0, next = 0 if * ecaps are absent, hope users check all the way to next.
*/ if (hidden)
*(__le32 *)&vdev->vconfig[epos] &=
cpu_to_le32((0xffcU << 20)); else
ecaps++;
if (!ecaps)
*(u32 *)&vdev->vconfig[PCI_CFG_SPACE_SIZE] = 0;
return 0;
}
/* * Nag about hardware bugs, hopefully to have vendors fix them, but at least * to collect a list of dependencies for the VF INTx pin quirk below.
*/ staticconststruct pci_device_id known_bogus_vf_intx_pin[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x270c) },
{}
};
/* * For each device we allocate a pci_config_map that indicates the * capability occupying each dword and thus the struct perm_bits we * use for read and write. We also allocate a virtualized config * space which tracks reads and writes to bits that we emulate for * the user. Initial values filled from device. * * Using shared struct perm_bits between all vfio-pci devices saves * us from allocating cfg_size buffers for virt and write for every * device. We could remove vconfig and allocate individual buffers * for each area requiring emulated bits, but the array of pointers * would be comparable in size (at least for standard config space).
*/ int vfio_config_init(struct vfio_pci_core_device *vdev)
{ struct pci_dev *pdev = vdev->pdev;
u8 *map, *vconfig; int ret;
/* * Config space, caps and ecaps are all dword aligned, so we could * use one byte per dword to record the type. However, there are * no requirements on the length of a capability, so the gap between * capabilities needs byte granularity.
*/
map = kmalloc(pdev->cfg_size, GFP_KERNEL_ACCOUNT); if (!map) return -ENOMEM;
/* * Per SR-IOV spec rev 1.1, 3.4.1.18 the interrupt pin register * does not apply to VFs and VFs must implement this register * as read-only with value zero. Userspace is not readily able * to identify whether a device is a VF and thus that the pin * definition on the device is bogus should it violate this * requirement. We already virtualize the pin register for * other purposes, so we simply need to replace the bogus value * and consider VFs when we determine INTx IRQ count.
*/ if (vconfig[PCI_INTERRUPT_PIN] &&
!pci_match_id(known_bogus_vf_intx_pin, pdev))
pci_warn(pdev, "Hardware bug: VF reports bogus INTx pin %d\n",
vconfig[PCI_INTERRUPT_PIN]);
vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */
} if (pdev->no_command_memory) { /* * VFs and devices that set pdev->no_command_memory do not * implement the memory enable bit of the COMMAND register * therefore we'll not have it set in our initial copy of * config space after pci_enable_device(). For consistency * with PFs, set the virtual enable bit here.
*/
*(__le16 *)&vconfig[PCI_COMMAND] |=
cpu_to_le16(PCI_COMMAND_MEMORY);
}
/* * Find the remaining number of bytes in a dword that match the given * position. Stop at either the end of the capability or the dword boundary.
*/ static size_t vfio_pci_cap_remaining_dword(struct vfio_pci_core_device *vdev,
loff_t pos)
{
u8 cap = vdev->pci_config_map[pos];
size_t i;
for (i = 1; (pos + i) % 4 && vdev->pci_config_map[pos + i] == cap; i++) /* nop */;
/* * Chop accesses into aligned chunks containing no more than a * single capability. Caller increments to the next chunk.
*/
count = min(count, vfio_pci_cap_remaining_dword(vdev, *ppos)); if (count >= 4 && !(*ppos % 4))
count = 4; elseif (count >= 2 && !(*ppos % 2))
count = 2; else
count = 1;
ret = count;
cap_id = vdev->pci_config_map[*ppos];
if (cap_id == PCI_CAP_ID_INVALID) {
perm = &unassigned_perms;
cap_start = *ppos;
} elseif (cap_id == PCI_CAP_ID_INVALID_VIRT) {
perm = &virt_perms;
cap_start = *ppos;
} else { if (*ppos >= PCI_CFG_SPACE_SIZE) { /* * We can get a cap_id that exceeds PCI_EXT_CAP_ID_MAX * if we're hiding an unknown capability at the start * of the extended capability list. Use default, ro * access, which will virtualize the id and next values.
*/ if (cap_id > PCI_EXT_CAP_ID_MAX)
perm = &direct_ro_perms; else
perm = &ecap_perms[cap_id];
/** * vfio_pci_core_range_intersect_range() - Determine overlap between a buffer * and register offset ranges. * @buf_start: start offset of the buffer * @buf_cnt: number of buffer bytes * @reg_start: start register offset * @reg_cnt: number of register bytes * @buf_offset: start offset of overlap in the buffer * @intersect_count: number of overlapping bytes * @register_offset: start offset of overlap in register * * Returns: true if there is overlap, false if not. * The overlap start and size is returned through function args.
*/ bool vfio_pci_core_range_intersect_range(loff_t buf_start, size_t buf_cnt,
loff_t reg_start, size_t reg_cnt,
loff_t *buf_offset,
size_t *intersect_count,
size_t *register_offset)
{ if (buf_start <= reg_start &&
buf_start + buf_cnt > reg_start) {
*buf_offset = reg_start - buf_start;
*intersect_count = min_t(size_t, reg_cnt,
buf_start + buf_cnt - reg_start);
*register_offset = 0; returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.