|   | 
      | 
  
  
      | 
      | 
  
 
     | 
    | 
  
  
     | 
    | 
  
  
    |   | 
      | 
  
  
    | 
         
xen-devel
[Xen-devel] 2.6.32 PV Xen donU guest panic on nested call to	arch_enter_
 
I'm posting this because I am writing a patch to fix a 2.6.32 based PV 
Xen domU panic due to a nested call to arch/x86/include/asm/paravirt.h 
arch_enter_lazy_mmu_mode() (see details below).  The following BUG_ON() 
was triggered:
   arch/x86/kernel/paravirt.c
   static inline void enter_lazy(enum paravirt_lazy_mode mode)
   {
           BUG_ON(percpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
           percpu_write(paravirt_lazy_mode, mode);
   }
because enter_lazy() was called twice, once through mm/memory.c 
copy_pte_range() and a second time through an interrupt path.
 The easy fix is to disable interrupts in copy_pte_range() before calling 
arch_enter_lazy_mmu_mode() and re-enable them after the call to 
arch_leave_lazy_mmu_mode() but I'm asking if there is a better way to 
handle this.  If disabling interrupts is best, there are other calls to 
arch_enter_lazy_mmu_mode() that appear to have the same interruption 
issue.  It may be best then to disable interrupts in 
arch_enter_lazy_mmu_mode() or paravirt_enter_lazy_mmu().
 Here is how the nested call to arch_enter_lazy_mmu_mode() was made.  The 
first call path is:
   do_fork()
     copy_process()
       dup_mm()
         dup_mmap()
           copy_page_range()
             copy_pud_range()
               copy_pmd_range()
                 copy_pte_range()
                   arch_enter_lazy_mmu_mode()
                     paravirt_enter_lazy_mmu()
                       enter_lazy()
We bubble back up to mm/memory.c copy_pte_range().  The guest is 
interrupted in that function.  Here is the edited interrupt call stack 
that gets us to arch_enter_lazy_mmu_mode() for the second time without 
an intervening arch_leave_lazy_mmu_mode(), triggering the BUG_ON() in 
enter_lazy():
   xen_evtchn_do_upcall()
    handle_irq()
      blkif_interrupt()
        do_blkif_request()
          blkif_queue_request()
            gnttab_alloc_grant_references()
              get_free_entries()
                gnttab_expand()
                  gnttab_map()
                    arch_gnttab_map_shared()
                      apply_to_page_range(... map_pte_fn ...)
We get to enter_lazy() downstream from apply_to_page_range():
   apply_to_page_range(... map_pte_fn ...)
     apply_to_pud_range(... map_pte_fn ...)
       apply_to_pmd_range(... map_pte_fn ...)
          apply_to_pte_range(... map_pte_fn ...)
            arch_enter_lazy_mmu_mode()
              paravirt_enter_lazy_mmu()
                enter_lazy()
The spin locks acquired indirectly through mm/memory.c copy_pte_range() 
are obtained with spin_lock() and spin_acquire() which I believe do not 
disable interrupts.
Thanks,
Chuck
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
 
 |   
 
| <Prev in Thread] | 
Current Thread | 
[Next in Thread>
 |  
- [Xen-devel] 2.6.32 PV Xen donU guest panic on nested call to	arch_enter_lazy_mmu_mode(),
Chuck Anderson <=
 
 
 |  
  
 | 
    | 
  
  
    |   | 
    |