aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Murzin <vladimir.murzin@arm.com>2016-11-02 07:55:34 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2016-11-14 05:32:54 -0500
commit2988509dd8a0e9c2b64192a46ec2fe8211af6d3c (patch)
tree10d3d4a9c17e13cf4603949bd768ea5a4ae2f0c1
parente29bd6f26703088930a5b3595623cf155ddea600 (diff)
ARM: KVM: Support vGICv3 ITS
This patch allows to build and use vGICv3 ITS in 32-bit mode. Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--Documentation/virtual/kvm/api.txt2
-rw-r--r--arch/arm/include/uapi/asm/kvm.h2
-rw-r--r--arch/arm/kvm/Kconfig1
-rw-r--r--arch/arm/kvm/Makefile1
-rw-r--r--arch/arm/kvm/arm.c6
-rw-r--r--arch/arm64/kvm/Kconfig4
-rw-r--r--arch/arm64/kvm/reset.c6
-rw-r--r--virt/kvm/arm/vgic/vgic-kvm-device.c2
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio-v3.c2
-rw-r--r--virt/kvm/arm/vgic/vgic.h26
10 files changed, 11 insertions, 41 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 739db9ab16b2..2feeae6a4c3f 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
21984.71 KVM_SIGNAL_MSI 21984.71 KVM_SIGNAL_MSI
2199 2199
2200Capability: KVM_CAP_SIGNAL_MSI 2200Capability: KVM_CAP_SIGNAL_MSI
2201Architectures: x86 arm64 2201Architectures: x86 arm arm64
2202Type: vm ioctl 2202Type: vm ioctl
2203Parameters: struct kvm_msi (in) 2203Parameters: struct kvm_msi (in)
2204Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error 2204Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index b38c10c73579..af05f8e0903e 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -87,9 +87,11 @@ struct kvm_regs {
87/* Supported VGICv3 address types */ 87/* Supported VGICv3 address types */
88#define KVM_VGIC_V3_ADDR_TYPE_DIST 2 88#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
89#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 89#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
90#define KVM_VGIC_ITS_ADDR_TYPE 4
90 91
91#define KVM_VGIC_V3_DIST_SIZE SZ_64K 92#define KVM_VGIC_V3_DIST_SIZE SZ_64K
92#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K) 93#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
94#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
93 95
94#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ 96#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
95#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */ 97#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 3e1cd0452d67..90d0176fb30d 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -34,6 +34,7 @@ config KVM
34 select HAVE_KVM_IRQFD 34 select HAVE_KVM_IRQFD
35 select HAVE_KVM_IRQCHIP 35 select HAVE_KVM_IRQCHIP
36 select HAVE_KVM_IRQ_ROUTING 36 select HAVE_KVM_IRQ_ROUTING
37 select HAVE_KVM_MSI
37 depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER 38 depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
38 ---help--- 39 ---help---
39 Support hosting virtualized guest machines. 40 Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index f19842ea5418..d571243ab4d1 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
32obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o 32obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
33obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o 33obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
34obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o 34obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
35obj-y += $(KVM)/arm/vgic/vgic-its.o
35obj-y += $(KVM)/irqchip.o 36obj-y += $(KVM)/irqchip.o
36obj-y += $(KVM)/arm/arch_timer.o 37obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 19b5f5c1c0ff..8f92efa8460e 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -221,6 +221,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
221 case KVM_CAP_MAX_VCPUS: 221 case KVM_CAP_MAX_VCPUS:
222 r = KVM_MAX_VCPUS; 222 r = KVM_MAX_VCPUS;
223 break; 223 break;
224 case KVM_CAP_MSI_DEVID:
225 if (!kvm)
226 r = -EINVAL;
227 else
228 r = kvm->arch.vgic.msis_require_devid;
229 break;
224 default: 230 default:
225 r = kvm_arch_dev_ioctl_check_extension(kvm, ext); 231 r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
226 break; 232 break;
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6eaf12c1d627..52cb7ad9b2fd 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
16 16
17if VIRTUALIZATION 17if VIRTUALIZATION
18 18
19config KVM_ARM_VGIC_V3_ITS
20 bool
21
22config KVM 19config KVM
23 bool "Kernel-based Virtual Machine (KVM) support" 20 bool "Kernel-based Virtual Machine (KVM) support"
24 depends on OF 21 depends on OF
@@ -34,7 +31,6 @@ config KVM
34 select KVM_VFIO 31 select KVM_VFIO
35 select HAVE_KVM_EVENTFD 32 select HAVE_KVM_EVENTFD
36 select HAVE_KVM_IRQFD 33 select HAVE_KVM_IRQFD
37 select KVM_ARM_VGIC_V3_ITS
38 select KVM_ARM_PMU if HW_PERF_EVENTS 34 select KVM_ARM_PMU if HW_PERF_EVENTS
39 select HAVE_KVM_MSI 35 select HAVE_KVM_MSI
40 select HAVE_KVM_IRQCHIP 36 select HAVE_KVM_IRQCHIP
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 5bc460884639..e95d4f68bf54 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
86 case KVM_CAP_VCPU_ATTRIBUTES: 86 case KVM_CAP_VCPU_ATTRIBUTES:
87 r = 1; 87 r = 1;
88 break; 88 break;
89 case KVM_CAP_MSI_DEVID:
90 if (!kvm)
91 r = -EINVAL;
92 else
93 r = kvm->arch.vgic.msis_require_devid;
94 break;
95 default: 89 default:
96 r = 0; 90 r = 0;
97 } 91 }
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index ce1f4ed9daf4..fbe87a63d250 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
221 ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops, 221 ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
222 KVM_DEV_TYPE_ARM_VGIC_V3); 222 KVM_DEV_TYPE_ARM_VGIC_V3);
223 223
224#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
225 if (ret) 224 if (ret)
226 break; 225 break;
227 ret = kvm_vgic_register_its_device(); 226 ret = kvm_vgic_register_its_device();
228#endif
229 break; 227 break;
230 } 228 }
231 229
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 0d3c76a4208b..50f42f0f8c4f 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
42 return reg | ((u64)val << lower); 42 return reg | ((u64)val << lower);
43} 43}
44 44
45#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
46bool vgic_has_its(struct kvm *kvm) 45bool vgic_has_its(struct kvm *kvm)
47{ 46{
48 struct vgic_dist *dist = &kvm->arch.vgic; 47 struct vgic_dist *dist = &kvm->arch.vgic;
@@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
52 51
53 return dist->has_its; 52 return dist->has_its;
54} 53}
55#endif
56 54
57static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu, 55static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
58 gpa_t addr, unsigned int len) 56 gpa_t addr, unsigned int len)
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 9d9e014765a2..859f65c6e056 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -84,37 +84,11 @@ int vgic_v3_probe(const struct gic_kvm_info *info);
84int vgic_v3_map_resources(struct kvm *kvm); 84int vgic_v3_map_resources(struct kvm *kvm);
85int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address); 85int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
86 86
87#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
88int vgic_register_its_iodevs(struct kvm *kvm); 87int vgic_register_its_iodevs(struct kvm *kvm);
89bool vgic_has_its(struct kvm *kvm); 88bool vgic_has_its(struct kvm *kvm);
90int kvm_vgic_register_its_device(void); 89int kvm_vgic_register_its_device(void);
91void vgic_enable_lpis(struct kvm_vcpu *vcpu); 90void vgic_enable_lpis(struct kvm_vcpu *vcpu);
92int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi); 91int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
93#else
94static inline int vgic_register_its_iodevs(struct kvm *kvm)
95{
96 return -ENODEV;
97}
98
99static inline bool vgic_has_its(struct kvm *kvm)
100{
101 return false;
102}
103
104static inline int kvm_vgic_register_its_device(void)
105{
106 return -ENODEV;
107}
108
109static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
110{
111}
112
113static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
114{
115 return -ENODEV;
116}
117#endif
118 92
119int kvm_register_vgic_device(unsigned long type); 93int kvm_register_vgic_device(unsigned long type);
120int vgic_lazy_init(struct kvm *kvm); 94int vgic_lazy_init(struct kvm *kvm);