linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] KVM: Add coalesced PIO support
@ 2018-07-10  9:55 Wanpeng Li
  2018-07-10 12:54 ` kbuild test robot
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Wanpeng Li @ 2018-07-10  9:55 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Paolo Bonzini, Radim Krčmář, Eduardo Habkost

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 <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
---
 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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: Add coalesced PIO support
  2018-07-10  9:55 [PATCH] KVM: Add coalesced PIO support Wanpeng Li
@ 2018-07-10 12:54 ` kbuild test robot
  2018-07-10 14:53 ` kbuild test robot
  2018-07-10 22:11 ` kbuild test robot
  2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2018-07-10 12:54 UTC (permalink / raw)
  To: Wanpeng Li
  Cc: kbuild-all, linux-kernel, kvm, Paolo Bonzini,
	Radim Krčmář,
	Eduardo Habkost

[-- Attachment #1: Type: text/plain, Size: 2613 bytes --]

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25444 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: Add coalesced PIO support
  2018-07-10  9:55 [PATCH] KVM: Add coalesced PIO support Wanpeng Li
  2018-07-10 12:54 ` kbuild test robot
@ 2018-07-10 14:53 ` kbuild test robot
  2018-07-10 22:11 ` kbuild test robot
  2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2018-07-10 14:53 UTC (permalink / raw)
  To: Wanpeng Li
  Cc: kbuild-all, linux-kernel, kvm, Paolo Bonzini,
	Radim Krčmář,
	Eduardo Habkost

[-- Attachment #1: Type: text/plain, Size: 3052 bytes --]

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 19070 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: Add coalesced PIO support
  2018-07-10  9:55 [PATCH] KVM: Add coalesced PIO support Wanpeng Li
  2018-07-10 12:54 ` kbuild test robot
  2018-07-10 14:53 ` kbuild test robot
@ 2018-07-10 22:11 ` kbuild test robot
  2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2018-07-10 22:11 UTC (permalink / raw)
  To: Wanpeng Li
  Cc: kbuild-all, linux-kernel, kvm, Paolo Bonzini,
	Radim Krčmář,
	Eduardo Habkost

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-07-10 22:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-10  9:55 [PATCH] KVM: Add coalesced PIO support Wanpeng Li
2018-07-10 12:54 ` kbuild test robot
2018-07-10 14:53 ` kbuild test robot
2018-07-10 22:11 ` kbuild test robot

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).