Replace local_irq_disable/enable with local_irq_save/restore in the path
where is executed on slave CPUs. This is required because irqs are disabled
while the guest is running on the slave CPUs.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama...@hitachi.com>
Cc: Avi Kivity <a...@redhat.com>
Cc: Marcelo Tosatti <mtosa...@redhat.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: "H. Peter Anvin" <h...@zytor.com>
---

 arch/x86/kvm/mmu.c |   20 ++++++++++++--------
 arch/x86/kvm/vmx.c |    5 +++--
 arch/x86/kvm/x86.c |    7 ++++---
 arch/x86/mm/gup.c  |    7 ++++---
 4 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index be3cea4..6139e1d 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -549,13 +549,14 @@ static u64 mmu_spte_get_lockless(u64 *sptep)
        return __get_spte_lockless(sptep);
 }
 
-static void walk_shadow_page_lockless_begin(struct kvm_vcpu *vcpu)
+static void walk_shadow_page_lockless_begin(struct kvm_vcpu *vcpu,
+                                           unsigned long *flags)
 {
        /*
         * Prevent page table teardown by making any free-er wait during
         * kvm_flush_remote_tlbs() IPI to all active vcpus.
         */
-       local_irq_disable();
+       local_irq_save(*flags);
        vcpu->mode = READING_SHADOW_PAGE_TABLES;
        /*
         * Make sure a following spte read is not reordered ahead of the write
@@ -564,7 +565,8 @@ static void walk_shadow_page_lockless_begin(struct kvm_vcpu 
*vcpu)
        smp_mb();
 }
 
-static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu)
+static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu,
+                                         unsigned long *flags)
 {
        /*
         * Make sure the write to vcpu->mode is not reordered in front of
@@ -573,7 +575,7 @@ static void walk_shadow_page_lockless_end(struct kvm_vcpu 
*vcpu)
         */
        smp_mb();
        vcpu->mode = OUTSIDE_GUEST_MODE;
-       local_irq_enable();
+       local_irq_restore(*flags);
 }
 
 static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
@@ -2959,12 +2961,13 @@ static u64 walk_shadow_page_get_mmio_spte(struct 
kvm_vcpu *vcpu, u64 addr)
 {
        struct kvm_shadow_walk_iterator iterator;
        u64 spte = 0ull;
+       unsigned long flags;
 
-       walk_shadow_page_lockless_begin(vcpu);
+       walk_shadow_page_lockless_begin(vcpu, &flags);
        for_each_shadow_entry_lockless(vcpu, addr, iterator, spte)
                if (!is_shadow_present_pte(spte))
                        break;
-       walk_shadow_page_lockless_end(vcpu);
+       walk_shadow_page_lockless_end(vcpu, &flags);
 
        return spte;
 }
@@ -4043,15 +4046,16 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, 
u64 addr, u64 sptes[4])
        struct kvm_shadow_walk_iterator iterator;
        u64 spte;
        int nr_sptes = 0;
+       unsigned long flags;
 
-       walk_shadow_page_lockless_begin(vcpu);
+       walk_shadow_page_lockless_begin(vcpu, &flags);
        for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
                sptes[iterator.level-1] = spte;
                nr_sptes++;
                if (!is_shadow_present_pte(spte))
                        break;
        }
-       walk_shadow_page_lockless_end(vcpu);
+       walk_shadow_page_lockless_end(vcpu, &flags);
 
        return nr_sptes;
 }
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 32eb588..6ea77e4 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1516,12 +1516,13 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int 
cpu)
        if (vmx->loaded_vmcs->cpu != cpu) {
                struct desc_ptr *gdt = &__get_cpu_var(host_gdt);
                unsigned long sysenter_esp;
+               unsigned long flags;
 
                kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
-               local_irq_disable();
+               local_irq_save(flags);
                list_add(&vmx->loaded_vmcs->loaded_vmcss_on_cpu_link,
                         &per_cpu(loaded_vmcss_on_cpu, cpu));
-               local_irq_enable();
+               local_irq_restore(flags);
 
                /*
                 * Linux uses per-cpu TSS and GDT, so set these when switching
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index be6d549..4a69c66 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5229,6 +5229,7 @@ static void process_nmi(struct kvm_vcpu *vcpu)
 static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 {
        int r;
+       unsigned long flags;
        bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
                vcpu->run->request_interrupt_window;
        bool req_immediate_exit = 0;
@@ -5314,13 +5315,13 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
         */
        smp_mb();
 
-       local_irq_disable();
+       local_irq_save(flags);
 
        if (vcpu->mode == EXITING_GUEST_MODE || vcpu->requests
            || need_resched() || signal_pending(current)) {
                vcpu->mode = OUTSIDE_GUEST_MODE;
                smp_wmb();
-               local_irq_enable();
+               local_irq_restore(flags);
                preempt_enable();
                kvm_x86_ops->cancel_injection(vcpu);
                r = 1;
@@ -5359,7 +5360,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 
        vcpu->mode = OUTSIDE_GUEST_MODE;
        smp_wmb();
-       local_irq_enable();
+       local_irq_restore(flags);
 
        ++vcpu->stat.exits;
 
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
index dd74e46..6679525 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -315,6 +315,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, 
int write,
        struct mm_struct *mm = current->mm;
        unsigned long addr, len, end;
        unsigned long next;
+       unsigned long flags;
        pgd_t *pgdp;
        int nr = 0;
 
@@ -349,7 +350,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, 
int write,
         * (which we do on x86, with the above PAE exception), we can follow the
         * address down to the the page and take a ref on it.
         */
-       local_irq_disable();
+       local_irq_save(flags);
        pgdp = pgd_offset(mm, addr);
        do {
                pgd_t pgd = *pgdp;
@@ -360,7 +361,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, 
int write,
                if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
                        goto slow;
        } while (pgdp++, addr = next, addr != end);
-       local_irq_enable();
+       local_irq_restore(flags);
 
        VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);
        return nr;
@@ -369,7 +370,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, 
int write,
                int ret;
 
 slow:
-               local_irq_enable();
+               local_irq_restore(flags);
 slow_irqon:
                /* Try to get the remaining pages with get_user_pages */
                start += nr << PAGE_SHIFT;


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to