diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-08-04 07:59:56 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-08-04 07:59:56 -0400 |
commit | 6f49b2f3414622d3e41135a65dac98968956662b (patch) | |
tree | efd4c358a40b9e6adb9dd35de3407bbf17bd2935 | |
parent | abe9efa79be02cf2ba27f643b214b07877bb050b (diff) | |
parent | 89581f06b2bc225f0c9822fa52e714aa2e3810dd (diff) |
Merge tag 'kvm-arm-for-4.8-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/ARM Changes for v4.8 - Take 2
Includes GSI routing support to go along with the new VGIC and a small fix that
has been cooking in -next for a while.
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 46 | ||||
-rw-r--r-- | arch/arm/kvm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/kvm/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/kvm/irq.h | 19 | ||||
-rw-r--r-- | arch/arm64/kvm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm64/kvm/Makefile | 1 | ||||
-rw-r--r-- | arch/arm64/kvm/inject_fault.c | 12 | ||||
-rw-r--r-- | arch/arm64/kvm/irq.h | 19 | ||||
-rw-r--r-- | arch/x86/kvm/irq.h | 3 | ||||
-rw-r--r-- | include/kvm/arm_vgic.h | 7 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 12 | ||||
-rw-r--r-- | include/uapi/linux/kvm.h | 5 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-init.c | 4 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-irqfd.c | 116 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic.c | 7 | ||||
-rw-r--r-- | virt/kvm/irqchip.c | 28 |
16 files changed, 225 insertions, 59 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 5237e1b2fd66..da3c395ed174 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -1433,13 +1433,16 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed. | |||
1433 | 4.52 KVM_SET_GSI_ROUTING | 1433 | 4.52 KVM_SET_GSI_ROUTING |
1434 | 1434 | ||
1435 | Capability: KVM_CAP_IRQ_ROUTING | 1435 | Capability: KVM_CAP_IRQ_ROUTING |
1436 | Architectures: x86 s390 | 1436 | Architectures: x86 s390 arm arm64 |
1437 | Type: vm ioctl | 1437 | Type: vm ioctl |
1438 | Parameters: struct kvm_irq_routing (in) | 1438 | Parameters: struct kvm_irq_routing (in) |
1439 | Returns: 0 on success, -1 on error | 1439 | Returns: 0 on success, -1 on error |
1440 | 1440 | ||
1441 | Sets the GSI routing table entries, overwriting any previously set entries. | 1441 | Sets the GSI routing table entries, overwriting any previously set entries. |
1442 | 1442 | ||
1443 | On arm/arm64, GSI routing has the following limitation: | ||
1444 | - GSI routing does not apply to KVM_IRQ_LINE but only to KVM_IRQFD. | ||
1445 | |||
1443 | struct kvm_irq_routing { | 1446 | struct kvm_irq_routing { |
1444 | __u32 nr; | 1447 | __u32 nr; |
1445 | __u32 flags; | 1448 | __u32 flags; |
@@ -1468,7 +1471,13 @@ struct kvm_irq_routing_entry { | |||
1468 | #define KVM_IRQ_ROUTING_S390_ADAPTER 3 | 1471 | #define KVM_IRQ_ROUTING_S390_ADAPTER 3 |
1469 | #define KVM_IRQ_ROUTING_HV_SINT 4 | 1472 | #define KVM_IRQ_ROUTING_HV_SINT 4 |
1470 | 1473 | ||
1471 | No flags are specified so far, the corresponding field must be set to zero. | 1474 | flags: |
1475 | - KVM_MSI_VALID_DEVID: used along with KVM_IRQ_ROUTING_MSI routing entry | ||
1476 | type, specifies that the devid field contains a valid value. The per-VM | ||
1477 | KVM_CAP_MSI_DEVID capability advertises the requirement to provide | ||
1478 | the device ID. If this capability is not available, userspace should | ||
1479 | never set the KVM_MSI_VALID_DEVID flag as the ioctl might fail. | ||
1480 | - zero otherwise | ||
1472 | 1481 | ||
1473 | struct kvm_irq_routing_irqchip { | 1482 | struct kvm_irq_routing_irqchip { |
1474 | __u32 irqchip; | 1483 | __u32 irqchip; |
@@ -1479,9 +1488,16 @@ struct kvm_irq_routing_msi { | |||
1479 | __u32 address_lo; | 1488 | __u32 address_lo; |
1480 | __u32 address_hi; | 1489 | __u32 address_hi; |
1481 | __u32 data; | 1490 | __u32 data; |
1482 | __u32 pad; | 1491 | union { |
1492 | __u32 pad; | ||
1493 | __u32 devid; | ||
1494 | }; | ||
1483 | }; | 1495 | }; |
1484 | 1496 | ||
1497 | If KVM_MSI_VALID_DEVID is set, devid contains a unique device identifier | ||
1498 | for the device that wrote the MSI message. For PCI, this is usually a | ||
1499 | BFD identifier in the lower 16 bits. | ||
1500 | |||
1485 | On x86, address_hi is ignored unless the KVM_X2APIC_API_USE_32BIT_IDS | 1501 | On x86, address_hi is ignored unless the KVM_X2APIC_API_USE_32BIT_IDS |
1486 | feature of KVM_CAP_X2APIC_API capability is enabled. If it is enabled, | 1502 | feature of KVM_CAP_X2APIC_API capability is enabled. If it is enabled, |
1487 | address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of | 1503 | address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of |
@@ -2199,14 +2215,14 @@ struct kvm_msi { | |||
2199 | __u8 pad[12]; | 2215 | __u8 pad[12]; |
2200 | }; | 2216 | }; |
2201 | 2217 | ||
2202 | flags: KVM_MSI_VALID_DEVID: devid contains a valid value | 2218 | flags: KVM_MSI_VALID_DEVID: devid contains a valid value. The per-VM |
2203 | devid: If KVM_MSI_VALID_DEVID is set, contains a unique device identifier | 2219 | KVM_CAP_MSI_DEVID capability advertises the requirement to provide |
2204 | for the device that wrote the MSI message. | 2220 | the device ID. If this capability is not available, userspace |
2205 | For PCI, this is usually a BFD identifier in the lower 16 bits. | 2221 | should never set the KVM_MSI_VALID_DEVID flag as the ioctl might fail. |
2206 | 2222 | ||
2207 | The per-VM KVM_CAP_MSI_DEVID capability advertises the need to provide | 2223 | If KVM_MSI_VALID_DEVID is set, devid contains a unique device identifier |
2208 | the device ID. If this capability is not set, userland cannot rely on | 2224 | for the device that wrote the MSI message. For PCI, this is usually a |
2209 | the kernel to allow the KVM_MSI_VALID_DEVID flag being set. | 2225 | BFD identifier in the lower 16 bits. |
2210 | 2226 | ||
2211 | On x86, address_hi is ignored unless the KVM_CAP_X2APIC_API capability is | 2227 | On x86, address_hi is ignored unless the KVM_CAP_X2APIC_API capability is |
2212 | enabled. If it is enabled, address_hi bits 31-8 provide bits 31-8 of the | 2228 | enabled. If it is enabled, address_hi bits 31-8 provide bits 31-8 of the |
@@ -2383,9 +2399,13 @@ Note that closing the resamplefd is not sufficient to disable the | |||
2383 | irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment | 2399 | irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment |
2384 | and need not be specified with KVM_IRQFD_FLAG_DEASSIGN. | 2400 | and need not be specified with KVM_IRQFD_FLAG_DEASSIGN. |
2385 | 2401 | ||
2386 | On ARM/ARM64, the gsi field in the kvm_irqfd struct specifies the Shared | 2402 | On arm/arm64, gsi routing being supported, the following can happen: |
2387 | Peripheral Interrupt (SPI) index, such that the GIC interrupt ID is | 2403 | - in case no routing entry is associated to this gsi, injection fails |
2388 | given by gsi + 32. | 2404 | - in case the gsi is associated to an irqchip routing entry, |
2405 | irqchip.pin + 32 corresponds to the injected SPI ID. | ||
2406 | - in case the gsi is associated to an MSI routing entry, the MSI | ||
2407 | message and device ID are translated into an LPI (support restricted | ||
2408 | to GICv3 ITS in-kernel emulation). | ||
2389 | 2409 | ||
2390 | 4.76 KVM_PPC_ALLOCATE_HTAB | 2410 | 4.76 KVM_PPC_ALLOCATE_HTAB |
2391 | 2411 | ||
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 95a000515e43..3e1cd0452d67 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig | |||
@@ -32,6 +32,8 @@ config KVM | |||
32 | select KVM_VFIO | 32 | select KVM_VFIO |
33 | select HAVE_KVM_EVENTFD | 33 | select HAVE_KVM_EVENTFD |
34 | select HAVE_KVM_IRQFD | 34 | select HAVE_KVM_IRQFD |
35 | select HAVE_KVM_IRQCHIP | ||
36 | select HAVE_KVM_IRQ_ROUTING | ||
35 | depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER | 37 | depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER |
36 | ---help--- | 38 | ---help--- |
37 | Support hosting virtualized guest machines. | 39 | Support hosting virtualized guest machines. |
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 5e28df80dca7..10d77a66cad5 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile | |||
@@ -29,4 +29,5 @@ obj-y += $(KVM)/arm/vgic/vgic-v2.o | |||
29 | obj-y += $(KVM)/arm/vgic/vgic-mmio.o | 29 | obj-y += $(KVM)/arm/vgic/vgic-mmio.o |
30 | obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o | 30 | obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o |
31 | obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o | 31 | obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o |
32 | obj-y += $(KVM)/irqchip.o | ||
32 | obj-y += $(KVM)/arm/arch_timer.o | 33 | obj-y += $(KVM)/arm/arch_timer.o |
diff --git a/arch/arm/kvm/irq.h b/arch/arm/kvm/irq.h new file mode 100644 index 000000000000..b74099b905fd --- /dev/null +++ b/arch/arm/kvm/irq.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * irq.h: in kernel interrupt controller related definitions | ||
3 | * Copyright (c) 2016 Red Hat, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This header is included by irqchip.c. However, on ARM, interrupt | ||
10 | * controller declarations are located in include/kvm/arm_vgic.h since | ||
11 | * they are mostly shared between arm and arm64. | ||
12 | */ | ||
13 | |||
14 | #ifndef __IRQ_H | ||
15 | #define __IRQ_H | ||
16 | |||
17 | #include <kvm/arm_vgic.h> | ||
18 | |||
19 | #endif | ||
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 9d2eff0b3ad3..9c9edc98d271 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig | |||
@@ -37,6 +37,8 @@ config KVM | |||
37 | select KVM_ARM_VGIC_V3 | 37 | select KVM_ARM_VGIC_V3 |
38 | select KVM_ARM_PMU if HW_PERF_EVENTS | 38 | select KVM_ARM_PMU if HW_PERF_EVENTS |
39 | select HAVE_KVM_MSI | 39 | select HAVE_KVM_MSI |
40 | select HAVE_KVM_IRQCHIP | ||
41 | select HAVE_KVM_IRQ_ROUTING | ||
40 | ---help--- | 42 | ---help--- |
41 | Support hosting virtualized guest machines. | 43 | Support hosting virtualized guest machines. |
42 | We don't support KVM with 16K page tables yet, due to the multiple | 44 | We don't support KVM with 16K page tables yet, due to the multiple |
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index a5b96642a9cb..695eb3c7ef41 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile | |||
@@ -30,5 +30,6 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v2.o | |||
30 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o | 30 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o |
31 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o | 31 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o |
32 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o | 32 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o |
33 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o | ||
33 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o | 34 | kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o |
34 | kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o | 35 | kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o |
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index e9e0e6db73f6..898c0e6aedd4 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c | |||
@@ -132,16 +132,14 @@ static u64 get_except_vector(struct kvm_vcpu *vcpu, enum exception_type type) | |||
132 | static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr) | 132 | static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr) |
133 | { | 133 | { |
134 | unsigned long cpsr = *vcpu_cpsr(vcpu); | 134 | unsigned long cpsr = *vcpu_cpsr(vcpu); |
135 | bool is_aarch32; | 135 | bool is_aarch32 = vcpu_mode_is_32bit(vcpu); |
136 | u32 esr = 0; | 136 | u32 esr = 0; |
137 | 137 | ||
138 | is_aarch32 = vcpu_mode_is_32bit(vcpu); | ||
139 | |||
140 | *vcpu_spsr(vcpu) = cpsr; | ||
141 | *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); | 138 | *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); |
142 | |||
143 | *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); | 139 | *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); |
140 | |||
144 | *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; | 141 | *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; |
142 | *vcpu_spsr(vcpu) = cpsr; | ||
145 | 143 | ||
146 | vcpu_sys_reg(vcpu, FAR_EL1) = addr; | 144 | vcpu_sys_reg(vcpu, FAR_EL1) = addr; |
147 | 145 | ||
@@ -172,11 +170,11 @@ static void inject_undef64(struct kvm_vcpu *vcpu) | |||
172 | unsigned long cpsr = *vcpu_cpsr(vcpu); | 170 | unsigned long cpsr = *vcpu_cpsr(vcpu); |
173 | u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT); | 171 | u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT); |
174 | 172 | ||
175 | *vcpu_spsr(vcpu) = cpsr; | ||
176 | *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); | 173 | *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); |
177 | |||
178 | *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); | 174 | *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); |
175 | |||
179 | *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; | 176 | *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; |
177 | *vcpu_spsr(vcpu) = cpsr; | ||
180 | 178 | ||
181 | /* | 179 | /* |
182 | * Build an unknown exception, depending on the instruction | 180 | * Build an unknown exception, depending on the instruction |
diff --git a/arch/arm64/kvm/irq.h b/arch/arm64/kvm/irq.h new file mode 100644 index 000000000000..b74099b905fd --- /dev/null +++ b/arch/arm64/kvm/irq.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * irq.h: in kernel interrupt controller related definitions | ||
3 | * Copyright (c) 2016 Red Hat, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This header is included by irqchip.c. However, on ARM, interrupt | ||
10 | * controller declarations are located in include/kvm/arm_vgic.h since | ||
11 | * they are mostly shared between arm and arm64. | ||
12 | */ | ||
13 | |||
14 | #ifndef __IRQ_H | ||
15 | #define __IRQ_H | ||
16 | |||
17 | #include <kvm/arm_vgic.h> | ||
18 | |||
19 | #endif | ||
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 61ebdc13a29a..035731eb3897 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
@@ -120,4 +120,7 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu); | |||
120 | 120 | ||
121 | int apic_has_pending_timer(struct kvm_vcpu *vcpu); | 121 | int apic_has_pending_timer(struct kvm_vcpu *vcpu); |
122 | 122 | ||
123 | int kvm_setup_default_irq_routing(struct kvm *kvm); | ||
124 | int kvm_setup_empty_irq_routing(struct kvm *kvm); | ||
125 | |||
123 | #endif | 126 | #endif |
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 540da5149ba7..19b698ef3336 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #define VGIC_MAX_SPI 1019 | 34 | #define VGIC_MAX_SPI 1019 |
35 | #define VGIC_MAX_RESERVED 1023 | 35 | #define VGIC_MAX_RESERVED 1023 |
36 | #define VGIC_MIN_LPI 8192 | 36 | #define VGIC_MIN_LPI 8192 |
37 | #define KVM_IRQCHIP_NUM_PINS (1020 - 32) | ||
37 | 38 | ||
38 | enum vgic_type { | 39 | enum vgic_type { |
39 | VGIC_V2, /* Good ol' GICv2 */ | 40 | VGIC_V2, /* Good ol' GICv2 */ |
@@ -314,4 +315,10 @@ static inline int kvm_vgic_get_max_vcpus(void) | |||
314 | 315 | ||
315 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); | 316 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); |
316 | 317 | ||
318 | /** | ||
319 | * kvm_vgic_setup_default_irq_routing: | ||
320 | * Setup a default flat gsi routing table mapping all SPIs | ||
321 | */ | ||
322 | int kvm_vgic_setup_default_irq_routing(struct kvm *kvm); | ||
323 | |||
317 | #endif /* __KVM_ARM_VGIC_H */ | 324 | #endif /* __KVM_ARM_VGIC_H */ |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index aafd702f3e21..01e908ac4a39 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -317,7 +317,13 @@ struct kvm_kernel_irq_routing_entry { | |||
317 | unsigned irqchip; | 317 | unsigned irqchip; |
318 | unsigned pin; | 318 | unsigned pin; |
319 | } irqchip; | 319 | } irqchip; |
320 | struct msi_msg msi; | 320 | struct { |
321 | u32 address_lo; | ||
322 | u32 address_hi; | ||
323 | u32 data; | ||
324 | u32 flags; | ||
325 | u32 devid; | ||
326 | } msi; | ||
321 | struct kvm_s390_adapter_int adapter; | 327 | struct kvm_s390_adapter_int adapter; |
322 | struct kvm_hv_sint hv_sint; | 328 | struct kvm_hv_sint hv_sint; |
323 | }; | 329 | }; |
@@ -1003,12 +1009,12 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq) | |||
1003 | 1009 | ||
1004 | #ifdef CONFIG_S390 | 1010 | #ifdef CONFIG_S390 |
1005 | #define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that... | 1011 | #define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that... |
1012 | #elif defined(CONFIG_ARM64) | ||
1013 | #define KVM_MAX_IRQ_ROUTES 4096 | ||
1006 | #else | 1014 | #else |
1007 | #define KVM_MAX_IRQ_ROUTES 1024 | 1015 | #define KVM_MAX_IRQ_ROUTES 1024 |
1008 | #endif | 1016 | #endif |
1009 | 1017 | ||
1010 | int kvm_setup_default_irq_routing(struct kvm *kvm); | ||
1011 | int kvm_setup_empty_irq_routing(struct kvm *kvm); | ||
1012 | int kvm_set_irq_routing(struct kvm *kvm, | 1018 | int kvm_set_irq_routing(struct kvm *kvm, |
1013 | const struct kvm_irq_routing_entry *entries, | 1019 | const struct kvm_irq_routing_entry *entries, |
1014 | unsigned nr, | 1020 | unsigned nr, |
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index e98bb4cce639..300ef255d1e0 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h | |||
@@ -882,7 +882,10 @@ struct kvm_irq_routing_msi { | |||
882 | __u32 address_lo; | 882 | __u32 address_lo; |
883 | __u32 address_hi; | 883 | __u32 address_hi; |
884 | __u32 data; | 884 | __u32 data; |
885 | __u32 pad; | 885 | union { |
886 | __u32 pad; | ||
887 | __u32 devid; | ||
888 | }; | ||
886 | }; | 889 | }; |
887 | 890 | ||
888 | struct kvm_irq_routing_s390_adapter { | 891 | struct kvm_irq_routing_s390_adapter { |
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c index 1e30ce08700d..fb4b0a79a950 100644 --- a/virt/kvm/arm/vgic/vgic-init.c +++ b/virt/kvm/arm/vgic/vgic-init.c | |||
@@ -264,6 +264,10 @@ int vgic_init(struct kvm *kvm) | |||
264 | kvm_for_each_vcpu(i, vcpu, kvm) | 264 | kvm_for_each_vcpu(i, vcpu, kvm) |
265 | kvm_vgic_vcpu_init(vcpu); | 265 | kvm_vgic_vcpu_init(vcpu); |
266 | 266 | ||
267 | ret = kvm_vgic_setup_default_irq_routing(kvm); | ||
268 | if (ret) | ||
269 | goto out; | ||
270 | |||
267 | dist->initialized = true; | 271 | dist->initialized = true; |
268 | out: | 272 | out: |
269 | return ret; | 273 | return ret; |
diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c index c675513270bb..b31a51a14efb 100644 --- a/virt/kvm/arm/vgic/vgic-irqfd.c +++ b/virt/kvm/arm/vgic/vgic-irqfd.c | |||
@@ -17,36 +17,116 @@ | |||
17 | #include <linux/kvm.h> | 17 | #include <linux/kvm.h> |
18 | #include <linux/kvm_host.h> | 18 | #include <linux/kvm_host.h> |
19 | #include <trace/events/kvm.h> | 19 | #include <trace/events/kvm.h> |
20 | #include <kvm/arm_vgic.h> | ||
21 | #include "vgic.h" | ||
20 | 22 | ||
21 | int kvm_irq_map_gsi(struct kvm *kvm, | 23 | /** |
22 | struct kvm_kernel_irq_routing_entry *entries, | 24 | * vgic_irqfd_set_irq: inject the IRQ corresponding to the |
23 | int gsi) | 25 | * irqchip routing entry |
26 | * | ||
27 | * This is the entry point for irqfd IRQ injection | ||
28 | */ | ||
29 | static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e, | ||
30 | struct kvm *kvm, int irq_source_id, | ||
31 | int level, bool line_status) | ||
24 | { | 32 | { |
25 | return 0; | 33 | unsigned int spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS; |
34 | |||
35 | if (!vgic_valid_spi(kvm, spi_id)) | ||
36 | return -EINVAL; | ||
37 | return kvm_vgic_inject_irq(kvm, 0, spi_id, level); | ||
26 | } | 38 | } |
27 | 39 | ||
28 | int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned int irqchip, | 40 | /** |
29 | unsigned int pin) | 41 | * kvm_set_routing_entry: populate a kvm routing entry |
42 | * from a user routing entry | ||
43 | * | ||
44 | * @kvm: the VM this entry is applied to | ||
45 | * @e: kvm kernel routing entry handle | ||
46 | * @ue: user api routing entry handle | ||
47 | * return 0 on success, -EINVAL on errors. | ||
48 | */ | ||
49 | #ifdef KVM_CAP_X2APIC_API | ||
50 | int kvm_set_routing_entry(struct kvm *kvm, | ||
51 | struct kvm_kernel_irq_routing_entry *e, | ||
52 | const struct kvm_irq_routing_entry *ue) | ||
53 | #else | ||
54 | /* Remove this version and the ifdefery once merged into 4.8 */ | ||
55 | int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e, | ||
56 | const struct kvm_irq_routing_entry *ue) | ||
57 | #endif | ||
30 | { | 58 | { |
31 | return pin; | 59 | int r = -EINVAL; |
60 | |||
61 | switch (ue->type) { | ||
62 | case KVM_IRQ_ROUTING_IRQCHIP: | ||
63 | e->set = vgic_irqfd_set_irq; | ||
64 | e->irqchip.irqchip = ue->u.irqchip.irqchip; | ||
65 | e->irqchip.pin = ue->u.irqchip.pin; | ||
66 | if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) || | ||
67 | (e->irqchip.irqchip >= KVM_NR_IRQCHIPS)) | ||
68 | goto out; | ||
69 | break; | ||
70 | case KVM_IRQ_ROUTING_MSI: | ||
71 | e->set = kvm_set_msi; | ||
72 | e->msi.address_lo = ue->u.msi.address_lo; | ||
73 | e->msi.address_hi = ue->u.msi.address_hi; | ||
74 | e->msi.data = ue->u.msi.data; | ||
75 | e->msi.flags = ue->flags; | ||
76 | e->msi.devid = ue->u.msi.devid; | ||
77 | break; | ||
78 | default: | ||
79 | goto out; | ||
80 | } | ||
81 | r = 0; | ||
82 | out: | ||
83 | return r; | ||
32 | } | 84 | } |
33 | 85 | ||
34 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, | 86 | /** |
35 | u32 irq, int level, bool line_status) | 87 | * kvm_set_msi: inject the MSI corresponding to the |
88 | * MSI routing entry | ||
89 | * | ||
90 | * This is the entry point for irqfd MSI injection | ||
91 | * and userspace MSI injection. | ||
92 | */ | ||
93 | int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | ||
94 | struct kvm *kvm, int irq_source_id, | ||
95 | int level, bool line_status) | ||
36 | { | 96 | { |
37 | unsigned int spi = irq + VGIC_NR_PRIVATE_IRQS; | 97 | struct kvm_msi msi; |
38 | 98 | ||
39 | trace_kvm_set_irq(irq, level, irq_source_id); | 99 | msi.address_lo = e->msi.address_lo; |
100 | msi.address_hi = e->msi.address_hi; | ||
101 | msi.data = e->msi.data; | ||
102 | msi.flags = e->msi.flags; | ||
103 | msi.devid = e->msi.devid; | ||
40 | 104 | ||
41 | BUG_ON(!vgic_initialized(kvm)); | 105 | if (!vgic_has_its(kvm)) |
106 | return -ENODEV; | ||
42 | 107 | ||
43 | return kvm_vgic_inject_irq(kvm, 0, spi, level); | 108 | return vgic_its_inject_msi(kvm, &msi); |
44 | } | 109 | } |
45 | 110 | ||
46 | /* MSI not implemented yet */ | 111 | int kvm_vgic_setup_default_irq_routing(struct kvm *kvm) |
47 | int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | ||
48 | struct kvm *kvm, int irq_source_id, | ||
49 | int level, bool line_status) | ||
50 | { | 112 | { |
51 | return 0; | 113 | struct kvm_irq_routing_entry *entries; |
114 | struct vgic_dist *dist = &kvm->arch.vgic; | ||
115 | u32 nr = dist->nr_spis; | ||
116 | int i, ret; | ||
117 | |||
118 | entries = kcalloc(nr, sizeof(struct kvm_kernel_irq_routing_entry), | ||
119 | GFP_KERNEL); | ||
120 | if (!entries) | ||
121 | return -ENOMEM; | ||
122 | |||
123 | for (i = 0; i < nr; i++) { | ||
124 | entries[i].gsi = i; | ||
125 | entries[i].type = KVM_IRQ_ROUTING_IRQCHIP; | ||
126 | entries[i].u.irqchip.irqchip = 0; | ||
127 | entries[i].u.irqchip.pin = i; | ||
128 | } | ||
129 | ret = kvm_set_irq_routing(kvm, entries, nr, 0); | ||
130 | kfree(entries); | ||
131 | return ret; | ||
52 | } | 132 | } |
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index 39f3358c6d91..e7aeac719e09 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c | |||
@@ -711,10 +711,3 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq) | |||
711 | return map_is_active; | 711 | return map_is_active; |
712 | } | 712 | } |
713 | 713 | ||
714 | int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) | ||
715 | { | ||
716 | if (vgic_has_its(kvm)) | ||
717 | return vgic_its_inject_msi(kvm, msi); | ||
718 | else | ||
719 | return -ENODEV; | ||
720 | } | ||
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index df99e9c3b64d..3bcc9990adf7 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c | |||
@@ -62,12 +62,14 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) | |||
62 | { | 62 | { |
63 | struct kvm_kernel_irq_routing_entry route; | 63 | struct kvm_kernel_irq_routing_entry route; |
64 | 64 | ||
65 | if (!irqchip_in_kernel(kvm) || msi->flags != 0) | 65 | if (!irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVID)) |
66 | return -EINVAL; | 66 | return -EINVAL; |
67 | 67 | ||
68 | route.msi.address_lo = msi->address_lo; | 68 | route.msi.address_lo = msi->address_lo; |
69 | route.msi.address_hi = msi->address_hi; | 69 | route.msi.address_hi = msi->address_hi; |
70 | route.msi.data = msi->data; | 70 | route.msi.data = msi->data; |
71 | route.msi.flags = msi->flags; | ||
72 | route.msi.devid = msi->devid; | ||
71 | 73 | ||
72 | return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); | 74 | return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); |
73 | } | 75 | } |
@@ -177,6 +179,7 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
177 | unsigned flags) | 179 | unsigned flags) |
178 | { | 180 | { |
179 | struct kvm_irq_routing_table *new, *old; | 181 | struct kvm_irq_routing_table *new, *old; |
182 | struct kvm_kernel_irq_routing_entry *e; | ||
180 | u32 i, j, nr_rt_entries = 0; | 183 | u32 i, j, nr_rt_entries = 0; |
181 | int r; | 184 | int r; |
182 | 185 | ||
@@ -200,23 +203,25 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
200 | new->chip[i][j] = -1; | 203 | new->chip[i][j] = -1; |
201 | 204 | ||
202 | for (i = 0; i < nr; ++i) { | 205 | for (i = 0; i < nr; ++i) { |
203 | struct kvm_kernel_irq_routing_entry *e; | ||
204 | |||
205 | r = -ENOMEM; | 206 | r = -ENOMEM; |
206 | e = kzalloc(sizeof(*e), GFP_KERNEL); | 207 | e = kzalloc(sizeof(*e), GFP_KERNEL); |
207 | if (!e) | 208 | if (!e) |
208 | goto out; | 209 | goto out; |
209 | 210 | ||
210 | r = -EINVAL; | 211 | r = -EINVAL; |
211 | if (ue->flags) { | 212 | switch (ue->type) { |
212 | kfree(e); | 213 | case KVM_IRQ_ROUTING_MSI: |
213 | goto out; | 214 | if (ue->flags & ~KVM_MSI_VALID_DEVID) |
215 | goto free_entry; | ||
216 | break; | ||
217 | default: | ||
218 | if (ue->flags) | ||
219 | goto free_entry; | ||
220 | break; | ||
214 | } | 221 | } |
215 | r = setup_routing_entry(kvm, new, e, ue); | 222 | r = setup_routing_entry(kvm, new, e, ue); |
216 | if (r) { | 223 | if (r) |
217 | kfree(e); | 224 | goto free_entry; |
218 | goto out; | ||
219 | } | ||
220 | ++ue; | 225 | ++ue; |
221 | } | 226 | } |
222 | 227 | ||
@@ -233,7 +238,10 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
233 | 238 | ||
234 | new = old; | 239 | new = old; |
235 | r = 0; | 240 | r = 0; |
241 | goto out; | ||
236 | 242 | ||
243 | free_entry: | ||
244 | kfree(e); | ||
237 | out: | 245 | out: |
238 | free_irq_routing_table(new); | 246 | free_irq_routing_table(new); |
239 | 247 | ||