Lines Matching +full:non +full:- +full:contiguous
1 // SPDX-License-Identifier: GPL-2.0-only
8 * Register a device specific region through which to provide read-only
34 * igd_opregion_shift_copy() - Copy OpRegion to user buffer and shift position.
44 * Return: 0 on success, -EFAULT otherwise.
55 return -EFAULT; in igd_opregion_shift_copy()
59 *remaining -= bytes; in igd_opregion_shift_copy()
68 unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS; in vfio_pci_igd_rw()
69 struct igd_opregion_vbt *opregionvbt = vdev->region[i].data; in vfio_pci_igd_rw()
73 if (pos >= vdev->region[i].size || iswrite) in vfio_pci_igd_rw()
74 return -EINVAL; in vfio_pci_igd_rw()
76 count = min_t(size_t, count, vdev->region[i].size - pos); in vfio_pci_igd_rw()
81 size_t bytes = min_t(size_t, remaining, OPREGION_VERSION - pos); in vfio_pci_igd_rw()
84 opregionvbt->opregion + pos, &pos, in vfio_pci_igd_rw()
86 return -EFAULT; in vfio_pci_igd_rw()
92 OPREGION_VERSION + sizeof(__le16) - pos); in vfio_pci_igd_rw()
93 __le16 version = *(__le16 *)(opregionvbt->opregion + in vfio_pci_igd_rw()
97 if (le16_to_cpu(version) == 0x0200 && opregionvbt->vbt_ex) in vfio_pci_igd_rw()
102 (pos - OPREGION_VERSION), in vfio_pci_igd_rw()
104 return -EFAULT; in vfio_pci_igd_rw()
109 size_t bytes = min_t(size_t, remaining, OPREGION_RVDA - pos); in vfio_pci_igd_rw()
112 opregionvbt->opregion + pos, &pos, in vfio_pci_igd_rw()
114 return -EFAULT; in vfio_pci_igd_rw()
120 OPREGION_RVDA + sizeof(__le64) - pos); in vfio_pci_igd_rw()
121 __le64 rvda = cpu_to_le64(opregionvbt->vbt_ex ? in vfio_pci_igd_rw()
125 (u8 *)&rvda + (pos - OPREGION_RVDA), in vfio_pci_igd_rw()
127 return -EFAULT; in vfio_pci_igd_rw()
132 size_t bytes = min_t(size_t, remaining, OPREGION_SIZE - pos); in vfio_pci_igd_rw()
135 opregionvbt->opregion + pos, &pos, in vfio_pci_igd_rw()
137 return -EFAULT; in vfio_pci_igd_rw()
142 copy_to_user(buf + off, opregionvbt->vbt_ex + (pos - OPREGION_SIZE), in vfio_pci_igd_rw()
144 return -EFAULT; in vfio_pci_igd_rw()
154 struct igd_opregion_vbt *opregionvbt = region->data; in vfio_pci_igd_release()
156 if (opregionvbt->vbt_ex) in vfio_pci_igd_release()
157 memunmap(opregionvbt->vbt_ex); in vfio_pci_igd_release()
159 memunmap(opregionvbt->opregion); in vfio_pci_igd_release()
170 __le32 *dwordp = (__le32 *)(vdev->vconfig + OPREGION_PCI_ADDR); in vfio_pci_igd_opregion_init()
176 ret = pci_read_config_dword(vdev->pdev, OPREGION_PCI_ADDR, &addr); in vfio_pci_igd_opregion_init()
181 return -ENODEV; in vfio_pci_igd_opregion_init()
185 return -ENOMEM; in vfio_pci_igd_opregion_init()
187 opregionvbt->opregion = memremap(addr, OPREGION_SIZE, MEMREMAP_WB); in vfio_pci_igd_opregion_init()
188 if (!opregionvbt->opregion) { in vfio_pci_igd_opregion_init()
190 return -ENOMEM; in vfio_pci_igd_opregion_init()
193 if (memcmp(opregionvbt->opregion, OPREGION_SIGNATURE, 16)) { in vfio_pci_igd_opregion_init()
194 memunmap(opregionvbt->opregion); in vfio_pci_igd_opregion_init()
196 return -EINVAL; in vfio_pci_igd_opregion_init()
199 size = le32_to_cpu(*(__le32 *)(opregionvbt->opregion + 16)); in vfio_pci_igd_opregion_init()
201 memunmap(opregionvbt->opregion); in vfio_pci_igd_opregion_init()
203 return -EINVAL; in vfio_pci_igd_opregion_init()
221 * between 2.0 and 2.1), exposing OpRegion and VBT as a contiguous range in vfio_pci_igd_opregion_init()
223 * non-contiguous VBT through a single vfio region. From r/w ops view, in vfio_pci_igd_opregion_init()
224 * only contiguous VBT after OpRegion with version 2.1+ is exposed, in vfio_pci_igd_opregion_init()
225 * regardless the host OpRegion is 2.0 or non-contiguous 2.1+. The r/w in vfio_pci_igd_opregion_init()
226 * ops will on-the-fly shift the actural offset into VBT so that data at in vfio_pci_igd_opregion_init()
229 version = le16_to_cpu(*(__le16 *)(opregionvbt->opregion + in vfio_pci_igd_opregion_init()
232 u64 rvda = le64_to_cpu(*(__le64 *)(opregionvbt->opregion + in vfio_pci_igd_opregion_init()
234 u32 rvds = le32_to_cpu(*(__le32 *)(opregionvbt->opregion + in vfio_pci_igd_opregion_init()
237 /* The extended VBT is valid only when RVDA/RVDS are non-zero */ in vfio_pci_igd_opregion_init()
251 opregionvbt->vbt_ex = memremap(addr, rvds, MEMREMAP_WB); in vfio_pci_igd_opregion_init()
252 if (!opregionvbt->vbt_ex) { in vfio_pci_igd_opregion_init()
253 memunmap(opregionvbt->opregion); in vfio_pci_igd_opregion_init()
255 return -ENOMEM; in vfio_pci_igd_opregion_init()
265 if (opregionvbt->vbt_ex) in vfio_pci_igd_opregion_init()
266 memunmap(opregionvbt->vbt_ex); in vfio_pci_igd_opregion_init()
268 memunmap(opregionvbt->opregion); in vfio_pci_igd_opregion_init()
275 memset(vdev->pci_config_map + OPREGION_PCI_ADDR, in vfio_pci_igd_opregion_init()
285 unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS; in vfio_pci_igd_cfg_rw()
286 struct pci_dev *pdev = vdev->region[i].data; in vfio_pci_igd_cfg_rw()
291 if (pos >= vdev->region[i].size || iswrite) in vfio_pci_igd_cfg_rw()
292 return -EINVAL; in vfio_pci_igd_cfg_rw()
294 size = count = min(count, (size_t)(vdev->region[i].size - pos)); in vfio_pci_igd_cfg_rw()
303 if (copy_to_user(buf + count - size, &val, 1)) in vfio_pci_igd_cfg_rw()
304 return -EFAULT; in vfio_pci_igd_cfg_rw()
307 size--; in vfio_pci_igd_cfg_rw()
319 if (copy_to_user(buf + count - size, &lval, 2)) in vfio_pci_igd_cfg_rw()
320 return -EFAULT; in vfio_pci_igd_cfg_rw()
323 size -= 2; in vfio_pci_igd_cfg_rw()
335 if (copy_to_user(buf + count - size, &lval, 4)) in vfio_pci_igd_cfg_rw()
336 return -EFAULT; in vfio_pci_igd_cfg_rw()
339 size -= 4; in vfio_pci_igd_cfg_rw()
351 if (copy_to_user(buf + count - size, &lval, 2)) in vfio_pci_igd_cfg_rw()
352 return -EFAULT; in vfio_pci_igd_cfg_rw()
355 size -= 2; in vfio_pci_igd_cfg_rw()
365 if (copy_to_user(buf + count - size, &val, 1)) in vfio_pci_igd_cfg_rw()
366 return -EFAULT; in vfio_pci_igd_cfg_rw()
369 size--; in vfio_pci_igd_cfg_rw()
380 struct pci_dev *pdev = region->data; in vfio_pci_igd_cfg_release()
397 return -ENODEV; in vfio_pci_igd_cfg_init()
399 if (host_bridge->vendor != PCI_VENDOR_ID_INTEL || in vfio_pci_igd_cfg_init()
400 host_bridge->class != (PCI_CLASS_BRIDGE_HOST << 8)) { in vfio_pci_igd_cfg_init()
402 return -EINVAL; in vfio_pci_igd_cfg_init()
408 &vfio_pci_igd_cfg_regops, host_bridge->cfg_size, in vfio_pci_igd_cfg_init()
417 return -ENODEV; in vfio_pci_igd_cfg_init()
419 if (lpc_bridge->vendor != PCI_VENDOR_ID_INTEL || in vfio_pci_igd_cfg_init()
420 lpc_bridge->class != (PCI_CLASS_BRIDGE_ISA << 8)) { in vfio_pci_igd_cfg_init()
422 return -EINVAL; in vfio_pci_igd_cfg_init()
428 &vfio_pci_igd_cfg_regops, lpc_bridge->cfg_size, in vfio_pci_igd_cfg_init()