2018-07-10 09:56:38

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH] KVM: Add coalesced PIO support

Windows I/O, such as the real-time clock. The address register (port
0x70 in the RTC case) can use coalesced I/O, cutting the number of
userspace exits by half when reading or writing the RTC.

Guest access rtc like this: write register index to 0x70, then write or
read data from 0x71. writing 0x70 port is just as index and do nothing
else. So we can use coalesced mmio to handle this scene to reduce VM-EXIT
time.

In our environment, 12 windows guests running on a Skylake server:

Before patch:

IO Port Access Samples Samples% Time% Avg time

0x70:POUT 20675 46.04% 92.72% 67.15us ( +- 7.93% )

After patch:

IO Port Access Samples Samples% Time% Avg time

0x70:POUT 17509 45.42% 42.08% 6.37us ( +- 20.37% )

Thanks to Peng Hao's initial patch.

Cc: Paolo Bonzini <[email protected]>
Cc: Radim Krčmář <[email protected]>
Cc: Eduardo Habkost <[email protected]>
Signed-off-by: Wanpeng Li <[email protected]>
---
Documentation/virtual/kvm/00-INDEX | 2 ++
Documentation/virtual/kvm/api.txt | 7 +++++++
Documentation/virtual/kvm/coalesced-io.txt | 17 +++++++++++++++++
include/uapi/linux/kvm.h | 4 ++--
virt/kvm/coalesced_mmio.c | 16 +++++++++++++---
virt/kvm/kvm_main.c | 2 ++
6 files changed, 43 insertions(+), 5 deletions(-)
create mode 100644 Documentation/virtual/kvm/coalesced-io.txt

diff --git a/Documentation/virtual/kvm/00-INDEX b/Documentation/virtual/kvm/00-INDEX
index 3492458..a4a09a0 100644
--- a/Documentation/virtual/kvm/00-INDEX
+++ b/Documentation/virtual/kvm/00-INDEX
@@ -9,6 +9,8 @@ arm
- internal ABI between the kernel and HYP (for arm/arm64)
cpuid.txt
- KVM-specific cpuid leaves (x86).
+coalesced-io.txt
+ - Coalesced MMIO and coalesced PIO.
devices/
- KVM_CAP_DEVICE_CTRL userspace API.
halt-polling.txt
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index d10944e..4190796 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4618,3 +4618,10 @@ This capability indicates that KVM supports paravirtualized Hyper-V TLB Flush
hypercalls:
HvFlushVirtualAddressSpace, HvFlushVirtualAddressSpaceEx,
HvFlushVirtualAddressList, HvFlushVirtualAddressListEx.
+
+8.19 KVM_CAP_COALESCED_PIO
+
+Architectures: x86, s390, ppc, arm64
+
+This Capability indicates that kvm supports writing to a coalesced-pio region
+is not reported to userspace until the next non-coalesced pio is issued.
diff --git a/Documentation/virtual/kvm/coalesced-io.txt b/Documentation/virtual/kvm/coalesced-io.txt
new file mode 100644
index 0000000..5233559
--- /dev/null
+++ b/Documentation/virtual/kvm/coalesced-io.txt
@@ -0,0 +1,17 @@
+----
+Coalesced MMIO and coalesced PIO can be used to optimize writes to
+simple device registers. Writes to a coalesced-I/O region are not
+reported to userspace until the next non-coalesced I/O is issued,
+in a similar fashion to write combining hardware. In KVM, coalesced
+writes are handled in the kernel without exits to userspace, and
+are thus several times faster.
+
+Examples of devices that can benefit from coalesced I/O include:
+
+- devices whose memory is accessed with many consecutive writes, for
+ example the EGA/VGA video RAM.
+
+- windows I/O, such as the real-time clock. The address register (port
+ 0x70 in the RTC case) can use coalesced I/O, cutting the number of
+ userspace exits by half when reading or writing the RTC.
+----
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index b6270a3..53370fc 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -420,13 +420,13 @@ struct kvm_run {
struct kvm_coalesced_mmio_zone {
__u64 addr;
__u32 size;
- __u32 pad;
+ __u32 pio;
};

struct kvm_coalesced_mmio {
__u64 phys_addr;
__u32 len;
- __u32 pad;
+ __u32 pio;
__u8 data[8];
};

diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 9e65feb..fc66a834 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -83,6 +83,7 @@ static int coalesced_mmio_write(struct kvm_vcpu *vcpu,
ring->coalesced_mmio[ring->last].phys_addr = addr;
ring->coalesced_mmio[ring->last].len = len;
memcpy(ring->coalesced_mmio[ring->last].data, val, len);
+ ring->coalesced_mmio[ring->last].pio = dev->zone.pio;
smp_wmb();
ring->last = (ring->last + 1) % KVM_COALESCED_MMIO_MAX;
spin_unlock(&dev->kvm->ring_lock);
@@ -149,8 +150,12 @@ int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm,
dev->zone = *zone;

mutex_lock(&kvm->slots_lock);
- ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, zone->addr,
- zone->size, &dev->dev);
+ if (zone->pio)
+ ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, zone->addr,
+ zone->size, &dev->dev);
+ else
+ ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, zone->addr,
+ zone->size, &dev->dev);
if (ret < 0)
goto out_free_dev;
list_add_tail(&dev->list, &kvm->coalesced_zones);
@@ -174,7 +179,12 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,

