cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

pci.h (7189B)


      1/*
      2 * vfio based device assignment support - PCI devices
      3 *
      4 * Copyright Red Hat, Inc. 2012-2015
      5 *
      6 * Authors:
      7 *  Alex Williamson <alex.williamson@redhat.com>
      8 *
      9 * This work is licensed under the terms of the GNU GPL, version 2.  See
     10 * the COPYING file in the top-level directory.
     11 */
     12#ifndef HW_VFIO_VFIO_PCI_H
     13#define HW_VFIO_VFIO_PCI_H
     14
     15#include "exec/memory.h"
     16#include "hw/pci/pci.h"
     17#include "hw/vfio/vfio-common.h"
     18#include "qemu/event_notifier.h"
     19#include "qemu/queue.h"
     20#include "qemu/timer.h"
     21#include "qom/object.h"
     22
     23#define PCI_ANY_ID (~0)
     24
     25struct VFIOPCIDevice;
     26
     27typedef struct VFIOIOEventFD {
     28    QLIST_ENTRY(VFIOIOEventFD) next;
     29    MemoryRegion *mr;
     30    hwaddr addr;
     31    unsigned size;
     32    uint64_t data;
     33    EventNotifier e;
     34    VFIORegion *region;
     35    hwaddr region_addr;
     36    bool dynamic; /* Added runtime, removed on device reset */
     37    bool vfio;
     38} VFIOIOEventFD;
     39
     40typedef struct VFIOQuirk {
     41    QLIST_ENTRY(VFIOQuirk) next;
     42    void *data;
     43    QLIST_HEAD(, VFIOIOEventFD) ioeventfds;
     44    int nr_mem;
     45    MemoryRegion *mem;
     46    void (*reset)(struct VFIOPCIDevice *vdev, struct VFIOQuirk *quirk);
     47} VFIOQuirk;
     48
     49typedef struct VFIOBAR {
     50    VFIORegion region;
     51    MemoryRegion *mr;
     52    size_t size;
     53    uint8_t type;
     54    bool ioport;
     55    bool mem64;
     56    QLIST_HEAD(, VFIOQuirk) quirks;
     57} VFIOBAR;
     58
     59typedef struct VFIOVGARegion {
     60    MemoryRegion mem;
     61    off_t offset;
     62    int nr;
     63    QLIST_HEAD(, VFIOQuirk) quirks;
     64} VFIOVGARegion;
     65
     66typedef struct VFIOVGA {
     67    off_t fd_offset;
     68    int fd;
     69    VFIOVGARegion region[QEMU_PCI_VGA_NUM_REGIONS];
     70} VFIOVGA;
     71
     72typedef struct VFIOINTx {
     73    bool pending; /* interrupt pending */
     74    bool kvm_accel; /* set when QEMU bypass through KVM enabled */
     75    uint8_t pin; /* which pin to pull for qemu_set_irq */
     76    EventNotifier interrupt; /* eventfd triggered on interrupt */
     77    EventNotifier unmask; /* eventfd for unmask on QEMU bypass */
     78    PCIINTxRoute route; /* routing info for QEMU bypass */
     79    uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
     80    QEMUTimer *mmap_timer; /* enable mmaps after periods w/o interrupts */
     81} VFIOINTx;
     82
     83typedef struct VFIOMSIVector {
     84    /*
     85     * Two interrupt paths are configured per vector.  The first, is only used
     86     * for interrupts injected via QEMU.  This is typically the non-accel path,
     87     * but may also be used when we want QEMU to handle masking and pending
     88     * bits.  The KVM path bypasses QEMU and is therefore higher performance,
     89     * but requires masking at the device.  virq is used to track the MSI route
     90     * through KVM, thus kvm_interrupt is only available when virq is set to a
     91     * valid (>= 0) value.
     92     */
     93    EventNotifier interrupt;
     94    EventNotifier kvm_interrupt;
     95    struct VFIOPCIDevice *vdev; /* back pointer to device */
     96    int virq;
     97    bool use;
     98} VFIOMSIVector;
     99
    100enum {
    101    VFIO_INT_NONE = 0,
    102    VFIO_INT_INTx = 1,
    103    VFIO_INT_MSI  = 2,
    104    VFIO_INT_MSIX = 3,
    105};
    106
    107/* Cache of MSI-X setup */
    108typedef struct VFIOMSIXInfo {
    109    uint8_t table_bar;
    110    uint8_t pba_bar;
    111    uint16_t entries;
    112    uint32_t table_offset;
    113    uint32_t pba_offset;
    114    unsigned long *pending;
    115} VFIOMSIXInfo;
    116
    117#define TYPE_VFIO_PCI "vfio-pci"
    118OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI)
    119
    120struct VFIOPCIDevice {
    121    PCIDevice pdev;
    122    VFIODevice vbasedev;
    123    VFIOINTx intx;
    124    unsigned int config_size;
    125    uint8_t *emulated_config_bits; /* QEMU emulated bits, little-endian */
    126    off_t config_offset; /* Offset of config space region within device fd */
    127    unsigned int rom_size;
    128    off_t rom_offset; /* Offset of ROM region within device fd */
    129    void *rom;
    130    int msi_cap_size;
    131    VFIOMSIVector *msi_vectors;
    132    VFIOMSIXInfo *msix;
    133    int nr_vectors; /* Number of MSI/MSIX vectors currently in use */
    134    int interrupt; /* Current interrupt type */
    135    VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
    136    VFIOVGA *vga; /* 0xa0000, 0x3b0, 0x3c0 */
    137    void *igd_opregion;
    138    PCIHostDeviceAddress host;
    139    EventNotifier err_notifier;
    140    EventNotifier req_notifier;
    141    int (*resetfn)(struct VFIOPCIDevice *);
    142    uint32_t vendor_id;
    143    uint32_t device_id;
    144    uint32_t sub_vendor_id;
    145    uint32_t sub_device_id;
    146    uint32_t features;
    147#define VFIO_FEATURE_ENABLE_VGA_BIT 0
    148#define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
    149#define VFIO_FEATURE_ENABLE_REQ_BIT 1
    150#define VFIO_FEATURE_ENABLE_REQ (1 << VFIO_FEATURE_ENABLE_REQ_BIT)
    151#define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2
    152#define VFIO_FEATURE_ENABLE_IGD_OPREGION \
    153                                (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT)
    154    OnOffAuto display;
    155    uint32_t display_xres;
    156    uint32_t display_yres;
    157    int32_t bootindex;
    158    uint32_t igd_gms;
    159    OffAutoPCIBAR msix_relo;
    160    uint8_t pm_cap;
    161    uint8_t nv_gpudirect_clique;
    162    bool pci_aer;
    163    bool req_enabled;
    164    bool has_flr;
    165    bool has_pm_reset;
    166    bool rom_read_failed;
    167    bool no_kvm_intx;
    168    bool no_kvm_msi;
    169    bool no_kvm_msix;
    170    bool no_geforce_quirks;
    171    bool no_kvm_ioeventfd;
    172    bool no_vfio_ioeventfd;
    173    bool enable_ramfb;
    174    VFIODisplay *dpy;
    175    Notifier irqchip_change_notifier;
    176};
    177
    178/* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match hw */
    179static inline bool vfio_pci_is(VFIOPCIDevice *vdev, uint32_t vendor, uint32_t device)
    180{
    181    return (vendor == PCI_ANY_ID || vendor == vdev->vendor_id) &&
    182           (device == PCI_ANY_ID || device == vdev->device_id);
    183}
    184
    185static inline bool vfio_is_vga(VFIOPCIDevice *vdev)
    186{
    187    PCIDevice *pdev = &vdev->pdev;
    188    uint16_t class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
    189
    190    return class == PCI_CLASS_DISPLAY_VGA;
    191}
    192
    193uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
    194void vfio_pci_write_config(PCIDevice *pdev,
    195                           uint32_t addr, uint32_t val, int len);
    196
    197uint64_t vfio_vga_read(void *opaque, hwaddr addr, unsigned size);
    198void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size);
    199
    200bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev);
    201void vfio_vga_quirk_setup(VFIOPCIDevice *vdev);
    202void vfio_vga_quirk_exit(VFIOPCIDevice *vdev);
    203void vfio_vga_quirk_finalize(VFIOPCIDevice *vdev);
    204void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr);
    205void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr);
    206void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr);
    207void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
    208int vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
    209void vfio_quirk_reset(VFIOPCIDevice *vdev);
    210VFIOQuirk *vfio_quirk_alloc(int nr_mem);
    211void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr);
    212
    213extern const PropertyInfo qdev_prop_nv_gpudirect_clique;
    214
    215int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
    216
    217int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
    218                               struct vfio_region_info *info,
    219                               Error **errp);
    220int vfio_pci_nvidia_v100_ram_init(VFIOPCIDevice *vdev, Error **errp);
    221int vfio_pci_nvlink2_init(VFIOPCIDevice *vdev, Error **errp);
    222
    223void vfio_display_reset(VFIOPCIDevice *vdev);
    224int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
    225void vfio_display_finalize(VFIOPCIDevice *vdev);
    226
    227#endif /* HW_VFIO_VFIO_PCI_H */