mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 13:30:52 +00:00
VFIO updates for 2.4-rc0
- "real" host page size API (Peter Crosthwaite) - platform device irqfd support (Eric Auger) - spapr container disconnect fix (Alexey Kardashevskiy) - quirk for broken Chelsio hardware (Gabriel Laupre) - coverity fix (Paolo Bonzini) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVmse1AAoJECObm247sIsi1SIP+gM8ym1C5ARch3jatPo/zQMC Jn0kDwBiHJWHP9M80SpQlmf6esUB6fiAHJc+G6OjwWVFvOCYIePZI4rUrnbU4A5s yzDrPVz+yU6zV5dMuUGgJSyts8v3xOnITV3z+TXkAKUULjQGaAfStEDB2jKmb3a7 O+i+IOIuTct5E2K+6yNfQlIkPQnkLmjA6bfDGRHUuP7upbJcdAgAtAFz/j8y6GCW ehGNUuXqG5pUwmjsrQHK4hIWK68QVrfcMJ3wl9rVY7M9A+QmXXaklfTxutpVHGV9 9TGtLNwvEt0ggIGA3kQdMvv5WC4dyuILXlBetRp3raVq4K8E1ttn59d49A5HpBKE OYsTslRzFIRzBVfi4cQY0lLvsoBptKGOgY3cmIm3V4w8uhlJBxtHtHbqRvoY6i6M m17WmJKyhcRvy/t6mm9mozsGTWJe6powDpiXV1GfWl1AvRL2dn+DLGp5V0XJGokd xgCDPalmOD0xu4gZL1SQkfbB/wBv32B6fgpjRNTKs9LxYUsvcu/LhQDFzkXfaH1B lwh1WX+FAmz0+zfOmCIR5Qnuo/RPjRqGOvFmJW/5WE9P+DKcUxeBnaElJUByDBzk henxiXBFvdSiqPWewRv12Z7/HFANFiXp+lz9xU60aT8ZYl943EeHY16Xm76fyH/v I1bUFqSsNNFn4nrxJKu3 =jxcI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150706.0' into staging VFIO updates for 2.4-rc0 - "real" host page size API (Peter Crosthwaite) - platform device irqfd support (Eric Auger) - spapr container disconnect fix (Alexey Kardashevskiy) - quirk for broken Chelsio hardware (Gabriel Laupre) - coverity fix (Paolo Bonzini) # gpg: Signature made Mon Jul 6 19:23:49 2015 BST 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-20150706.0: vfio/pci : Add pba_offset PCI quirk for Chelsio T5 devices vfio: Unregister IOMMU notifiers when container is destroyed hw/vfio/platform: add irqfd support kvm: some fixes to kvm_resamplefds_allowed sysbus: add irq_routing_notifier intc: arm_gic_kvm: set the qemu_irq/gsi mapping kvm-all.c: add qemu_irq/gsi hash table and utility routines kvm: rename kvm_irqchip_[add,remove]_irqfd_notifier with gsi suffix vfio: cpu: Use "real" page size API cpu-all: complete "real" host page size API vfio: fix return type of pread Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Conflicts: kvm-all.c
This commit is contained in:
commit
1452673888
@ -109,7 +109,13 @@ qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n)
|
||||
|
||||
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
|
||||
{
|
||||
SysBusDeviceClass *sbd = SYS_BUS_DEVICE_GET_CLASS(dev);
|
||||
|
||||
qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq);
|
||||
|
||||
if (sbd->connect_irq_notifier) {
|
||||
sbd->connect_irq_notifier(dev, irq);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether an MMIO region exists */
|
||||
|
@ -570,6 +570,12 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
|
||||
*/
|
||||
i += (GIC_INTERNAL * s->num_cpu);
|
||||
qdev_init_gpio_in(dev, kvm_arm_gic_set_irq, i);
|
||||
|
||||
for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
|
||||
qemu_irq irq = qdev_get_gpio_in(dev, i);
|
||||
kvm_irqchip_set_qemuirq_gsi(kvm_state, irq, i);
|
||||
}
|
||||
|
||||
/* We never use our outbound IRQ/FIQ lines but provide them so that
|
||||
* we maintain the same interface as the non-KVM GIC.
|
||||
*/
|
||||
|
@ -1316,8 +1316,8 @@ static int virtio_ccw_add_irqfd(VirtioCcwDevice *dev, int n)
|
||||
VirtQueue *vq = virtio_get_queue(vdev, n);
|
||||
EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
|
||||
|
||||
return kvm_irqchip_add_irqfd_notifier(kvm_state, notifier, NULL,
|
||||
dev->routes.gsi[n]);
|
||||
return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, notifier, NULL,
|
||||
dev->routes.gsi[n]);
|
||||
}
|
||||
|
||||
static void virtio_ccw_remove_irqfd(VirtioCcwDevice *dev, int n)
|
||||
@ -1327,8 +1327,8 @@ static void virtio_ccw_remove_irqfd(VirtioCcwDevice *dev, int n)
|
||||
EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
|
||||
int ret;
|
||||
|
||||
ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, notifier,
|
||||
dev->routes.gsi[n]);
|
||||
ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, notifier,
|
||||
dev->routes.gsi[n]);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
|
@ -772,11 +772,19 @@ static void vfio_disconnect_container(VFIOGroup *group)
|
||||
|
||||
if (QLIST_EMPTY(&container->group_list)) {
|
||||
VFIOAddressSpace *space = container->space;
|
||||
VFIOGuestIOMMU *giommu, *tmp;
|
||||
|
||||
if (container->iommu_data.release) {
|
||||
container->iommu_data.release(container);
|
||||
}
|
||||
QLIST_REMOVE(container, next);
|
||||
|
||||
QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) {
|
||||
memory_region_unregister_iommu_notifier(&giommu->n);
|
||||
QLIST_REMOVE(giommu, giommu_next);
|
||||
g_free(giommu);
|
||||
}
|
||||
|
||||
trace_vfio_disconnect_container(container->fd);
|
||||
close(container->fd);
|
||||
g_free(container);
|
||||
|
@ -597,7 +597,7 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,
|
||||
return;
|
||||
}
|
||||
|
||||
if (kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->kvm_interrupt,
|
||||
if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt,
|
||||
NULL, virq) < 0) {
|
||||
kvm_irqchip_release_virq(kvm_state, virq);
|
||||
event_notifier_cleanup(&vector->kvm_interrupt);
|
||||
@ -609,8 +609,8 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,
|
||||
|
||||
static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
|
||||
{
|
||||
kvm_irqchip_remove_irqfd_notifier(kvm_state, &vector->kvm_interrupt,
|
||||
vector->virq);
|
||||
kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt,
|
||||
vector->virq);
|
||||
kvm_irqchip_release_virq(kvm_state, vector->virq);
|
||||
vector->virq = -1;
|
||||
event_notifier_cleanup(&vector->kvm_interrupt);
|
||||
@ -939,7 +939,7 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
|
||||
};
|
||||
uint64_t size;
|
||||
off_t off = 0;
|
||||
size_t bytes;
|
||||
ssize_t bytes;
|
||||
|
||||
if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO, ®_info)) {
|
||||
error_report("vfio: Error getting ROM info: %m");
|
||||
@ -2252,6 +2252,33 @@ static int vfio_early_setup_msix(VFIOPCIDevice *vdev)
|
||||
vdev->msix->pba_offset = pba & ~PCI_MSIX_FLAGS_BIRMASK;
|
||||
vdev->msix->entries = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;
|
||||
|
||||
/*
|
||||
* Test the size of the pba_offset variable and catch if it extends outside
|
||||
* of the specified BAR. If it is the case, we need to apply a hardware
|
||||
* specific quirk if the device is known or we have a broken configuration.
|
||||
*/
|
||||
if (vdev->msix->pba_offset >=
|
||||
vdev->bars[vdev->msix->pba_bar].region.size) {
|
||||
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
uint16_t vendor = pci_get_word(pdev->config + PCI_VENDOR_ID);
|
||||
uint16_t device = pci_get_word(pdev->config + PCI_DEVICE_ID);
|
||||
|
||||
/*
|
||||
* Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5
|
||||
* adapters. The T5 hardware returns an incorrect value of 0x8000 for
|
||||
* the VF PBA offset while the BAR itself is only 8k. The correct value
|
||||
* is 0x1000, so we hard code that here.
|
||||
*/
|
||||
if (vendor == PCI_VENDOR_ID_CHELSIO && (device & 0xff00) == 0x5800) {
|
||||
vdev->msix->pba_offset = 0x1000;
|
||||
} else {
|
||||
error_report("vfio: Hardware reports invalid configuration, "
|
||||
"MSIX PBA outside of specified BAR");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
trace_vfio_early_setup_msix(vdev->vbasedev.name, pos,
|
||||
vdev->msix->table_bar,
|
||||
vdev->msix->table_offset,
|
||||
@ -2388,7 +2415,7 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
|
||||
* potentially insert a direct-mapped subregion before and after it.
|
||||
*/
|
||||
if (vdev->msix && vdev->msix->table_bar == nr) {
|
||||
size = vdev->msix->table_offset & qemu_host_page_mask;
|
||||
size = vdev->msix->table_offset & qemu_real_host_page_mask;
|
||||
}
|
||||
|
||||
strncat(name, " mmap", sizeof(name) - strlen(name) - 1);
|
||||
@ -2401,8 +2428,9 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
|
||||
if (vdev->msix && vdev->msix->table_bar == nr) {
|
||||
uint64_t start;
|
||||
|
||||
start = HOST_PAGE_ALIGN((uint64_t)vdev->msix->table_offset +
|
||||
(vdev->msix->entries * PCI_MSIX_ENTRY_SIZE));
|
||||
start = REAL_HOST_PAGE_ALIGN((uint64_t)vdev->msix->table_offset +
|
||||
(vdev->msix->entries *
|
||||
PCI_MSIX_ENTRY_SIZE));
|
||||
|
||||
size = start < bar->region.size ? bar->region.size - start : 0;
|
||||
strncat(name, " msix-hi", sizeof(name) - strlen(name) - 1);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "hw/sysbus.h"
|
||||
#include "trace.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "sysemu/kvm.h"
|
||||
|
||||
/*
|
||||
* Functions used whatever the injection method
|
||||
@ -51,6 +52,7 @@ static VFIOINTp *vfio_init_intp(VFIODevice *vbasedev,
|
||||
intp->pin = info.index;
|
||||
intp->flags = info.flags;
|
||||
intp->state = VFIO_IRQ_INACTIVE;
|
||||
intp->kvm_accel = false;
|
||||
|
||||
sysbus_init_irq(sbdev, &intp->qemuirq);
|
||||
|
||||
@ -61,6 +63,13 @@ static VFIOINTp *vfio_init_intp(VFIODevice *vbasedev,
|
||||
error_report("vfio: Error: trigger event_notifier_init failed ");
|
||||
return NULL;
|
||||
}
|
||||
/* Get an eventfd for resample/unmask */
|
||||
ret = event_notifier_init(&intp->unmask, 0);
|
||||
if (ret) {
|
||||
g_free(intp);
|
||||
error_report("vfio: Error: resamplefd event_notifier_init failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QLIST_INSERT_HEAD(&vdev->intp_list, intp, next);
|
||||
return intp;
|
||||
@ -315,6 +324,94 @@ static int vfio_start_eventfd_injection(VFIOINTp *intp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions used for irqfd
|
||||
*/
|
||||
|
||||
/**
|
||||
* vfio_set_resample_eventfd - sets the resamplefd for an IRQ
|
||||
* @intp: the IRQ struct handle
|
||||
* programs the VFIO driver to unmask this IRQ when the
|
||||
* intp->unmask eventfd is triggered
|
||||
*/
|
||||
static int vfio_set_resample_eventfd(VFIOINTp *intp)
|
||||
{
|
||||
VFIODevice *vbasedev = &intp->vdev->vbasedev;
|
||||
struct vfio_irq_set *irq_set;
|
||||
int argsz, ret;
|
||||
int32_t *pfd;
|
||||
|
||||
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_UNMASK;
|
||||
irq_set->index = intp->pin;
|
||||
irq_set->start = 0;
|
||||
irq_set->count = 1;
|
||||
pfd = (int32_t *)&irq_set->data;
|
||||
*pfd = event_notifier_get_fd(&intp->unmask);
|
||||
qemu_set_fd_handler(*pfd, NULL, NULL, NULL);
|
||||
ret = ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
||||
g_free(irq_set);
|
||||
if (ret < 0) {
|
||||
error_report("vfio: Failed to set resample eventfd: %m");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void vfio_start_irqfd_injection(SysBusDevice *sbdev, qemu_irq irq)
|
||||
{
|
||||
VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
|
||||
VFIOINTp *intp;
|
||||
|
||||
if (!kvm_irqfds_enabled() || !kvm_resamplefds_enabled() ||
|
||||
!vdev->irqfd_allowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
QLIST_FOREACH(intp, &vdev->intp_list, next) {
|
||||
if (intp->qemuirq == irq) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(intp);
|
||||
|
||||
/* Get to a known interrupt state */
|
||||
qemu_set_fd_handler(event_notifier_get_fd(&intp->interrupt),
|
||||
NULL, NULL, vdev);
|
||||
|
||||
vfio_mask_single_irqindex(&vdev->vbasedev, intp->pin);
|
||||
qemu_set_irq(intp->qemuirq, 0);
|
||||
|
||||
if (kvm_irqchip_add_irqfd_notifier(kvm_state, &intp->interrupt,
|
||||
&intp->unmask, irq) < 0) {
|
||||
goto fail_irqfd;
|
||||
}
|
||||
|
||||
if (vfio_set_trigger_eventfd(intp, NULL) < 0) {
|
||||
goto fail_vfio;
|
||||
}
|
||||
if (vfio_set_resample_eventfd(intp) < 0) {
|
||||
goto fail_vfio;
|
||||
}
|
||||
|
||||
/* Let's resume injection with irqfd setup */
|
||||
vfio_unmask_single_irqindex(&vdev->vbasedev, intp->pin);
|
||||
|
||||
intp->kvm_accel = true;
|
||||
|
||||
trace_vfio_platform_start_irqfd_injection(intp->pin,
|
||||
event_notifier_get_fd(&intp->interrupt),
|
||||
event_notifier_get_fd(&intp->unmask));
|
||||
return;
|
||||
fail_vfio:
|
||||
kvm_irqchip_remove_irqfd_notifier(kvm_state, &intp->interrupt, irq);
|
||||
fail_irqfd:
|
||||
vfio_start_eventfd_injection(intp);
|
||||
vfio_unmask_single_irqindex(&vdev->vbasedev, intp->pin);
|
||||
return;
|
||||
}
|
||||
|
||||
/* VFIO skeleton */
|
||||
|
||||
static void vfio_platform_compute_needs_reset(VFIODevice *vbasedev)
|
||||
@ -584,17 +681,20 @@ static Property vfio_platform_dev_properties[] = {
|
||||
DEFINE_PROP_BOOL("x-mmap", VFIOPlatformDevice, vbasedev.allow_mmap, true),
|
||||
DEFINE_PROP_UINT32("mmap-timeout-ms", VFIOPlatformDevice,
|
||||
mmap_timeout, 1100),
|
||||
DEFINE_PROP_BOOL("x-irqfd", VFIOPlatformDevice, irqfd_allowed, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void vfio_platform_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = vfio_platform_realize;
|
||||
dc->props = vfio_platform_dev_properties;
|
||||
dc->vmsd = &vfio_platform_vmstate;
|
||||
dc->desc = "VFIO-based platform device assignment";
|
||||
sbc->connect_irq_notifier = vfio_start_irqfd_injection;
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
}
|
||||
|
||||
|
@ -495,7 +495,7 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
|
||||
VirtQueue *vq = virtio_get_queue(vdev, queue_no);
|
||||
EventNotifier *n = virtio_queue_get_guest_notifier(vq);
|
||||
int ret;
|
||||
ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq);
|
||||
ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -509,7 +509,7 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
|
||||
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
||||
int ret;
|
||||
|
||||
ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq);
|
||||
ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
|
@ -183,10 +183,13 @@ extern unsigned long reserved_va;
|
||||
|
||||
/* ??? These should be the larger of uintptr_t and target_ulong. */
|
||||
extern uintptr_t qemu_real_host_page_size;
|
||||
extern uintptr_t qemu_real_host_page_mask;
|
||||
extern uintptr_t qemu_host_page_size;
|
||||
extern uintptr_t qemu_host_page_mask;
|
||||
|
||||
#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
|
||||
#define REAL_HOST_PAGE_ALIGN(addr) (((addr) + qemu_real_host_page_size - 1) & \
|
||||
qemu_real_host_page_mask)
|
||||
|
||||
/* same as PROT_xxx */
|
||||
#define PAGE_READ 0x0001
|
||||
|
@ -114,6 +114,8 @@
|
||||
#define PCI_VENDOR_ID_ENSONIQ 0x1274
|
||||
#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
|
||||
|
||||
#define PCI_VENDOR_ID_CHELSIO 0x1425
|
||||
|
||||
#define PCI_VENDOR_ID_FREESCALE 0x1957
|
||||
#define PCI_DEVICE_ID_MPC8533E 0x0030
|
||||
|
||||
|
@ -58,6 +58,7 @@ typedef struct SysBusDeviceClass {
|
||||
* omitted then. (This is not considered a fatal error.)
|
||||
*/
|
||||
char *(*explicit_ofw_unit_address)(const SysBusDevice *dev);
|
||||
void (*connect_irq_notifier)(SysBusDevice *dev, qemu_irq irq);
|
||||
} SysBusDeviceClass;
|
||||
|
||||
struct SysBusDevice {
|
||||
|
@ -41,6 +41,7 @@ typedef struct VFIOINTp {
|
||||
int state; /* inactive, pending, active */
|
||||
uint8_t pin; /* index */
|
||||
uint32_t flags; /* IRQ info flags */
|
||||
bool kvm_accel; /* set when QEMU bypass through KVM enabled */
|
||||
} VFIOINTp;
|
||||
|
||||
/* function type for user side eventfd handler */
|
||||
@ -57,6 +58,7 @@ typedef struct VFIOPlatformDevice {
|
||||
uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
|
||||
QEMUTimer *mmap_timer; /* allows fast-path resume after IRQ hit */
|
||||
QemuMutex intp_mutex; /* protect the intp_list IRQ state */
|
||||
bool irqfd_allowed; /* debug option to force irqfd on/off */
|
||||
} VFIOPlatformDevice;
|
||||
|
||||
typedef struct VFIOPlatformDeviceClass {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qemu/queue.h"
|
||||
#include "qom/cpu.h"
|
||||
#include "exec/memattrs.h"
|
||||
#include "hw/irq.h"
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
#include <linux/kvm.h>
|
||||
@ -151,6 +152,7 @@ extern bool kvm_readonly_mem_allowed;
|
||||
#define kvm_halt_in_kernel() (false)
|
||||
#define kvm_eventfds_enabled() (false)
|
||||
#define kvm_irqfds_enabled() (false)
|
||||
#define kvm_resamplefds_enabled() (false)
|
||||
#define kvm_msi_via_irqfd_enabled() (false)
|
||||
#define kvm_gsi_routing_allowed() (false)
|
||||
#define kvm_gsi_direct_mapping() (false)
|
||||
@ -416,9 +418,15 @@ void kvm_irqchip_release_virq(KVMState *s, int virq);
|
||||
|
||||
int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
|
||||
|
||||
int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
|
||||
EventNotifier *rn, int virq);
|
||||
int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
|
||||
int virq);
|
||||
int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
|
||||
EventNotifier *rn, int virq);
|
||||
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
|
||||
EventNotifier *rn, qemu_irq irq);
|
||||
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
|
||||
qemu_irq irq);
|
||||
void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi);
|
||||
void kvm_pc_gsi_handler(void *opaque, int n, int level);
|
||||
void kvm_pc_setup_irq_routing(bool pci_enabled);
|
||||
void kvm_init_irq_routing(KVMState *s);
|
||||
|
40
kvm-all.c
40
kvm-all.c
@ -35,6 +35,7 @@
|
||||
#include "exec/address-spaces.h"
|
||||
#include "qemu/event_notifier.h"
|
||||
#include "trace.h"
|
||||
#include "hw/irq.h"
|
||||
|
||||
#include "hw/boards.h"
|
||||
|
||||
@ -84,6 +85,7 @@ struct KVMState
|
||||
* unsigned, and treating them as signed here can break things */
|
||||
unsigned irq_set_ioctl;
|
||||
unsigned int sigmask_len;
|
||||
GHashTable *gsimap;
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
struct kvm_irq_routing *irq_routes;
|
||||
int nr_allocated_irq_routes;
|
||||
@ -1332,19 +1334,49 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
|
||||
}
|
||||
#endif /* !KVM_CAP_IRQ_ROUTING */
|
||||
|
||||
int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
|
||||
EventNotifier *rn, int virq)
|
||||
int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
|
||||
EventNotifier *rn, int virq)
|
||||
{
|
||||
return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n),
|
||||
rn ? event_notifier_get_fd(rn) : -1, virq, true);
|
||||
}
|
||||
|
||||
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
|
||||
int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
|
||||
int virq)
|
||||
{
|
||||
return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n), -1, virq,
|
||||
false);
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
|
||||
EventNotifier *rn, qemu_irq irq)
|
||||
{
|
||||
gpointer key, gsi;
|
||||
gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
|
||||
|
||||
if (!found) {
|
||||
return -ENXIO;
|
||||
}
|
||||
return kvm_irqchip_add_irqfd_notifier_gsi(s, n, rn, GPOINTER_TO_INT(gsi));
|
||||
}
|
||||
|
||||
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
|
||||
qemu_irq irq)
|
||||
{
|
||||
gpointer key, gsi;
|
||||
gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
|
||||
|
||||
if (!found) {
|
||||
return -ENXIO;
|
||||
}
|
||||
return kvm_irqchip_remove_irqfd_notifier_gsi(s, n, GPOINTER_TO_INT(gsi));
|
||||
}
|
||||
|
||||
void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi)
|
||||
{
|
||||
g_hash_table_insert(s->gsimap, irq, GINT_TO_POINTER(gsi));
|
||||
}
|
||||
|
||||
static void kvm_irqchip_create(MachineState *machine, KVMState *s)
|
||||
{
|
||||
int ret;
|
||||
@ -1380,6 +1412,8 @@ static void kvm_irqchip_create(MachineState *machine, KVMState *s)
|
||||
kvm_halt_in_kernel_allowed = true;
|
||||
|
||||
kvm_init_irq_routing(s);
|
||||
|
||||
s->gsimap = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
}
|
||||
|
||||
/* Find number of supported CPUs using the recommended
|
||||
|
@ -24,6 +24,7 @@ bool kvm_kernel_irqchip;
|
||||
bool kvm_async_interrupts_allowed;
|
||||
bool kvm_eventfds_allowed;
|
||||
bool kvm_irqfds_allowed;
|
||||
bool kvm_resamplefds_allowed;
|
||||
bool kvm_msi_via_irqfd_allowed;
|
||||
bool kvm_gsi_routing_allowed;
|
||||
bool kvm_gsi_direct_mapping;
|
||||
@ -137,13 +138,14 @@ int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
|
||||
EventNotifier *rn, int virq)
|
||||
int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
|
||||
EventNotifier *rn, int virq)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
|
||||
int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
|
||||
int virq)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
@ -1594,6 +1594,7 @@ vfio_platform_intp_interrupt(int pin, int fd) "Inject IRQ #%d (fd = %d)"
|
||||
vfio_platform_intp_inject_pending_lockheld(int pin, int fd) "Inject pending IRQ #%d (fd = %d)"
|
||||
vfio_platform_populate_interrupts(int pin, int count, int flags) "- IRQ index %d: count %d, flags=0x%x"
|
||||
vfio_intp_interrupt_set_pending(int index) "irq %d is set PENDING"
|
||||
vfio_platform_start_irqfd_injection(int index, int fd, int resamplefd) "IRQ index=%d, fd = %d, resamplefd = %d"
|
||||
|
||||
#hw/acpi/memory_hotplug.c
|
||||
mhp_acpi_invalid_slot_selected(uint32_t slot) "0x%"PRIx32
|
||||
|
@ -118,6 +118,7 @@ typedef struct PageDesc {
|
||||
#define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS)
|
||||
|
||||
uintptr_t qemu_real_host_page_size;
|
||||
uintptr_t qemu_real_host_page_mask;
|
||||
uintptr_t qemu_host_page_size;
|
||||
uintptr_t qemu_host_page_mask;
|
||||
|
||||
@ -307,6 +308,7 @@ void page_size_init(void)
|
||||
/* NOTE: we can always suppose that qemu_host_page_size >=
|
||||
TARGET_PAGE_SIZE */
|
||||
qemu_real_host_page_size = getpagesize();
|
||||
qemu_real_host_page_mask = ~(qemu_real_host_page_size - 1);
|
||||
if (qemu_host_page_size == 0) {
|
||||
qemu_host_page_size = qemu_real_host_page_size;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user