From: Sheng Yang <sheng@linux.intel.com>
To: Avi Kivity <avi@redhat.com>, Marcelo Tosatti <mtosatti@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
kvm@vger.kernel.org, Sheng Yang <sheng@linux.intel.com>
Subject: [PATCH 2/2][RFC] KVM: Emulate MSI-X table and PBA in kernel
Date: Wed, 22 Dec 2010 16:44:55 +0800 [thread overview]
Message-ID: <1293007495-32325-3-git-send-email-sheng@linux.intel.com> (raw)
In-Reply-To: <1293007495-32325-1-git-send-email-sheng@linux.intel.com>
Then we can support mask bit operation of assigned devices now.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/kvm/Makefile | 2 +-
arch/x86/kvm/x86.c | 8 +-
include/linux/kvm.h | 22 ++++
include/linux/kvm_host.h | 25 +++++
virt/kvm/assigned-dev.c | 30 ++++++
virt/kvm/kvm_main.c | 38 +++++++-
virt/kvm/msix_mmio.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++
virt/kvm/msix_mmio.h | 24 +++++
8 files changed, 386 insertions(+), 7 deletions(-)
create mode 100644 virt/kvm/msix_mmio.c
create mode 100644 virt/kvm/msix_mmio.h
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index f15501f..3a0d851 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -7,7 +7,7 @@ CFLAGS_vmx.o := -I.
kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
coalesced_mmio.o irq_comm.o eventfd.o \
- assigned-dev.o)
+ assigned-dev.o msix_mmio.o)
kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o)
kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ed373ba..0be5837 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1965,6 +1965,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_X86_ROBUST_SINGLESTEP:
case KVM_CAP_XSAVE:
case KVM_CAP_ASYNC_PF:
+ case KVM_CAP_MSIX_MMIO:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -3802,6 +3803,7 @@ static int emulator_write_emulated_onepage(unsigned long addr,
struct kvm_vcpu *vcpu)
{
gpa_t gpa;
+ int r;
gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, exception);
@@ -3817,14 +3819,16 @@ static int emulator_write_emulated_onepage(unsigned long addr,
mmio:
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
+ r = vcpu_mmio_write(vcpu, gpa, bytes, val);
/*
* Is this MMIO handled locally?
*/
- if (!vcpu_mmio_write(vcpu, gpa, bytes, val))
+ if (!r)
return X86EMUL_CONTINUE;
vcpu->mmio_needed = 1;
- vcpu->run->exit_reason = KVM_EXIT_MMIO;
+ vcpu->run->exit_reason = (r == -ENOTSYNC) ?
+ KVM_EXIT_MSIX_ROUTING_UPDATE : KVM_EXIT_MMIO;
vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa;
vcpu->run->mmio.len = vcpu->mmio_size = bytes;
vcpu->run->mmio.is_write = vcpu->mmio_is_write = 1;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index ea2dc1a..44838fe 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -161,6 +161,7 @@ struct kvm_pit_config {
#define KVM_EXIT_NMI 16
#define KVM_EXIT_INTERNAL_ERROR 17
#define KVM_EXIT_OSI 18
+#define KVM_EXIT_MSIX_ROUTING_UPDATE 19
/* For KVM_EXIT_INTERNAL_ERROR */
#define KVM_INTERNAL_ERROR_EMULATION 1
@@ -541,6 +542,7 @@ struct kvm_ppc_pvinfo {
#define KVM_CAP_PPC_GET_PVINFO 57
#define KVM_CAP_PPC_IRQ_LEVEL 58
#define KVM_CAP_ASYNC_PF 59
+#define KVM_CAP_MSIX_MMIO 60
#ifdef KVM_CAP_IRQ_ROUTING
@@ -672,6 +674,9 @@ struct kvm_clock_data {
#define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config)
#define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data)
#define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data)
+/* Available with KVM_CAP_MSIX_MMIO */
+#define KVM_REGISTER_MSIX_MMIO _IOW(KVMIO, 0x7d, struct kvm_msix_mmio_user)
+#define KVM_UNREGISTER_MSIX_MMIO _IOW(KVMIO, 0x7e, struct kvm_msix_mmio_user)
/* Available with KVM_CAP_PIT_STATE2 */
#define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2)
#define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2)
@@ -795,4 +800,21 @@ struct kvm_assigned_msix_entry {
__u16 padding[3];
};
+#define KVM_MSIX_MMIO_TYPE_ASSIGNED_DEV (1 << 0)
+
+#define KVM_MSIX_MMIO_TYPE_BASE_TABLE (1 << 8)
+#define KVM_MSIX_MMIO_TYPE_BASE_PBA (1 << 9)
+
+#define KVM_MSIX_MMIO_TYPE_DEV_MASK 0x00ff
+#define KVM_MSIX_MMIO_TYPE_BASE_MASK 0xff00
+struct kvm_msix_mmio_user {
+ __u32 dev_id;
+ __u16 type;
+ __u16 max_entries_nr;
+ __u64 base_addr;
+ __u64 base_va;
+ __u64 flags;
+ __u64 reserved[4];
+};
+
#endif /* __LINUX_KVM_H */
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ac026ad..15fdd0d 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -231,6 +231,27 @@ struct kvm_memslots {
KVM_PRIVATE_MEM_SLOTS];
};
+#define KVM_MSIX_MMIO_MAX 32
+
+struct kvm_msix_mmio {
+ u32 dev_id;
+ u16 type;
+ u16 max_entries_nr;
+ u64 flags;
+ gpa_t table_base_addr;
+ hva_t table_base_va;
+ gpa_t pba_base_addr;
+ hva_t pba_base_va;
+};
+
+struct kvm_msix_mmio_dev {
+ struct kvm *kvm;
+ struct kvm_io_device table_dev;
+ int mmio_nr;
+ struct kvm_msix_mmio mmio[KVM_MSIX_MMIO_MAX];
+ struct mutex lock;
+};
+
struct kvm {
spinlock_t mmu_lock;
raw_spinlock_t requests_lock;
@@ -279,6 +300,7 @@ struct kvm {
long mmu_notifier_count;
long tlbs_dirty;
#endif
+ struct kvm_msix_mmio_dev msix_mmio_dev;
};
/* The guest did something we don't support. */
@@ -551,6 +573,9 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
int kvm_request_irq_source_id(struct kvm *kvm);
void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
+int kvm_assigned_device_update_msix_mask_bit(struct kvm *kvm,
+ int assigned_dev_id, int entry, u32 flag);
+
/* For vcpu->arch.iommu_flags */
#define KVM_IOMMU_CACHE_COHERENCY 0x1
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
index ae72ae6..ec48bfe 100644
--- a/virt/kvm/assigned-dev.c
+++ b/virt/kvm/assigned-dev.c
@@ -785,3 +785,33 @@ out:
return r;
}
+int kvm_assigned_device_update_msix_mask_bit(struct kvm *kvm,
+ int assigned_dev_id, int entry, u32 flag)
+{
+ int r = -EFAULT;
+ struct kvm_assigned_dev_kernel *adev;
+ int i;
+
+ if (!irqchip_in_kernel(kvm))
+ return r;
+
+ mutex_lock(&kvm->lock);
+ adev = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+ assigned_dev_id);
+ if (!adev)
+ goto out;
+
+ for (i = 0; i < adev->entries_nr; i++)
+ if (adev->host_msix_entries[i].entry == entry) {
+ if (flag)
+ disable_irq_nosync(
+ adev->host_msix_entries[i].vector);
+ else
+ enable_irq(adev->host_msix_entries[i].vector);
+ r = 0;
+ break;
+ }
+out:
+ mutex_unlock(&kvm->lock);
+ return r;
+}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 83f5bf6..4be7cfe 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -56,6 +56,7 @@
#include "coalesced_mmio.h"
#include "async_pf.h"
+#include "msix_mmio.h"
#define CREATE_TRACE_POINTS
#include <trace/events/kvm.h>
@@ -521,6 +522,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
#else
kvm_arch_flush_shadow(kvm);
#endif
+ kvm_unregister_msix_mmio_dev(kvm);
kvm_arch_destroy_vm(kvm);
kvm_free_physmem(kvm);
cleanup_srcu_struct(&kvm->srcu);
@@ -1877,6 +1879,24 @@ static long kvm_vm_ioctl(struct file *filp,
mutex_unlock(&kvm->lock);
break;
#endif
+ case KVM_REGISTER_MSIX_MMIO: {
+ struct kvm_msix_mmio_user mmio_user;
+
+ r = -EFAULT;
+ if (copy_from_user(&mmio_user, argp, sizeof mmio_user))
+ goto out;
+ r = kvm_vm_ioctl_register_msix_mmio(kvm, &mmio_user);
+ break;
+ }
+ case KVM_UNREGISTER_MSIX_MMIO: {
+ struct kvm_msix_mmio_user mmio_user;
+
+ r = -EFAULT;
+ if (copy_from_user(&mmio_user, argp, sizeof mmio_user))
+ goto out;
+ r = kvm_vm_ioctl_unregister_msix_mmio(kvm, &mmio_user);
+ break;
+ }
default:
r = kvm_arch_vm_ioctl(filp, ioctl, arg);
if (r == -ENOTTY)
@@ -1988,6 +2008,12 @@ static int kvm_dev_ioctl_create_vm(void)
return r;
}
#endif
+ r = kvm_register_msix_mmio_dev(kvm);
+ if (r < 0) {
+ kvm_put_kvm(kvm);
+ return r;
+ }
+
r = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
if (r < 0)
kvm_put_kvm(kvm);
@@ -2223,14 +2249,18 @@ static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
int len, const void *val)
{
- int i;
+ int i, r = -EOPNOTSUPP;
struct kvm_io_bus *bus;
bus = srcu_dereference(kvm->buses[bus_idx], &kvm->srcu);
- for (i = 0; i < bus->dev_count; i++)
- if (!kvm_iodevice_write(bus->devs[i], addr, len, val))
+ for (i = 0; i < bus->dev_count; i++) {
+ r = kvm_iodevice_write(bus->devs[i], addr, len, val);
+ if (r == -ENOTSYNC)
+ break;
+ else if (!r)
return 0;
- return -EOPNOTSUPP;
+ }
+ return r;
}
/* kvm_io_bus_read - called under kvm->slots_lock */
diff --git a/virt/kvm/msix_mmio.c b/virt/kvm/msix_mmio.c
new file mode 100644
index 0000000..e6064e0
--- /dev/null
+++ b/virt/kvm/msix_mmio.c
@@ -0,0 +1,244 @@
+/*
+ * MSI-X MMIO emulation
+ *
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Author:
+ * Sheng Yang <sheng.yang@intel.com>
+ */
+
+#include <linux/kvm_host.h>
+#include <linux/kvm.h>
+
+#include "msix_mmio.h"
+#include "iodev.h"
+
+static int update_msix_mask_bit(struct kvm *kvm, struct kvm_msix_mmio *mmio,
+ int entry, u32 flag)
+{
+ if (mmio->type & KVM_MSIX_MMIO_TYPE_ASSIGNED_DEV)
+ return kvm_assigned_device_update_msix_mask_bit(kvm,
+ mmio->dev_id, entry, flag);
+ return -EFAULT;
+}
+
+/* Caller must hold dev->lock */
+static int get_mmio_table_index(struct kvm_msix_mmio_dev *dev,
+ gpa_t addr, int len)
+{
+ gpa_t start, end;
+ int i, r = -EINVAL;
+
+ for (i = 0; i < dev->mmio_nr; i++) {
+ start = dev->mmio[i].table_base_addr;
+ end = dev->mmio[i].table_base_addr + PCI_MSIX_ENTRY_SIZE *
+ dev->mmio[i].max_entries_nr;
+ if (addr >= start && addr + len <= end) {
+ r = i;
+ break;
+ }
+ }
+
+ return r;
+}
+
+static int msix_table_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
+ void *val)
+{
+ struct kvm_msix_mmio_dev *mmio_dev =
+ container_of(this, struct kvm_msix_mmio_dev, table_dev);
+ struct kvm_msix_mmio *mmio;
+ int idx, ret = 0, entry, offset, r;
+
+ mutex_lock(&mmio_dev->lock);
+ idx = get_mmio_table_index(mmio_dev, addr, len);
+ if (idx < 0) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+ if ((addr & 0x3) || (len != 4 && len != 8))
+ goto out;
+ mmio = &mmio_dev->mmio[idx];
+
+ entry = (addr - mmio->table_base_addr) / PCI_MSIX_ENTRY_SIZE;
+ offset = addr & 0xf;
+ r = copy_from_user(val, (void *)(mmio->table_base_va +
+ entry * PCI_MSIX_ENTRY_SIZE + offset), len);
+ if (r)
+ goto out;
+out:
+ mutex_unlock(&mmio_dev->lock);
+ return ret;
+}
+
+static int msix_table_mmio_write(struct kvm_io_device *this, gpa_t addr,
+ int len, const void *val)
+{
+ struct kvm_msix_mmio_dev *mmio_dev =
+ container_of(this, struct kvm_msix_mmio_dev, table_dev);
+ struct kvm_msix_mmio *mmio;
+ int idx, entry, offset, ret = 0, r = 0;
+ gpa_t entry_base;
+ u32 old_ctrl, new_ctrl;
+
+ mutex_lock(&mmio_dev->lock);
+ idx = get_mmio_table_index(mmio_dev, addr, len);
+ if (idx < 0) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+ if ((addr & 0x3) || (len != 4 && len != 8))
+ goto out;
+ mmio = &mmio_dev->mmio[idx];
+ entry = (addr - mmio->table_base_addr) / PCI_MSIX_ENTRY_SIZE;
+ entry_base = mmio->table_base_va + entry * PCI_MSIX_ENTRY_SIZE;
+ offset = addr & 0xF;
+
+ if (copy_from_user(&old_ctrl,
+ entry_base + PCI_MSIX_ENTRY_VECTOR_CTRL,
+ sizeof old_ctrl))
+ goto out;
+
+ /* No allow writing to other fields when entry is unmasked */
+ if (!(old_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) &&
+ offset != PCI_MSIX_ENTRY_VECTOR_CTRL)
+ goto out;
+
+ if (copy_to_user(entry_base + offset, val, len))
+ goto out;
+
+ if (copy_from_user(&new_ctrl,
+ entry_base + PCI_MSIX_ENTRY_VECTOR_CTRL,
+ sizeof new_ctrl))
+ goto out;
+
+ if ((offset < PCI_MSIX_ENTRY_VECTOR_CTRL && len == 4) ||
+ (offset < PCI_MSIX_ENTRY_DATA && len == 8))
+ ret = -ENOTSYNC;
+ if (old_ctrl == new_ctrl)
+ goto out;
+ if (!(old_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) &&
+ (new_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT))
+ r = update_msix_mask_bit(mmio_dev->kvm, mmio, entry, 1);
+ else if ((old_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) &&
+ !(new_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT))
+ r = update_msix_mask_bit(mmio_dev->kvm, mmio, entry, 0);
+ if (r || ret)
+ ret = -ENOTSYNC;
+out:
+ mutex_unlock(&mmio_dev->lock);
+ return ret;
+}
+static const struct kvm_io_device_ops msix_mmio_table_ops = {
+ .read = msix_table_mmio_read,
+ .write = msix_table_mmio_write,
+};
+
+int kvm_register_msix_mmio_dev(struct kvm *kvm)
+{
+ int ret;
+
+ kvm_iodevice_init(&kvm->msix_mmio_dev.table_dev, &msix_mmio_table_ops);
+ mutex_init(&kvm->msix_mmio_dev.lock);
+ kvm->msix_mmio_dev.kvm = kvm;
+ mutex_lock(&kvm->slots_lock);
+ ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS,
+ &kvm->msix_mmio_dev.table_dev);
+ mutex_unlock(&kvm->slots_lock);
+ return ret;
+}
+
+int kvm_unregister_msix_mmio_dev(struct kvm *kvm)
+{
+ int ret;
+
+ mutex_lock(&kvm->slots_lock);
+ ret = kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS,
+ &kvm->msix_mmio_dev.table_dev);
+ mutex_unlock(&kvm->slots_lock);
+ return ret;
+}
+
+int kvm_vm_ioctl_register_msix_mmio(struct kvm *kvm,
+ struct kvm_msix_mmio_user *mmio_user)
+{
+ struct kvm_msix_mmio_dev *mmio_dev = &kvm->msix_mmio_dev;
+ struct kvm_msix_mmio *mmio = NULL;
+ int r = 0, i;
+
+ mutex_lock(&mmio_dev->lock);
+ for (i = 0; i < mmio_dev->mmio_nr; i++) {
+ if (mmio_dev->mmio[i].dev_id == mmio_user->dev_id &&
+ (mmio_dev->mmio[i].type & KVM_MSIX_MMIO_TYPE_DEV_MASK) ==
+ (mmio_user->type & KVM_MSIX_MMIO_TYPE_DEV_MASK)) {
+ mmio = &mmio_dev->mmio[i];
+ if (mmio->max_entries_nr != mmio_user->max_entries_nr) {
+ r = -EINVAL;
+ goto out;
+ }
+ break;
+ }
+ }
+ if (!mmio) {
+ if (mmio_dev->mmio_nr == KVM_MSIX_MMIO_MAX) {
+ r = -ENOSPC;
+ goto out;
+ }
+ mmio = &mmio_dev->mmio[mmio_dev->mmio_nr];
+ mmio_dev->mmio_nr++;
+ }
+ mmio->max_entries_nr = mmio_user->max_entries_nr;
+ mmio->dev_id = mmio_user->dev_id;
+ mmio->flags = mmio_user->flags;
+ if ((mmio_user->type & KVM_MSIX_MMIO_TYPE_DEV_MASK) ==
+ KVM_MSIX_MMIO_TYPE_ASSIGNED_DEV)
+ mmio->type = KVM_MSIX_MMIO_TYPE_ASSIGNED_DEV;
+
+ if ((mmio_user->type & KVM_MSIX_MMIO_TYPE_BASE_MASK) ==
+ KVM_MSIX_MMIO_TYPE_BASE_TABLE) {
+ mmio->type |= KVM_MSIX_MMIO_TYPE_BASE_TABLE;
+ mmio->table_base_addr = mmio_user->base_addr;
+ mmio->table_base_va = mmio_user->base_va;
+ } else if ((mmio_user->type & KVM_MSIX_MMIO_TYPE_BASE_MASK) ==
+ KVM_MSIX_MMIO_TYPE_BASE_PBA) {
+ mmio->type |= KVM_MSIX_MMIO_TYPE_BASE_PBA;
+ mmio->pba_base_addr = mmio_user->base_addr;
+ mmio->pba_base_va = mmio_user->base_va;
+ }
+out:
+ mutex_unlock(&mmio_dev->lock);
+ return r;
+}
+
+int kvm_vm_ioctl_unregister_msix_mmio(struct kvm *kvm,
+ struct kvm_msix_mmio_user *mmio)
+{
+ struct kvm_msix_mmio_dev *mmio_dev = &kvm->msix_mmio_dev;
+ int r = 0, i, j;
+ bool found = 0;
+
+ mutex_lock(&mmio_dev->lock);
+ BUG_ON(mmio_dev->mmio_nr >= KVM_MSIX_MMIO_MAX);
+ for (i = 0; i < mmio_dev->mmio_nr; i++) {
+ if (mmio_dev->mmio[i].max_entries_nr != 0 &&
+ mmio_dev->mmio[i].dev_id == mmio->dev_id &&
+ mmio_dev->mmio[i].type == mmio->type) {
+ found = true;
+ for (j = i; j < mmio_dev->mmio_nr - 1; j++)
+ mmio_dev->mmio[j] = mmio_dev->mmio[j + 1];
+ mmio_dev->mmio[mmio_dev->mmio_nr].max_entries_nr = 0;
+ mmio_dev->mmio[mmio_dev->mmio_nr].dev_id = 0;
+ mmio_dev->mmio[mmio_dev->mmio_nr].type = 0;
+ mmio_dev->mmio_nr--;
+ break;
+ }
+ }
+ if (!found)
+ r = -EINVAL;
+ mutex_unlock(&mmio_dev->lock);
+ return r;
+}
+
diff --git a/virt/kvm/msix_mmio.h b/virt/kvm/msix_mmio.h
new file mode 100644
index 0000000..87caa29
--- /dev/null
+++ b/virt/kvm/msix_mmio.h
@@ -0,0 +1,24 @@
+#ifndef __KVM_MSIX_MMIO_H__
+#define __KVM_MSIX_MMIO_H__
+/*
+ * MSI-X MMIO emulation
+ *
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Author:
+ * Sheng Yang <sheng.yang@intel.com>
+ */
+
+#include <linux/pci.h>
+
+int kvm_register_msix_mmio_dev(struct kvm *kvm);
+int kvm_unregister_msix_mmio_dev(struct kvm *kvm);
+int kvm_vm_ioctl_register_msix_mmio(struct kvm *kvm,
+ struct kvm_msix_mmio_user *mmio);
+int kvm_vm_ioctl_unregister_msix_mmio(struct kvm *kvm,
+ struct kvm_msix_mmio_user *mmio);
+
+#endif
--
1.7.0.1
next prev parent reply other threads:[~2010-12-22 8:44 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-22 8:44 [PATCH 0/2 v6] MSI-X mask bit support for KVM Sheng Yang
2010-12-22 8:44 ` [PATCH 1/2] KVM: Move struct kvm_io_device to kvm_host.h Sheng Yang
2010-12-22 8:44 ` Sheng Yang [this message]
2010-12-28 12:26 ` [PATCH 2/2][RFC] KVM: Emulate MSI-X table and PBA in kernel Avi Kivity
2010-12-29 7:18 ` Sheng Yang
2010-12-29 8:31 ` Michael S. Tsirkin
2010-12-29 8:55 ` Sheng Yang
2010-12-29 9:28 ` Michael S. Tsirkin
2010-12-30 7:32 ` Sheng Yang
2010-12-30 7:47 ` Michael S. Tsirkin
2010-12-30 7:55 ` Sheng Yang
2010-12-30 8:15 ` Michael S. Tsirkin
2010-12-30 8:24 ` Sheng Yang
2010-12-30 8:52 ` Michael S. Tsirkin
2010-12-30 9:13 ` Sheng Yang
2010-12-30 9:30 ` Avi Kivity
2010-12-30 10:32 ` Michael S. Tsirkin
2010-12-30 10:37 ` Avi Kivity
2010-12-30 11:07 ` Michael S. Tsirkin
2010-12-30 11:27 ` Avi Kivity
2010-12-30 12:17 ` Michael S. Tsirkin
2010-12-31 3:05 ` Sheng Yang
2011-01-02 9:26 ` Michael S. Tsirkin
2011-01-02 10:26 ` Avi Kivity
2011-01-02 10:39 ` Michael S. Tsirkin
2011-01-02 10:58 ` Avi Kivity
2011-01-02 11:51 ` Michael S. Tsirkin
2011-01-02 13:34 ` Avi Kivity
2011-01-02 13:57 ` Michael S. Tsirkin
2010-12-30 9:28 ` Avi Kivity
2010-12-30 10:03 ` Michael S. Tsirkin
2010-12-28 4:05 ` [PATCH 0/2 v6] MSI-X mask bit support for KVM Sheng Yang
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=1293007495-32325-3-git-send-email-sheng@linux.intel.com \
--to=sheng@linux.intel.com \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=mst@redhat.com \
--cc=mtosatti@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.