summary refs log tree commit diff stats
path: root/include/hw/vfio/vfio-common.h
blob: 92381c6160925613dfc1d1de678479f70976c796 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 * common header for vfio based device assignment support
 *
 * Copyright Red Hat, Inc. 2012
 *
 * Authors:
 *  Alex Williamson <alex.williamson@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 * Based on qemu-kvm device-assignment:
 *  Adapted for KVM by Qumranet.
 *  Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com)
 *  Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com)
 *  Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com)
 *  Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com)
 *  Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com)
 */

#ifndef HW_VFIO_VFIO_COMMON_H
#define HW_VFIO_VFIO_COMMON_H

#include "system/memory.h"
#include "qemu/queue.h"
#ifdef CONFIG_LINUX
#include <linux/vfio.h>
#endif
#include "system/system.h"
#include "hw/vfio/vfio-container-base.h"
#include "system/host_iommu_device.h"
#include "system/iommufd.h"

#define VFIO_MSG_PREFIX "vfio %s: "

enum {
    VFIO_DEVICE_TYPE_PCI = 0,
    VFIO_DEVICE_TYPE_PLATFORM = 1,
    VFIO_DEVICE_TYPE_CCW = 2,
    VFIO_DEVICE_TYPE_AP = 3,
};

typedef struct VFIODeviceOps VFIODeviceOps;
typedef struct VFIOMigration VFIOMigration;

typedef struct IOMMUFDBackend IOMMUFDBackend;
typedef struct VFIOIOASHwpt VFIOIOASHwpt;

typedef struct VFIODevice {
    QLIST_ENTRY(VFIODevice) next;
    QLIST_ENTRY(VFIODevice) container_next;
    QLIST_ENTRY(VFIODevice) global_next;
    struct VFIOGroup *group;
    VFIOContainerBase *bcontainer;
    char *sysfsdev;
    char *name;
    DeviceState *dev;
    int fd;
    int type;
    bool mdev;
    bool reset_works;
    bool needs_reset;
    bool no_mmap;
    bool ram_block_discard_allowed;
    OnOffAuto enable_migration;
    OnOffAuto migration_multifd_transfer;
    bool migration_events;
    VFIODeviceOps *ops;
    unsigned int num_irqs;
    unsigned int num_regions;
    unsigned int flags;
    VFIOMigration *migration;
    Error *migration_blocker;
    OnOffAuto pre_copy_dirty_page_tracking;
    OnOffAuto device_dirty_page_tracking;
    bool dirty_pages_supported;
    bool dirty_tracking; /* Protected by BQL */
    bool iommu_dirty_tracking;
    HostIOMMUDevice *hiod;
    int devid;
    IOMMUFDBackend *iommufd;
    VFIOIOASHwpt *hwpt;
    QLIST_ENTRY(VFIODevice) hwpt_next;
} VFIODevice;

struct VFIODeviceOps {
    void (*vfio_compute_needs_reset)(VFIODevice *vdev);
    int (*vfio_hot_reset_multi)(VFIODevice *vdev);
    void (*vfio_eoi)(VFIODevice *vdev);
    Object *(*vfio_get_object)(VFIODevice *vdev);

    /**
     * @vfio_save_config
     *
     * Save device config state
     *
     * @vdev: #VFIODevice for which to save the config
     * @f: #QEMUFile where to send the data
     * @errp: pointer to Error*, to store an error if it happens.
     *
     * Returns zero to indicate success and negative for error
     */
    int (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f, Error **errp);

    /**
     * @vfio_load_config
     *
     * Load device config state
     *
     * @vdev: #VFIODevice for which to load the config
     * @f: #QEMUFile where to get the data
     *
     * Returns zero to indicate success and negative for error
     */
    int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f);
};

void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
                            int action, int fd, Error **errp);

void vfio_reset_handler(void *opaque);
bool vfio_device_is_mdev(VFIODevice *vbasedev);
bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp);
bool vfio_attach_device(char *name, VFIODevice *vbasedev,
                        AddressSpace *as, Error **errp);
void vfio_detach_device(VFIODevice *vbasedev);
VFIODevice *vfio_get_vfio_device(Object *obj);

typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList;
extern VFIODeviceList vfio_device_list;

#ifdef CONFIG_LINUX
int vfio_get_region_info(VFIODevice *vbasedev, int index,
                         struct vfio_region_info **info);
int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
                             uint32_t subtype, struct vfio_region_info **info);
bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type);
#endif

/* Returns 0 on success, or a negative errno. */
bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp);
void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp);
void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops,
                      DeviceState *dev, bool ram_discard);
int vfio_device_get_aw_bits(VFIODevice *vdev);
#endif /* HW_VFIO_VFIO_COMMON_H */