mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 12:09:58 +00:00
Updates for QEMU 2.3-rc0:
- Error reporting and static cleanup (Alexey Kardashevskiy) - Runtime mmap disable for tracing (Samuel Pitoiset) - Support for host directed device request (Alex Williamson) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJU9K8qAAoJECObm247sIsiiEEP/icPd/4UGOUwKGS0BgLS+dCH YhCxul/el8rQ7620Zndi7VIBml8GvUPssV3hGA0flyuWXD4eWyObMa6ovuDout1d lo/0Qcz/3Z5CYXVcNnB1vUXN9JLhPsRxZKwMTfX/cZn4X2gTP6hydin1tUJ0rtJe SvlGegE0/NeUpQQsS7gHqePBPqpB+XypOPvcnXtk3gpNfFo6suZVxzzrUImeSIcv KMpNLr6hKl/Nv0lRAEt59LhoCc6FFhmXhgQEpoebIyMPl26o9T9irX6uB/TYfn+m YvV0IFzYtIrPivnvP2NDPYJ3fvSViGCRNB2eGZYOFTrHeCKxFSGQopjeUnI7qzHX JyytAKS4S7XnXJvWBoO7IEDwcsaxfb4nUtl62kaoruBZsROd7qQdhpyCz5ckTsJh wMwch5uA3VibWe5QAUV0b4hJIwz4ttD1kJKOT7IaHfM7/sd4TjlSJaVGAToBwSTW 53G24P5SN6n/WRFnocGMi8AkXNzP2/hDaJIvwlOWfdjFWhuJJce+CwPA99oPznPI FlwIofmDeKaFEb6xakUEAf+NvzpiSpYurAuqqUxdQE/BmEq7vS3TQac7tDT36aqa KFPNAvPXUZLe3YK/YcsIy6cX6bzGEbJAmgwyDkcWQA/wcgZWoUMSpMwYiBM25PYv NotvWxD+zA2q1NAehrS9 =RsA3 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150302.0' into staging Updates for QEMU 2.3-rc0: - Error reporting and static cleanup (Alexey Kardashevskiy) - Runtime mmap disable for tracing (Samuel Pitoiset) - Support for host directed device request (Alex Williamson) # gpg: Signature made Mon Mar 2 18:42:50 2015 GMT using RSA key ID 3BB08B22 # gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>" # gpg: aka "Alex Williamson <alex@shazbot.org>" # gpg: aka "Alex Williamson <alwillia@redhat.com>" # gpg: aka "Alex Williamson <alex.l.williamson@gmail.com>" * remotes/awilliam/tags/vfio-update-20150302.0: vfio-pci: Enable device request notification support vfio: allow to disable MMAP per device with -x-mmap=off option vfio: Make type1 listener symbols static vfio: Add ioctl number to error report Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3539bbb93e
@ -475,12 +475,12 @@ static void vfio_listener_region_del(MemoryListener *listener,
|
||||
}
|
||||
}
|
||||
|
||||
const MemoryListener vfio_memory_listener = {
|
||||
static const MemoryListener vfio_memory_listener = {
|
||||
.region_add = vfio_listener_region_add,
|
||||
.region_del = vfio_listener_region_del,
|
||||
};
|
||||
|
||||
void vfio_listener_release(VFIOContainer *container)
|
||||
static void vfio_listener_release(VFIOContainer *container)
|
||||
{
|
||||
memory_listener_unregister(&container->iommu_data.type1.listener);
|
||||
}
|
||||
@ -493,7 +493,7 @@ int vfio_mmap_region(Object *obj, VFIORegion *region,
|
||||
int ret = 0;
|
||||
VFIODevice *vbasedev = region->vbasedev;
|
||||
|
||||
if (VFIO_ALLOW_MMAP && size && region->flags &
|
||||
if (vbasedev->allow_mmap && size && region->flags &
|
||||
VFIO_REGION_INFO_FLAG_MMAP) {
|
||||
int prot = 0;
|
||||
|
||||
@ -932,8 +932,8 @@ static int vfio_container_do_ioctl(AddressSpace *as, int32_t groupid,
|
||||
if (group->container) {
|
||||
ret = ioctl(container->fd, req, param);
|
||||
if (ret < 0) {
|
||||
error_report("vfio: failed to ioctl container: ret=%d, %s",
|
||||
ret, strerror(errno));
|
||||
error_report("vfio: failed to ioctl %d to container: ret=%d, %s",
|
||||
_IOC_NR(req) - VFIO_BASE, ret, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
101
hw/vfio/pci.c
101
hw/vfio/pci.c
@ -153,13 +153,17 @@ typedef struct VFIOPCIDevice {
|
||||
VFIOVGA vga; /* 0xa0000, 0x3b0, 0x3c0 */
|
||||
PCIHostDeviceAddress host;
|
||||
EventNotifier err_notifier;
|
||||
EventNotifier req_notifier;
|
||||
uint32_t features;
|
||||
#define VFIO_FEATURE_ENABLE_VGA_BIT 0
|
||||
#define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
|
||||
#define VFIO_FEATURE_ENABLE_REQ_BIT 1
|
||||
#define VFIO_FEATURE_ENABLE_REQ (1 << VFIO_FEATURE_ENABLE_REQ_BIT)
|
||||
int32_t bootindex;
|
||||
uint8_t pm_cap;
|
||||
bool has_vga;
|
||||
bool pci_aer;
|
||||
bool req_enabled;
|
||||
bool has_flr;
|
||||
bool has_pm_reset;
|
||||
bool rom_read_failed;
|
||||
@ -3088,6 +3092,7 @@ static int vfio_populate_device(VFIOPCIDevice *vdev)
|
||||
|
||||
vdev->has_vga = true;
|
||||
}
|
||||
|
||||
irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
|
||||
|
||||
ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
|
||||
@ -3223,6 +3228,97 @@ static void vfio_unregister_err_notifier(VFIOPCIDevice *vdev)
|
||||
event_notifier_cleanup(&vdev->err_notifier);
|
||||
}
|
||||
|
||||
static void vfio_req_notifier_handler(void *opaque)
|
||||
{
|
||||
VFIOPCIDevice *vdev = opaque;
|
||||
|
||||
if (!event_notifier_test_and_clear(&vdev->req_notifier)) {
|
||||
return;
|
||||
}
|
||||
|
||||
qdev_unplug(&vdev->pdev.qdev, NULL);
|
||||
}
|
||||
|
||||
static void vfio_register_req_notifier(VFIOPCIDevice *vdev)
|
||||
{
|
||||
struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info),
|
||||
.index = VFIO_PCI_REQ_IRQ_INDEX };
|
||||
int argsz;
|
||||
struct vfio_irq_set *irq_set;
|
||||
int32_t *pfd;
|
||||
|
||||
if (!(vdev->features & VFIO_FEATURE_ENABLE_REQ)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ioctl(vdev->vbasedev.fd,
|
||||
VFIO_DEVICE_GET_IRQ_INFO, &irq_info) < 0 || irq_info.count < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event_notifier_init(&vdev->req_notifier, 0)) {
|
||||
error_report("vfio: Unable to init event notifier for device request");
|
||||
return;
|
||||
}
|
||||
|
||||
argsz = sizeof(*irq_set) + sizeof(*pfd);
|
||||
|
||||
irq_set = g_malloc0(argsz);
|
||||
irq_set->argsz = argsz;
|
||||
irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
|
||||
VFIO_IRQ_SET_ACTION_TRIGGER;
|
||||
irq_set->index = VFIO_PCI_REQ_IRQ_INDEX;
|
||||
irq_set->start = 0;
|
||||
irq_set->count = 1;
|
||||
pfd = (int32_t *)&irq_set->data;
|
||||
|
||||
*pfd = event_notifier_get_fd(&vdev->req_notifier);
|
||||
qemu_set_fd_handler(*pfd, vfio_req_notifier_handler, NULL, vdev);
|
||||
|
||||
if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
|
||||
error_report("vfio: Failed to set up device request notification");
|
||||
qemu_set_fd_handler(*pfd, NULL, NULL, vdev);
|
||||
event_notifier_cleanup(&vdev->req_notifier);
|
||||
} else {
|
||||
vdev->req_enabled = true;
|
||||
}
|
||||
|
||||
g_free(irq_set);
|
||||
}
|
||||
|
||||
static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev)
|
||||
{
|
||||
int argsz;
|
||||
struct vfio_irq_set *irq_set;
|
||||
int32_t *pfd;
|
||||
|
||||
if (!vdev->req_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
argsz = sizeof(*irq_set) + sizeof(*pfd);
|
||||
|
||||
irq_set = g_malloc0(argsz);
|
||||
irq_set->argsz = argsz;
|
||||
irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
|
||||
VFIO_IRQ_SET_ACTION_TRIGGER;
|
||||
irq_set->index = VFIO_PCI_REQ_IRQ_INDEX;
|
||||
irq_set->start = 0;
|
||||
irq_set->count = 1;
|
||||
pfd = (int32_t *)&irq_set->data;
|
||||
*pfd = -1;
|
||||
|
||||
if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
|
||||
error_report("vfio: Failed to de-assign device request fd: %m");
|
||||
}
|
||||
g_free(irq_set);
|
||||
qemu_set_fd_handler(event_notifier_get_fd(&vdev->req_notifier),
|
||||
NULL, NULL, vdev);
|
||||
event_notifier_cleanup(&vdev->req_notifier);
|
||||
|
||||
vdev->req_enabled = false;
|
||||
}
|
||||
|
||||
static int vfio_initfn(PCIDevice *pdev)
|
||||
{
|
||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
||||
@ -3370,6 +3466,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
||||
}
|
||||
|
||||
vfio_register_err_notifier(vdev);
|
||||
vfio_register_req_notifier(vdev);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -3397,6 +3494,7 @@ static void vfio_exitfn(PCIDevice *pdev)
|
||||
{
|
||||
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
||||
|
||||
vfio_unregister_req_notifier(vdev);
|
||||
vfio_unregister_err_notifier(vdev);
|
||||
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
|
||||
vfio_disable_interrupts(vdev);
|
||||
@ -3455,7 +3553,10 @@ static Property vfio_pci_dev_properties[] = {
|
||||
intx.mmap_timeout, 1100),
|
||||
DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
|
||||
VFIO_FEATURE_ENABLE_VGA_BIT, false),
|
||||
DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
|
||||
VFIO_FEATURE_ENABLE_REQ_BIT, true),
|
||||
DEFINE_PROP_INT32("bootindex", VFIOPCIDevice, bootindex, -1),
|
||||
DEFINE_PROP_BOOL("x-mmap", VFIOPCIDevice, vbasedev.allow_mmap, true),
|
||||
/*
|
||||
* TODO - support passed fds... is this necessary?
|
||||
* DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name),
|
||||
|
@ -36,7 +36,6 @@
|
||||
#endif
|
||||
|
||||
/* Extra debugging, trap acceleration paths for more logging */
|
||||
#define VFIO_ALLOW_MMAP 1
|
||||
#define VFIO_ALLOW_KVM_INTX 1
|
||||
#define VFIO_ALLOW_KVM_MSI 1
|
||||
#define VFIO_ALLOW_KVM_MSIX 1
|
||||
@ -102,6 +101,7 @@ typedef struct VFIODevice {
|
||||
int type;
|
||||
bool reset_works;
|
||||
bool needs_reset;
|
||||
bool allow_mmap;
|
||||
VFIODeviceOps *ops;
|
||||
unsigned int num_irqs;
|
||||
unsigned int num_regions;
|
||||
@ -131,7 +131,6 @@ void vfio_region_write(void *opaque, hwaddr addr,
|
||||
uint64_t data, unsigned size);
|
||||
uint64_t vfio_region_read(void *opaque,
|
||||
hwaddr addr, unsigned size);
|
||||
void vfio_listener_release(VFIOContainer *container);
|
||||
int vfio_mmap_region(Object *vdev, VFIORegion *region,
|
||||
MemoryRegion *mem, MemoryRegion *submem,
|
||||
void **map, size_t size, off_t offset,
|
||||
@ -143,7 +142,6 @@ int vfio_get_device(VFIOGroup *group, const char *name,
|
||||
VFIODevice *vbasedev);
|
||||
|
||||
extern const MemoryRegionOps vfio_region_ops;
|
||||
extern const MemoryListener vfio_memory_listener;
|
||||
extern QLIST_HEAD(vfio_group_head, VFIOGroup) vfio_group_list;
|
||||
extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces;
|
||||
|
||||
|
@ -333,6 +333,7 @@ enum {
|
||||
VFIO_PCI_MSI_IRQ_INDEX,
|
||||
VFIO_PCI_MSIX_IRQ_INDEX,
|
||||
VFIO_PCI_ERR_IRQ_INDEX,
|
||||
VFIO_PCI_REQ_IRQ_INDEX,
|
||||
VFIO_PCI_NUM_IRQS
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user