From: Feng Wu <feng.wu@intel.com>
To: alex.williamson@redhat.com
Cc: Feng Wu <feng.wu@intel.com>,
qemu-devel@nongnu.org, eric.auger@linaro.org
Subject: [Qemu-devel] [RFC PATCH v1 2/2] x86: Update VT-d Posted-Interrupts related information
Date: Tue, 25 Nov 2014 20:25:46 +0800 [thread overview]
Message-ID: <1416918346-21944-3-git-send-email-feng.wu@intel.com> (raw)
In-Reply-To: <1416918346-21944-1-git-send-email-feng.wu@intel.com>
VT-d Posted-Interrupts(PI) is an enhancement to CPU side Posted-Interrupt.
With VT-d Posted-Interrupts enabled, external interrupts from
direct-assigned devices can be delivered to guests without VMM
involvement when guest is running in non-root mode.
If VT-d PI is supported by KVM, we need to update the IRTE with
the new guest interrupt configuration.
Signed-off-by: Feng Wu <feng.wu@intel.com>
---
hw/misc/vfio.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index fd318a1..d453db4 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -281,6 +281,8 @@ static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
uint32_t val, int len);
static void vfio_mmap_set_enabled(VFIODevice *vdev, bool enabled);
+static void vfio_kvm_device_posting_irq(VFIODevice *vdev, uint32_t index,
+ uint32_t start, uint32_t count);
/*
* Common VFIO interrupt disable
@@ -765,6 +767,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
{
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
VFIOMSIVector *vector;
+ uint32_t start, count;
int ret;
DPRINTF("%s(%04x:%02x:%02x.%x) vector %d used\n", __func__,
@@ -812,6 +815,8 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
if (ret) {
error_report("vfio: failed to enable vectors, %d", ret);
}
+ start = 0;
+ count = vdev->nr_vectors;
} else {
int argsz;
struct vfio_irq_set *irq_set;
@@ -824,8 +829,8 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
VFIO_IRQ_SET_ACTION_TRIGGER;
irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
- irq_set->start = nr;
- irq_set->count = 1;
+ irq_set->start = start = nr;
+ irq_set->count = count = 1;
pfd = (int32_t *)&irq_set->data;
if (vector->virq >= 0) {
@@ -841,6 +846,11 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
}
}
+ if (msg) {
+ vfio_kvm_device_posting_irq(vdev, VFIO_PCI_MSIX_IRQ_INDEX,
+ start, count);
+ }
+
return 0;
}
@@ -997,6 +1007,9 @@ retry:
return;
}
+ vfio_kvm_device_posting_irq(vdev, VFIO_PCI_MSI_IRQ_INDEX,
+ 0, vdev->nr_vectors);
+
DPRINTF("%s(%04x:%02x:%02x.%x) Enabled %d MSI vectors\n", __func__,
vdev->host.domain, vdev->host.bus, vdev->host.slot,
vdev->host.function, vdev->nr_vectors);
@@ -1077,6 +1090,9 @@ static void vfio_update_msi(VFIODevice *vdev)
msg = msi_get_message(&vdev->pdev, i);
vfio_update_kvm_msi_virq(vector, msg);
}
+
+ vfio_kvm_device_posting_irq(vdev, VFIO_PCI_MSIX_IRQ_INDEX,
+ 0, vdev->nr_vectors);
}
/*
@@ -3622,6 +3638,46 @@ static void vfio_kvm_device_del_group(VFIOGroup *group)
#endif
}
+static void vfio_kvm_device_posting_irq(VFIODevice *vdev, uint32_t index,
+ uint32_t start, uint32_t count)
+{
+#ifdef CONFIG_KVM
+ int i, argsz;
+ struct kvm_posted_intr *pi_info = NULL;
+
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_DEVICE,
+ .attr = KVM_DEV_VFIO_DEVICE_POSTING_IRQ,
+ };
+
+ if (!kvm_enabled() ||
+ ioctl(vfio_kvm_device_fd, KVM_HAS_DEVICE_ATTR, &attr) != 0) {
+ return;
+ }
+
+ argsz = sizeof(*pi_info) + sizeof(int) * count;
+
+ pi_info = g_malloc0(argsz);
+ pi_info->argsz = argsz;
+ pi_info->fd = vdev->fd;
+ pi_info->index = index;
+ pi_info->start = start;
+ pi_info->count = count;
+
+ for (i = 0; i < count; i++) {
+ pi_info->virq[i] = vdev->msi_vectors[start+i].virq;;
+ }
+
+ attr.addr = (uint64_t)(unsigned long)pi_info;
+
+ if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+ error_report("Failed to configure PI for KVM VFIO device: %m\n");
+ }
+
+ g_free(pi_info);
+#endif
+}
+
static VFIOAddressSpace *vfio_get_address_space(AddressSpace *as)
{
VFIOAddressSpace *space;
--
1.7.1
prev parent reply other threads:[~2014-11-25 12:35 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-25 12:25 [Qemu-devel] [RFC PATCH v1 0/2] VFIO: add VT-d Posted-Interrupts support Feng Wu
2014-11-25 12:25 ` [Qemu-devel] [RFC PATCH v1 1/2] linux-headers: Update KVM headers Feng Wu
2014-11-25 12:25 ` Feng Wu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1416918346-21944-3-git-send-email-feng.wu@intel.com \
--to=feng.wu@intel.com \
--cc=alex.williamson@redhat.com \
--cc=eric.auger@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).