list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list)
if (coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
- kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &dev->dev);
+ if (zone->pio)
+ kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS,
+ &dev->dev);
+ else
+ kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS,
+ &dev->dev);
kvm_iodevice_destructor(&dev->dev);
}

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 8b47507f..32d34e1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2936,6 +2936,8 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
#ifdef CONFIG_KVM_MMIO
case KVM_CAP_COALESCED_MMIO:
return KVM_COALESCED_MMIO_PAGE_OFFSET;
+ case KVM_CAP_COALESCED_PIO:
+ return KVM_PIO_PAGE_OFFSET;
#endif
#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
case KVM_CAP_IRQ_ROUTING:
--
2.7.4



2018-07-10 12:56:19

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] KVM: Add coalesced PIO support

Hi Wanpeng,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v4.18-rc4 next-20180709]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Wanpeng-Li/KVM-Add-coalesced-PIO-support/20180710-182037
base: https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: i386-randconfig-x075-201827 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All errors (new ones prefixed by >>):

arch/x86/kvm/../../../virt/kvm/kvm_main.c: In function 'kvm_vm_ioctl_check_extension_generic':
>> arch/x86/kvm/../../../virt/kvm/kvm_main.c:2939:7: error: 'KVM_CAP_COALESCED_PIO' undeclared (first use in this function); did you mean 'KVM_CAP_COALESCED_MMIO'?
case KVM_CAP_COALESCED_PIO:
^~~~~~~~~~~~~~~~~~~~~
KVM_CAP_COALESCED_MMIO
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2939:7: note: each undeclared identifier is reported only once for each function it appears in

vim +2939 arch/x86/kvm/../../../virt/kvm/kvm_main.c

2918
2919 static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
2920 {
2921 switch (arg) {
2922 case KVM_CAP_USER_MEMORY:
2923 case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
2924 case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS:
2925 case KVM_CAP_INTERNAL_ERROR_DATA:
2926 #ifdef CONFIG_HAVE_KVM_MSI
2927 case KVM_CAP_SIGNAL_MSI:
2928 #endif
2929 #ifdef CONFIG_HAVE_KVM_IRQFD
2930 case KVM_CAP_IRQFD:
2931 case KVM_CAP_IRQFD_RESAMPLE:
2932 #endif
2933 case KVM_CAP_IOEVENTFD_ANY_LENGTH:
2934 case KVM_CAP_CHECK_EXTENSION_VM:
2935 return 1;
2936 #ifdef CONFIG_KVM_MMIO
2937 case KVM_CAP_COALESCED_MMIO:
2938 return KVM_COALESCED_MMIO_PAGE_OFFSET;
> 2939 case KVM_CAP_COALESCED_PIO:
2940 return KVM_PIO_PAGE_OFFSET;
2941 #endif
2942 #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
2943 case KVM_CAP_IRQ_ROUTING:
2944 return KVM_MAX_IRQ_ROUTES;
2945 #endif
2946 #if KVM_ADDRESS_SPACE_NUM > 1
2947 case KVM_CAP_MULTI_ADDRESS_SPACE:
2948 return KVM_ADDRESS_SPACE_NUM;
2949 #endif
2950 case KVM_CAP_MAX_VCPU_ID:
2951 return KVM_MAX_VCPU_ID;
2952 default:
2953 break;
2954 }
2955 return kvm_vm_ioctl_check_extension(kvm, arg);
2956 }
2957

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (2.62 kB)
.config.gz (24.85 kB)
Download all attachments

2018-07-10 14:55:21

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] KVM: Add coalesced PIO support

