mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 11:56:58 +00:00
Speculative prefetches from CPU to GPU memory until the GPU is ready after reset can cause harmless corrected RAS events to be logged on Grace systems. It is thus preferred that the mapping not be re-established until the GPU is ready post reset. The GPU readiness can be checked through BAR0 registers similar to the checking at the time of device probe. It can take several seconds for the GPU to be ready. So it is desirable that the time overlaps as much of the VM startup as possible to reduce impact on the VM bootup time. The GPU readiness state is thus checked on the first fault/huge_fault request or read/write access which amortizes the GPU readiness time. The first fault and read/write checks the GPU state when the reset_done flag - which denotes whether the GPU has just been reset. The memory_lock is taken across map/access to avoid races with GPU reset. Also check if the memory is enabled, before waiting for GPU to be ready. Otherwise the readiness check would block for 30s. Lastly added PM handling wrapping on read/write access. Cc: Shameer Kolothum <skolothumtho@nvidia.com> Cc: Alex Williamson <alex@shazbot.org> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Vikram Sethi <vsethi@nvidia.com> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com> Suggested-by: Alex Williamson <alex@shazbot.org> Signed-off-by: Ankit Agrawal <ankita@nvidia.com> Link: https://lore.kernel.org/r/20251127170632.3477-7-ankita@nvidia.com Signed-off-by: Alex Williamson <alex@shazbot.org>
137 lines
4.0 KiB
C
137 lines
4.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
#ifndef VFIO_PCI_PRIV_H
|
|
#define VFIO_PCI_PRIV_H
|
|
|
|
#include <linux/vfio_pci_core.h>
|
|
|
|
/* Special capability IDs predefined access */
|
|
#define PCI_CAP_ID_INVALID 0xFF /* default raw access */
|
|
#define PCI_CAP_ID_INVALID_VIRT 0xFE /* default virt access */
|
|
|
|
/* Cap maximum number of ioeventfds per device (arbitrary) */
|
|
#define VFIO_PCI_IOEVENTFD_MAX 1000
|
|
|
|
struct vfio_pci_ioeventfd {
|
|
struct list_head next;
|
|
struct vfio_pci_core_device *vdev;
|
|
struct virqfd *virqfd;
|
|
void __iomem *addr;
|
|
uint64_t data;
|
|
loff_t pos;
|
|
int bar;
|
|
int count;
|
|
bool test_mem;
|
|
};
|
|
|
|
bool vfio_pci_intx_mask(struct vfio_pci_core_device *vdev);
|
|
void vfio_pci_intx_unmask(struct vfio_pci_core_device *vdev);
|
|
|
|
int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev,
|
|
struct vfio_pci_eventfd __rcu **peventfd,
|
|
struct eventfd_ctx *ctx);
|
|
|
|
int vfio_pci_set_irqs_ioctl(struct vfio_pci_core_device *vdev, uint32_t flags,
|
|
unsigned index, unsigned start, unsigned count,
|
|
void *data);
|
|
|
|
ssize_t vfio_pci_config_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
|
size_t count, loff_t *ppos, bool iswrite);
|
|
|
|
ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
|
size_t count, loff_t *ppos, bool iswrite);
|
|
|
|
#ifdef CONFIG_VFIO_PCI_VGA
|
|
ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev, char __user *buf,
|
|
size_t count, loff_t *ppos, bool iswrite);
|
|
#else
|
|
static inline ssize_t vfio_pci_vga_rw(struct vfio_pci_core_device *vdev,
|
|
char __user *buf, size_t count,
|
|
loff_t *ppos, bool iswrite)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
#endif
|
|
|
|
int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
|
|
uint64_t data, int count, int fd);
|
|
|
|
int vfio_pci_init_perm_bits(void);
|
|
void vfio_pci_uninit_perm_bits(void);
|
|
|
|
int vfio_config_init(struct vfio_pci_core_device *vdev);
|
|
void vfio_config_free(struct vfio_pci_core_device *vdev);
|
|
|
|
int vfio_pci_set_power_state(struct vfio_pci_core_device *vdev,
|
|
pci_power_t state);
|
|
|
|
void vfio_pci_zap_and_down_write_memory_lock(struct vfio_pci_core_device *vdev);
|
|
u16 vfio_pci_memory_lock_and_enable(struct vfio_pci_core_device *vdev);
|
|
void vfio_pci_memory_unlock_and_restore(struct vfio_pci_core_device *vdev,
|
|
u16 cmd);
|
|
|
|
#ifdef CONFIG_VFIO_PCI_IGD
|
|
bool vfio_pci_is_intel_display(struct pci_dev *pdev);
|
|
int vfio_pci_igd_init(struct vfio_pci_core_device *vdev);
|
|
#else
|
|
static inline bool vfio_pci_is_intel_display(struct pci_dev *pdev)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline int vfio_pci_igd_init(struct vfio_pci_core_device *vdev)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_VFIO_PCI_ZDEV_KVM
|
|
int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
|
|
struct vfio_info_cap *caps);
|
|
int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev);
|
|
void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev);
|
|
#else
|
|
static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
|
|
struct vfio_info_cap *caps)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev)
|
|
{}
|
|
#endif
|
|
|
|
static inline bool vfio_pci_is_vga(struct pci_dev *pdev)
|
|
{
|
|
return (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
|
|
}
|
|
|
|
#ifdef CONFIG_VFIO_PCI_DMABUF
|
|
int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
|
|
struct vfio_device_feature_dma_buf __user *arg,
|
|
size_t argsz);
|
|
void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_device *vdev);
|
|
void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev, bool revoked);
|
|
#else
|
|
static inline int
|
|
vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
|
|
struct vfio_device_feature_dma_buf __user *arg,
|
|
size_t argsz)
|
|
{
|
|
return -ENOTTY;
|
|
}
|
|
static inline void vfio_pci_dma_buf_cleanup(struct vfio_pci_core_device *vdev)
|
|
{
|
|
}
|
|
static inline void vfio_pci_dma_buf_move(struct vfio_pci_core_device *vdev,
|
|
bool revoked)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#endif
|