diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-06 09:18:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-06 09:18:21 -0400 |
commit | 80fac0f577a35c437219a2786c1804ab8ca1e998 (patch) | |
tree | dfe87e66f937b2b42ba6b87c4538b7e5bea06d07 | |
parent | 4305f42401b29e2e024bd064618faf25aef5cb69 (diff) | |
parent | 45e11817d5703eceb65a673927a8bc74dc1286d6 (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull more KVM updates from Paolo Bonzini:
- ARM bugfix and MSI injection support
- x86 nested virt tweak and OOPS fix
- Simplify pvclock code (vdso bits acked by Andy Lutomirski).
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
nvmx: mark ept single context invalidation as supported
nvmx: remove comment about missing nested vpid support
KVM: lapic: fix access preemption timer stuff even if kernel_irqchip=off
KVM: documentation: fix KVM_CAP_X2APIC_API information
x86: vdso: use __pvclock_read_cycles
pvclock: introduce seqcount-like API
arm64: KVM: Set cpsr before spsr on fault injection
KVM: arm: vgic-irqfd: Workaround changing kvm_set_routing_entry prototype
KVM: arm/arm64: Enable MSI routing
KVM: arm/arm64: Enable irqchip routing
KVM: Move kvm_setup_default/empty_irq_routing declaration in arch specific header
KVM: irqchip: Convey devid to kvm_set_msi
KVM: Add devid in kvm_kernel_irq_routing_entry
KVM: api: Pass the devid in the msi routing entry
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 53 | ||||
-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/entry/vdso/vclock_gettime.c | 25 | ||||
-rw-r--r-- | arch/x86/include/asm/pvclock.h | 39 | ||||
-rw-r--r-- | arch/x86/kernel/pvclock.c | 17 | ||||
-rw-r--r-- | arch/x86/kvm/irq.h | 3 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 15 | ||||
-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 |
21 files changed, 273 insertions, 117 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 5237e1b2fd66..739db9ab16b2 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,18 +2215,19 @@ 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_X2APIC_API_USE_32BIT_IDS |
2212 | enabled. If it is enabled, address_hi bits 31-8 provide bits 31-8 of the | 2228 | feature of KVM_CAP_X2APIC_API capability is enabled. If it is enabled, |
2213 | destination id. Bits 7-0 of address_hi must be zero. | 2229 | address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of |
2230 | address_hi must be zero. | ||
2214 | 2231 | ||
2215 | 2232 | ||
2216 | 4.71 KVM_CREATE_PIT2 | 2233 | 4.71 KVM_CREATE_PIT2 |
@@ -2383,9 +2400,13 @@ Note that closing the resamplefd is not sufficient to disable the | |||
2383 | irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment | 2400 | irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment |
2384 | and need not be specified with KVM_IRQFD_FLAG_DEASSIGN. | 2401 | and need not be specified with KVM_IRQFD_FLAG_DEASSIGN. |
2385 | 2402 | ||
2386 | On ARM/ARM64, the gsi field in the kvm_irqfd struct specifies the Shared | 2403 | On arm/arm64, gsi routing being supported, the following can happen: |
2387 | Peripheral Interrupt (SPI) index, such that the GIC interrupt ID is | 2404 | - in case no routing entry is associated to this gsi, injection fails |
2388 | given by gsi + 32. | 2405 | - in case the gsi is associated to an irqchip routing entry, |
2406 | irqchip.pin + 32 corresponds to the injected SPI ID. | ||
2407 | - in case the gsi is associated to an MSI routing entry, the MSI | ||
2408 | message and device ID are translated into an LPI (support restricted | ||
2409 | to GICv3 ITS in-kernel emulation). | ||
2389 | 2410 | ||
2390 | 4.76 KVM_PPC_ALLOCATE_HTAB | 2411 | 4.76 KVM_PPC_ALLOCATE_HTAB |
2391 | 2412 | ||
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/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c index 2f02d23a05ef..94d54d0defa7 100644 --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c | |||
@@ -96,9 +96,8 @@ static notrace cycle_t vread_pvclock(int *mode) | |||
96 | { | 96 | { |
97 | const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti; | 97 | const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti; |
98 | cycle_t ret; | 98 | cycle_t ret; |
99 | u64 tsc, pvti_tsc; | 99 | u64 last; |
100 | u64 last, delta, pvti_system_time; | 100 | u32 version; |
101 | u32 version, pvti_tsc_to_system_mul, pvti_tsc_shift; | ||
102 | 101 | ||
103 | /* | 102 | /* |
104 | * Note: The kernel and hypervisor must guarantee that cpu ID | 103 | * Note: The kernel and hypervisor must guarantee that cpu ID |
@@ -123,29 +122,15 @@ static notrace cycle_t vread_pvclock(int *mode) | |||
123 | */ | 122 | */ |
124 | 123 | ||
125 | do { | 124 | do { |
126 | version = pvti->version; | 125 | version = pvclock_read_begin(pvti); |
127 | |||
128 | smp_rmb(); | ||
129 | 126 | ||
130 | if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) { | 127 | if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) { |
131 | *mode = VCLOCK_NONE; | 128 | *mode = VCLOCK_NONE; |
132 | return 0; | 129 | return 0; |
133 | } | 130 | } |
134 | 131 | ||
135 | tsc = rdtsc_ordered(); | 132 | ret = __pvclock_read_cycles(pvti); |
136 | pvti_tsc_to_system_mul = pvti->tsc_to_system_mul; | 133 | } while (pvclock_read_retry(pvti, version)); |
137 | pvti_tsc_shift = pvti->tsc_shift; | ||
138 | pvti_system_time = pvti->system_time; | ||
139 | pvti_tsc = pvti->tsc_timestamp; | ||
140 | |||
141 | /* Make sure that the version double-check is last. */ | ||
142 | smp_rmb(); | ||
143 | } while (unlikely((version & 1) || version != pvti->version)); | ||
144 | |||
145 | delta = tsc - pvti_tsc; | ||
146 | ret = pvti_system_time + | ||
147 | pvclock_scale_delta(delta, pvti_tsc_to_system_mul, | ||
148 | pvti_tsc_shift); | ||
149 | 134 | ||
150 | /* refer to vread_tsc() comment for rationale */ | 135 | /* refer to vread_tsc() comment for rationale */ |
151 | last = gtod->cycle_last; | 136 | last = gtod->cycle_last; |
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index 7c1c89598688..d019f0cc80ec 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h | |||
@@ -25,6 +25,24 @@ void pvclock_resume(void); | |||
25 | 25 | ||
26 | void pvclock_touch_watchdogs(void); | 26 | void pvclock_touch_watchdogs(void); |
27 | 27 | ||
28 | static __always_inline | ||
29 | unsigned pvclock_read_begin(const struct pvclock_vcpu_time_info *src) | ||
30 | { | ||
31 | unsigned version = src->version & ~1; | ||
32 | /* Make sure that the version is read before the data. */ | ||
33 | virt_rmb(); | ||
34 | return version; | ||
35 | } | ||
36 | |||
37 | static __always_inline | ||
38 | bool pvclock_read_retry(const struct pvclock_vcpu_time_info *src, | ||
39 | unsigned version) | ||
40 | { | ||
41 | /* Make sure that the version is re-read after the data. */ | ||
42 | virt_rmb(); | ||
43 | return unlikely(version != src->version); | ||
44 | } | ||
45 | |||
28 | /* | 46 | /* |
29 | * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, | 47 | * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, |
30 | * yielding a 64-bit result. | 48 | * yielding a 64-bit result. |
@@ -69,23 +87,12 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift) | |||
69 | } | 87 | } |
70 | 88 | ||
71 | static __always_inline | 89 | static __always_inline |
72 | unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, | 90 | cycle_t __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src) |
73 | cycle_t *cycles, u8 *flags) | ||
74 | { | 91 | { |
75 | unsigned version; | 92 | u64 delta = rdtsc_ordered() - src->tsc_timestamp; |
76 | cycle_t offset; | 93 | cycle_t offset = pvclock_scale_delta(delta, src->tsc_to_system_mul, |
77 | u64 delta; | 94 | src->tsc_shift); |
78 | 95 | return src->system_time + offset; | |
79 | version = src->version; | ||
80 | /* Make the latest version visible */ | ||
81 | smp_rmb(); | ||
82 | |||
83 | delta = rdtsc_ordered() - src->tsc_timestamp; | ||
84 | offset = pvclock_scale_delta(delta, src->tsc_to_system_mul, | ||
85 | src->tsc_shift); | ||
86 | *cycles = src->system_time + offset; | ||
87 | *flags = src->flags; | ||
88 | return version; | ||
89 | } | 96 | } |
90 | 97 | ||
91 | struct pvclock_vsyscall_time_info { | 98 | struct pvclock_vsyscall_time_info { |
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 06c58ce46762..3599404e3089 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c | |||
@@ -64,14 +64,9 @@ u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src) | |||
64 | u8 flags; | 64 | u8 flags; |
65 | 65 | ||
66 | do { | 66 | do { |
67 | version = src->version; | 67 | version = pvclock_read_begin(src); |
68 | /* Make the latest version visible */ | ||
69 | smp_rmb(); | ||
70 | |||
71 | flags = src->flags; | 68 | flags = src->flags; |
72 | /* Make sure that the version double-check is last. */ | 69 | } while (pvclock_read_retry(src, version)); |
73 | smp_rmb(); | ||
74 | } while ((src->version & 1) || version != src->version); | ||
75 | 70 | ||
76 | return flags & valid_flags; | 71 | return flags & valid_flags; |
77 | } | 72 | } |
@@ -84,10 +79,10 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) | |||
84 | u8 flags; | 79 | u8 flags; |
85 | 80 | ||
86 | do { | 81 | do { |
87 | version = __pvclock_read_cycles(src, &ret, &flags); | 82 | version = pvclock_read_begin(src); |
88 | /* Make sure that the version double-check is last. */ | 83 | ret = __pvclock_read_cycles(src); |
89 | smp_rmb(); | 84 | flags = src->flags; |
90 | } while ((src->version & 1) || version != src->version); | 85 | } while (pvclock_read_retry(src, version)); |
91 | 86 | ||
92 | if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) { | 87 | if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) { |
93 | src->flags &= ~PVCLOCK_GUEST_STOPPED; | 88 | src->flags &= ~PVCLOCK_GUEST_STOPPED; |
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/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 730cf174090a..b62c85229711 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -1349,6 +1349,9 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic) | |||
1349 | 1349 | ||
1350 | bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu) | 1350 | bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu) |
1351 | { | 1351 | { |
1352 | if (!lapic_in_kernel(vcpu)) | ||
1353 | return false; | ||
1354 | |||
1352 | return vcpu->arch.apic->lapic_timer.hv_timer_in_use; | 1355 | return vcpu->arch.apic->lapic_timer.hv_timer_in_use; |
1353 | } | 1356 | } |
1354 | EXPORT_SYMBOL_GPL(kvm_lapic_hv_timer_in_use); | 1357 | EXPORT_SYMBOL_GPL(kvm_lapic_hv_timer_in_use); |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index bc354f003ce1..a45d8580f91e 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2809,12 +2809,8 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) | |||
2809 | vmx->nested.nested_vmx_ept_caps |= | 2809 | vmx->nested.nested_vmx_ept_caps |= |
2810 | VMX_EPT_EXECUTE_ONLY_BIT; | 2810 | VMX_EPT_EXECUTE_ONLY_BIT; |
2811 | vmx->nested.nested_vmx_ept_caps &= vmx_capability.ept; | 2811 | vmx->nested.nested_vmx_ept_caps &= vmx_capability.ept; |
2812 | /* | 2812 | vmx->nested.nested_vmx_ept_caps |= VMX_EPT_EXTENT_GLOBAL_BIT | |
2813 | * For nested guests, we don't do anything specific | 2813 | VMX_EPT_EXTENT_CONTEXT_BIT; |
2814 | * for single context invalidation. Hence, only advertise | ||
2815 | * support for global context invalidation. | ||
2816 | */ | ||
2817 | vmx->nested.nested_vmx_ept_caps |= VMX_EPT_EXTENT_GLOBAL_BIT; | ||
2818 | } else | 2814 | } else |
2819 | vmx->nested.nested_vmx_ept_caps = 0; | 2815 | vmx->nested.nested_vmx_ept_caps = 0; |
2820 | 2816 | ||
@@ -2945,7 +2941,6 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2945 | vmx->nested.nested_vmx_secondary_ctls_high); | 2941 | vmx->nested.nested_vmx_secondary_ctls_high); |
2946 | break; | 2942 | break; |
2947 | case MSR_IA32_VMX_EPT_VPID_CAP: | 2943 | case MSR_IA32_VMX_EPT_VPID_CAP: |
2948 | /* Currently, no nested vpid support */ | ||
2949 | *pdata = vmx->nested.nested_vmx_ept_caps | | 2944 | *pdata = vmx->nested.nested_vmx_ept_caps | |
2950 | ((u64)vmx->nested.nested_vmx_vpid_caps << 32); | 2945 | ((u64)vmx->nested.nested_vmx_vpid_caps << 32); |
2951 | break; | 2946 | break; |
@@ -7609,12 +7604,16 @@ static int handle_invept(struct kvm_vcpu *vcpu) | |||
7609 | 7604 | ||
7610 | switch (type) { | 7605 | switch (type) { |
7611 | case VMX_EPT_EXTENT_GLOBAL: | 7606 | case VMX_EPT_EXTENT_GLOBAL: |
7607 | /* | ||
7608 | * TODO: track mappings and invalidate | ||
7609 | * single context requests appropriately | ||
7610 | */ | ||
7611 | case VMX_EPT_EXTENT_CONTEXT: | ||
7612 | kvm_mmu_sync_roots(vcpu); | 7612 | kvm_mmu_sync_roots(vcpu); |
7613 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); | 7613 | kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); |
7614 | nested_vmx_succeed(vcpu); | 7614 | nested_vmx_succeed(vcpu); |
7615 | break; | 7615 | break; |
7616 | default: | 7616 | default: |
7617 | /* Trap single context invalidation invept calls */ | ||
7618 | BUG_ON(1); | 7617 | BUG_ON(1); |
7619 | break; | 7618 | break; |
7620 | } | 7619 | } |
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 | ||