Hi Wanpeng,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on kvm/linux-next]
[also build test ERROR on v4.18-rc4 next-20180709]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Wanpeng-Li/KVM-Add-coalesced-PIO-support/20180710-182037
base: https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
config: mips-malta_kvm_defconfig (attached as .config)
compiler: mipsel-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=mips

All errors (new ones prefixed by >>):

arch/mips/kvm/../../../virt/kvm/kvm_main.c: In function 'kvm_vm_ioctl_check_extension_generic':
>> arch/mips/kvm/../../../virt/kvm/kvm_main.c:2939:7: error: 'KVM_CAP_COALESCED_PIO' undeclared (first use in this function); did you mean 'KVM_CAP_COALESCED_MMIO'?
case KVM_CAP_COALESCED_PIO:
^~~~~~~~~~~~~~~~~~~~~
KVM_CAP_COALESCED_MMIO
arch/mips/kvm/../../../virt/kvm/kvm_main.c:2939:7: note: each undeclared identifier is reported only once for each function it appears in
>> arch/mips/kvm/../../../virt/kvm/kvm_main.c:2940:10: error: 'KVM_PIO_PAGE_OFFSET' undeclared (first use in this function); did you mean 'KVM_TRC_PAGE_FAULT'?
return KVM_PIO_PAGE_OFFSET;
^~~~~~~~~~~~~~~~~~~
KVM_TRC_PAGE_FAULT

vim +2939 arch/mips/kvm/../../../virt/kvm/kvm_main.c

2918
2919 static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
2920 {
2921 switch (arg) {
2922 case KVM_CAP_USER_MEMORY:
2923 case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
2924 case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS:
2925 case KVM_CAP_INTERNAL_ERROR_DATA:
2926 #ifdef CONFIG_HAVE_KVM_MSI
2927 case KVM_CAP_SIGNAL_MSI:
2928 #endif
2929 #ifdef CONFIG_HAVE_KVM_IRQFD
2930 case KVM_CAP_IRQFD:
2931 case KVM_CAP_IRQFD_RESAMPLE:
2932 #endif
2933 case KVM_CAP_IOEVENTFD_ANY_LENGTH:
2934 case KVM_CAP_CHECK_EXTENSION_VM:
2935 return 1;
2936 #ifdef CONFIG_KVM_MMIO
2937 case KVM_CAP_COALESCED_MMIO:
2938 return KVM_COALESCED_MMIO_PAGE_OFFSET;
> 2939 case KVM_CAP_COALESCED_PIO:
> 2940 return KVM_PIO_PAGE_OFFSET;
2941 #endif
2942 #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
2943 case KVM_CAP_IRQ_ROUTING:
2944 return KVM_MAX_IRQ_ROUTES;
2945 #endif
2946 #if KVM_ADDRESS_SPACE_NUM > 1
2947 case KVM_CAP_MULTI_ADDRESS_SPACE:
2948 return KVM_ADDRESS_SPACE_NUM;
2949 #endif
2950 case KVM_CAP_MAX_VCPU_ID:
2951 return KVM_MAX_VCPU_ID;
2952 default:
2953 break;
2954 }
2955 return kvm_vm_ioctl_check_extension(kvm, arg);
2956 }
2957

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (3.06 kB)
.config.gz (18.62 kB)
Download all attachments

2018-07-10 22:13:00

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] KVM: Add coalesced PIO support

Hi Wanpeng,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on kvm/linux-next]
[also build test WARNING on v4.18-rc4 next-20180710]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Wanpeng-Li/KVM-Add-coalesced-PIO-support/20180710-182037
base: https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

