aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/irq.h2
-rw-r--r--arch/x86/kvm/irq_comm.c15
-rw-r--r--arch/x86/kvm/x86.c11
-rw-r--r--include/linux/kvm_host.h1
-rw-r--r--virt/kvm/irqchip.c5
-rw-r--r--virt/kvm/kvm_main.c5
7 files changed, 19 insertions, 21 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 84c8489531bb..f5bddf92faba 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -728,7 +728,6 @@ struct kvm_hv {
728 728
729enum kvm_irqchip_mode { 729enum kvm_irqchip_mode {
730 KVM_IRQCHIP_NONE, 730 KVM_IRQCHIP_NONE,
731 KVM_IRQCHIP_INIT_IN_PROGRESS, /* temporarily set during creation */
732 KVM_IRQCHIP_KERNEL, /* created with KVM_CREATE_IRQCHIP */ 731 KVM_IRQCHIP_KERNEL, /* created with KVM_CREATE_IRQCHIP */
733 KVM_IRQCHIP_SPLIT, /* created with KVM_CAP_SPLIT_IRQCHIP */ 732 KVM_IRQCHIP_SPLIT, /* created with KVM_CAP_SPLIT_IRQCHIP */
734}; 733};
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 0edd22c3344c..d5005cc26521 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -111,7 +111,7 @@ static inline int irqchip_in_kernel(struct kvm *kvm)
111 111
112 /* Matches smp_wmb() when setting irqchip_mode */ 112 /* Matches smp_wmb() when setting irqchip_mode */
113 smp_rmb(); 113 smp_rmb();
114 return mode > KVM_IRQCHIP_INIT_IN_PROGRESS; 114 return mode != KVM_IRQCHIP_NONE;
115} 115}
116 116
117void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); 117void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 4517a4c2ac3a..3cc3b2d130a0 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -274,16 +274,19 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
274 srcu_read_unlock(&kvm->irq_srcu, idx); 274 srcu_read_unlock(&kvm->irq_srcu, idx);
275} 275}
276 276
277bool kvm_arch_can_set_irq_routing(struct kvm *kvm)
278{
279 return irqchip_in_kernel(kvm);
280}
281
277int kvm_set_routing_entry(struct kvm *kvm, 282int kvm_set_routing_entry(struct kvm *kvm,
278 struct kvm_kernel_irq_routing_entry *e, 283 struct kvm_kernel_irq_routing_entry *e,
279 const struct kvm_irq_routing_entry *ue) 284 const struct kvm_irq_routing_entry *ue)
280{ 285{
281 /* also allow creation of routes during KVM_IRQCHIP_INIT_IN_PROGRESS */ 286 /* We can't check irqchip_in_kernel() here as some callers are
282 if (kvm->arch.irqchip_mode == KVM_IRQCHIP_NONE) 287 * currently inititalizing the irqchip. Other callers should therefore
283 return -EINVAL; 288 * check kvm_arch_can_set_irq_routing() before calling this function.
284 289 */
285 /* Matches smp_wmb() when setting irqchip_mode */
286 smp_rmb();
287 switch (ue->type) { 290 switch (ue->type) {
288 case KVM_IRQ_ROUTING_IRQCHIP: 291 case KVM_IRQ_ROUTING_IRQCHIP:
289 if (irqchip_split(kvm)) 292 if (irqchip_split(kvm))
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index be2ade58edb9..2fe9aa116288 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3919,14 +3919,9 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
3919 goto split_irqchip_unlock; 3919 goto split_irqchip_unlock;
3920 if (kvm->created_vcpus) 3920 if (kvm->created_vcpus)
3921 goto split_irqchip_unlock; 3921 goto split_irqchip_unlock;
3922 kvm->arch.irqchip_mode = KVM_IRQCHIP_INIT_IN_PROGRESS;
3923 r = kvm_setup_empty_irq_routing(kvm); 3922 r = kvm_setup_empty_irq_routing(kvm);
3924 if (r) { 3923 if (r)
3925 kvm->arch.irqchip_mode = KVM_IRQCHIP_NONE;
3926 /* Pairs with smp_rmb() when reading irqchip_mode */
3927 smp_wmb();
3928 goto split_irqchip_unlock; 3924 goto split_irqchip_unlock;
3929 }
3930 /* Pairs with irqchip_in_kernel. */ 3925 /* Pairs with irqchip_in_kernel. */
3931 smp_wmb(); 3926 smp_wmb();
3932 kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT; 3927 kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
@@ -4012,12 +4007,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
4012 goto create_irqchip_unlock; 4007 goto create_irqchip_unlock;
4013 } 4008 }
4014 4009
4015 kvm->arch.irqchip_mode = KVM_IRQCHIP_INIT_IN_PROGRESS;
4016 r = kvm_setup_default_irq_routing(kvm); 4010 r = kvm_setup_default_irq_routing(kvm);
4017 if (r) { 4011 if (r) {
4018 kvm->arch.irqchip_mode = KVM_IRQCHIP_NONE;
4019 /* Pairs with smp_rmb() when reading irqchip_mode */
4020 smp_wmb();
4021 kvm_ioapic_destroy(kvm); 4012 kvm_ioapic_destroy(kvm);
4022 kvm_pic_destroy(kvm); 4013 kvm_pic_destroy(kvm);
4023 goto create_irqchip_unlock; 4014 goto create_irqchip_unlock;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index a5bfffa8c8d4..25cf258a1c9b 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1018,6 +1018,7 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
1018#define KVM_MAX_IRQ_ROUTES 1024 1018#define KVM_MAX_IRQ_ROUTES 1024
1019#endif 1019#endif
1020 1020
1021bool kvm_arch_can_set_irq_routing(struct kvm *kvm);
1021int kvm_set_irq_routing(struct kvm *kvm, 1022int kvm_set_irq_routing(struct kvm *kvm,
1022 const struct kvm_irq_routing_entry *entries, 1023 const struct kvm_irq_routing_entry *entries,
1023 unsigned nr, 1024 unsigned nr,
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index cc30d01a56be..31e40c9e81df 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -172,6 +172,11 @@ void __attribute__((weak)) kvm_arch_irq_routing_update(struct kvm *kvm)
172{ 172{
173} 173}
174 174
175bool __weak kvm_arch_can_set_irq_routing(struct kvm *kvm)
176{
177 return true;
178}
179
175int kvm_set_irq_routing(struct kvm *kvm, 180int kvm_set_irq_routing(struct kvm *kvm,
176 const struct kvm_irq_routing_entry *ue, 181 const struct kvm_irq_routing_entry *ue,
177 unsigned nr, 182 unsigned nr,
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 035bc51f656f..6281cc2446d5 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3075,6 +3075,8 @@ static long kvm_vm_ioctl(struct file *filp,
3075 if (copy_from_user(&routing, argp, sizeof(routing))) 3075 if (copy_from_user(&routing, argp, sizeof(routing)))
3076 goto out; 3076 goto out;
3077 r = -EINVAL; 3077 r = -EINVAL;
3078 if (!kvm_arch_can_set_irq_routing(kvm))
3079 goto out;
3078 if (routing.nr > KVM_MAX_IRQ_ROUTES) 3080 if (routing.nr > KVM_MAX_IRQ_ROUTES)
3079 goto out; 3081 goto out;
3080 if (routing.flags) 3082 if (routing.flags)
@@ -3090,11 +3092,8 @@ static long kvm_vm_ioctl(struct file *filp,
3090 routing.nr * sizeof(*entries))) 3092 routing.nr * sizeof(*entries)))
3091 goto out_free_irq_routing; 3093 goto out_free_irq_routing;
3092 } 3094 }
3093 /* avoid races with KVM_CREATE_IRQCHIP on x86 */
3094 mutex_lock(&kvm->lock);
3095 r = kvm_set_irq_routing(kvm, entries, routing.nr, 3095 r = kvm_set_irq_routing(kvm, entries, routing.nr,
3096 routing.flags); 3096 routing.flags);
3097 mutex_unlock(&kvm->lock);
3098out_free_irq_routing: 3097out_free_irq_routing:
3099 vfree(entries); 3098 vfree(entries);
3100 break; 3099 break;