ia64/xen-unstable

changeset 2471:ef4fbfe250a7

bitkeeper revision 1.1159.1.148 (4142fe723Wt2mBhN5bsk_saNcZmnxg)

Live migration shadow table support for writable page tables.
author iap10@labyrinth.cl.cam.ac.uk
date Sat Sep 11 13:32:34 2004 +0000 (2004-09-11)
parents 538350dcb66f
children 4e0f3f0e2c97
files xen/arch/x86/domain.c xen/arch/x86/memory.c xen/arch/x86/shadow.c xen/arch/x86/traps.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Fri Sep 10 17:41:02 2004 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Sat Sep 11 13:32:34 2004 +0000
     1.3 @@ -869,11 +869,13 @@ int construct_dom0(struct domain *p,
     1.4  
     1.5      set_bit(DF_CONSTRUCTED, &p->flags);
     1.6  
     1.7 +    new_thread(p, dsi.v_kernentry, vstack_end, vstartinfo_start);
     1.8 +
     1.9  #if 0 /* XXXXX DO NOT CHECK IN ENABLED !!! (but useful for testing so leave) */
    1.10 -    shadow_mode_enable(&p->mm, SHM_test); 
    1.11 +    shadow_lock(&p->mm);
    1.12 +    shadow_mode_enable(p, SHM_test); 
    1.13 +    shadow_unlock(&p->mm);
    1.14  #endif
    1.15  
    1.16 -    new_thread(p, dsi.v_kernentry, vstack_end, vstartinfo_start);
    1.17 -
    1.18      return 0;
    1.19  }
     2.1 --- a/xen/arch/x86/memory.c	Fri Sep 10 17:41:02 2004 +0000
     2.2 +++ b/xen/arch/x86/memory.c	Sat Sep 11 13:32:34 2004 +0000
     2.3 @@ -1707,6 +1707,36 @@ void ptwr_reconnect_disconnected(void)
     2.4          MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
     2.5          domain_crash();
     2.6      }
     2.7 +
     2.8 +    if ( unlikely(current->mm.shadow_mode) )
     2.9 +    {
    2.10 +	unsigned long spte;
    2.11 +	unsigned long sstat = 
    2.12 +	    get_shadow_status(&current->mm, 
    2.13 +			      ptwr_info[cpu].disconnected_pte >> PAGE_SHIFT);
    2.14 +
    2.15 +	if ( sstat & PSH_shadowed ) 
    2.16 +	{ 
    2.17 +	    int i;
    2.18 +	    unsigned long spfn = sstat & PSH_pfn_mask;
    2.19 +	    l1_pgentry_t *sl1e = map_domain_mem( spfn << PAGE_SHIFT );
    2.20 +	    
    2.21 +	    for( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    2.22 +		l1pte_no_fault( &current->mm, 
    2.23 +				&l1_pgentry_val(
    2.24 +				    ptwr_info[cpu].disconnected_page[i]),
    2.25 +				&l1_pgentry_val(sl1e[i]) );
    2.26 +	    }
    2.27 +	    unmap_domain_mem( sl1e );
    2.28 +	    put_shadow_status(&current->mm);
    2.29 +	} 
    2.30 +
    2.31 +	l1pte_no_fault( &current->mm,
    2.32 +			&pte, &spte );
    2.33 +	__put_user(spte, (unsigned long *)&shadow_linear_pg_table
    2.34 +		   [ptwr_info[cpu].disconnected_l1va>>PAGE_SHIFT] );
    2.35 +    }
    2.36 +
    2.37      __flush_tlb_one(ptwr_info[cpu].disconnected_l1va);
    2.38      PTWR_PRINTK(PP_A, ("[A] disconnected_l1va at %p now %08lx\n",
    2.39                         writable_pte, pte));
    2.40 @@ -1752,6 +1782,37 @@ void ptwr_flush_inactive(void)
    2.41          MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte);
    2.42          domain_crash();
    2.43      }
    2.44 +
    2.45 +    if ( unlikely(current->mm.shadow_mode) )
    2.46 +    {
    2.47 +	unsigned long spte;
    2.48 +	unsigned long sstat = 
    2.49 +	    get_shadow_status(&current->mm, 
    2.50 +			      ptwr_info[cpu].writable_pte >> PAGE_SHIFT);
    2.51 +
    2.52 +	if ( sstat & PSH_shadowed ) 
    2.53 +	{ 
    2.54 +	    int i;
    2.55 +	    unsigned long spfn = sstat & PSH_pfn_mask;
    2.56 +	    l1_pgentry_t *sl1e = map_domain_mem( spfn << PAGE_SHIFT );
    2.57 +	    
    2.58 +	    for( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) {
    2.59 +		l1pte_no_fault( &current->mm, 
    2.60 +				&l1_pgentry_val(
    2.61 +				    ptwr_info[cpu].writable_page[i]),
    2.62 +				&l1_pgentry_val(sl1e[i]) );
    2.63 +					       
    2.64 +	    }
    2.65 +	    unmap_domain_mem( sl1e );
    2.66 +	    put_shadow_status(&current->mm);
    2.67 +	} 
    2.68 +
    2.69 +	l1pte_no_fault( &current->mm,
    2.70 +			&pte, &spte );
    2.71 +	__put_user(spte, (unsigned long *)&shadow_linear_pg_table
    2.72 +		   [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT] );
    2.73 +    }
    2.74 +
    2.75      __flush_tlb_one(ptwr_info[cpu].writable_l1va);
    2.76      PTWR_PRINTK(PP_I, ("[I] disconnected_l1va at %p now %08lx\n",
    2.77                         writable_pte, pte));
    2.78 @@ -1778,6 +1839,9 @@ int ptwr_do_page_fault(unsigned long add
    2.79           (__get_user(pte, (unsigned long *)
    2.80                       &linear_pg_table[addr >> PAGE_SHIFT]) == 0) )
    2.81      {
    2.82 +	if( (pte & _PAGE_RW) && (pte & _PAGE_PRESENT) )
    2.83 +	    return 0; /* we can't help. Maybe shadow mode can? */
    2.84 +
    2.85          pfn = pte >> PAGE_SHIFT;
    2.86  #if 0
    2.87          PTWR_PRINTK(PP_ALL, ("check pte %08lx = pfn %08lx for va %08lx\n", pte,
    2.88 @@ -1862,7 +1926,11 @@ int ptwr_do_page_fault(unsigned long add
    2.89                          &linear_pg_table[addr>>PAGE_SHIFT]);
    2.90                  domain_crash();
    2.91              }
    2.92 -            return 1;
    2.93 +
    2.94 +	    if( unlikely(current->mm.shadow_mode) )
    2.95 +		return 0;  /* fall through to shadow mode to propagate */
    2.96 +	    else
    2.97 +		return 1;
    2.98          }
    2.99      }
   2.100      return 0;
     3.1 --- a/xen/arch/x86/shadow.c	Fri Sep 10 17:41:02 2004 +0000
     3.2 +++ b/xen/arch/x86/shadow.c	Sat Sep 11 13:32:34 2004 +0000
     3.3 @@ -660,14 +660,14 @@ int shadow_fault( unsigned long va, long
     3.4      // write back updated gpte
     3.5      // XXX watch out for read-only L2 entries! (not used in Linux)
     3.6      if ( unlikely( __put_user( gpte, (unsigned long*)&linear_pg_table[va>>PAGE_SHIFT])) )
     3.7 -        BUG();  // fixme!
     3.8 +        domain_crash();  // fixme!
     3.9  
    3.10      if ( unlikely( __put_user( spte, (unsigned long*)&shadow_linear_pg_table[va>>PAGE_SHIFT])) )
    3.11      { 
    3.12          // failed:
    3.13          //  the L1 may not be shadowed, or the L2 entry may be insufficient
    3.14  
    3.15 -        unsigned long gpde, spde, gl1pfn, sl1pfn;
    3.16 +        unsigned long gpde, spde, gl1pfn, sl1pfn, sl1ss;
    3.17  
    3.18          SH_VVLOG("3: not shadowed or l2 insufficient gpte=%08lx  spte=%08lx",gpte,spte );
    3.19  
    3.20 @@ -675,8 +675,8 @@ int shadow_fault( unsigned long va, long
    3.21  
    3.22          gl1pfn = gpde>>PAGE_SHIFT;
    3.23  
    3.24 -        
    3.25 -        if ( ! (sl1pfn=__shadow_status(&current->mm, gl1pfn) ) )
    3.26 +        sl1ss = __shadow_status(&current->mm, gl1pfn);
    3.27 +        if ( ! (sl1ss & PSH_shadowed) )
    3.28          {
    3.29              // this L1 is NOT already shadowed so we need to shadow it
    3.30              struct pfn_info *sl1pfn_info;
    3.31 @@ -719,6 +719,7 @@ int shadow_fault( unsigned long va, long
    3.32  
    3.33              SH_VVLOG("4b: was shadowed, l2 missing ( %08lx )",sl1pfn);
    3.34  
    3.35 +            sl1pfn = sl1ss & PSH_pfn_mask;
    3.36              l2pde_general( m, &gpde, &spde, sl1pfn );
    3.37  
    3.38              linear_l2_table[va>>L2_PAGETABLE_SHIFT] = mk_l2_pgentry(gpde);
     4.1 --- a/xen/arch/x86/traps.c	Fri Sep 10 17:41:02 2004 +0000
     4.2 +++ b/xen/arch/x86/traps.c	Sat Sep 11 13:32:34 2004 +0000
     4.3 @@ -121,9 +121,29 @@ void show_guest_stack()
     4.4      
     4.5  }
     4.6  
     4.7 +void show_trace(unsigned long *esp)
     4.8 +{
     4.9 +    unsigned long *stack, addr;
    4.10 +    int i;
    4.11 +
    4.12 +    printk("Call Trace from ESP=%p: ", esp);
    4.13 +    stack = esp;
    4.14 +    i = 0;
    4.15 +    while (((long) stack & (STACK_SIZE-1)) != 0) {
    4.16 +        addr = *stack++;
    4.17 +        if (kernel_text_address(addr)) {
    4.18 +            if (i && ((i % 6) == 0))
    4.19 +                printk("\n   ");
    4.20 +            printk("[<%08lx>] ", addr);
    4.21 +            i++;
    4.22 +        }
    4.23 +    }
    4.24 +    printk("\n");
    4.25 +}
    4.26 +
    4.27  void show_stack(unsigned long *esp)
    4.28  {
    4.29 -    unsigned long *stack, addr;
    4.30 +    unsigned long *stack;
    4.31      int i;
    4.32  
    4.33      printk("Stack trace from ESP=%p:\n", esp);
    4.34 @@ -142,19 +162,7 @@ void show_stack(unsigned long *esp)
    4.35      }
    4.36      printk("\n");
    4.37  
    4.38 -    printk("Call Trace from ESP=%p: ", esp);
    4.39 -    stack = esp;
    4.40 -    i = 0;
    4.41 -    while (((long) stack & (STACK_SIZE-1)) != 0) {
    4.42 -        addr = *stack++;
    4.43 -        if (kernel_text_address(addr)) {
    4.44 -            if (i && ((i % 6) == 0))
    4.45 -                printk("\n   ");
    4.46 -            printk("[<%08lx>] ", addr);
    4.47 -            i++;
    4.48 -        }
    4.49 -    }
    4.50 -    printk("\n");
    4.51 +    show_trace( esp );
    4.52  }
    4.53  
    4.54  void show_registers(struct pt_regs *regs)
     5.1 --- a/xen/include/asm-x86/shadow.h	Fri Sep 10 17:41:02 2004 +0000
     5.2 +++ b/xen/include/asm-x86/shadow.h	Sat Sep 11 13:32:34 2004 +0000
     5.3 @@ -118,13 +118,18 @@ static inline int __mark_dirty( struct m
     5.4      }
     5.5      else
     5.6      {
     5.7 -        extern void show_traceX(void);
     5.8          SH_LOG("mark_dirty OOR! mfn=%x pfn=%x max=%x (mm %p)",
     5.9                 mfn, pfn, m->shadow_dirty_bitmap_size, m );
    5.10 -        SH_LOG("dom=%u caf=%08x taf=%08x\n", 
    5.11 -               frame_table[mfn].u.inuse.domain->domain,
    5.12 +        SH_LOG("dom=%p caf=%08x taf=%08x\n", 
    5.13 +               frame_table[mfn].u.inuse.domain,
    5.14                 frame_table[mfn].count_info, 
    5.15                 frame_table[mfn].u.inuse.type_info );
    5.16 +		{
    5.17 +			extern void show_trace(unsigned long *esp);		
    5.18 +			unsigned long *esp;
    5.19 +			__asm__ __volatile__ ("movl %%esp,%0" : "=r" (esp) : );
    5.20 +			show_trace(esp);
    5.21 +		}
    5.22      }
    5.23  
    5.24      return rc;
    5.25 @@ -134,7 +139,7 @@ static inline int __mark_dirty( struct m
    5.26  static inline int mark_dirty( struct mm_struct *m, unsigned int mfn )
    5.27  {
    5.28      int rc;
    5.29 -    ASSERT(local_irq_is_enabled());
    5.30 +    //ASSERT(local_irq_is_enabled());
    5.31      //if(spin_is_locked(&m->shadow_lock)) printk("+");
    5.32      shadow_lock(m);
    5.33      rc = __mark_dirty( m, mfn );
    5.34 @@ -388,7 +393,7 @@ static inline unsigned long get_shadow_s
    5.35         independnetly. 
    5.36      */
    5.37  
    5.38 -    ASSERT(local_irq_is_enabled());
    5.39 +    //ASSERT(local_irq_is_enabled());
    5.40      //if(spin_is_locked(&m->shadow_lock)) printk("*");
    5.41      shadow_lock(m);
    5.42  
    5.43 @@ -585,7 +590,7 @@ static inline void shadow_mk_pagetable( 
    5.44  
    5.45      if ( unlikely(mm->shadow_mode) )
    5.46      {
    5.47 -        ASSERT(local_irq_is_enabled());
    5.48 +        //ASSERT(local_irq_is_enabled());
    5.49          shadow_lock(mm);
    5.50          __shadow_mk_pagetable(mm);
    5.51          shadow_unlock(mm);