include/trace/events/kvm.h:213:1: sparse: expression using sizeof(void)
include/trace/events/kvm.h:213:1: sparse: expression using sizeof(void)
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2767:57: sparse: cast removes address space of expression
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2767:57: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct compat_sigset_t const [noderef] [usertype] <asn:1>*compat @@ got sn:1>*compat @@
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2767:57: expected struct compat_sigset_t const [noderef] [usertype] <asn:1>*compat
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2767:57: got void *<noident>
include/linux/slab.h:631:13: sparse: undefined identifier '__builtin_mul_overflow'
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2939:14: sparse: undefined identifier 'KVM_CAP_COALESCED_PIO'
>> arch/x86/kvm/../../../virt/kvm/kvm_main.c:2939:14: sparse: incompatible types for 'case' statement
include/linux/overflow.h:220:13: sparse: undefined identifier '__builtin_mul_overflow'
include/linux/overflow.h:220:13: sparse: incorrect type in conditional
include/linux/overflow.h:220:13: got void
include/linux/slab.h:631:13: sparse: call with no type!
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2939:14: sparse: Expected constant expression in case statement
arch/x86/kvm/../../../virt/kvm/kvm_main.c: In function 'kvm_vm_ioctl_check_extension_generic':
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2939:7: error: 'KVM_CAP_COALESCED_PIO' undeclared (first use in this function); did you mean 'KVM_CAP_COALESCED_MMIO'?
case KVM_CAP_COALESCED_PIO:
^~~~~~~~~~~~~~~~~~~~~
KVM_CAP_COALESCED_MMIO
arch/x86/kvm/../../../virt/kvm/kvm_main.c:2939:7: note: each undeclared identifier is reported only once for each function it appears in

vim +/case +2939 arch/x86/kvm/../../../virt/kvm/kvm_main.c

