KVM: provide irq_unsafe kvm_guest_{enter|exit}
authorChristian Borntraeger <borntraeger@de.ibm.com>
Thu, 30 Apr 2015 11:43:30 +0000 (13:43 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 7 May 2015 09:28:21 +0000 (11:28 +0200)
Several kvm architectures disable interrupts before kvm_guest_enter.
kvm_guest_enter then uses local_irq_save/restore to disable interrupts
again or for the first time. Lets provide underscore versions of
kvm_guest_{enter|exit} that assume being called locked.
kvm_guest_enter now disables interrupts for the full function and
thus we can remove the check for preemptible.

This patch then adopts s390/kvm to use local_irq_disable/enable calls
which are slighty cheaper that local_irq_save/restore and call these
new functions.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/s390/kvm/kvm-s390.c
include/linux/kvm_host.h

index 8cd8e7b288c5db84bf358785bb9aee4510c69050..2be391bb85579929cd8b7bbfc8b79acbc0953fff 100644 (file)
@@ -1993,12 +1993,14 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
                 * As PF_VCPU will be used in fault handler, between
                 * guest_enter and guest_exit should be no uaccess.
                 */
-               preempt_disable();
-               kvm_guest_enter();
-               preempt_enable();
+               local_irq_disable();
+               __kvm_guest_enter();
+               local_irq_enable();
                exit_reason = sie64a(vcpu->arch.sie_block,
                                     vcpu->run->s.regs.gprs);
-               kvm_guest_exit();
+               local_irq_disable();
+               __kvm_guest_exit();
+               local_irq_enable();
                vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
 
                rc = vcpu_post_run(vcpu, exit_reason);
index ad45054309a0fcaea6d12392cf02560f3d46ab95..efc16df1fc5d27f57bb53bcae973dfbe965181f8 100644 (file)
@@ -762,16 +762,10 @@ static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
 }
 #endif
 
-static inline void kvm_guest_enter(void)
+/* must be called with irqs disabled */
+static inline void __kvm_guest_enter(void)
 {
-       unsigned long flags;
-
-       BUG_ON(preemptible());
-
-       local_irq_save(flags);
        guest_enter();
-       local_irq_restore(flags);
-
        /* KVM does not hold any references to rcu protected data when it
         * switches CPU into a guest mode. In fact switching to a guest mode
         * is very similar to exiting to userspace from rcu point of view. In
@@ -783,12 +777,27 @@ static inline void kvm_guest_enter(void)
                rcu_virt_note_context_switch(smp_processor_id());
 }
 
+/* must be called with irqs disabled */
+static inline void __kvm_guest_exit(void)
+{
+       guest_exit();
+}
+
+static inline void kvm_guest_enter(void)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       __kvm_guest_enter();
+       local_irq_restore(flags);
+}
+
 static inline void kvm_guest_exit(void)
 {
        unsigned long flags;
 
        local_irq_save(flags);
-       guest_exit();
+       __kvm_guest_exit();
        local_irq_restore(flags);
 }