2740
2741 #ifdef CONFIG_KVM_COMPAT
2742 static long kvm_vcpu_compat_ioctl(struct file *filp,
2743 unsigned int ioctl, unsigned long arg)
2744 {
2745 struct kvm_vcpu *vcpu = filp->private_data;
2746 void __user *argp = compat_ptr(arg);
2747 int r;
2748
2749 if (vcpu->kvm->mm != current->mm)
2750 return -EIO;
2751
2752 switch (ioctl) {
2753 case KVM_SET_SIGNAL_MASK: {
2754 struct kvm_signal_mask __user *sigmask_arg = argp;
2755 struct kvm_signal_mask kvm_sigmask;
2756 sigset_t sigset;
2757
2758 if (argp) {
2759 r = -EFAULT;
2760 if (copy_from_user(&kvm_sigmask, argp,
2761 sizeof(kvm_sigmask)))
2762 goto out;
2763 r = -EINVAL;
2764 if (kvm_sigmask.len != sizeof(compat_sigset_t))
2765 goto out;
2766 r = -EFAULT;
> 2767 if (get_compat_sigset(&sigset, (void *)sigmask_arg->sigset))
2768 goto out;
2769 r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
2770 } else
2771 r = kvm_vcpu_ioctl_set_sigmask(vcpu, NULL);
2772 break;
2773 }
2774 default:
2775 r = kvm_vcpu_ioctl(filp, ioctl, arg);
2776 }
2777
2778 out:
2779 return r;
2780 }
2781 #endif
2782
2783 static int kvm_device_ioctl_attr(struct kvm_device *dev,
2784 int (*accessor)(struct kvm_device *dev,
2785 struct kvm_device_attr *attr),
2786 unsigned long arg)
2787 {
2788 struct kvm_device_attr attr;
2789
2790 if (!accessor)
2791 return -EPERM;
2792
2793 if (copy_from_user(&attr, (void __user *)arg, sizeof(attr)))
2794 return -EFAULT;
2795
2796 return accessor(dev, &attr);
2797 }
2798
2799 static long kvm_device_ioctl(struct file *filp, unsigned int ioctl,
2800 unsigned long arg)
2801 {
2802 struct kvm_device *dev = filp->private_data;
2803
2804 switch (ioctl) {
2805 case KVM_SET_DEVICE_ATTR:
2806 return kvm_device_ioctl_attr(dev, dev->ops->set_attr, arg);
2807 case KVM_GET_DEVICE_ATTR:
2808 return kvm_device_ioctl_attr(dev, dev->ops->get_attr, arg);
2809 case KVM_HAS_DEVICE_ATTR:
2810 return kvm_device_ioctl_attr(dev, dev->ops->has_attr, arg);
2811 default:
2812 if (dev->ops->ioctl)
2813 return dev->ops->ioctl(dev, ioctl, arg);
2814
2815 return -ENOTTY;
2816 }
2817 }
2818
2819 static int kvm_device_release(struct inode *inode, struct file *filp)
2820 {
2821 struct kvm_device *dev = filp->private_data;
2822 struct kvm *kvm = dev->kvm;
2823
2824 kvm_put_kvm(kvm);
2825 return 0;
2826 }
2827
2828 static const struct file_operations kvm_device_fops = {
2829 .unlocked_ioctl = kvm_device_ioctl,
2830 .release = kvm_device_release,
2831 KVM_COMPAT(kvm_device_ioctl),
2832 };
2833
2834 struct kvm_device *kvm_device_from_filp(struct file *filp)
2835 {
2836 if (filp->f_op != &kvm_device_fops)
2837 return NULL;
2838
2839 return filp->private_data;
2840 }
2841
2842 static struct kvm_device_ops *kvm_device_ops_table[KVM_DEV_TYPE_MAX] = {
2843 #ifdef CONFIG_KVM_MPIC
2844 [KVM_DEV_TYPE_FSL_MPIC_20] = &kvm_mpic_ops,
2845 [KVM_DEV_TYPE_FSL_MPIC_42] = &kvm_mpic_ops,
2846 #endif
2847 };
2848
2849 int kvm_register_device_ops(struct kvm_device_ops *ops, u32 type)
2850 {
2851 if (type >= ARRAY_SIZE(kvm_device_ops_table))
2852 return -ENOSPC;
2853
2854 if (kvm_device_ops_table[type] != NULL)
2855 return -EEXIST;
2856
2857 kvm_device_ops_table[type] = ops;
2858 return 0;
2859 }
2860
2861 void kvm_unregister_device_ops(u32 type)
2862 {
2863 if (kvm_device_ops_table[type] != NULL)
2864 kvm_device_ops_table[type] = NULL;
2865 }
2866
2867 static int kvm_ioctl_create_device(struct kvm *kvm,
2868 struct kvm_create_device *cd)
2869 {
2870 struct kvm_device_ops *ops = NULL;
2871 struct kvm_device *dev;
2872 bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
2873 int ret;
2874
2875 if (cd->type >= ARRAY_SIZE(kvm_device_ops_table))
2876 return -ENODEV;
2877
2878 ops = kvm_device_ops_table[cd->type];
2879 if (ops == NULL)
2880 return -ENODEV;
2881
2882 if (test)
2883 return 0;
2884
2885 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2886 if (!dev)
2887 return -ENOMEM;
2888
2889 dev->ops = ops;
2890 dev->kvm = kvm;
2891
2892 mutex_lock(&kvm->lock);
2893 ret = ops->create(dev, cd->type);
2894 if (ret < 0) {
2895 mutex_unlock(&kvm->lock);
2896 kfree(dev);
2897 return ret;
2898 }
2899 list_add(&dev->vm_node, &kvm->devices);
2900 mutex_unlock(&kvm->lock);
2901
2902 if (ops->init)
2903 ops->init(dev);
2904
2905 ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
2906 if (ret < 0) {
2907 mutex_lock(&kvm->lock);
2908 list_del(&dev->vm_node);
2909 mutex_unlock(&kvm->lock);
2910 ops->destroy(dev);
2911 return ret;
2912 }
2913
2914 kvm_get_kvm(kvm);
2915 cd->fd = ret;
2916 return 0;
2917 }
2918
2919 static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
2920 {
2921 switch (arg) {
2922 case KVM_CAP_USER_MEMORY:
2923 case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
2924 case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS:
2925 case KVM_CAP_INTERNAL_ERROR_DATA:
2926 #ifdef CONFIG_HAVE_KVM_MSI
2927 case KVM_CAP_SIGNAL_MSI:
2928 #endif
2929 #ifdef CONFIG_HAVE_KVM_IRQFD
2930 case KVM_CAP_IRQFD:
2931 case KVM_CAP_IRQFD_RESAMPLE:
2932 #endif
2933 case KVM_CAP_IOEVENTFD_ANY_LENGTH:
2934 case KVM_CAP_CHECK_EXTENSION_VM:
2935 return 1;
2936 #ifdef CONFIG_KVM_MMIO
2937 case KVM_CAP_COALESCED_MMIO:
2938 return KVM_COALESCED_MMIO_PAGE_OFFSET;
> 2939 case KVM_CAP_COALESCED_PIO:
2940 return KVM_PIO_PAGE_OFFSET;
2941 #endif
2942 #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
2943 case KVM_CAP_IRQ_ROUTING:
2944 return KVM_MAX_IRQ_ROUTES;
2945 #endif
2946 #if KVM_ADDRESS_SPACE_NUM > 1
2947 case KVM_CAP_MULTI_ADDRESS_SPACE:
2948 return KVM_ADDRESS_SPACE_NUM;
2949 #endif
2950 case KVM_CAP_MAX_VCPU_ID:
2951 return KVM_MAX_VCPU_ID;
2952 default:
2953 break;
2954 }
2955 return kvm_vm_ioctl_check_extension(kvm, arg);
2956 }
2957

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation