ia64/xen-unstable

changeset 14494:2216a45bf058

merge with xen-unstable.hg
author awilliam@xenbuild2.aw
date Tue Mar 20 15:19:38 2007 -0600 (2007-03-20)
parents f74e837c3902 3fd9b0c71b8c
children 93e11f6d6791
files patches/linux-2.6.18/crash-kernel-32-on-64.patch xen/include/asm-ia64/mm.h
line diff
     1.1 --- a/Config.mk	Tue Mar 20 10:07:11 2007 -0600
     1.2 +++ b/Config.mk	Tue Mar 20 15:19:38 2007 -0600
     1.3 @@ -36,6 +36,12 @@ endif
     1.4  cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
     1.5                /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
     1.6  
     1.7 +# cc-ver
     1.8 +# Usage: ifeq ($(call cc-ver,$(CC),0x030400),y)
     1.9 +cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
    1.10 +           '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \
    1.11 +           then echo y; else echo n; fi ;)
    1.12 +
    1.13  ifneq ($(debug),y)
    1.14  CFLAGS += -DNDEBUG
    1.15  else
     2.1 --- a/docs/xen-api/xenapi-datamodel.tex	Tue Mar 20 10:07:11 2007 -0600
     2.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Tue Mar 20 15:19:38 2007 -0600
     2.3 @@ -9359,10 +9359,10 @@ Quals & Field & Type & Description \\
     2.4  $\mathit{RO}_\mathit{run}$ &  {\tt crash\_dumps} & (crashdump ref) Set & list of crash dumps that refer to this disk \\
     2.5  $\mathit{RW}$ &  {\tt virtual\_size} & int & size of disk as presented to the guest (in bytes). Note that, depending on storage backend type, requested size may not be respected exactly \\
     2.6  $\mathit{RO}_\mathit{run}$ &  {\tt physical\_utilisation} & int & amount of physical space that the disk image is currently taking up on the storage repository (in bytes) \\
     2.7 -$\mathit{RO}_\mathit{ins}$ &  {\tt sector\_size} & int & sector size of VDI (in bytes) \\
     2.8  $\mathit{RO}_\mathit{ins}$ &  {\tt type} & vdi\_type & type of the VDI \\
     2.9  $\mathit{RW}$ &  {\tt sharable} & bool & true if this disk may be shared \\
    2.10  $\mathit{RW}$ &  {\tt read\_only} & bool & true if this disk may ONLY be mounted read-only \\
    2.11 +$\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
    2.12  \hline
    2.13  \end{longtable}
    2.14  \subsection{RPCs associated with class: VDI}
    2.15 @@ -9812,38 +9812,6 @@ value of the field
    2.16  \vspace{0.3cm}
    2.17  \vspace{0.3cm}
    2.18  \vspace{0.3cm}
    2.19 -\subsubsection{RPC name:~get\_sector\_size}
    2.20 -
    2.21 -{\bf Overview:} 
    2.22 -Get the sector\_size field of the given VDI.
    2.23 -
    2.24 - \noindent {\bf Signature:} 
    2.25 -\begin{verbatim} int get_sector_size (session_id s, VDI ref self)\end{verbatim}
    2.26 -
    2.27 -
    2.28 -\noindent{\bf Arguments:}
    2.29 -
    2.30 - 
    2.31 -\vspace{0.3cm}
    2.32 -\begin{tabular}{|c|c|p{7cm}|}
    2.33 - \hline
    2.34 -{\bf type} & {\bf name} & {\bf description} \\ \hline
    2.35 -{\tt VDI ref } & self & reference to the object \\ \hline 
    2.36 -
    2.37 -\end{tabular}
    2.38 -
    2.39 -\vspace{0.3cm}
    2.40 -
    2.41 - \noindent {\bf Return Type:} 
    2.42 -{\tt 
    2.43 -int
    2.44 -}
    2.45 -
    2.46 -
    2.47 -value of the field
    2.48 -\vspace{0.3cm}
    2.49 -\vspace{0.3cm}
    2.50 -\vspace{0.3cm}
    2.51  \subsubsection{RPC name:~get\_type}
    2.52  
    2.53  {\bf Overview:} 
    2.54 @@ -10008,6 +9976,143 @@ void
    2.55  \vspace{0.3cm}
    2.56  \vspace{0.3cm}
    2.57  \vspace{0.3cm}
    2.58 +\subsubsection{RPC name:~get\_other\_config}
    2.59 +
    2.60 +{\bf Overview:} 
    2.61 +Get the other\_config field of the given VDI.
    2.62 +
    2.63 + \noindent {\bf Signature:} 
    2.64 +\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, VDI ref self)\end{verbatim}
    2.65 +
    2.66 +
    2.67 +\noindent{\bf Arguments:}
    2.68 +
    2.69 + 
    2.70 +\vspace{0.3cm}
    2.71 +\begin{tabular}{|c|c|p{7cm}|}
    2.72 + \hline
    2.73 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    2.74 +{\tt VDI ref } & self & reference to the object \\ \hline 
    2.75 +
    2.76 +\end{tabular}
    2.77 +
    2.78 +\vspace{0.3cm}
    2.79 +
    2.80 + \noindent {\bf Return Type:} 
    2.81 +{\tt 
    2.82 +(string $\rightarrow$ string) Map
    2.83 +}
    2.84 +
    2.85 +
    2.86 +value of the field
    2.87 +\vspace{0.3cm}
    2.88 +\vspace{0.3cm}
    2.89 +\vspace{0.3cm}
    2.90 +\subsubsection{RPC name:~set\_other\_config}
    2.91 +
    2.92 +{\bf Overview:} 
    2.93 +Set the other\_config field of the given VDI.
    2.94 +
    2.95 + \noindent {\bf Signature:} 
    2.96 +\begin{verbatim} void set_other_config (session_id s, VDI ref self, (string -> string) Map value)\end{verbatim}
    2.97 +
    2.98 +
    2.99 +\noindent{\bf Arguments:}
   2.100 +
   2.101 + 
   2.102 +\vspace{0.3cm}
   2.103 +\begin{tabular}{|c|c|p{7cm}|}
   2.104 + \hline
   2.105 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.106 +{\tt VDI ref } & self & reference to the object \\ \hline 
   2.107 +
   2.108 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
   2.109 +
   2.110 +\end{tabular}
   2.111 +
   2.112 +\vspace{0.3cm}
   2.113 +
   2.114 + \noindent {\bf Return Type:} 
   2.115 +{\tt 
   2.116 +void
   2.117 +}
   2.118 +
   2.119 +
   2.120 +
   2.121 +\vspace{0.3cm}
   2.122 +\vspace{0.3cm}
   2.123 +\vspace{0.3cm}
   2.124 +\subsubsection{RPC name:~add\_to\_other\_config}
   2.125 +
   2.126 +{\bf Overview:} 
   2.127 +Add the given key-value pair to the other\_config field of the given VDI.
   2.128 +
   2.129 + \noindent {\bf Signature:} 
   2.130 +\begin{verbatim} void add_to_other_config (session_id s, VDI ref self, string key, string value)\end{verbatim}
   2.131 +
   2.132 +
   2.133 +\noindent{\bf Arguments:}
   2.134 +
   2.135 + 
   2.136 +\vspace{0.3cm}
   2.137 +\begin{tabular}{|c|c|p{7cm}|}
   2.138 + \hline
   2.139 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.140 +{\tt VDI ref } & self & reference to the object \\ \hline 
   2.141 +
   2.142 +{\tt string } & key & Key to add \\ \hline 
   2.143 +
   2.144 +{\tt string } & value & Value to add \\ \hline 
   2.145 +
   2.146 +\end{tabular}
   2.147 +
   2.148 +\vspace{0.3cm}
   2.149 +
   2.150 + \noindent {\bf Return Type:} 
   2.151 +{\tt 
   2.152 +void
   2.153 +}
   2.154 +
   2.155 +
   2.156 +
   2.157 +\vspace{0.3cm}
   2.158 +\vspace{0.3cm}
   2.159 +\vspace{0.3cm}
   2.160 +\subsubsection{RPC name:~remove\_from\_other\_config}
   2.161 +
   2.162 +{\bf Overview:} 
   2.163 +Remove the given key and its corresponding value from the other\_config
   2.164 +field of the given VDI.  If the key is not in that Map, then do nothing.
   2.165 +
   2.166 + \noindent {\bf Signature:} 
   2.167 +\begin{verbatim} void remove_from_other_config (session_id s, VDI ref self, string key)\end{verbatim}
   2.168 +
   2.169 +
   2.170 +\noindent{\bf Arguments:}
   2.171 +
   2.172 + 
   2.173 +\vspace{0.3cm}
   2.174 +\begin{tabular}{|c|c|p{7cm}|}
   2.175 + \hline
   2.176 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   2.177 +{\tt VDI ref } & self & reference to the object \\ \hline 
   2.178 +
   2.179 +{\tt string } & key & Key to remove \\ \hline 
   2.180 +
   2.181 +\end{tabular}
   2.182 +
   2.183 +\vspace{0.3cm}
   2.184 +
   2.185 + \noindent {\bf Return Type:} 
   2.186 +{\tt 
   2.187 +void
   2.188 +}
   2.189 +
   2.190 +
   2.191 +
   2.192 +\vspace{0.3cm}
   2.193 +\vspace{0.3cm}
   2.194 +\vspace{0.3cm}
   2.195  \subsubsection{RPC name:~create}
   2.196  
   2.197  {\bf Overview:} 
     3.1 --- a/extras/mini-os/arch/x86/mm.c	Tue Mar 20 10:07:11 2007 -0600
     3.2 +++ b/extras/mini-os/arch/x86/mm.c	Tue Mar 20 15:19:38 2007 -0600
     3.3 @@ -49,7 +49,7 @@
     3.4  #endif
     3.5  
     3.6  unsigned long *phys_to_machine_mapping;
     3.7 -extern char *stack;
     3.8 +extern char stack[];
     3.9  extern void page_walk(unsigned long virt_addr);
    3.10  
    3.11  void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, 
    3.12 @@ -453,7 +453,7 @@ void arch_init_mm(unsigned long* start_p
    3.13      printk("  _text:        %p\n", &_text);
    3.14      printk("  _etext:       %p\n", &_etext);
    3.15      printk("  _edata:       %p\n", &_edata);
    3.16 -    printk("  stack start:  %p\n", &stack);
    3.17 +    printk("  stack start:  %p\n", stack);
    3.18      printk("  _end:         %p\n", &_end);
    3.19  
    3.20      /* First page follows page table pages and 3 more pages (store page etc) */
     4.1 --- a/extras/mini-os/gnttab.c	Tue Mar 20 10:07:11 2007 -0600
     4.2 +++ b/extras/mini-os/gnttab.c	Tue Mar 20 15:19:38 2007 -0600
     4.3 @@ -135,7 +135,7 @@ gnttab_alloc_and_grant(void **map)
     4.4      return gref;
     4.5  }
     4.6  
     4.7 -static const char *gnttabop_error_msgs[] = GNTTABOP_error_msgs;
     4.8 +static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs;
     4.9  
    4.10  const char *
    4.11  gnttabop_error(int16_t status)
     5.1 --- a/extras/mini-os/hypervisor.c	Tue Mar 20 10:07:11 2007 -0600
     5.2 +++ b/extras/mini-os/hypervisor.c	Tue Mar 20 15:19:38 2007 -0600
     5.3 @@ -35,8 +35,8 @@
     5.4  
     5.5  void do_hypervisor_callback(struct pt_regs *regs)
     5.6  {
     5.7 -    u32 	       l1, l2;
     5.8 -    unsigned int   l1i, l2i, port;
     5.9 +    unsigned long  l1, l2, l1i, l2i;
    5.10 +    unsigned int   port;
    5.11      int            cpu = 0;
    5.12      shared_info_t *s = HYPERVISOR_shared_info;
    5.13      vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
     6.1 --- a/extras/mini-os/include/wait.h	Tue Mar 20 10:07:11 2007 -0600
     6.2 +++ b/extras/mini-os/include/wait.h	Tue Mar 20 15:19:38 2007 -0600
     6.3 @@ -74,6 +74,13 @@ static inline void wake_up(struct wait_q
     6.4      local_irq_restore(flags);   \
     6.5  } while (0)
     6.6  
     6.7 +#define remove_waiter(w) do {   \
     6.8 +    unsigned long flags;        \
     6.9 +    local_irq_save(flags);      \
    6.10 +    remove_wait_queue(&w);      \
    6.11 +    local_irq_restore(flags);   \
    6.12 +} while (0)
    6.13 +
    6.14  #define wait_event(wq, condition) do{             \
    6.15      unsigned long flags;                          \
    6.16      if(condition)                                 \
     7.1 --- a/extras/mini-os/include/xenbus.h	Tue Mar 20 10:07:11 2007 -0600
     7.2 +++ b/extras/mini-os/include/xenbus.h	Tue Mar 20 15:19:38 2007 -0600
     7.3 @@ -13,6 +13,7 @@ void init_xenbus(void);
     7.4  char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
     7.5  
     7.6  char *xenbus_watch_path(xenbus_transaction_t xbt, const char *path);
     7.7 +void wait_for_watch(void);
     7.8  char* xenbus_wait_for_value(const char*,const char*);
     7.9  
    7.10  /* Associates a value with a path.  Returns a malloc'd error string on
     8.1 --- a/extras/mini-os/xenbus/xenbus.c	Tue Mar 20 10:07:11 2007 -0600
     8.2 +++ b/extras/mini-os/xenbus/xenbus.c	Tue Mar 20 15:19:38 2007 -0600
     8.3 @@ -72,11 +72,12 @@ static void memcpy_from_ring(const void 
     8.4      memcpy(dest + c1, ring, c2);
     8.5  }
     8.6  
     8.7 -static inline void wait_for_watch(void)
     8.8 +void wait_for_watch(void)
     8.9  {
    8.10      DEFINE_WAIT(w);
    8.11      add_waiter(w,watch_queue);
    8.12      schedule();
    8.13 +    remove_waiter(w);
    8.14      wake(current);
    8.15  }
    8.16  
     9.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S	Tue Mar 20 10:07:11 2007 -0600
     9.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S	Tue Mar 20 15:19:38 2007 -0600
     9.3 @@ -28,5 +28,5 @@
     9.4  #define NOTE_KERNELCAP_END ASM_ELF_NOTE_END
     9.5  
     9.6  NOTE_KERNELCAP_BEGIN(1, 1)
     9.7 -NOTE_KERNELCAP(1, "nosegneg")  /* Change 1 back to 0 when glibc is fixed! */
     9.8 +NOTE_KERNELCAP(0, "nosegneg")
     9.9  NOTE_KERNELCAP_END
    10.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Tue Mar 20 10:07:11 2007 -0600
    10.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Tue Mar 20 15:19:38 2007 -0600
    10.3 @@ -256,8 +256,9 @@ void pte_free(struct page *pte)
    10.4  		unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT);
    10.5  
    10.6  		if (!pte_write(*virt_to_ptep(va)))
    10.7 -			BUG_ON(HYPERVISOR_update_va_mapping(
    10.8 -			       va, pfn_pte(pfn, PAGE_KERNEL), 0));
    10.9 +			if (HYPERVISOR_update_va_mapping(
   10.10 +				va, pfn_pte(pfn, PAGE_KERNEL), 0))
   10.11 +				BUG();
   10.12  	} else
   10.13  		clear_bit(PG_pinned, &pte->flags);
   10.14  
   10.15 @@ -672,14 +673,23 @@ void mm_unpin(struct mm_struct *mm)
   10.16  void mm_pin_all(void)
   10.17  {
   10.18  	struct page *page;
   10.19 +	unsigned long flags;
   10.20  
   10.21  	if (xen_feature(XENFEAT_writable_page_tables))
   10.22  		return;
   10.23  
   10.24 +	/*
   10.25 +	 * Allow uninterrupted access to the pgd_list. Also protects
   10.26 +	 * __pgd_pin() by disabling preemption.
   10.27 +	 * All other CPUs must be at a safe point (e.g., in stop_machine
   10.28 +	 * or offlined entirely).
   10.29 +	 */
   10.30 +	spin_lock_irqsave(&pgd_lock, flags);
   10.31  	for (page = pgd_list; page; page = (struct page *)page->index) {
   10.32  		if (!test_bit(PG_pinned, &page->flags))
   10.33  			__pgd_pin((pgd_t *)page_address(page));
   10.34  	}
   10.35 +	spin_unlock_irqrestore(&pgd_lock, flags);
   10.36  }
   10.37  
   10.38  void _arch_dup_mmap(struct mm_struct *mm)
    11.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Tue Mar 20 10:07:11 2007 -0600
    11.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Tue Mar 20 15:19:38 2007 -0600
    11.3 @@ -597,8 +597,10 @@ void __init xen_init_pt(void)
    11.4  	early_make_page_readonly(level2_kernel_pgt,
    11.5  				 XENFEAT_writable_page_tables);
    11.6  
    11.7 -	xen_pgd_pin(__pa_symbol(init_level4_pgt));
    11.8 -	xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
    11.9 +	if (!xen_feature(XENFEAT_writable_page_tables)) {
   11.10 +		xen_pgd_pin(__pa_symbol(init_level4_pgt));
   11.11 +		xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
   11.12 +	}
   11.13  
   11.14  	set_pgd((pgd_t *)(init_level4_user_pgt + 511), 
   11.15  		mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
    12.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Tue Mar 20 10:07:11 2007 -0600
    12.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Tue Mar 20 15:19:38 2007 -0600
    12.3 @@ -79,14 +79,17 @@ void mm_pin(struct mm_struct *mm)
    12.4  	spin_lock(&mm->page_table_lock);
    12.5  
    12.6  	mm_walk(mm, PAGE_KERNEL_RO);
    12.7 -	BUG_ON(HYPERVISOR_update_va_mapping(
    12.8 -		       (unsigned long)mm->pgd,
    12.9 -		       pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO),
   12.10 -		       UVMF_TLB_FLUSH));
   12.11 -	BUG_ON(HYPERVISOR_update_va_mapping(
   12.12 -		       (unsigned long)__user_pgd(mm->pgd),
   12.13 -		       pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL_RO),
   12.14 -		       UVMF_TLB_FLUSH));
   12.15 +	if (HYPERVISOR_update_va_mapping(
   12.16 +		(unsigned long)mm->pgd,
   12.17 +		pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO),
   12.18 +		UVMF_TLB_FLUSH))
   12.19 +		BUG();
   12.20 +	if (HYPERVISOR_update_va_mapping(
   12.21 +		(unsigned long)__user_pgd(mm->pgd),
   12.22 +		pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT,
   12.23 +			PAGE_KERNEL_RO),
   12.24 +		UVMF_TLB_FLUSH))
   12.25 +		BUG();
   12.26  	xen_pgd_pin(__pa(mm->pgd)); /* kernel */
   12.27  	xen_pgd_pin(__pa(__user_pgd(mm->pgd))); /* user */
   12.28  	mm->context.pinned = 1;
   12.29 @@ -106,12 +109,15 @@ void mm_unpin(struct mm_struct *mm)
   12.30  
   12.31  	xen_pgd_unpin(__pa(mm->pgd));
   12.32  	xen_pgd_unpin(__pa(__user_pgd(mm->pgd)));
   12.33 -	BUG_ON(HYPERVISOR_update_va_mapping(
   12.34 -		       (unsigned long)mm->pgd,
   12.35 -		       pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0));
   12.36 -	BUG_ON(HYPERVISOR_update_va_mapping(
   12.37 -		       (unsigned long)__user_pgd(mm->pgd),
   12.38 -		       pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL), 0));
   12.39 +	if (HYPERVISOR_update_va_mapping(
   12.40 +		(unsigned long)mm->pgd,
   12.41 +		pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0))
   12.42 +		BUG();
   12.43 +	if (HYPERVISOR_update_va_mapping(
   12.44 +		(unsigned long)__user_pgd(mm->pgd),
   12.45 +		pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT,
   12.46 +			PAGE_KERNEL), 0))
   12.47 +		BUG();
   12.48  	mm_walk(mm, PAGE_KERNEL);
   12.49  	xen_tlb_flush();
   12.50  	mm->context.pinned = 0;
   12.51 @@ -127,43 +133,50 @@ void mm_pin_all(void)
   12.52  	if (xen_feature(XENFEAT_writable_page_tables))
   12.53  		return;
   12.54  
   12.55 +	/*
   12.56 +	 * Allow uninterrupted access to the mm_unpinned list. We don't
   12.57 +	 * actually take the mm_unpinned_lock as it is taken inside mm_pin().
   12.58 +	 * All other CPUs must be at a safe point (e.g., in stop_machine
   12.59 +	 * or offlined entirely).
   12.60 +	 */
   12.61 +	preempt_disable();
   12.62  	while (!list_empty(&mm_unpinned))	
   12.63  		mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
   12.64  				  context.unpinned));
   12.65 +	preempt_enable();
   12.66  }
   12.67  
   12.68  void _arch_dup_mmap(struct mm_struct *mm)
   12.69  {
   12.70 -    if (!mm->context.pinned)
   12.71 -        mm_pin(mm);
   12.72 +	if (!mm->context.pinned)
   12.73 +		mm_pin(mm);
   12.74  }
   12.75  
   12.76  void _arch_exit_mmap(struct mm_struct *mm)
   12.77  {
   12.78 -    struct task_struct *tsk = current;
   12.79 +	struct task_struct *tsk = current;
   12.80 +
   12.81 +	task_lock(tsk);
   12.82  
   12.83 -    task_lock(tsk);
   12.84 +	/*
   12.85 +	 * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
   12.86 +	 * *much* faster this way, as no tlb flushes means bigger wrpt batches.
   12.87 +	 */
   12.88 +	if (tsk->active_mm == mm) {
   12.89 +		tsk->active_mm = &init_mm;
   12.90 +		atomic_inc(&init_mm.mm_count);
   12.91  
   12.92 -    /*
   12.93 -     * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
   12.94 -     * *much* faster this way, as no tlb flushes means bigger wrpt batches.
   12.95 -     */
   12.96 -    if ( tsk->active_mm == mm )
   12.97 -    {
   12.98 -        tsk->active_mm = &init_mm;
   12.99 -        atomic_inc(&init_mm.mm_count);
  12.100 +		switch_mm(mm, &init_mm, tsk);
  12.101 +
  12.102 +		atomic_dec(&mm->mm_count);
  12.103 +		BUG_ON(atomic_read(&mm->mm_count) == 0);
  12.104 +	}
  12.105  
  12.106 -        switch_mm(mm, &init_mm, tsk);
  12.107 -
  12.108 -        atomic_dec(&mm->mm_count);
  12.109 -        BUG_ON(atomic_read(&mm->mm_count) == 0);
  12.110 -    }
  12.111 +	task_unlock(tsk);
  12.112  
  12.113 -    task_unlock(tsk);
  12.114 -
  12.115 -    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
  12.116 -         !mm->context.has_foreign_mappings )
  12.117 -        mm_unpin(mm);
  12.118 +	if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
  12.119 +	     !mm->context.has_foreign_mappings )
  12.120 +		mm_unpin(mm);
  12.121  }
  12.122  
  12.123  struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  12.124 @@ -183,8 +196,9 @@ void pte_free(struct page *pte)
  12.125  	unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
  12.126  
  12.127  	if (!pte_write(*virt_to_ptep(va)))
  12.128 -		BUG_ON(HYPERVISOR_update_va_mapping(
  12.129 -			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
  12.130 +		if (HYPERVISOR_update_va_mapping(
  12.131 +			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0))
  12.132 +			BUG();
  12.133  
  12.134  	ClearPageForeign(pte);
  12.135  	init_page_count(pte);
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Mar 20 10:07:11 2007 -0600
    13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Mar 20 15:19:38 2007 -0600
    13.3 @@ -1267,7 +1267,7 @@ static void net_tx_action(unsigned long 
    13.4  
    13.5  		/* Check the remap error code. */
    13.6  		if (unlikely(netbk_tx_check_mop(skb, &mop))) {
    13.7 -			printk(KERN_ALERT "#### netback grant fails\n");
    13.8 +			DPRINTK("netback grant failed.\n");
    13.9  			skb_shinfo(skb)->nr_frags = 0;
   13.10  			kfree_skb(skb);
   13.11  			continue;
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Tue Mar 20 10:07:11 2007 -0600
    14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Tue Mar 20 15:19:38 2007 -0600
    14.3 @@ -110,7 +110,6 @@ int xb_write(const void *data, unsigned 
    14.4  		/* Read indexes, then verify. */
    14.5  		cons = intf->req_cons;
    14.6  		prod = intf->req_prod;
    14.7 -		mb();
    14.8  		if (!check_indexes(cons, prod)) {
    14.9  			intf->req_cons = intf->req_prod = 0;
   14.10  			return -EIO;
   14.11 @@ -122,15 +121,18 @@ int xb_write(const void *data, unsigned 
   14.12  		if (avail > len)
   14.13  			avail = len;
   14.14  
   14.15 +		/* Must write data /after/ reading the consumer index. */
   14.16 +		mb();
   14.17 +
   14.18  		memcpy(dst, data, avail);
   14.19  		data += avail;
   14.20  		len -= avail;
   14.21  
   14.22 -		/* Other side must not see new header until data is there. */
   14.23 +		/* Other side must not see new producer until data is there. */
   14.24  		wmb();
   14.25  		intf->req_prod += avail;
   14.26  
   14.27 -		/* This implies mb() before other side sees interrupt. */
   14.28 +		/* Implies mb(): other side will see the updated producer. */
   14.29  		notify_remote_via_evtchn(xen_store_evtchn);
   14.30  	}
   14.31  
   14.32 @@ -165,7 +167,6 @@ int xb_read(void *data, unsigned len)
   14.33  		/* Read indexes, then verify. */
   14.34  		cons = intf->rsp_cons;
   14.35  		prod = intf->rsp_prod;
   14.36 -		mb();
   14.37  		if (!check_indexes(cons, prod)) {
   14.38  			intf->rsp_cons = intf->rsp_prod = 0;
   14.39  			return -EIO;
   14.40 @@ -177,7 +178,7 @@ int xb_read(void *data, unsigned len)
   14.41  		if (avail > len)
   14.42  			avail = len;
   14.43  
   14.44 -		/* We must read header before we read data. */
   14.45 +		/* Must read data /after/ reading the producer index. */
   14.46  		rmb();
   14.47  
   14.48  		memcpy(data, src, avail);
   14.49 @@ -190,7 +191,7 @@ int xb_read(void *data, unsigned len)
   14.50  
   14.51  		pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
   14.52  
   14.53 -		/* Implies mb(): they will see new header. */
   14.54 +		/* Implies mb(): other side will see the updated consumer. */
   14.55  		notify_remote_via_evtchn(xen_store_evtchn);
   14.56  	}
   14.57  
    15.1 --- a/linux-2.6-xen-sparse/include/asm-i386/kexec.h	Tue Mar 20 10:07:11 2007 -0600
    15.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/kexec.h	Tue Mar 20 15:19:38 2007 -0600
    15.3 @@ -47,6 +47,9 @@
    15.4  /* The native architecture */
    15.5  #define KEXEC_ARCH KEXEC_ARCH_386
    15.6  
    15.7 +/* We can also handle crash dumps from 64 bit kernel. */
    15.8 +#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
    15.9 +
   15.10  #define MAX_NOTE_BYTES 1024
   15.11  
   15.12  /* CPU does not save ss and esp on stack if execution is already
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/linux-2.6-xen-sparse/mm/Kconfig	Tue Mar 20 15:19:38 2007 -0600
    16.3 @@ -0,0 +1,157 @@
    16.4 +config SELECT_MEMORY_MODEL
    16.5 +	def_bool y
    16.6 +	depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL
    16.7 +
    16.8 +choice
    16.9 +	prompt "Memory model"
   16.10 +	depends on SELECT_MEMORY_MODEL
   16.11 +	default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT
   16.12 +	default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT
   16.13 +	default FLATMEM_MANUAL
   16.14 +
   16.15 +config FLATMEM_MANUAL
   16.16 +	bool "Flat Memory"
   16.17 +	depends on !(ARCH_DISCONTIGMEM_ENABLE || ARCH_SPARSEMEM_ENABLE) || ARCH_FLATMEM_ENABLE
   16.18 +	help
   16.19 +	  This option allows you to change some of the ways that
   16.20 +	  Linux manages its memory internally.  Most users will
   16.21 +	  only have one option here: FLATMEM.  This is normal
   16.22 +	  and a correct option.
   16.23 +
   16.24 +	  Some users of more advanced features like NUMA and
   16.25 +	  memory hotplug may have different options here.
   16.26 +	  DISCONTIGMEM is an more mature, better tested system,
   16.27 +	  but is incompatible with memory hotplug and may suffer
   16.28 +	  decreased performance over SPARSEMEM.  If unsure between
   16.29 +	  "Sparse Memory" and "Discontiguous Memory", choose
   16.30 +	  "Discontiguous Memory".
   16.31 +
   16.32 +	  If unsure, choose this option (Flat Memory) over any other.
   16.33 +
   16.34 +config DISCONTIGMEM_MANUAL
   16.35 +	bool "Discontiguous Memory"
   16.36 +	depends on ARCH_DISCONTIGMEM_ENABLE
   16.37 +	help
   16.38 +	  This option provides enhanced support for discontiguous
   16.39 +	  memory systems, over FLATMEM.  These systems have holes
   16.40 +	  in their physical address spaces, and this option provides
   16.41 +	  more efficient handling of these holes.  However, the vast
   16.42 +	  majority of hardware has quite flat address spaces, and
   16.43 +	  can have degraded performance from extra overhead that
   16.44 +	  this option imposes.
   16.45 +
   16.46 +	  Many NUMA configurations will have this as the only option.
   16.47 +
   16.48 +	  If unsure, choose "Flat Memory" over this option.
   16.49 +
   16.50 +config SPARSEMEM_MANUAL
   16.51 +	bool "Sparse Memory"
   16.52 +	depends on ARCH_SPARSEMEM_ENABLE
   16.53 +	help
   16.54 +	  This will be the only option for some systems, including
   16.55 +	  memory hotplug systems.  This is normal.
   16.56 +
   16.57 +	  For many other systems, this will be an alternative to
   16.58 +	  "Discontiguous Memory".  This option provides some potential
   16.59 +	  performance benefits, along with decreased code complexity,
   16.60 +	  but it is newer, and more experimental.
   16.61 +
   16.62 +	  If unsure, choose "Discontiguous Memory" or "Flat Memory"
   16.63 +	  over this option.
   16.64 +
   16.65 +endchoice
   16.66 +
   16.67 +config DISCONTIGMEM
   16.68 +	def_bool y
   16.69 +	depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL
   16.70 +
   16.71 +config SPARSEMEM
   16.72 +	def_bool y
   16.73 +	depends on SPARSEMEM_MANUAL
   16.74 +
   16.75 +config FLATMEM
   16.76 +	def_bool y
   16.77 +	depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL
   16.78 +
   16.79 +config FLAT_NODE_MEM_MAP
   16.80 +	def_bool y
   16.81 +	depends on !SPARSEMEM
   16.82 +
   16.83 +#
   16.84 +# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
   16.85 +# to represent different areas of memory.  This variable allows
   16.86 +# those dependencies to exist individually.
   16.87 +#
   16.88 +config NEED_MULTIPLE_NODES
   16.89 +	def_bool y
   16.90 +	depends on DISCONTIGMEM || NUMA
   16.91 +
   16.92 +config HAVE_MEMORY_PRESENT
   16.93 +	def_bool y
   16.94 +	depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM
   16.95 +
   16.96 +#
   16.97 +# SPARSEMEM_EXTREME (which is the default) does some bootmem
   16.98 +# allocations when memory_present() is called.  If this can not
   16.99 +# be done on your architecture, select this option.  However,
  16.100 +# statically allocating the mem_section[] array can potentially
  16.101 +# consume vast quantities of .bss, so be careful.
  16.102 +#
  16.103 +# This option will also potentially produce smaller runtime code
  16.104 +# with gcc 3.4 and later.
  16.105 +#
  16.106 +config SPARSEMEM_STATIC
  16.107 +	def_bool n
  16.108 +
  16.109 +#
  16.110 +# Architectecture platforms which require a two level mem_section in SPARSEMEM
  16.111 +# must select this option. This is usually for architecture platforms with
  16.112 +# an extremely sparse physical address space.
  16.113 +#
  16.114 +config SPARSEMEM_EXTREME
  16.115 +	def_bool y
  16.116 +	depends on SPARSEMEM && !SPARSEMEM_STATIC
  16.117 +
  16.118 +# eventually, we can have this option just 'select SPARSEMEM'
  16.119 +config MEMORY_HOTPLUG
  16.120 +	bool "Allow for memory hot-add"
  16.121 +	depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG
  16.122 +	depends on (IA64 || X86 || PPC64)
  16.123 +
  16.124 +comment "Memory hotplug is currently incompatible with Software Suspend"
  16.125 +	depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
  16.126 +
  16.127 +# Heavily threaded applications may benefit from splitting the mm-wide
  16.128 +# page_table_lock, so that faults on different parts of the user address
  16.129 +# space can be handled with less contention: split it at this NR_CPUS.
  16.130 +# Default to 4 for wider testing, though 8 might be more appropriate.
  16.131 +# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
  16.132 +# PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes.
  16.133 +# XEN on x86 architecture uses the mapping field on pagetable pages to store a
  16.134 +# pointer to the destructor. This conflicts with pte_lock_deinit().
  16.135 +#
  16.136 +config SPLIT_PTLOCK_CPUS
  16.137 +	int
  16.138 +	default "4096" if ARM && !CPU_CACHE_VIPT
  16.139 +	default "4096" if PARISC && !PA20
  16.140 +	default "4096" if X86_XEN || X86_64_XEN
  16.141 +	default "4"
  16.142 +
  16.143 +#
  16.144 +# support for page migration
  16.145 +#
  16.146 +config MIGRATION
  16.147 +	bool "Page migration"
  16.148 +	def_bool y
  16.149 +	depends on NUMA
  16.150 +	help
  16.151 +	  Allows the migration of the physical location of pages of processes
  16.152 +	  while the virtual addresses are not changed. This is useful for
  16.153 +	  example on NUMA systems to put pages nearer to the processors accessing
  16.154 +	  the page.
  16.155 +
  16.156 +config RESOURCES_64BIT
  16.157 +	bool "64 bit Memory and IO resources (EXPERIMENTAL)" if (!64BIT && EXPERIMENTAL)
  16.158 +	default 64BIT
  16.159 +	help
  16.160 +	  This option allows memory and IO resources to be 64 bit.
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch	Tue Mar 20 15:19:38 2007 -0600
    17.3 @@ -0,0 +1,30 @@
    17.4 +From: Andrew Morton <akpm@linux-foundation.org>
    17.5 +
    17.6 +In file included from arch/i386/kernel/setup.c:46:
    17.7 +include/linux/crash_dump.h:19:36: warning: extra tokens at end of #ifndef directive
    17.8 +
    17.9 +Cc: "Eric W. Biederman" <ebiederm@xmission.com>
   17.10 +Cc: Andi Kleen <ak@suse.de>
   17.11 +Cc: Horms <horms@verge.net.au>
   17.12 +Cc: Ian Campbell <ian.campbell@xensource.com>
   17.13 +Cc: Magnus Damm <magnus.damm@gmail.com>
   17.14 +Cc: Vivek Goyal <vgoyal@in.ibm.com>
   17.15 +Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
   17.16 +---
   17.17 +
   17.18 + include/linux/crash_dump.h |    2 +-
   17.19 + 1 file changed, 1 insertion(+), 1 deletion(-)
   17.20 +
   17.21 +diff -puN include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps-fix include/linux/crash_dump.h
   17.22 +--- a/include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps-fix
   17.23 ++++ a/include/linux/crash_dump.h
   17.24 +@@ -16,7 +16,7 @@ extern struct proc_dir_entry *proc_vmcor
   17.25 + 
   17.26 + /* Architecture code defines this if there are other possible ELF
   17.27 +  * machine types, e.g. on bi-arch capable hardware. */
   17.28 +-#ifndef vmcore_elf_check_arch_cross(x)
   17.29 ++#ifndef vmcore_elf_check_arch_cross
   17.30 + #define vmcore_elf_check_arch_cross(x) 0
   17.31 + #endif
   17.32 + 
   17.33 +_
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps.patch	Tue Mar 20 15:19:38 2007 -0600
    18.3 @@ -0,0 +1,66 @@
    18.4 +From: Ian Campbell <ian.campbell@xensource.com>
    18.5 +
    18.6 +The specific case I am encountering is kdump under Xen with a 64 bit
    18.7 +hypervisor and 32 bit kernel/userspace.  The dump created is 64 bit due to
    18.8 +the hypervisor but the dump kernel is 32 bit for maximum compatibility.
    18.9 +
   18.10 +It's possibly less likely to be useful in a purely native scenario but I
   18.11 +see no reason to disallow it.
   18.12 +
   18.13 +Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
   18.14 +Acked-by: Vivek Goyal <vgoyal@in.ibm.com>
   18.15 +Cc: Horms <horms@verge.net.au>
   18.16 +Cc: Magnus Damm <magnus.damm@gmail.com>
   18.17 +Cc: "Eric W. Biederman" <ebiederm@xmission.com>
   18.18 +Cc: Andi Kleen <ak@suse.de>
   18.19 +Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
   18.20 +---
   18.21 +
   18.22 + fs/proc/vmcore.c           |    2 +-
   18.23 + include/asm-i386/kexec.h   |    3 +++
   18.24 + include/linux/crash_dump.h |    8 ++++++++
   18.25 + 3 files changed, 12 insertions(+), 1 deletion(-)
   18.26 +
   18.27 +diff -puN fs/proc/vmcore.c~allow-i386-crash-kernels-to-handle-x86_64-dumps fs/proc/vmcore.c
   18.28 +--- a/fs/proc/vmcore.c~allow-i386-crash-kernels-to-handle-x86_64-dumps
   18.29 ++++ a/fs/proc/vmcore.c
   18.30 +@@ -514,7 +514,7 @@ static int __init parse_crash_elf64_head
   18.31 + 	/* Do some basic Verification. */
   18.32 + 	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
   18.33 + 		(ehdr.e_type != ET_CORE) ||
   18.34 +-		!elf_check_arch(&ehdr) ||
   18.35 ++		!vmcore_elf_check_arch(&ehdr) ||
   18.36 + 		ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
   18.37 + 		ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
   18.38 + 		ehdr.e_version != EV_CURRENT ||
   18.39 +diff -puN include/asm-i386/kexec.h~allow-i386-crash-kernels-to-handle-x86_64-dumps include/asm-i386/kexec.h
   18.40 +--- a/include/asm-i386/kexec.h~allow-i386-crash-kernels-to-handle-x86_64-dumps
   18.41 ++++ a/include/asm-i386/kexec.h
   18.42 +@@ -47,6 +47,9 @@
   18.43 + /* The native architecture */
   18.44 + #define KEXEC_ARCH KEXEC_ARCH_386
   18.45 + 
   18.46 ++/* We can also handle crash dumps from 64 bit kernel. */
   18.47 ++#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
   18.48 ++
   18.49 + #define MAX_NOTE_BYTES 1024
   18.50 + 
   18.51 + /* CPU does not save ss and esp on stack if execution is already
   18.52 +diff -puN include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps include/linux/crash_dump.h
   18.53 +--- a/include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps
   18.54 ++++ a/include/linux/crash_dump.h
   18.55 +@@ -14,5 +14,13 @@ extern ssize_t copy_oldmem_page(unsigned
   18.56 + extern const struct file_operations proc_vmcore_operations;
   18.57 + extern struct proc_dir_entry *proc_vmcore;
   18.58 + 
   18.59 ++/* Architecture code defines this if there are other possible ELF
   18.60 ++ * machine types, e.g. on bi-arch capable hardware. */
   18.61 ++#ifndef vmcore_elf_check_arch_cross(x)
   18.62 ++#define vmcore_elf_check_arch_cross(x) 0
   18.63 ++#endif
   18.64 ++
   18.65 ++#define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x))
   18.66 ++
   18.67 + #endif /* CONFIG_CRASH_DUMP */
   18.68 + #endif /* LINUX_CRASHDUMP_H */
   18.69 +_
    19.1 --- a/patches/linux-2.6.18/crash-kernel-32-on-64.patch	Tue Mar 20 10:07:11 2007 -0600
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,11 +0,0 @@
    19.4 ---- pristine-linux-2.6.18/include/asm-i386/elf.h	2006-09-20 04:42:06.000000000 +0100
    19.5 -+++ linux-2.6.18-xen/include/asm-i386/elf.h	2007-03-14 16:42:30.000000000 +0000
    19.6 -@@ -36,7 +36,7 @@
    19.7 -  * This is used to ensure we don't load something for the wrong architecture.
    19.8 -  */
    19.9 - #define elf_check_arch(x) \
   19.10 --	(((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
   19.11 -+	(((x)->e_machine == EM_386) || ((x)->e_machine == EM_486) || ((x)->e_machine == EM_X86_64))
   19.12 - 
   19.13 - /*
   19.14 -  * These are used to set parameters in the core dumps.
    20.1 --- a/patches/linux-2.6.18/series	Tue Mar 20 10:07:11 2007 -0600
    20.2 +++ b/patches/linux-2.6.18/series	Tue Mar 20 15:19:38 2007 -0600
    20.3 @@ -19,4 +19,5 @@ x86-elfnote-as-preprocessor-macro.patch
    20.4  fixaddr-top.patch
    20.5  git-c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4.patch
    20.6  softlockup-no-idle-hz.patch
    20.7 -crash-kernel-32-on-64.patch
    20.8 +allow-i386-crash-kernels-to-handle-x86_64-dumps.patch
    20.9 +allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch
    21.1 --- a/tools/Rules.mk	Tue Mar 20 10:07:11 2007 -0600
    21.2 +++ b/tools/Rules.mk	Tue Mar 20 15:19:38 2007 -0600
    21.3 @@ -23,6 +23,11 @@ LDFLAGS += $(shell getconf LFS_LDFLAGS)
    21.4  CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs)
    21.5  CFLAGS += $(CFLAGS-y)
    21.6  
    21.7 +# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
    21.8 +ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn)
    21.9 +$(error Xen tools require at least gcc-3.4)
   21.10 +endif
   21.11 +
   21.12  %.opic: %.c
   21.13  	$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
   21.14  
    22.1 --- a/tools/blktap/drivers/block-qcow.c	Tue Mar 20 10:07:11 2007 -0600
    22.2 +++ b/tools/blktap/drivers/block-qcow.c	Tue Mar 20 15:19:38 2007 -0600
    22.3 @@ -1057,6 +1057,7 @@ int tdqcow_queue_write(struct disk_drive
    22.4  						    index_in_cluster+n);
    22.5  		if (!cluster_offset) {
    22.6  			DPRINTF("Ooops, no write cluster offset!\n");
    22.7 +			aio_unlock(s, sector);
    22.8  			return cb(dd, -EIO, sector, nb_sectors, id, private);
    22.9  		}
   22.10  
    23.1 --- a/tools/firmware/Makefile	Tue Mar 20 10:07:11 2007 -0600
    23.2 +++ b/tools/firmware/Makefile	Tue Mar 20 15:19:38 2007 -0600
    23.3 @@ -14,7 +14,7 @@ SUBDIRS += hvmloader
    23.4  
    23.5  .PHONY: all
    23.6  all:
    23.7 -	@set -e; if [ $$((`bcc -v 2>&1 | grep version | cut -d' ' -f 3 | awk -F. '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -lt $$((0x00100e)) ] ; then \
    23.8 +	@set -e; if [ $$((`( bcc -v 2>&1 | grep version || echo 0.0.0 ) | cut -d' ' -f 3 | awk -F. '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -lt $$((0x00100e)) ] ; then \
    23.9  	echo "***********************************************************"; \
   23.10  	echo "Require dev86 package version >= 0.16.14 to build firmware!"; \
   23.11  	echo "(visit http://www.cix.co.uk/~mayday for more information)"; \
    24.1 --- a/tools/firmware/hvmloader/32bitbios_support.c	Tue Mar 20 10:07:11 2007 -0600
    24.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c	Tue Mar 20 15:19:38 2007 -0600
    24.3 @@ -17,157 +17,129 @@
    24.4   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    24.5   * Place - Suite 330, Boston, MA 02111-1307 USA.
    24.6   */
    24.7 +
    24.8  #include <inttypes.h>
    24.9  #include <elf.h>
   24.10  #ifdef __sun__
   24.11  #include <sys/machelf.h>
   24.12  #endif
   24.13  
   24.14 -#include <xen/hvm/e820.h>
   24.15  #include "util.h"
   24.16  #include "config.h"
   24.17  
   24.18  #include "../rombios/32bit/32bitbios_flat.h"
   24.19  #include "../rombios/32bit/jumptable.h"
   24.20  
   24.21 -
   24.22 -/*
   24.23 - * relocate ELF file of type ET_REL
   24.24 - */
   24.25 -static int relocate_elf(unsigned char *elfarray) {
   24.26 +/* Relocate ELF file of type ET_REL */
   24.27 +static void relocate_elf(char *elfarray)
   24.28 +{
   24.29      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
   24.30      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
   24.31 -    int i;
   24.32 +    Elf32_Sym  *syms, *sym;
   24.33 +    Elf32_Rel  *rels;
   24.34 +    char       *code;
   24.35 +    uint32_t   *loc, fix;
   24.36 +    int i, j;
   24.37  
   24.38 -    if (ehdr->e_type != ET_REL) {
   24.39 -        printf("Not a relocatable BIOS object file. Has type %d, need %d\n",
   24.40 -               ehdr->e_type, ET_REL);
   24.41 -        return -1;
   24.42 -    }
   24.43 -
   24.44 -    for (i = 0; i < ehdr->e_shnum; i++)
   24.45 +    for ( i = 0; i < ehdr->e_shnum; i++ )
   24.46          shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset];
   24.47  
   24.48 -    for (i = 0; i < ehdr->e_shnum; i++) {
   24.49 -        if (shdr[i].sh_type == SHT_REL) {
   24.50 -            Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]);
   24.51 -            Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]);
   24.52 -            Elf32_Sym  *syms      = (Elf32_Sym *)symtabsec->sh_addr;
   24.53 -            Elf32_Rel  *rels      = (Elf32_Rel *)shdr[i].sh_addr;
   24.54 -            unsigned char *code   = (unsigned char *)targetsec->sh_addr;
   24.55 -            int j;
   24.56 +    for ( i = 0; i < ehdr->e_shnum; i++ )
   24.57 +    {
   24.58 +        if ( shdr[i].sh_type == SHT_RELA )
   24.59 +            printf("Unsupported section type SHT_RELA\n");
   24.60  
   24.61 -            /* must not have been stripped */
   24.62 -            if (shdr[i].sh_size == 0)
   24.63 -                return -6;
   24.64 +        if ( shdr[i].sh_type != SHT_REL )
   24.65 +            continue;
   24.66 +
   24.67 +        syms = (Elf32_Sym *)shdr[shdr[i].sh_link].sh_addr;
   24.68 +        rels = (Elf32_Rel *)shdr[i].sh_addr;
   24.69 +        code = (char      *)shdr[shdr[i].sh_info].sh_addr;
   24.70  
   24.71 -            for (j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) {
   24.72 -                int idx           = ELF32_R_SYM(rels[j].r_info);
   24.73 -                Elf32_Sym *symbol = &syms[idx];
   24.74 -                uint32_t *loc     = (uint32_t *)&code[rels[j].r_offset];
   24.75 -                uint32_t fix      = shdr[symbol->st_shndx].sh_addr +
   24.76 -                                    symbol->st_value;
   24.77 +        for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )
   24.78 +        {
   24.79 +            sym = &syms[ELF32_R_SYM(rels[j].r_info)];
   24.80 +            loc = (uint32_t *)&code[rels[j].r_offset];
   24.81 +            fix = shdr[sym->st_shndx].sh_addr + sym->st_value;
   24.82  
   24.83 -                switch (ELF32_R_TYPE(rels[j].r_info)) {
   24.84 -                    case R_386_PC32:
   24.85 -                        *loc += (fix - (uint32_t)loc);
   24.86 -                    break;
   24.87 +            switch ( ELF32_R_TYPE(rels[j].r_info) )
   24.88 +            {
   24.89 +            case R_386_PC32:
   24.90 +                *loc += fix - (uint32_t)loc;
   24.91 +                break;
   24.92  
   24.93 -                    case R_386_32:
   24.94 -                        *loc += fix;
   24.95 -                    break;
   24.96 -                }
   24.97 +            case R_386_32:
   24.98 +                *loc += fix;
   24.99 +                break;
  24.100              }
  24.101 -        } else if (shdr[i].sh_type == SHT_RELA) {
  24.102 -            return -2;
  24.103          }
  24.104      }
  24.105 -    return 0;
  24.106  }
  24.107  
  24.108 -/* scan the rombios for the destination of the jumptable */
  24.109 -static char* get_jump_table_start(void)
  24.110 +/* Scan the rombios for the destination of the jump table. */
  24.111 +static char *get_jump_table_start(void)
  24.112  {
  24.113      char *bios_mem;
  24.114  
  24.115      for ( bios_mem = (char *)ROMBIOS_BEGIN;
  24.116            bios_mem != (char *)ROMBIOS_END;
  24.117 -          bios_mem++ ) {
  24.118 -        if (strncmp(bios_mem, "___JMPT", 7) == 0)
  24.119 +          bios_mem++ )
  24.120 +        if ( !strncmp(bios_mem, "___JMPT", 7) )
  24.121              return bios_mem;
  24.122 -    }
  24.123  
  24.124      return NULL;
  24.125  }
  24.126  
  24.127 -/* copy relocated jumptable into the rombios */
  24.128 -static int copy_jumptable(unsigned char *elfarray)
  24.129 +/* Copy relocated jumptable into the rombios. */
  24.130 +static void copy_jumptable(char *elfarray)
  24.131  {
  24.132 -    int rc = 0;
  24.133      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
  24.134      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
  24.135 -    Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx];
  24.136 -    char *secstrings = (char *)&elfarray[shdr_strings->sh_offset];
  24.137 -    uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start();
  24.138 -    uint32_t *biosjumptable    = NULL;
  24.139 +    char *secstrings = &elfarray[shdr[ehdr->e_shstrndx].sh_offset];
  24.140 +    char *jump_table = get_jump_table_start();
  24.141      int i;
  24.142  
  24.143 -    if (rombiosjumptable == NULL) {
  24.144 -        return -3;
  24.145 +    /* Find the section with the jump table and copy to lower BIOS memory. */
  24.146 +    for ( i = 0; i < ehdr->e_shnum; i++ )
  24.147 +        if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) )
  24.148 +            break;
  24.149 +
  24.150 +    if ( i == ehdr->e_shnum )
  24.151 +    {
  24.152 +        printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
  24.153 +        return;
  24.154      }
  24.155  
  24.156 -     /* find the section with the jump table  and copy to lower BIOS memory */
  24.157 -    for (i = 0; i < ehdr->e_shnum; i++) {
  24.158 -        if (!strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name)) {
  24.159 -            uint32_t biosjumptableentries;
  24.160 -            biosjumptable        = (uint32_t *)shdr[i].sh_addr;
  24.161 -            biosjumptableentries = shdr[i].sh_size / 4;
  24.162 -            for (int j = 0; j < biosjumptableentries; j++) {
  24.163 -                rombiosjumptable[j] = biosjumptable[j];
  24.164 -                if (biosjumptable[j] == 0 &&
  24.165 -                    j < (biosjumptableentries - 1)) {
  24.166 -                    printf("WARNING: jumptable entry %d is NULL!\n",j);
  24.167 -                }
  24.168 -            }
  24.169 -            break;
  24.170 -        }
  24.171 +    if ( jump_table == NULL )
  24.172 +    {
  24.173 +        printf("Could not find jump table in file.\n");
  24.174 +        return;
  24.175      }
  24.176  
  24.177 -    if (biosjumptable == NULL) {
  24.178 -        printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
  24.179 -        rc = -4;
  24.180 -    }
  24.181 -
  24.182 -    return 0;
  24.183 +    memcpy(jump_table, (char *)shdr[i].sh_addr, shdr[i].sh_size);
  24.184  }
  24.185  
  24.186 -static int relocate_32bitbios(unsigned char *elfarray, uint32_t elfarraysize)
  24.187 +static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
  24.188  {
  24.189 -    int rc = 0;
  24.190      uint32_t mask = (64 * 1024) - 1;
  24.191 -    uint32_t to_malloc = (elfarraysize + mask) & ~mask; /* round to 64kb */
  24.192 -    unsigned char *highbiosarea;
  24.193 +    char *highbiosarea;
  24.194  
  24.195 -    highbiosarea = (unsigned char *)(long)
  24.196 -                           e820_malloc((uint64_t)to_malloc,
  24.197 -                                       E820_RESERVED,
  24.198 -                                       (uint64_t)0xffffffff);
  24.199 -
  24.200 -    if (highbiosarea != 0) {
  24.201 -        memcpy(highbiosarea, elfarray, elfarraysize);
  24.202 -        rc = relocate_elf(highbiosarea);
  24.203 -        if (rc == 0) {
  24.204 -            rc = copy_jumptable(highbiosarea);
  24.205 -        }
  24.206 -    } else {
  24.207 -        rc = -5;
  24.208 +    highbiosarea = (char *)(long)
  24.209 +        e820_malloc((elfarraysize + mask) & ~mask, /* round to 64kb */
  24.210 +                    E820_RESERVED,
  24.211 +                    (uint64_t)0xffffffff);
  24.212 +    if ( highbiosarea == NULL )
  24.213 +    {
  24.214 +        printf("No available memory for BIOS high memory area\n");
  24.215 +        return;
  24.216      }
  24.217  
  24.218 -    return rc;
  24.219 +    memcpy(highbiosarea, elfarray, elfarraysize);
  24.220 +    relocate_elf(highbiosarea);
  24.221 +    copy_jumptable(highbiosarea);
  24.222  }
  24.223  
  24.224 -int highbios_setup(void)
  24.225 +void highbios_setup(void)
  24.226  {
  24.227 -    return relocate_32bitbios((unsigned char *)highbios_array,
  24.228 -                              sizeof(highbios_array));
  24.229 +    relocate_32bitbios((char *)highbios_array, sizeof(highbios_array));
  24.230  }
    25.1 --- a/tools/firmware/hvmloader/acpi/build.c	Tue Mar 20 10:07:11 2007 -0600
    25.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Tue Mar 20 15:19:38 2007 -0600
    25.3 @@ -20,7 +20,6 @@
    25.4  #include "ssdt_tpm.h"
    25.5  #include "../config.h"
    25.6  #include "../util.h"
    25.7 -#include <xen/hvm/e820.h>
    25.8  
    25.9  #define align16(sz)        (((sz) + 15) & ~15)
   25.10  #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
    26.1 --- a/tools/firmware/hvmloader/hvmloader.c	Tue Mar 20 10:07:11 2007 -0600
    26.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Tue Mar 20 15:19:38 2007 -0600
    26.3 @@ -29,7 +29,6 @@
    26.4  #include "pci_regs.h"
    26.5  #include <xen/version.h>
    26.6  #include <xen/hvm/params.h>
    26.7 -#include <xen/hvm/e820.h>
    26.8  
    26.9  /* memory map */
   26.10  #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
   26.11 @@ -297,25 +296,57 @@ static void pci_setup(void)
   26.12      }
   26.13  }
   26.14  
   26.15 -static 
   26.16 -int must_load_nic(void) 
   26.17 +/*
   26.18 + * If the network card is in the boot order, load the Etherboot option ROM.
   26.19 + * Read the boot order bytes from CMOS and check if any of them are 0x4.
   26.20 + */
   26.21 +static int must_load_nic(void) 
   26.22  {
   26.23 -    /* If the network card is in the boot order, load the Etherboot 
   26.24 -     * option ROM.  Read the boot order bytes from CMOS and check 
   26.25 -     * if any of them are 0x4. */
   26.26      uint8_t boot_order;
   26.27  
   26.28 -    /* Read CMOS register 0x3d (boot choices 0 and 1) */
   26.29 -    outb(0x70, 0x3d);
   26.30 -    boot_order = inb(0x71);
   26.31 -    if ( (boot_order & 0xf) == 0x4 || (boot_order & 0xf0) == 0x40 ) 
   26.32 +    /* Read CMOS register 0x3d (boot choices 0 and 1). */
   26.33 +    boot_order = cmos_inb(0x3d);
   26.34 +    if ( ((boot_order & 0xf) == 0x4) || ((boot_order & 0xf0) == 0x40) ) 
   26.35          return 1;
   26.36 -    /* Read CMOS register 0x38 (boot choice 2 and FDD test flag) */
   26.37 -    outb(0x70, 0x38);
   26.38 -    boot_order = inb(0x71);
   26.39 -    if ( (boot_order & 0xf0) == 0x40 ) 
   26.40 -        return 1;
   26.41 -    return 0;
   26.42 +
   26.43 +    /* Read CMOS register 0x38 (boot choice 2 and FDD test flag). */
   26.44 +    boot_order = cmos_inb(0x38);
   26.45 +    return ((boot_order & 0xf0) == 0x40);
   26.46 +}
   26.47 +
   26.48 +/* Replace possibly erroneous memory-size CMOS fields with correct values. */
   26.49 +static void cmos_write_memory_size(void)
   26.50 +{
   26.51 +    struct e820entry *map = E820_MAP;
   26.52 +    int i, nr = *E820_MAP_NR;
   26.53 +    uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0;
   26.54 +
   26.55 +    for ( i = 0; i < nr; i++ )
   26.56 +        if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) )
   26.57 +            break;
   26.58 +
   26.59 +    if ( i != nr )
   26.60 +    {
   26.61 +        alt_mem = ext_mem = map[i].addr + map[i].size;
   26.62 +        ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
   26.63 +        if ( ext_mem > 0xffff )
   26.64 +            ext_mem = 0xffff;
   26.65 +        alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
   26.66 +    }
   26.67 +
   26.68 +    /* All BIOSes: conventional memory (640kB). */
   26.69 +    cmos_outb(0x15, (uint8_t)(base_mem >> 0));
   26.70 +    cmos_outb(0x16, (uint8_t)(base_mem >> 8));
   26.71 +
   26.72 +    /* All BIOSes: extended memory (1kB chunks above 1MB). */
   26.73 +    cmos_outb(0x17, (uint8_t)( ext_mem >> 0));
   26.74 +    cmos_outb(0x18, (uint8_t)( ext_mem >> 8));
   26.75 +    cmos_outb(0x30, (uint8_t)( ext_mem >> 0));
   26.76 +    cmos_outb(0x31, (uint8_t)( ext_mem >> 8));
   26.77 +
   26.78 +    /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */
   26.79 +    cmos_outb(0x34, (uint8_t)( alt_mem >> 0));
   26.80 +    cmos_outb(0x35, (uint8_t)( alt_mem >> 8));
   26.81  }
   26.82  
   26.83  int main(void)
   26.84 @@ -366,6 +397,8 @@ int main(void)
   26.85          ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
   26.86      }
   26.87  
   26.88 +    cmos_write_memory_size();
   26.89 +
   26.90      if ( !check_amd() )
   26.91      {
   26.92          printf("Loading VMXAssist ...\n");
    27.1 --- a/tools/firmware/hvmloader/smbios.c	Tue Mar 20 10:07:11 2007 -0600
    27.2 +++ b/tools/firmware/hvmloader/smbios.c	Tue Mar 20 15:19:38 2007 -0600
    27.3 @@ -22,7 +22,6 @@
    27.4  
    27.5  #include <stdint.h>
    27.6  #include <xen/version.h>
    27.7 -#include <xen/hvm/e820.h>
    27.8  #include "smbios.h"
    27.9  #include "smbios_types.h"
   27.10  #include "util.h"
   27.11 @@ -129,47 +128,32 @@ write_smbios_tables(void *start,
   27.12      return (size_t)((char *)p - (char *)start);
   27.13  }
   27.14  
   27.15 -/* This tries to figure out how much pseudo-physical memory (in MB)
   27.16 -   is allocated to the current domU.
   27.17 -
   27.18 -   It iterates through the e820 table, adding up the 'usable' and
   27.19 -   'reserved' entries and rounding up to the nearest MB.
   27.20 -
   27.21 -   The e820map is not at e820 in hvmloader, so this uses the
   27.22 -   E820_MAP_* constants from e820.h to pick it up where libxenguest
   27.23 -   left it.
   27.24 - */
   27.25 +/* Calculate how much pseudo-physical memory (in MB) is allocated to us. */
   27.26  static uint64_t
   27.27  get_memsize(void)
   27.28  {
   27.29 -    struct e820entry *map = NULL;
   27.30 -    uint8_t num_entries = 0;
   27.31 +    struct e820entry *map = E820_MAP;
   27.32 +    uint8_t num_entries = *E820_MAP_NR;
   27.33      uint64_t memsize = 0;
   27.34 -    uint8_t i;
   27.35 +    int i;
   27.36  
   27.37 -    map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET);
   27.38 -    num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET));
   27.39 -
   27.40 -    /* walk through e820map, ignoring any entries that aren't marked
   27.41 -       as usable or reserved. */
   27.42 -
   27.43 +    /*
   27.44 +     * Walk through e820map, ignoring any entries that aren't marked
   27.45 +     * as usable or reserved.
   27.46 +     */
   27.47      for ( i = 0; i < num_entries; i++ )
   27.48      {
   27.49 -        if (map->type == E820_RAM || map->type == E820_RESERVED)
   27.50 +        if ( (map->type == E820_RAM) || (map->type == E820_RESERVED) )
   27.51              memsize += map->size;
   27.52          map++;
   27.53      }
   27.54  
   27.55 -    /* Round up to the nearest MB.  The user specifies domU
   27.56 -       pseudo-physical memory in megabytes, so not doing this
   27.57 -       could easily lead to reporting one less MB than the user
   27.58 -       specified. */
   27.59 -    if ( memsize & ((1<<20)-1) )
   27.60 -        memsize = (memsize >> 20) + 1;
   27.61 -    else
   27.62 -        memsize = (memsize >> 20);
   27.63 -
   27.64 -    return memsize;
   27.65 +    /*
   27.66 +     * Round up to the nearest MB.  The user specifies domU pseudo-physical 
   27.67 +     * memory in megabytes, so not doing this could easily lead to reporting 
   27.68 +     * one less MB than the user specified.
   27.69 +     */
   27.70 +    return (memsize + (1 << 20) - 1) >> 20;
   27.71  }
   27.72  
   27.73  void
    28.1 --- a/tools/firmware/hvmloader/util.c	Tue Mar 20 10:07:11 2007 -0600
    28.2 +++ b/tools/firmware/hvmloader/util.c	Tue Mar 20 15:19:38 2007 -0600
    28.3 @@ -27,17 +27,17 @@
    28.4  
    28.5  void outb(uint16_t addr, uint8_t val)
    28.6  {
    28.7 -    __asm__ __volatile__ ( "outb %%al, %%dx" :: "d"(addr), "a"(val) );
    28.8 +    __asm__ __volatile__ ( "outb %%al, %%dx" : : "d" (addr), "a" (val) );
    28.9  }
   28.10  
   28.11  void outw(uint16_t addr, uint16_t val)
   28.12  {
   28.13 -    __asm__ __volatile__ ( "outw %%ax, %%dx" :: "d"(addr), "a"(val) );
   28.14 +    __asm__ __volatile__ ( "outw %%ax, %%dx" : : "d" (addr), "a" (val) );
   28.15  }
   28.16  
   28.17  void outl(uint16_t addr, uint32_t val)
   28.18  {
   28.19 -    __asm__ __volatile__ ( "outl %%eax, %%dx" :: "d"(addr), "a"(val) );
   28.20 +    __asm__ __volatile__ ( "outl %%eax, %%dx" : : "d" (addr), "a" (val) );
   28.21  }
   28.22  
   28.23  uint8_t inb(uint16_t addr)
   28.24 @@ -61,6 +61,18 @@ uint32_t inl(uint16_t addr)
   28.25      return val;
   28.26  }
   28.27  
   28.28 +uint8_t cmos_inb(uint8_t idx)
   28.29 +{
   28.30 +    outb(0x70, idx);
   28.31 +    return inb(0x71);
   28.32 +}
   28.33 +
   28.34 +void cmos_outb(uint8_t idx, uint8_t val)
   28.35 +{
   28.36 +    outb(0x70, idx);
   28.37 +    outb(0x71, val);
   28.38 +}
   28.39 +
   28.40  char *itoa(char *a, unsigned int i)
   28.41  {
   28.42      unsigned int _i = i, x = 0;
   28.43 @@ -280,9 +292,6 @@ uuid_to_string(char *dest, uint8_t *uuid
   28.44      *p = '\0';
   28.45  }
   28.46  
   28.47 -#include <xen/hvm/e820.h>
   28.48 -#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET)
   28.49 -#define E820_MAP    ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
   28.50  uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask)
   28.51  {
   28.52      uint64_t addr = 0;
    29.1 --- a/tools/firmware/hvmloader/util.h	Tue Mar 20 10:07:11 2007 -0600
    29.2 +++ b/tools/firmware/hvmloader/util.h	Tue Mar 20 15:19:38 2007 -0600
    29.3 @@ -26,6 +26,10 @@ uint8_t  inb(uint16_t addr);
    29.4  uint16_t inw(uint16_t addr);
    29.5  uint32_t inl(uint16_t addr);
    29.6  
    29.7 +/* CMOS access */
    29.8 +uint8_t cmos_inb(uint8_t idx);
    29.9 +void cmos_outb(uint8_t idx, uint8_t val);
   29.10 +
   29.11  /* APIC access */
   29.12  uint32_t ioapic_read(uint32_t reg);
   29.13  void ioapic_write(uint32_t reg, uint32_t val);
   29.14 @@ -78,9 +82,13 @@ int vprintf(const char *fmt, va_list ap)
   29.15  /* Allocate region of specified type in the e820 table. */
   29.16  uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask);
   29.17  
   29.18 +/* General e820 access. */
   29.19 +#include <xen/hvm/e820.h>
   29.20 +#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET)
   29.21 +#define E820_MAP    ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
   29.22 +
   29.23  /* Prepare the 32bit BIOS */
   29.24 -int highbios_setup(void);
   29.25 -
   29.26 +void highbios_setup(void);
   29.27  
   29.28  #define isdigit(c) ((c) >= '0' && (c) <= '9')
   29.29  
    30.1 --- a/tools/firmware/rombios/rombios.c	Tue Mar 20 10:07:11 2007 -0600
    30.2 +++ b/tools/firmware/rombios/rombios.c	Tue Mar 20 15:19:38 2007 -0600
    30.3 @@ -4196,178 +4196,86 @@ ASM_END
    30.4      case 0xe8:
    30.5          switch(regs.u.r8.al)
    30.6          {
    30.7 -         case 0x20: // coded by osmaker aka K.J.
    30.8 -            if(regs.u.r32.edx == 0x534D4150) /* SMAP */
    30.9 -            {
   30.10 -#ifdef HVMASSIST
   30.11 -		if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
   30.12 -		    Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
   30.13 -
   30.14 -		    if (regs.u.r16.bx + 0x14 <= e820_table_size) {
   30.15 -			memcpyb(ES, regs.u.r16.di,
   30.16 -				0xe000, 0x10 + regs.u.r16.bx, 0x14);
   30.17 -		    }
   30.18 -		    regs.u.r32.ebx += 0x14;
   30.19 -		    if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
   30.20 -			regs.u.r32.ebx = 0;
   30.21 -		    regs.u.r32.eax = 0x534D4150;
   30.22 -		    regs.u.r32.ecx = 0x14;
   30.23 -		    CLEAR_CF();
   30.24 -		    return;
   30.25 -		} else if (regs.u.r16.bx == 1) {
   30.26 -		    extended_memory_size = inb_cmos(0x35);
   30.27 -		    extended_memory_size <<= 8;
   30.28 -		    extended_memory_size |= inb_cmos(0x34);
   30.29 -		    extended_memory_size *= 64;
   30.30 -		    if (extended_memory_size > 0x3bc000) // greater than EFF00000???
   30.31 -		    {
   30.32 -			extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
   30.33 -		    }
   30.34 -		    extended_memory_size *= 1024;
   30.35 -		    extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
   30.36 -
   30.37 -		    if (extended_memory_size <= 15728640)
   30.38 -		    {
   30.39 -			extended_memory_size = inb_cmos(0x31);
   30.40 -			extended_memory_size <<= 8;
   30.41 -			extended_memory_size |= inb_cmos(0x30);
   30.42 -			extended_memory_size *= 1024;
   30.43 -		    }
   30.44 -
   30.45 -		    write_word(ES, regs.u.r16.di, 0x0000);
   30.46 -		    write_word(ES, regs.u.r16.di+2, 0x0010);
   30.47 -		    write_word(ES, regs.u.r16.di+4, 0x0000);
   30.48 -		    write_word(ES, regs.u.r16.di+6, 0x0000);
   30.49 -
   30.50 -		    write_word(ES, regs.u.r16.di+8, extended_memory_size);
   30.51 -		    extended_memory_size >>= 16;
   30.52 -		    write_word(ES, regs.u.r16.di+10, extended_memory_size);
   30.53 -		    extended_memory_size >>= 16;
   30.54 -		    write_word(ES, regs.u.r16.di+12, extended_memory_size);
   30.55 -		    extended_memory_size >>= 16;
   30.56 -		    write_word(ES, regs.u.r16.di+14, extended_memory_size);
   30.57 -
   30.58 -		    write_word(ES, regs.u.r16.di+16, 0x1);
   30.59 -		    write_word(ES, regs.u.r16.di+18, 0x0);
   30.60 -
   30.61 -		    regs.u.r32.ebx = 0;
   30.62 -		    regs.u.r32.eax = 0x534D4150;
   30.63 -		    regs.u.r32.ecx = 0x14;
   30.64 -		    CLEAR_CF();
   30.65 -		    return;
   30.66 -		} else { /* AX=E820, DX=534D4150, BX unrecognized */
   30.67 -		    goto int15_unimplemented;
   30.68 -		}
   30.69 -#else
   30.70 -                switch(regs.u.r16.bx)
   30.71 -                {
   30.72 -                    case 0:
   30.73 -                        write_word(ES, regs.u.r16.di, 0x00);
   30.74 -                        write_word(ES, regs.u.r16.di+2, 0x00);
   30.75 -                        write_word(ES, regs.u.r16.di+4, 0x00);
   30.76 -                        write_word(ES, regs.u.r16.di+6, 0x00);
   30.77 -
   30.78 -                        write_word(ES, regs.u.r16.di+8, 0xFC00);
   30.79 -                        write_word(ES, regs.u.r16.di+10, 0x0009);
   30.80 -                        write_word(ES, regs.u.r16.di+12, 0x0000);
   30.81 -                        write_word(ES, regs.u.r16.di+14, 0x0000);
   30.82 -
   30.83 -                        write_word(ES, regs.u.r16.di+16, 0x1);
   30.84 -                        write_word(ES, regs.u.r16.di+18, 0x0);
   30.85 -
   30.86 -                        regs.u.r32.ebx = 1;
   30.87 -
   30.88 -                        regs.u.r32.eax = 0x534D4150;
   30.89 -                        regs.u.r32.ecx = 0x14;
   30.90 -                        CLEAR_CF();
   30.91 -                        return;
   30.92 -                        break;
   30.93 -                    case 1:
   30.94 -                        extended_memory_size = inb_cmos(0x35);
   30.95 -                        extended_memory_size <<= 8;
   30.96 -                        extended_memory_size |= inb_cmos(0x34);
   30.97 -                        extended_memory_size *= 64;
   30.98 -                        if(extended_memory_size > 0x3bc000) // greater than EFF00000???
   30.99 -                        {
  30.100 -                            extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
  30.101 -                        }
  30.102 -                        extended_memory_size *= 1024;
  30.103 -                        extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
  30.104 -
  30.105 -                        if(extended_memory_size <= 15728640)
  30.106 -                        {
  30.107 -                            extended_memory_size = inb_cmos(0x31);
  30.108 -                            extended_memory_size <<= 8;
  30.109 -                            extended_memory_size |= inb_cmos(0x30);
  30.110 -                            extended_memory_size *= 1024;
  30.111 -                        }
  30.112 -
  30.113 -                        write_word(ES, regs.u.r16.di, 0x0000);
  30.114 -                        write_word(ES, regs.u.r16.di+2, 0x0010);
  30.115 -                        write_word(ES, regs.u.r16.di+4, 0x0000);
  30.116 -                        write_word(ES, regs.u.r16.di+6, 0x0000);
  30.117 -
  30.118 -                        write_word(ES, regs.u.r16.di+8, extended_memory_size);
  30.119 -                        extended_memory_size >>= 16;
  30.120 -                        write_word(ES, regs.u.r16.di+10, extended_memory_size);
  30.121 -                        extended_memory_size >>= 16;
  30.122 -                        write_word(ES, regs.u.r16.di+12, extended_memory_size);
  30.123 -                        extended_memory_size >>= 16;
  30.124 -                        write_word(ES, regs.u.r16.di+14, extended_memory_size);
  30.125 -
  30.126 -                        write_word(ES, regs.u.r16.di+16, 0x1);
  30.127 -                        write_word(ES, regs.u.r16.di+18, 0x0);
  30.128 -
  30.129 -                        regs.u.r32.ebx = 0;
  30.130 -                        regs.u.r32.eax = 0x534D4150;
  30.131 -                        regs.u.r32.ecx = 0x14;
  30.132 -                        CLEAR_CF();
  30.133 -                        return;
  30.134 -                        break;
  30.135 -                    default:  /* AX=E820, DX=534D4150, BX unrecognized */
  30.136 -                        goto int15_unimplemented;
  30.137 +        case 0x20: {
  30.138 +            Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
  30.139 +
  30.140 +            if (regs.u.r32.edx != 0x534D4150) /* SMAP */
  30.141 +                goto int15_unimplemented;
  30.142 +
  30.143 +            if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
  30.144 +                if (regs.u.r16.bx + 0x14 <= e820_table_size)
  30.145 +                    memcpyb(ES, regs.u.r16.di,
  30.146 +                            0xe000, 0x10 + regs.u.r16.bx, 0x14);
  30.147 +                regs.u.r32.ebx += 0x14;
  30.148 +                if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
  30.149 +                    regs.u.r32.ebx = 0;
  30.150 +            } else if (regs.u.r16.bx == 1) {
  30.151 +                Bit32u base, type;
  30.152 +                Bit16u off;
  30.153 +                for (off = 0; off < e820_table_size; off += 0x14) {
  30.154 +                    base = read_dword(0xe000, 0x10 + off);
  30.155 +                    type = read_dword(0xe000, 0x20 + off);
  30.156 +                    if ((base >= 0x100000) && (type == 1))
  30.157                          break;
  30.158                  }
  30.159 -#endif
  30.160 -	    } else {
  30.161 -	      // if DX != 0x534D4150)
  30.162 -	      goto int15_unimplemented;
  30.163 -	    }
  30.164 +                if (off == e820_table_size) {
  30.165 +                    SET_CF();
  30.166 +                    break;
  30.167 +                }
  30.168 +                memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14);
  30.169 +                regs.u.r32.ebx = 0;
  30.170 +            } else { /* AX=E820, DX=534D4150, BX unrecognized */
  30.171 +                goto int15_unimplemented;
  30.172 +            }
  30.173 +
  30.174 +            regs.u.r32.eax = 0x534D4150;
  30.175 +            regs.u.r32.ecx = 0x14;
  30.176 +            CLEAR_CF();
  30.177              break;
  30.178 -
  30.179 -        case 0x01: 
  30.180 -          // do we have any reason to fail here ?
  30.181 -          CLEAR_CF();
  30.182 -
  30.183 -          // my real system sets ax and bx to 0
  30.184 -          // this is confirmed by Ralph Brown list
  30.185 -          // but syslinux v1.48 is known to behave 
  30.186 -          // strangely if ax is set to 0
  30.187 -          // regs.u.r16.ax = 0;
  30.188 -          // regs.u.r16.bx = 0;
  30.189 -
  30.190 -          // Get the amount of extended memory (above 1M)
  30.191 -          regs.u.r8.cl = inb_cmos(0x30);
  30.192 -          regs.u.r8.ch = inb_cmos(0x31);
  30.193 +        }
  30.194 +
  30.195 +        case 0x01: {
  30.196 +            Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14;
  30.197 +            Bit32u base, type, size;
  30.198 +
  30.199 +            // do we have any reason to fail here ?
  30.200 +            CLEAR_CF();
  30.201 +
  30.202 +            // Get the amount of extended memory (above 1M)
  30.203 +            regs.u.r8.cl = inb_cmos(0x30);
  30.204 +            regs.u.r8.ch = inb_cmos(0x31);
  30.205            
  30.206 -          // limit to 15M
  30.207 -          if(regs.u.r16.cx > 0x3c00)
  30.208 -          {
  30.209 -            regs.u.r16.cx = 0x3c00;
  30.210 -          }
  30.211 -
  30.212 -          // Get the amount of extended memory above 16M in 64k blocs
  30.213 -          regs.u.r8.dl = inb_cmos(0x34);
  30.214 -          regs.u.r8.dh = inb_cmos(0x35);
  30.215 -
  30.216 -          // Set configured memory equal to extended memory
  30.217 -          regs.u.r16.ax = regs.u.r16.cx;
  30.218 -          regs.u.r16.bx = regs.u.r16.dx;
  30.219 -          break;
  30.220 +            // limit to 15M
  30.221 +            if (regs.u.r16.cx > (15*1024))
  30.222 +                regs.u.r16.cx = 15*1024;
  30.223 +
  30.224 +            // Find first RAM E820 entry >= 1MB.
  30.225 +            for (off = 0; off < e820_table_size; off += 0x14) {
  30.226 +                base = read_dword(0xe000, 0x10 + off);
  30.227 +                type = read_dword(0xe000, 0x20 + off);
  30.228 +                if ((base >= 0x100000) && (type == 1))
  30.229 +                    break;
  30.230 +            }
  30.231 +
  30.232 +            // If there is RAM above 16MB, return amount in 64kB chunks.
  30.233 +            regs.u.r16.dx = 0;
  30.234 +            if (off != e820_table_size) {
  30.235 +                size = base + read_dword(0xe000, 0x18 + off);
  30.236 +                if (size > 0x1000000) {
  30.237 +                    size -= 0x1000000;
  30.238 +                    regs.u.r16.dx = (Bit16u)(size >> 16);
  30.239 +                }
  30.240 +            }
  30.241 +
  30.242 +            // Set configured memory equal to extended memory
  30.243 +            regs.u.r16.ax = regs.u.r16.cx;
  30.244 +            regs.u.r16.bx = regs.u.r16.dx;
  30.245 +            break;
  30.246 +        }
  30.247  	default:  /* AH=0xE8?? but not implemented */
  30.248 -	  goto int15_unimplemented;
  30.249 -       }
  30.250 -       break;
  30.251 +            goto int15_unimplemented;
  30.252 +        }
  30.253 +        break;
  30.254      int15_unimplemented:
  30.255         // fall into the default
  30.256      default:
    31.1 --- a/tools/ioemu/target-i386-dm/exec-dm.c	Tue Mar 20 10:07:11 2007 -0600
    31.2 +++ b/tools/ioemu/target-i386-dm/exec-dm.c	Tue Mar 20 15:19:38 2007 -0600
    31.3 @@ -450,6 +450,9 @@ static inline int paddr_is_ram(target_ph
    31.4  #define phys_ram_addr(x) (phys_ram_base + (x))
    31.5  #endif
    31.6  
    31.7 +extern unsigned long *logdirty_bitmap;
    31.8 +extern unsigned long logdirty_bitmap_size;
    31.9 +
   31.10  void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
   31.11                              int len, int is_write)
   31.12  {
   31.13 @@ -485,9 +488,20 @@ void cpu_physical_memory_rw(target_phys_
   31.14                      l = 1;
   31.15                  }
   31.16              } else if (paddr_is_ram(addr)) {
   31.17 -                /* Reading from RAM */
   31.18 +                /* Writing to RAM */
   31.19                  ptr = phys_ram_addr(addr);
   31.20                  memcpy(ptr, buf, l);
   31.21 +                if (logdirty_bitmap != NULL) {
   31.22 +                    /* Record that we have dirtied this frame */
   31.23 +                    unsigned long pfn = addr >> TARGET_PAGE_BITS;
   31.24 +                    if (pfn / 8 >= logdirty_bitmap_size) {
   31.25 +                        fprintf(logfile, "dirtying pfn %x >= bitmap size %x\n",
   31.26 +                                pfn, logdirty_bitmap_size * 8);
   31.27 +                    } else {
   31.28 +                        logdirty_bitmap[pfn / HOST_LONG_BITS]
   31.29 +                            |= 1UL << pfn % HOST_LONG_BITS;
   31.30 +                    }
   31.31 +                }
   31.32  #ifdef __ia64__
   31.33                  sync_icache(ptr, l);
   31.34  #endif 
    32.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Tue Mar 20 10:07:11 2007 -0600
    32.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Tue Mar 20 15:19:38 2007 -0600
    32.3 @@ -439,6 +439,18 @@ void cpu_ioreq_xor(CPUState *env, ioreq_
    32.4      req->data = tmp1;
    32.5  }
    32.6  
    32.7 +void cpu_ioreq_xchg(CPUState *env, ioreq_t *req)
    32.8 +{
    32.9 +    unsigned long tmp1;
   32.10 +
   32.11 +    if (req->data_is_ptr != 0)
   32.12 +        hw_error("expected scalar value");
   32.13 +
   32.14 +    read_physical(req->addr, req->size, &tmp1);
   32.15 +    write_physical(req->addr, req->size, &req->data);
   32.16 +    req->data = tmp1;
   32.17 +}
   32.18 +
   32.19  void __handle_ioreq(CPUState *env, ioreq_t *req)
   32.20  {
   32.21      if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
   32.22 @@ -463,6 +475,9 @@ void __handle_ioreq(CPUState *env, ioreq
   32.23      case IOREQ_TYPE_XOR:
   32.24          cpu_ioreq_xor(env, req);
   32.25          break;
   32.26 +    case IOREQ_TYPE_XCHG:
   32.27 +        cpu_ioreq_xchg(env, req);
   32.28 +        break;
   32.29      default:
   32.30          hw_error("Invalid ioreq type 0x%x\n", req->type);
   32.31      }
    33.1 --- a/tools/ioemu/xenstore.c	Tue Mar 20 10:07:11 2007 -0600
    33.2 +++ b/tools/ioemu/xenstore.c	Tue Mar 20 15:19:38 2007 -0600
    33.3 @@ -11,9 +11,14 @@
    33.4  #include "vl.h"
    33.5  #include "block_int.h"
    33.6  #include <unistd.h>
    33.7 +#include <sys/ipc.h>
    33.8 +#include <sys/shm.h>
    33.9 +#include <sys/types.h>
   33.10 +#include <sys/stat.h>
   33.11 +#include <fcntl.h>
   33.12  
   33.13  static struct xs_handle *xsh = NULL;
   33.14 -static char *hd_filename[MAX_DISKS];
   33.15 +static char *media_filename[MAX_DISKS];
   33.16  static QEMUTimer *insert_timer = NULL;
   33.17  
   33.18  #define UWAIT_MAX (30*1000000) /* thirty seconds */
   33.19 @@ -40,10 +45,10 @@ static void insert_media(void *opaque)
   33.20      int i;
   33.21  
   33.22      for (i = 0; i < MAX_DISKS; i++) {
   33.23 -	if (hd_filename[i]) {
   33.24 -	    do_change(bs_table[i]->device_name, hd_filename[i]);
   33.25 -	    free(hd_filename[i]);
   33.26 -	    hd_filename[i] = NULL;
   33.27 +	if (media_filename[i] && bs_table[i]) {
   33.28 +	    do_change(bs_table[i]->device_name, media_filename[i]);
   33.29 +	    free(media_filename[i]);
   33.30 +	    media_filename[i] = NULL;
   33.31  	}
   33.32      }
   33.33  }
   33.34 @@ -82,7 +87,7 @@ void xenstore_parse_domain_config(int do
   33.35      unsigned int len, num, hd_index;
   33.36  
   33.37      for(i = 0; i < MAX_DISKS; i++)
   33.38 -        hd_filename[i] = NULL;
   33.39 +        media_filename[i] = NULL;
   33.40  
   33.41      xsh = xs_daemon_open();
   33.42      if (xsh == NULL) {
   33.43 @@ -128,19 +133,12 @@ void xenstore_parse_domain_config(int do
   33.44  	    continue;
   33.45  	free(type);
   33.46  	type = xs_read(xsh, XBT_NULL, buf, &len);
   33.47 -	/* read params to get the patch of the image -- read it last
   33.48 -	 * so that we have its path in buf when setting up the
   33.49 -	 * watch */
   33.50  	if (pasprintf(&buf, "%s/params", bpath) == -1)
   33.51  	    continue;
   33.52  	free(params);
   33.53  	params = xs_read(xsh, XBT_NULL, buf, &len);
   33.54  	if (params == NULL)
   33.55  	    continue;
   33.56 -	if (params[0]) {
   33.57 -	    hd_filename[hd_index] = params;	/* strdup() */
   33.58 -	    params = NULL;		/* don't free params on re-use */
   33.59 -	}
   33.60          /* 
   33.61           * check if device has a phantom vbd; the phantom is hooked
   33.62           * to the frontend device (for ease of cleanup), so lookup 
   33.63 @@ -151,38 +149,42 @@ void xenstore_parse_domain_config(int do
   33.64  	    continue;
   33.65  	free(fpath);
   33.66          fpath = xs_read(xsh, XBT_NULL, buf, &len);
   33.67 -	if (fpath != NULL) {
   33.68 +	if (fpath) {
   33.69  	    if (pasprintf(&buf, "%s/dev", fpath) == -1)
   33.70  	        continue;
   33.71 +	    free(params);
   33.72              params = xs_read(xsh, XBT_NULL, buf , &len);
   33.73 -	    if (params != NULL) {
   33.74 -                free(hd_filename[hd_index]);
   33.75 -                hd_filename[hd_index] = params;
   33.76 -                params = NULL;              /* don't free params on re-use */
   33.77 +	    if (params) {
   33.78                  /* 
   33.79                   * wait for device, on timeout silently fail because we will 
   33.80                   * fail to open below
   33.81                   */
   33.82 -                waitForDevice(hd_filename[hd_index]);
   33.83 +                waitForDevice(params);
   33.84              }
   33.85          }
   33.86 +
   33.87  	bs_table[hd_index] = bdrv_new(dev);
   33.88 -        /* re-establish buf */
   33.89 -	if (pasprintf(&buf, "%s/params", bpath) == -1)
   33.90 -	    continue;
   33.91  	/* check if it is a cdrom */
   33.92  	if (type && !strcmp(type, "cdrom")) {
   33.93  	    bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
   33.94 -	    xs_watch(xsh, buf, dev);
   33.95 +	    if (pasprintf(&buf, "%s/params", bpath) != -1)
   33.96 +		xs_watch(xsh, buf, dev);
   33.97  	}
   33.98 -	if (hd_filename[hd_index]) {
   33.99 -            if (bdrv_open(bs_table[hd_index], hd_filename[hd_index],
  33.100 -			  0 /* snapshot */) < 0)
  33.101 +	/* open device now if media present */
  33.102 +	if (params[0]) {
  33.103 +            if (bdrv_open(bs_table[hd_index], params, 0 /* snapshot */) < 0)
  33.104                  fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
  33.105 -                        hd_filename[hd_index]);
  33.106 +                        params);
  33.107  	}
  33.108      }
  33.109  
  33.110 +    /* Set a watch for log-dirty requests from the migration tools */
  33.111 +    if (pasprintf(&buf, "%s/logdirty/next-active", path) != -1) {
  33.112 +        xs_watch(xsh, buf, "logdirty");
  33.113 +        fprintf(logfile, "Watching %s\n", buf);
  33.114 +    }
  33.115 +
  33.116 +
  33.117   out:
  33.118      free(type);
  33.119      free(params);
  33.120 @@ -201,6 +203,116 @@ int xenstore_fd(void)
  33.121      return -1;
  33.122  }
  33.123  
  33.124 +unsigned long *logdirty_bitmap = NULL;
  33.125 +unsigned long logdirty_bitmap_size;
  33.126 +extern int vga_ram_size, bios_size;
  33.127 +
  33.128 +void xenstore_process_logdirty_event(void)
  33.129 +{
  33.130 +    char *act;
  33.131 +    static char *active_path = NULL;
  33.132 +    static char *next_active_path = NULL;
  33.133 +    static char *seg = NULL;
  33.134 +    unsigned int len;
  33.135 +    int i;
  33.136 +
  33.137 +    fprintf(logfile, "Triggered log-dirty buffer switch\n");
  33.138 +
  33.139 +    if (!seg) {
  33.140 +        char *path, *p, *key_ascii, key_terminated[17] = {0,};
  33.141 +        key_t key;
  33.142 +        int shmid;
  33.143 +
  33.144 +        /* Find and map the shared memory segment for log-dirty bitmaps */
  33.145 +        if (!(path = xs_get_domain_path(xsh, domid))) {            
  33.146 +            fprintf(logfile, "Log-dirty: can't get domain path in store\n");
  33.147 +            exit(1);
  33.148 +        }
  33.149 +        if (!(path = realloc(path, strlen(path) 
  33.150 +                             + strlen("/logdirty/next-active") + 1))) {
  33.151 +            fprintf(logfile, "Log-dirty: out of memory\n");
  33.152 +            exit(1);
  33.153 +        }
  33.154 +        strcat(path, "/logdirty/");
  33.155 +        p = path + strlen(path);
  33.156 +        strcpy(p, "key");
  33.157 +        
  33.158 +        key_ascii = xs_read(xsh, XBT_NULL, path, &len);
  33.159 +        if (!key_ascii) {
  33.160 +            /* No key yet: wait for the next watch */
  33.161 +            free(path);
  33.162 +            return;
  33.163 +        }
  33.164 +        strncpy(key_terminated, key_ascii, 16);
  33.165 +        free(key_ascii);
  33.166 +        key = (key_t) strtoull(key_terminated, NULL, 16);
  33.167 +
  33.168 +        /* Figure out how bit the log-dirty bitmaps are */
  33.169 +        logdirty_bitmap_size = ((phys_ram_size + 0x20 
  33.170 +                                 - (vga_ram_size + bios_size)) 
  33.171 +                                >> (TARGET_PAGE_BITS)); /* nr of bits in map*/
  33.172 +        if (logdirty_bitmap_size > HVM_BELOW_4G_MMIO_START >> TARGET_PAGE_BITS)
  33.173 +            logdirty_bitmap_size += 
  33.174 +                HVM_BELOW_4G_MMIO_LENGTH >> TARGET_PAGE_BITS; /* still bits */
  33.175 +        logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
  33.176 +                                / HOST_LONG_BITS); /* longs */
  33.177 +        logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
  33.178 +
  33.179 +        /* Map the shared-memory segment */
  33.180 +        if ((shmid = shmget(key, 
  33.181 +                            2 * logdirty_bitmap_size, 
  33.182 +                            S_IRUSR|S_IWUSR)) == -1 
  33.183 +            || (seg = shmat(shmid, NULL, 0)) == (void *)-1) {
  33.184 +            fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n",
  33.185 +                    (unsigned long long) key, strerror(errno));
  33.186 +            exit(1);
  33.187 +        }
  33.188 +
  33.189 +        fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
  33.190 +
  33.191 +        /* Double-check that the bitmaps are the size we expect */
  33.192 +        if (logdirty_bitmap_size != *(uint32_t *)seg) {
  33.193 +            fprintf(logfile, "Log-dirty: got %lu, calc %lu\n", 
  33.194 +                    *(uint32_t *)seg, logdirty_bitmap_size);
  33.195 +            return;
  33.196 +        }
  33.197 +
  33.198 +        /* Remember the paths for the next-active and active entries */
  33.199 +        strcpy(p, "active");
  33.200 +        if (!(active_path = strdup(path))) {
  33.201 +            fprintf(logfile, "Log-dirty: out of memory\n");
  33.202 +            exit(1);
  33.203 +        }
  33.204 +        strcpy(p, "next-active");
  33.205 +        if (!(next_active_path = strdup(path))) {
  33.206 +            fprintf(logfile, "Log-dirty: out of memory\n");
  33.207 +            exit(1);
  33.208 +        }
  33.209 +        free(path);
  33.210 +    }
  33.211 +    
  33.212 +    /* Read the required active buffer from the store */
  33.213 +    act = xs_read(xsh, XBT_NULL, next_active_path, &len);
  33.214 +    if (!act) {
  33.215 +        fprintf(logfile, "Log-dirty: can't read next-active\n");
  33.216 +        exit(1);
  33.217 +    }
  33.218 +
  33.219 +    /* Switch buffers */
  33.220 +    i = act[0] - '0';
  33.221 +    if (i != 0 && i != 1) {
  33.222 +        fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
  33.223 +        exit(1);
  33.224 +    }
  33.225 +    logdirty_bitmap = seg + i * logdirty_bitmap_size;
  33.226 +
  33.227 +    /* Ack that we've switched */
  33.228 +    xs_write(xsh, XBT_NULL, active_path, act, len);
  33.229 +    free(act);
  33.230 +}
  33.231 +
  33.232 +
  33.233 +
  33.234  void xenstore_process_event(void *opaque)
  33.235  {
  33.236      char **vec, *image = NULL;
  33.237 @@ -210,6 +322,11 @@ void xenstore_process_event(void *opaque
  33.238      if (!vec)
  33.239  	return;
  33.240  
  33.241 +    if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
  33.242 +        xenstore_process_logdirty_event();
  33.243 +        goto out;
  33.244 +    }
  33.245 +
  33.246      if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
  33.247  	strlen(vec[XS_WATCH_TOKEN]) != 3)
  33.248  	goto out;
  33.249 @@ -220,13 +337,13 @@ void xenstore_process_event(void *opaque
  33.250  
  33.251      do_eject(0, vec[XS_WATCH_TOKEN]);
  33.252      bs_table[hd_index]->filename[0] = 0;
  33.253 -    if (hd_filename[hd_index]) {
  33.254 -	free(hd_filename[hd_index]);
  33.255 -	hd_filename[hd_index] = NULL;
  33.256 +    if (media_filename[hd_index]) {
  33.257 +	free(media_filename[hd_index]);
  33.258 +	media_filename[hd_index] = NULL;
  33.259      }
  33.260  
  33.261      if (image[0]) {
  33.262 -	hd_filename[hd_index] = strdup(image);
  33.263 +	media_filename[hd_index] = strdup(image);
  33.264  	xenstore_check_new_media_present(5000);
  33.265      }
  33.266  
    34.1 --- a/tools/libxc/Makefile	Tue Mar 20 10:07:11 2007 -0600
    34.2 +++ b/tools/libxc/Makefile	Tue Mar 20 15:19:38 2007 -0600
    34.3 @@ -57,7 +57,7 @@ GUEST_SRCS-$(CONFIG_IA64)    += xc_dom_c
    34.4  
    34.5  CFLAGS   += -Werror -Wmissing-prototypes
    34.6  CFLAGS   += -fno-strict-aliasing
    34.7 -CFLAGS   += $(INCLUDES) -I.
    34.8 +CFLAGS   += $(INCLUDES) -I. -I../xenstore
    34.9  
   34.10  # Needed for posix_fadvise64() in xc_linux.c
   34.11  CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE
    35.1 --- a/tools/libxc/xc_core.c	Tue Mar 20 10:07:11 2007 -0600
    35.2 +++ b/tools/libxc/xc_core.c	Tue Mar 20 15:19:38 2007 -0600
    35.3 @@ -349,11 +349,7 @@ xc_domain_dumpcore_via_callback(int xc_h
    35.4      /* Map the shared info frame */
    35.5      live_shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
    35.6                                         PROT_READ, info.shared_info_frame);
    35.7 -    if ( !live_shinfo 
    35.8 -#ifdef __ia64__
    35.9 -         && !info.hvm
   35.10 -#endif
   35.11 -        )
   35.12 +    if ( !live_shinfo && !info.hvm )
   35.13      {
   35.14          PERROR("Couldn't map live_shinfo");
   35.15          goto out;
    36.1 --- a/tools/libxc/xc_core_x86.c	Tue Mar 20 10:07:11 2007 -0600
    36.2 +++ b/tools/libxc/xc_core_x86.c	Tue Mar 20 15:19:38 2007 -0600
    36.3 @@ -21,12 +21,15 @@
    36.4  #include "xg_private.h"
    36.5  #include "xc_core.h"
    36.6  
    36.7 +static int max_gpfn(int xc_handle, domid_t domid)
    36.8 +{
    36.9 +    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid);
   36.10 +}
   36.11 +
   36.12  int
   36.13  xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
   36.14  {
   36.15 -    if ( info->hvm )
   36.16 -        return 1;
   36.17 -    return 0;
   36.18 +    return info->hvm;
   36.19  }
   36.20  
   36.21  int
   36.22 @@ -35,14 +38,14 @@ xc_core_arch_memory_map_get(int xc_handl
   36.23                              xc_core_memory_map_t **mapp,
   36.24                              unsigned int *nr_entries)
   36.25  {
   36.26 -    unsigned long max_pfn = live_shinfo->arch.max_pfn;
   36.27 -    xc_core_memory_map_t *map = NULL;
   36.28 +    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
   36.29 +    xc_core_memory_map_t *map;
   36.30  
   36.31      map = malloc(sizeof(*map));
   36.32 -    if ( !map )
   36.33 +    if ( map == NULL )
   36.34      {
   36.35          PERROR("Could not allocate memory");
   36.36 -        goto out;
   36.37 +        return -1;
   36.38      }
   36.39  
   36.40      map->addr = 0;
   36.41 @@ -51,11 +54,6 @@ xc_core_arch_memory_map_get(int xc_handl
   36.42      *mapp = map;
   36.43      *nr_entries = 1;
   36.44      return 0;
   36.45 -
   36.46 -out:
   36.47 -    if ( map )
   36.48 -        free(map);
   36.49 -    return -1;
   36.50  }
   36.51  
   36.52  int
   36.53 @@ -67,7 +65,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
   36.54      xen_pfn_t *live_p2m_frame_list_list = NULL;
   36.55      xen_pfn_t *live_p2m_frame_list = NULL;
   36.56      uint32_t dom = info->domid;
   36.57 -    unsigned long max_pfn = live_shinfo->arch.max_pfn;
   36.58 +    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
   36.59      int ret = -1;
   36.60      int err;
   36.61  
    37.1 --- a/tools/libxc/xc_hvm_build.c	Tue Mar 20 10:07:11 2007 -0600
    37.2 +++ b/tools/libxc/xc_hvm_build.c	Tue Mar 20 15:19:38 2007 -0600
    37.3 @@ -137,6 +137,12 @@ static void build_e820map(void *e820_pag
    37.4      e820entry[nr_map].type = E820_RAM;
    37.5      nr_map++;
    37.6  
    37.7 +    /* Explicitly reserve space for special pages (ioreq and xenstore). */
    37.8 +    e820entry[nr_map].addr = mem_size - PAGE_SIZE * 3;
    37.9 +    e820entry[nr_map].size = PAGE_SIZE * 3;
   37.10 +    e820entry[nr_map].type = E820_RESERVED;
   37.11 +    nr_map++;
   37.12 +
   37.13      if ( extra_mem_size )
   37.14      {
   37.15          e820entry[nr_map].addr = (1ULL << 32);
   37.16 @@ -280,7 +286,6 @@ static int setup_guest(int xc_handle,
   37.17      /* NB. evtchn_upcall_mask is unused: leave as zero. */
   37.18      memset(&shared_info->evtchn_mask[0], 0xff,
   37.19             sizeof(shared_info->evtchn_mask));
   37.20 -    shared_info->arch.max_pfn = page_array[nr_pages - 1];
   37.21      munmap(shared_info, PAGE_SIZE);
   37.22  
   37.23      if ( v_end > HVM_BELOW_4G_RAM_END )
    38.1 --- a/tools/libxc/xc_hvm_restore.c	Tue Mar 20 10:07:11 2007 -0600
    38.2 +++ b/tools/libxc/xc_hvm_restore.c	Tue Mar 20 15:19:38 2007 -0600
    38.3 @@ -70,9 +70,6 @@ int xc_hvm_restore(int xc_handle, int io
    38.4  {
    38.5      DECLARE_DOMCTL;
    38.6  
    38.7 -    /* The new domain's shared-info frame number. */
    38.8 -    unsigned long shared_info_frame;
    38.9 -
   38.10      /* A copy of the CPU context of the guest. */
   38.11      vcpu_guest_context_t ctxt;
   38.12  
   38.13 @@ -86,8 +83,6 @@ int xc_hvm_restore(int xc_handle, int io
   38.14      uint8_t *hvm_buf = NULL;
   38.15      unsigned long long v_end, memsize;
   38.16      unsigned long shared_page_nr;
   38.17 -    shared_info_t *shared_info = NULL;
   38.18 -    xen_pfn_t arch_max_pfn;
   38.19  
   38.20      unsigned long pfn;
   38.21      unsigned int prev_pc, this_pc;
   38.22 @@ -96,8 +91,6 @@ int xc_hvm_restore(int xc_handle, int io
   38.23      /* Types of the pfns in the current region */
   38.24      unsigned long region_pfn_type[MAX_BATCH_SIZE];
   38.25  
   38.26 -    struct xen_add_to_physmap xatp;
   38.27 -
   38.28      /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
   38.29      unsigned long nr_pages;
   38.30  
   38.31 @@ -146,7 +139,6 @@ int xc_hvm_restore(int xc_handle, int io
   38.32          pfns[i] = i;
   38.33      for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < pfn_array_size; i++ )
   38.34          pfns[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
   38.35 -    arch_max_pfn = pfns[max_pfn];/* used later */
   38.36  
   38.37      /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
   38.38      rc = xc_domain_memory_populate_physmap(
   38.39 @@ -350,29 +342,6 @@ int xc_hvm_restore(int xc_handle, int io
   38.40          goto out;
   38.41      }
   38.42  
   38.43 -    /* Shared-info pfn */
   38.44 -    if (!read_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) {
   38.45 -        ERROR("reading the shared-info pfn failed!\n");
   38.46 -        goto out;
   38.47 -    }
   38.48 -    /* Map the shared-info frame where it was before */
   38.49 -    xatp.domid = dom;
   38.50 -    xatp.space = XENMAPSPACE_shared_info;
   38.51 -    xatp.idx   = 0;
   38.52 -    xatp.gpfn  = shared_info_frame;
   38.53 -    if ( (rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp)) != 0 ) {
   38.54 -        ERROR("setting the shared-info pfn failed!\n");
   38.55 -        goto out;
   38.56 -    }
   38.57 -    if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) ||
   38.58 -         ((shared_info = xc_map_foreign_range(
   38.59 -             xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
   38.60 -             shared_info_frame)) == NULL) )
   38.61 -        goto out;
   38.62 -    /* shared_info.arch.max_pfn is used by dump-core */
   38.63 -    shared_info->arch.max_pfn = arch_max_pfn;
   38.64 -    munmap(shared_info, PAGE_SIZE);
   38.65 -
   38.66      rc = 0;
   38.67      goto out;
   38.68  
    39.1 --- a/tools/libxc/xc_hvm_save.c	Tue Mar 20 10:07:11 2007 -0600
    39.2 +++ b/tools/libxc/xc_hvm_save.c	Tue Mar 20 15:19:38 2007 -0600
    39.3 @@ -54,6 +54,11 @@ static unsigned long hvirt_start;
    39.4  /* #levels of page tables used by the current guest */
    39.5  static unsigned int pt_levels;
    39.6  
    39.7 +/* Shared-memory bitmaps for getting log-dirty bits from qemu */
    39.8 +static unsigned long *qemu_bitmaps[2];
    39.9 +static int qemu_active;
   39.10 +static int qemu_non_active;
   39.11 +
   39.12  int xc_hvm_drain_io(int handle, domid_t dom)
   39.13  {
   39.14      DECLARE_HYPERCALL;
   39.15 @@ -77,7 +82,8 @@ int xc_hvm_drain_io(int handle, domid_t 
   39.16  */
   39.17  
   39.18  #define BITS_PER_LONG (sizeof(unsigned long) * 8)
   39.19 -#define BITMAP_SIZE   ((pfn_array_size + BITS_PER_LONG - 1) / 8)
   39.20 +#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
   39.21 +#define BITMAP_SIZE   (BITS_TO_LONGS(pfn_array_size) * sizeof(unsigned long))
   39.22  
   39.23  #define BITMAP_ENTRY(_nr,_bmap) \
   39.24     ((unsigned long *)(_bmap))[(_nr)/BITS_PER_LONG]
   39.25 @@ -124,6 +130,7 @@ static inline int permute( int i, int nr
   39.26      return i;
   39.27  }
   39.28  
   39.29 +
   39.30  static uint64_t tv_to_us(struct timeval *new)
   39.31  {
   39.32      return (new->tv_sec * 1000000) + new->tv_usec;
   39.33 @@ -277,7 +284,9 @@ static int suspend_and_state(int (*suspe
   39.34  }
   39.35  
   39.36  int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
   39.37 -                  uint32_t max_factor, uint32_t flags, int (*suspend)(int))
   39.38 +                uint32_t max_factor, uint32_t flags, int (*suspend)(int),
   39.39 +                void *(*init_qemu_maps)(int, unsigned), 
   39.40 +                void (*qemu_flip_buffer)(int, int))
   39.41  {
   39.42      xc_dominfo_t info;
   39.43  
   39.44 @@ -293,9 +302,6 @@ int xc_hvm_save(int xc_handle, int io_fd
   39.45      /* The size of an array big enough to contain all guest pfns */
   39.46      unsigned long pfn_array_size;
   39.47  
   39.48 -    /* The new domain's shared-info frame number. */
   39.49 -    unsigned long shared_info_frame;
   39.50 -
   39.51      /* Other magic frames: ioreqs and xenstore comms */
   39.52      unsigned long ioreq_pfn, bufioreq_pfn, store_pfn;
   39.53  
   39.54 @@ -309,9 +315,6 @@ int xc_hvm_save(int xc_handle, int io_fd
   39.55      uint32_t hvm_buf_size;
   39.56      uint8_t *hvm_buf = NULL;
   39.57  
   39.58 -    /* Live mapping of shared info structure */
   39.59 -    shared_info_t *live_shinfo = NULL;
   39.60 -
   39.61      /* base of the region in which domain memory is mapped */
   39.62      unsigned char *region_base = NULL;
   39.63  
   39.64 @@ -363,7 +366,6 @@ int xc_hvm_save(int xc_handle, int io_fd
   39.65          ERROR("HVM:Could not get vcpu context");
   39.66          goto out;
   39.67      }
   39.68 -    shared_info_frame = info.shared_info_frame;
   39.69  
   39.70      /* cheesy sanity check */
   39.71      if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) {
   39.72 @@ -372,13 +374,6 @@ int xc_hvm_save(int xc_handle, int io_fd
   39.73          goto out;
   39.74      }
   39.75  
   39.76 -    /* Map the shared info frame */
   39.77 -    if(!(live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   39.78 -                                            PROT_READ, shared_info_frame))) {
   39.79 -        ERROR("HVM:Couldn't map live_shinfo");
   39.80 -        goto out;
   39.81 -    }
   39.82 -
   39.83      if ( xc_get_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, &store_pfn)
   39.84           || xc_get_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, &ioreq_pfn)
   39.85           || xc_get_hvm_param(xc_handle, dom, 
   39.86 @@ -392,8 +387,6 @@ int xc_hvm_save(int xc_handle, int io_fd
   39.87              "nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); 
   39.88  
   39.89      if (live) {
   39.90 -        ERROR("hvm domain doesn't support live migration now.\n");
   39.91 -        goto out;
   39.92          
   39.93          if (xc_shadow_control(xc_handle, dom,
   39.94                                XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
   39.95 @@ -453,6 +446,15 @@ int xc_hvm_save(int xc_handle, int io_fd
   39.96      to_skip = malloc(BITMAP_SIZE);
   39.97  
   39.98  
   39.99 +    if (live) {
  39.100 +        /* Get qemu-dm logging dirty pages too */
  39.101 +        void *seg = init_qemu_maps(dom, BITMAP_SIZE);
  39.102 +        qemu_bitmaps[0] = seg;
  39.103 +        qemu_bitmaps[1] = seg + BITMAP_SIZE;
  39.104 +        qemu_active = 0;
  39.105 +        qemu_non_active = 1;
  39.106 +    }
  39.107 +
  39.108      hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0);
  39.109      if ( hvm_buf_size == -1 )
  39.110      {
  39.111 @@ -509,13 +511,6 @@ int xc_hvm_save(int xc_handle, int io_fd
  39.112  
  39.113          DPRINTF("Saving HVM domain memory pages: iter %d   0%%", iter);
  39.114  
  39.115 -        if (last_iter && (max_pfn != live_shinfo->arch.max_pfn)) {
  39.116 -            DPRINTF("calculated max_pfn as %#lx, shinfo says %#lx\n",
  39.117 -                    max_pfn, live_shinfo->arch.max_pfn);
  39.118 -            ERROR("Max pfn doesn't match shared info");
  39.119 -            goto out;
  39.120 -        }
  39.121 -
  39.122          while( N < pfn_array_size ){
  39.123  
  39.124              unsigned int this_pc = (N * 100) / pfn_array_size;
  39.125 @@ -663,8 +658,7 @@ int xc_hvm_save(int xc_handle, int io_fd
  39.126                      goto out;
  39.127                  }
  39.128  
  39.129 -                DPRINTF("SUSPEND shinfo %08lx eip %08lx edx %08lx\n",
  39.130 -                        info.shared_info_frame,
  39.131 +                DPRINTF("SUSPEND eip %08lx edx %08lx\n",
  39.132                          (unsigned long)ctxt.user_regs.eip,
  39.133                          (unsigned long)ctxt.user_regs.edx);
  39.134              }
  39.135 @@ -677,10 +671,23 @@ int xc_hvm_save(int xc_handle, int io_fd
  39.136                  goto out;
  39.137              }
  39.138  
  39.139 +            /* Pull in the dirty bits from qemu too */
  39.140 +            if (!last_iter) {
  39.141 +                qemu_active = qemu_non_active;
  39.142 +                qemu_non_active = qemu_active ? 0 : 1;
  39.143 +                qemu_flip_buffer(dom, qemu_active);
  39.144 +                for (j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++) {
  39.145 +                    to_send[j] |= qemu_bitmaps[qemu_non_active][j];
  39.146 +                    qemu_bitmaps[qemu_non_active][j] = 0;
  39.147 +                }
  39.148 +            } else {
  39.149 +                for (j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++) 
  39.150 +                    to_send[j] |= qemu_bitmaps[qemu_active][j];
  39.151 +            }
  39.152 +
  39.153              sent_last_iter = sent_this_iter;
  39.154  
  39.155              print_stats(xc_handle, dom, sent_this_iter, &stats, 1);
  39.156 -
  39.157          }
  39.158  
  39.159  
  39.160 @@ -739,12 +746,6 @@ int xc_hvm_save(int xc_handle, int io_fd
  39.161          ERROR("write HVM info failed!\n");
  39.162      }
  39.163  
  39.164 -    /* Shared-info pfn */
  39.165 -    if (!write_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) {
  39.166 -        ERROR("write shared-info pfn failed!\n");
  39.167 -        goto out;
  39.168 -    }
  39.169 - 
  39.170      /* Success! */
  39.171      rc = 0;
  39.172  
    40.1 --- a/tools/libxc/xc_private.c	Tue Mar 20 10:07:11 2007 -0600
    40.2 +++ b/tools/libxc/xc_private.c	Tue Mar 20 15:19:38 2007 -0600
    40.3 @@ -263,6 +263,15 @@ int xc_memory_op(int xc_handle,
    40.4              goto out1;
    40.5          }
    40.6          break;
    40.7 +    case XENMEM_current_reservation:
    40.8 +    case XENMEM_maximum_reservation:
    40.9 +    case XENMEM_maximum_gpfn:
   40.10 +        if ( lock_pages(arg, sizeof(domid_t)) )
   40.11 +        {
   40.12 +            PERROR("Could not lock");
   40.13 +            goto out1;
   40.14 +        }
   40.15 +        break;
   40.16      }
   40.17  
   40.18      ret = do_xen_hypercall(xc_handle, &hypercall);
   40.19 @@ -287,6 +296,11 @@ int xc_memory_op(int xc_handle,
   40.20      case XENMEM_add_to_physmap:
   40.21          unlock_pages(arg, sizeof(struct xen_add_to_physmap));
   40.22          break;
   40.23 +    case XENMEM_current_reservation:
   40.24 +    case XENMEM_maximum_reservation:
   40.25 +    case XENMEM_maximum_gpfn:
   40.26 +        unlock_pages(arg, sizeof(domid_t));
   40.27 +        break;
   40.28      }
   40.29  
   40.30   out1:
    41.1 --- a/tools/libxc/xenguest.h	Tue Mar 20 10:07:11 2007 -0600
    41.2 +++ b/tools/libxc/xenguest.h	Tue Mar 20 15:19:38 2007 -0600
    41.3 @@ -32,8 +32,10 @@ int xc_linux_save(int xc_handle, int io_
    41.4   * @return 0 on success, -1 on failure
    41.5   */
    41.6  int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
    41.7 -                  uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
    41.8 -                  int (*suspend)(int domid));
    41.9 +                uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
   41.10 +                int (*suspend)(int domid),  
   41.11 +                void *(*init_qemu_maps)(int, unsigned), 
   41.12 +                void (*qemu_flip_buffer)(int, int));
   41.13  
   41.14  /**
   41.15   * This function will restore a saved domain running Linux.
    42.1 --- a/tools/libxc/xg_private.c	Tue Mar 20 10:07:11 2007 -0600
    42.2 +++ b/tools/libxc/xg_private.c	Tue Mar 20 15:19:38 2007 -0600
    42.3 @@ -201,7 +201,9 @@ unsigned long csum_page(void *page)
    42.4  __attribute__((weak)) 
    42.5      int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
    42.6                      uint32_t max_factor, uint32_t flags,
    42.7 -                    int (*suspend)(int domid))
    42.8 +                    int (*suspend)(int domid), 
    42.9 +                    void *(*init_qemu_maps)(int, unsigned), 
   42.10 +                    void (*qemu_flip_buffer)(int, int))
   42.11  {
   42.12      errno = ENOSYS;
   42.13      return -1;
    43.1 --- a/tools/libxen/include/xen_vbd.h	Tue Mar 20 10:07:11 2007 -0600
    43.2 +++ b/tools/libxen/include/xen_vbd.h	Tue Mar 20 15:19:38 2007 -0600
    43.3 @@ -72,7 +72,6 @@ typedef struct xen_vbd_record
    43.4      struct xen_vm_record_opt *vm;
    43.5      struct xen_vdi_record_opt *vdi;
    43.6      char *device;
    43.7 -    char *image;
    43.8      bool bootable;
    43.9      enum xen_vbd_mode mode;
   43.10      enum xen_vbd_type type;
    44.1 --- a/tools/libxen/include/xen_vdi.h	Tue Mar 20 10:07:11 2007 -0600
    44.2 +++ b/tools/libxen/include/xen_vdi.h	Tue Mar 20 15:19:38 2007 -0600
    44.3 @@ -1,5 +1,5 @@
    44.4  /*
    44.5 - * Copyright (c) 2006, XenSource Inc.
    44.6 + * Copyright (c) 2006-2007, XenSource Inc.
    44.7   *
    44.8   * This library is free software; you can redistribute it and/or
    44.9   * modify it under the terms of the GNU Lesser General Public
   44.10 @@ -22,6 +22,7 @@
   44.11  #include "xen_common.h"
   44.12  #include "xen_crashdump_decl.h"
   44.13  #include "xen_sr_decl.h"
   44.14 +#include "xen_string_string_map.h"
   44.15  #include "xen_vbd_decl.h"
   44.16  #include "xen_vdi_decl.h"
   44.17  #include "xen_vdi_type.h"
   44.18 @@ -73,11 +74,10 @@ typedef struct xen_vdi_record
   44.19      struct xen_crashdump_record_opt_set *crash_dumps;
   44.20      int64_t virtual_size;
   44.21      int64_t physical_utilisation;
   44.22 -    int64_t sector_size;
   44.23 -    char *location;
   44.24      enum xen_vdi_type type;
   44.25      bool sharable;
   44.26      bool read_only;
   44.27 +    xen_string_string_map *other_config;
   44.28  } xen_vdi_record;
   44.29  
   44.30  /**
   44.31 @@ -251,13 +251,6 @@ xen_vdi_get_physical_utilisation(xen_ses
   44.32  
   44.33  
   44.34  /**
   44.35 - * Get the sector_size field of the given VDI.
   44.36 - */
   44.37 -extern bool
   44.38 -xen_vdi_get_sector_size(xen_session *session, int64_t *result, xen_vdi vdi);
   44.39 -
   44.40 -
   44.41 -/**
   44.42   * Get the type field of the given VDI.
   44.43   */
   44.44  extern bool
   44.45 @@ -279,6 +272,13 @@ xen_vdi_get_read_only(xen_session *sessi
   44.46  
   44.47  
   44.48  /**
   44.49 + * Get the other_config field of the given VDI.
   44.50 + */
   44.51 +extern bool
   44.52 +xen_vdi_get_other_config(xen_session *session, xen_string_string_map **result, xen_vdi vdi);
   44.53 +
   44.54 +
   44.55 +/**
   44.56   * Set the name/label field of the given VDI.
   44.57   */
   44.58  extern bool
   44.59 @@ -314,6 +314,30 @@ xen_vdi_set_read_only(xen_session *sessi
   44.60  
   44.61  
   44.62  /**
   44.63 + * Set the other_config field of the given VDI.
   44.64 + */
   44.65 +extern bool
   44.66 +xen_vdi_set_other_config(xen_session *session, xen_vdi vdi, xen_string_string_map *other_config);
   44.67 +
   44.68 +
   44.69 +/**
   44.70 + * Add the given key-value pair to the other_config field of the given
   44.71 + * VDI.
   44.72 + */
   44.73 +extern bool
   44.74 +xen_vdi_add_to_other_config(xen_session *session, xen_vdi vdi, char *key, char *value);
   44.75 +
   44.76 +
   44.77 +/**
   44.78 + * Remove the given key and its corresponding value from the
   44.79 + * other_config field of the given VDI.  If the key is not in that Map, then
   44.80 + * do nothing.
   44.81 + */
   44.82 +extern bool
   44.83 +xen_vdi_remove_from_other_config(xen_session *session, xen_vdi vdi, char *key);
   44.84 +
   44.85 +
   44.86 +/**
   44.87   * Take an exact copy of the VDI; the snapshot lives in the same
   44.88   * Storage Repository as its parent.
   44.89   */
    45.1 --- a/tools/libxen/src/xen_vbd.c	Tue Mar 20 10:07:11 2007 -0600
    45.2 +++ b/tools/libxen/src/xen_vbd.c	Tue Mar 20 15:19:38 2007 -0600
    45.3 @@ -54,9 +54,6 @@ static const struct_member xen_vbd_recor
    45.4          { .key = "device",
    45.5            .type = &abstract_type_string,
    45.6            .offset = offsetof(xen_vbd_record, device) },
    45.7 -        { .key = "image",
    45.8 -          .type = &abstract_type_string,
    45.9 -          .offset = offsetof(xen_vbd_record, image) },
   45.10          { .key = "bootable",
   45.11            .type = &abstract_type_bool,
   45.12            .offset = offsetof(xen_vbd_record, bootable) },
    46.1 --- a/tools/libxen/src/xen_vdi.c	Tue Mar 20 10:07:11 2007 -0600
    46.2 +++ b/tools/libxen/src/xen_vdi.c	Tue Mar 20 15:19:38 2007 -0600
    46.3 @@ -1,5 +1,5 @@
    46.4  /*
    46.5 - * Copyright (c) 2006, XenSource Inc.
    46.6 + * Copyright (c) 2006-2007, XenSource Inc.
    46.7   *
    46.8   * This library is free software; you can redistribute it and/or
    46.9   * modify it under the terms of the GNU Lesser General Public
   46.10 @@ -24,6 +24,7 @@
   46.11  #include "xen_crashdump.h"
   46.12  #include "xen_internal.h"
   46.13  #include "xen_sr.h"
   46.14 +#include "xen_string_string_map.h"
   46.15  #include "xen_vbd.h"
   46.16  #include "xen_vdi.h"
   46.17  #include "xen_vdi_type_internal.h"
   46.18 @@ -64,12 +65,6 @@ static const struct_member xen_vdi_recor
   46.19          { .key = "physical_utilisation",
   46.20            .type = &abstract_type_int,
   46.21            .offset = offsetof(xen_vdi_record, physical_utilisation) },
   46.22 -        { .key = "sector_size",
   46.23 -          .type = &abstract_type_int,
   46.24 -          .offset = offsetof(xen_vdi_record, sector_size) },
   46.25 -        { .key = "location",
   46.26 -          .type = &abstract_type_string,
   46.27 -          .offset = offsetof(xen_vdi_record, location) },
   46.28          { .key = "type",
   46.29            .type = &xen_vdi_type_abstract_type_,
   46.30            .offset = offsetof(xen_vdi_record, type) },
   46.31 @@ -78,7 +73,10 @@ static const struct_member xen_vdi_recor
   46.32            .offset = offsetof(xen_vdi_record, sharable) },
   46.33          { .key = "read_only",
   46.34            .type = &abstract_type_bool,
   46.35 -          .offset = offsetof(xen_vdi_record, read_only) }
   46.36 +          .offset = offsetof(xen_vdi_record, read_only) },
   46.37 +        { .key = "other_config",
   46.38 +          .type = &abstract_type_string_string_map,
   46.39 +          .offset = offsetof(xen_vdi_record, other_config) }
   46.40      };
   46.41  
   46.42  const abstract_type xen_vdi_record_abstract_type_ =
   46.43 @@ -105,6 +103,7 @@ xen_vdi_record_free(xen_vdi_record *reco
   46.44      xen_sr_record_opt_free(record->sr);
   46.45      xen_vbd_record_opt_set_free(record->vbds);
   46.46      xen_crashdump_record_opt_set_free(record->crash_dumps);
   46.47 +    xen_string_string_map_free(record->other_config);
   46.48      free(record);
   46.49  }
   46.50  
   46.51 @@ -315,22 +314,6 @@ xen_vdi_get_physical_utilisation(xen_ses
   46.52  
   46.53  
   46.54  bool
   46.55 -xen_vdi_get_sector_size(xen_session *session, int64_t *result, xen_vdi vdi)
   46.56 -{
   46.57 -    abstract_value param_values[] =
   46.58 -        {
   46.59 -            { .type = &abstract_type_string,
   46.60 -              .u.string_val = vdi }
   46.61 -        };
   46.62 -
   46.63 -    abstract_type result_type = abstract_type_int;
   46.64 -
   46.65 -    XEN_CALL_("VDI.get_sector_size");
   46.66 -    return session->ok;
   46.67 -}
   46.68 -
   46.69 -
   46.70 -bool
   46.71  xen_vdi_get_type(xen_session *session, enum xen_vdi_type *result, xen_vdi vdi)
   46.72  {
   46.73      abstract_value param_values[] =
   46.74 @@ -378,6 +361,23 @@ xen_vdi_get_read_only(xen_session *sessi
   46.75  
   46.76  
   46.77  bool
   46.78 +xen_vdi_get_other_config(xen_session *session, xen_string_string_map **result, xen_vdi vdi)
   46.79 +{
   46.80 +    abstract_value param_values[] =
   46.81 +        {
   46.82 +            { .type = &abstract_type_string,
   46.83 +              .u.string_val = vdi }
   46.84 +        };
   46.85 +
   46.86 +    abstract_type result_type = abstract_type_string_string_map;
   46.87 +
   46.88 +    *result = NULL;
   46.89 +    XEN_CALL_("VDI.get_other_config");
   46.90 +    return session->ok;
   46.91 +}
   46.92 +
   46.93 +
   46.94 +bool
   46.95  xen_vdi_set_name_label(xen_session *session, xen_vdi vdi, char *label)
   46.96  {
   46.97      abstract_value param_values[] =
   46.98 @@ -458,6 +458,56 @@ xen_vdi_set_read_only(xen_session *sessi
   46.99  
  46.100  
  46.101  bool
  46.102 +xen_vdi_set_other_config(xen_session *session, xen_vdi vdi, xen_string_string_map *other_config)
  46.103 +{
  46.104 +    abstract_value param_values[] =
  46.105 +        {
  46.106 +            { .type = &abstract_type_string,
  46.107 +              .u.string_val = vdi },
  46.108 +            { .type = &abstract_type_string_string_map,
  46.109 +              .u.set_val = (arbitrary_set *)other_config }
  46.110 +        };
  46.111 +
  46.112 +    xen_call_(session, "VDI.set_other_config", param_values, 2, NULL, NULL);
  46.113 +    return session->ok;
  46.114 +}
  46.115 +
  46.116 +
  46.117 +bool
  46.118 +xen_vdi_add_to_other_config(xen_session *session, xen_vdi vdi, char *key, char *value)
  46.119 +{
  46.120 +    abstract_value param_values[] =
  46.121 +        {
  46.122 +            { .type = &abstract_type_string,
  46.123 +              .u.string_val = vdi },
  46.124 +            { .type = &abstract_type_string,
  46.125 +              .u.string_val = key },
  46.126 +            { .type = &abstract_type_string,
  46.127 +              .u.string_val = value }
  46.128 +        };
  46.129 +
  46.130 +    xen_call_(session, "VDI.add_to_other_config", param_values, 3, NULL, NULL);
  46.131 +    return session->ok;
  46.132 +}
  46.133 +
  46.134 +
  46.135 +bool
  46.136 +xen_vdi_remove_from_other_config(xen_session *session, xen_vdi vdi, char *key)
  46.137 +{
  46.138 +    abstract_value param_values[] =
  46.139 +        {
  46.140 +            { .type = &abstract_type_string,
  46.141 +              .u.string_val = vdi },
  46.142 +            { .type = &abstract_type_string,
  46.143 +              .u.string_val = key }
  46.144 +        };
  46.145 +
  46.146 +    xen_call_(session, "VDI.remove_from_other_config", param_values, 2, NULL, NULL);
  46.147 +    return session->ok;
  46.148 +}
  46.149 +
  46.150 +
  46.151 +bool
  46.152  xen_vdi_snapshot(xen_session *session, xen_vdi *result, xen_vdi vdi)
  46.153  {
  46.154      abstract_value param_values[] =
    47.1 --- a/tools/libxen/test/test_bindings.c	Tue Mar 20 10:07:11 2007 -0600
    47.2 +++ b/tools/libxen/test/test_bindings.c	Tue Mar 20 15:19:38 2007 -0600
    47.3 @@ -421,8 +421,7 @@ static xen_vm create_new_vm(xen_session 
    47.4              .name_label = "MyRootFS",
    47.5              .name_description = "MyRootFS description",
    47.6              .sr = &sr_record,
    47.7 -            .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
    47.8 -            .sector_size = 512,
    47.9 +            .virtual_size = (INT64_C(1) << 30),  // 1GiB
   47.10              .type = XEN_VDI_TYPE_SYSTEM,
   47.11              .sharable = false,
   47.12              .read_only = false
    48.1 --- a/tools/python/scripts/test_hvm_create.py	Tue Mar 20 10:07:11 2007 -0600
    48.2 +++ b/tools/python/scripts/test_hvm_create.py	Tue Mar 20 15:19:38 2007 -0600
    48.3 @@ -39,14 +39,13 @@ vm_cfg = {
    48.4  local_vdi_cfg = {
    48.5      'name_label': 'gentoo.hvm',
    48.6      'name_description': '',
    48.7 -    'location': 'file:/root/gentoo.amd64.hvm.img',
    48.8      'virtual_size': 0,
    48.9 -    'sector_size': 0,
   48.10      'type': 'system',
   48.11      'parent': '',
   48.12      'SR_name': 'Local',
   48.13      'sharable': False,
   48.14      'read_only': False,
   48.15 +    'other_config': {'location': 'file:/root/gentoo.amd64.hvm.img'},
   48.16  }    
   48.17  
   48.18  local_vbd_cfg = {
    49.1 --- a/tools/python/scripts/test_vm_create.py	Tue Mar 20 10:07:11 2007 -0600
    49.2 +++ b/tools/python/scripts/test_vm_create.py	Tue Mar 20 15:19:38 2007 -0600
    49.3 @@ -39,8 +39,7 @@ vm_cfg = {
    49.4  vdi_cfg = {
    49.5      'name_label': 'API_VDI',
    49.6      'name_description': '',
    49.7 -    'virtual_size': 100 * 1024 * 1024,
    49.8 -    'sector_size': 1024,
    49.9 +    'virtual_size': 100 * 1024 * 1024 * 1024,
   49.10      'type': 'system',
   49.11      'parent': '',
   49.12      'SR_name': 'QCoW',
   49.13 @@ -60,14 +59,13 @@ vbd_cfg = {
   49.14  local_vdi_cfg = {
   49.15      'name_label': 'gentoo.amd64.img',
   49.16      'name_description': '',
   49.17 -    'location': 'file:/root/gentoo.amd64.img',
   49.18      'virtual_size': 0,
   49.19 -    'sector_size': 0,
   49.20      'type': 'system',
   49.21      'parent': '',
   49.22      'SR_name': 'Local',
   49.23      'sharable': False,
   49.24      'read_only': False,
   49.25 +    'other_config': {'location': 'file:/root/gentoo.amd64.img'},
   49.26  }    
   49.27  
   49.28  local_vbd_cfg = {
    50.1 --- a/tools/python/scripts/xapi.py	Tue Mar 20 10:07:11 2007 -0600
    50.2 +++ b/tools/python/scripts/xapi.py	Tue Mar 20 15:19:38 2007 -0600
    50.3 @@ -40,8 +40,7 @@ VM_LIST_FORMAT = '%(name_label)-18s %(me
    50.4                   ' %(power_state)-10s %(uuid)-36s'
    50.5  SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \
    50.6                   '%(type)-10s'
    50.7 -VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\
    50.8 -                  '%(sector_size)-8s'
    50.9 +VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s'
   50.10  VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'
   50.11  TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
   50.12  VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
   50.13 @@ -96,12 +95,9 @@ OPTIONS = {
   50.14      
   50.15      'vdi-create': [(('--name-label',), {'help': 'Name for VDI'}),
   50.16                     (('--name-description',), {'help': 'Description for VDI'}),
   50.17 -                   (('--sector-size',), {'type': 'int',
   50.18 -                                         'help': 'Sector size',
   50.19 -                                         'default': 0}),
   50.20                     (('--virtual-size',), {'type': 'int',
   50.21                                            'default': 0,
   50.22 -                                          'help': 'Size of VDI in sectors'}),
   50.23 +                                          'help': 'Size of VDI in bytes'}),
   50.24                     (('--type',), {'choices': ['system', 'user', 'ephemeral'],
   50.25                                    'default': 'system',
   50.26                                    'help': 'VDI type'}),
   50.27 @@ -569,8 +565,7 @@ def xapi_vdi_list(args, async = False):
   50.28      if not is_long:
   50.29          print VDI_LIST_FORMAT % {'name_label': 'VDI Label',
   50.30                                   'uuid' : 'UUID',
   50.31 -                                 'virtual_size': 'Bytes',
   50.32 -                                 'sector_size': 'Sector Size'}
   50.33 +                                 'virtual_size': 'Bytes'}
   50.34          
   50.35          for vdi in vdis:
   50.36              vdi_struct = execute(server, 'VDI.get_record', (session, vdi))
    51.1 --- a/tools/python/scripts/xapi.vdicfg.py	Tue Mar 20 10:07:11 2007 -0600
    51.2 +++ b/tools/python/scripts/xapi.vdicfg.py	Tue Mar 20 15:19:38 2007 -0600
    51.3 @@ -1,7 +1,6 @@
    51.4  name_label = 'VDI 1'
    51.5  name_description = ''
    51.6 -virtual_size = 10 * 1024 * 1024
    51.7 -sector_size = 1024
    51.8 +virtual_size = 10 * 1024 * 1024 * 1024
    51.9  type = 'system'
   51.10  sharable = False
   51.11  read_only = False
    52.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Tue Mar 20 10:07:11 2007 -0600
    52.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue Mar 20 15:19:38 2007 -0600
    52.3 @@ -50,17 +50,21 @@ static PyObject *pyxc_error_to_exception
    52.4      const xc_error *err = xc_get_last_error();
    52.5      const char *desc = xc_error_code_to_desc(err->code);
    52.6  
    52.7 -    if (err->code == XC_ERROR_NONE)
    52.8 +    if ( err->code == XC_ERROR_NONE )
    52.9          return PyErr_SetFromErrno(xc_error_obj);
   52.10  
   52.11 -    if (err->message[0] != '\0')
   52.12 +    if ( err->message[0] != '\0' )
   52.13  	pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
   52.14      else
   52.15  	pyerr = Py_BuildValue("(is)", err->code, desc);
   52.16  
   52.17      xc_clear_last_error();
   52.18  
   52.19 -    PyErr_SetObject(xc_error_obj, pyerr);
   52.20 +    if ( pyerr != NULL )
   52.21 +    {
   52.22 +        PyErr_SetObject(xc_error_obj, pyerr);
   52.23 +        Py_DECREF(pyerr);
   52.24 +    }
   52.25  
   52.26      return NULL;
   52.27  }
   52.28 @@ -70,13 +74,13 @@ static PyObject *pyxc_domain_dumpcore(Xc
   52.29      uint32_t dom;
   52.30      char *corefile;
   52.31  
   52.32 -    if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
   52.33 +    if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) )
   52.34          return NULL;
   52.35  
   52.36      if ( (corefile == NULL) || (corefile[0] == '\0') )
   52.37          return NULL;
   52.38  
   52.39 -    if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
   52.40 +    if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
   52.41          return pyxc_error_to_exception();
   52.42      
   52.43      Py_INCREF(zero);
   52.44 @@ -168,10 +172,10 @@ static PyObject *pyxc_domain_shutdown(Xc
   52.45  {
   52.46      uint32_t dom, reason;
   52.47  
   52.48 -    if (!PyArg_ParseTuple(args, "ii", &dom, &reason))
   52.49 +    if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
   52.50        return NULL;
   52.51  
   52.52 -    if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0)
   52.53 +    if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
   52.54          return pyxc_error_to_exception();
   52.55      
   52.56      Py_INCREF(zero);
   52.57 @@ -183,10 +187,10 @@ static PyObject *pyxc_domain_resume(XcOb
   52.58      uint32_t dom;
   52.59      int fast;
   52.60  
   52.61 -    if (!PyArg_ParseTuple(args, "ii", &dom, &fast))
   52.62 +    if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
   52.63          return NULL;
   52.64  
   52.65 -    if (xc_domain_resume(self->xc_handle, dom, fast) != 0)
   52.66 +    if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
   52.67          return pyxc_error_to_exception();
   52.68  
   52.69      Py_INCREF(zero);
   52.70 @@ -282,7 +286,7 @@ static PyObject *pyxc_domain_getinfo(XcO
   52.71                                       PyObject *args,
   52.72                                       PyObject *kwds)
   52.73  {
   52.74 -    PyObject *list, *info_dict;
   52.75 +    PyObject *list, *info_dict, *pyhandle;
   52.76  
   52.77      uint32_t first_dom = 0;
   52.78      int max_doms = 1024, nr_doms, i, j;
   52.79 @@ -308,26 +312,34 @@ static PyObject *pyxc_domain_getinfo(XcO
   52.80      list = PyList_New(nr_doms);
   52.81      for ( i = 0 ; i < nr_doms; i++ )
   52.82      {
   52.83 -        PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
   52.84 +        info_dict = Py_BuildValue(
   52.85 +            "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
   52.86 +            ",s:L,s:L,s:L,s:i,s:i}",
   52.87 +            "domid",           (int)info[i].domid,
   52.88 +            "online_vcpus",    info[i].nr_online_vcpus,
   52.89 +            "max_vcpu_id",     info[i].max_vcpu_id,
   52.90 +            "hvm",             info[i].hvm,
   52.91 +            "dying",           info[i].dying,
   52.92 +            "crashed",         info[i].crashed,
   52.93 +            "shutdown",        info[i].shutdown,
   52.94 +            "paused",          info[i].paused,
   52.95 +            "blocked",         info[i].blocked,
   52.96 +            "running",         info[i].running,
   52.97 +            "mem_kb",          (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
   52.98 +            "cpu_time",        (long long)info[i].cpu_time,
   52.99 +            "maxmem_kb",       (long long)info[i].max_memkb,
  52.100 +            "ssidref",         (int)info[i].ssidref,
  52.101 +            "shutdown_reason", info[i].shutdown_reason);
  52.102 +        pyhandle = PyList_New(sizeof(xen_domain_handle_t));
  52.103 +        if ( (pyhandle == NULL) || (info_dict == NULL) )
  52.104 +        {
  52.105 +            Py_DECREF(list);
  52.106 +            if ( pyhandle  != NULL ) { Py_DECREF(pyhandle);  }
  52.107 +            if ( info_dict != NULL ) { Py_DECREF(info_dict); }
  52.108 +            return NULL;
  52.109 +        }
  52.110          for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
  52.111              PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
  52.112 -        info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
  52.113 -                                  ",s:l,s:L,s:l,s:i,s:i}",
  52.114 -                                  "domid",       info[i].domid,
  52.115 -                                  "online_vcpus", info[i].nr_online_vcpus,
  52.116 -                                  "max_vcpu_id", info[i].max_vcpu_id,
  52.117 -                                  "hvm",       info[i].hvm,
  52.118 -                                  "dying",     info[i].dying,
  52.119 -                                  "crashed",   info[i].crashed,
  52.120 -                                  "shutdown",  info[i].shutdown,
  52.121 -                                  "paused",    info[i].paused,
  52.122 -                                  "blocked",   info[i].blocked,
  52.123 -                                  "running",   info[i].running,
  52.124 -                                  "mem_kb",    info[i].nr_pages*(XC_PAGE_SIZE/1024),
  52.125 -                                  "cpu_time",  info[i].cpu_time,
  52.126 -                                  "maxmem_kb", info[i].max_memkb,
  52.127 -                                  "ssidref",   info[i].ssidref,
  52.128 -                                  "shutdown_reason", info[i].shutdown_reason);
  52.129          PyDict_SetItemString(info_dict, "handle", pyhandle);
  52.130          Py_DECREF(pyhandle);
  52.131          PyList_SetItem(list, i, info_dict);
    53.1 --- a/tools/python/xen/util/blkif.py	Tue Mar 20 10:07:11 2007 -0600
    53.2 +++ b/tools/python/xen/util/blkif.py	Tue Mar 20 15:19:38 2007 -0600
    53.3 @@ -66,16 +66,23 @@ def blkdev_segment(name):
    53.4                  'type'         : 'Disk' }
    53.5      return val
    53.6  
    53.7 -def blkdev_uname_to_file(uname):
    53.8 -    """Take a blkdev uname and return the corresponding filename."""
    53.9 -    fn = None
   53.10 +def _parse_uname(uname):
   53.11 +    fn = taptype = None
   53.12      if uname.find(":") != -1:
   53.13          (typ, fn) = uname.split(":", 1)
   53.14          if typ == "phy" and not fn.startswith("/"):
   53.15              fn = "/dev/%s" %(fn,)
   53.16          if typ == "tap":
   53.17 -            (typ, fn) = fn.split(":", 1)
   53.18 -    return fn
   53.19 +            (taptype, fn) = fn.split(":", 1)
   53.20 +    return (fn, taptype)
   53.21 +
   53.22 +def blkdev_uname_to_file(uname):
   53.23 +    """Take a blkdev uname and return the corresponding filename."""
   53.24 +    return _parse_uname(uname)[0]
   53.25 +
   53.26 +def blkdev_uname_to_taptype(uname):
   53.27 +    """Take a blkdev uname and return the blktap type."""
   53.28 +    return _parse_uname(uname)[1]
   53.29  
   53.30  def mount_mode(name):
   53.31      mode = None
    54.1 --- a/tools/python/xen/util/xmlrpclib2.py	Tue Mar 20 10:07:11 2007 -0600
    54.2 +++ b/tools/python/xen/util/xmlrpclib2.py	Tue Mar 20 15:19:38 2007 -0600
    54.3 @@ -227,24 +227,30 @@ class TCPXMLRPCServer(SocketServer.Threa
    54.4              response = xmlrpclib.dumps(response,
    54.5                                         methodresponse=1,
    54.6                                         allow_none=1)
    54.7 -        except xmlrpclib.Fault, fault:
    54.8 -            response = xmlrpclib.dumps(fault)
    54.9          except Exception, exn:
   54.10 -            if self.xenapi:
   54.11 -                if _is_not_supported(exn):
   54.12 -                    errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
   54.13 +            try:
   54.14 +                if self.xenapi:
   54.15 +                    if _is_not_supported(exn):
   54.16 +                         errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
   54.17 +                    else:
   54.18 +                         log.exception('Internal error handling %s', method)
   54.19 +                         errdesc = ['INTERNAL_ERROR', str(exn)]
   54.20 +
   54.21 +                    response = xmlrpclib.dumps(
   54.22 +                          ({ "Status": "Failure",
   54.23 +                             "ErrorDescription": errdesc },),
   54.24 +                          methodresponse = 1)
   54.25                  else:
   54.26 -                    log.exception('Internal error handling %s', method)
   54.27 -                    errdesc = ['INTERNAL_ERROR', str(exn)]
   54.28 -                response = xmlrpclib.dumps(
   54.29 -                    ({ "Status": "Failure",
   54.30 -                       "ErrorDescription": errdesc },),
   54.31 -                    methodresponse = 1)
   54.32 -            else:
   54.33 -                log.exception('Internal error handling %s', method)
   54.34 -                import xen.xend.XendClient
   54.35 -                response = xmlrpclib.dumps(
   54.36 -                    xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
   54.37 +                    import xen.xend.XendClient
   54.38 +                    if isinstance(exn, xmlrpclib.Fault):
   54.39 +                        response = xmlrpclib.dumps(exn)
   54.40 +                    else:
   54.41 +                        log.exception('Internal error handling %s', method)
   54.42 +                        response = xmlrpclib.dumps(
   54.43 +                            xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
   54.44 +            except:
   54.45 +                log.exception('Internal error handling error')
   54.46 +
   54.47          return response
   54.48  
   54.49  
   54.50 @@ -253,7 +259,7 @@ def _is_not_supported(exn):
   54.51      try:
   54.52          m = notSupportedRE.search(exn[0])
   54.53          return m is not None
   54.54 -    except TypeError, e:
   54.55 +    except:
   54.56          return False
   54.57  
   54.58  
    55.1 --- a/tools/python/xen/xend/XendAPI.py	Tue Mar 20 10:07:11 2007 -0600
    55.2 +++ b/tools/python/xen/xend/XendAPI.py	Tue Mar 20 15:19:38 2007 -0600
    55.3 @@ -36,6 +36,9 @@ from xen.xend.XendVMMetrics import XendV
    55.4  from xen.xend.XendAPIConstants import *
    55.5  from xen.util.xmlrpclib2 import stringify
    55.6  
    55.7 +from xen.util.blkif import blkdev_name_to_number
    55.8 +
    55.9 +
   55.10  AUTH_NONE = 'none'
   55.11  AUTH_PAM = 'pam'
   55.12  
   55.13 @@ -662,7 +665,8 @@ class XendAPI(object):
   55.14                      ('add_to_other_config', None),
   55.15                      ('remove_from_other_config', None),
   55.16                      ('dmesg', 'String'),
   55.17 -                    ('get_log', 'String')]
   55.18 +                    ('get_log', 'String'),
   55.19 +                    ('send_debug_keys', None)]
   55.20      
   55.21      host_funcs = [('get_by_name_label', 'Set(host)')]
   55.22  
   55.23 @@ -749,6 +753,11 @@ class XendAPI(object):
   55.24          log_buffer = log_file.read()
   55.25          return xen_api_success(log_buffer)
   55.26  
   55.27 +    def host_send_debug_keys(self, _, host_ref, keys):
   55.28 +        node = XendNode.instance()
   55.29 +        node.send_debug_keys(keys)
   55.30 +        return xen_api_success_void()
   55.31 +
   55.32      def host_get_record(self, session, host_ref):
   55.33          node = XendNode.instance()
   55.34          dom = XendDomain.instance()
   55.35 @@ -1070,6 +1079,7 @@ class XendAPI(object):
   55.36                    ('hard_reboot', None),
   55.37                    ('suspend', None),
   55.38                    ('resume', None),
   55.39 +                  ('send_sysrq', None),
   55.40                    ('add_to_HVM_boot_params', None),
   55.41                    ('remove_from_HVM_boot_params', None),
   55.42                    ('add_to_VCPUs_params', None),
   55.43 @@ -1077,7 +1087,8 @@ class XendAPI(object):
   55.44                    ('add_to_platform', None),
   55.45                    ('remove_from_platform', None),
   55.46                    ('add_to_other_config', None),
   55.47 -                  ('remove_from_other_config', None)]
   55.48 +                  ('remove_from_other_config', None),
   55.49 +                  ('send_trigger', None)]
   55.50      
   55.51      VM_funcs  = [('create', 'VM'),
   55.52                   ('get_by_name_label', 'Set(VM)')]
   55.53 @@ -1513,6 +1524,24 @@ class XendAPI(object):
   55.54          return XendTask.log_progress(0, 100, do_vm_func,
   55.55                                       "domain_unpause", vm_ref)
   55.56  
   55.57 +    def VM_send_sysrq(self, _, vm_ref, req):
   55.58 +        xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
   55.59 +        if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
   55.60 +            return xen_api_error(
   55.61 +                ['VM_BAD_POWER_STATE', vm_ref,
   55.62 +                 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
   55.63 +                 XendDomain.POWER_STATE_NAMES[xeninfo.state]])
   55.64 +        xeninfo.send_sysrq(req)
   55.65 +        return xen_api_success_void()
   55.66 +
   55.67 +
   55.68 +    def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
   55.69 +        xendom = XendDomain.instance()
   55.70 +        xeninfo = xendom.get_vm_by_uuid(vm_ref)
   55.71 +        xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
   55.72 +        return xen_api_success_void()
   55.73 +        
   55.74 +
   55.75      # Xen API: Class VM_metrics
   55.76      # ----------------------------------------------------------------
   55.77  
   55.78 @@ -1538,12 +1567,13 @@ class XendAPI(object):
   55.79          return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number())
   55.80  
   55.81      def VM_metrics_get_vcpus_utilisation(self, _, ref):
   55.82 -        return xen_api_success(self._VM_metrics_get(ref).get_metrics_get_vcpus_utilisation())
   55.83 +        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation())
   55.84  
   55.85      # Xen API: Class VBD
   55.86      # ----------------------------------------------------------------
   55.87  
   55.88 -    VBD_attr_ro = ['metrics']
   55.89 +    VBD_attr_ro = ['metrics',
   55.90 +                   'runtime_properties']
   55.91      VBD_attr_rw = ['VM',
   55.92                     'VDI',
   55.93                     'device',
   55.94 @@ -1584,23 +1614,28 @@ class XendAPI(object):
   55.95      # class methods
   55.96      def VBD_create(self, session, vbd_struct):
   55.97          xendom = XendDomain.instance()
   55.98 +        xennode = XendNode.instance()
   55.99 +        
  55.100          if not xendom.is_valid_vm(vbd_struct['VM']):
  55.101              return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
  55.102          
  55.103          dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
  55.104 -        vbd_ref = ''
  55.105 +        vdi = xennode.get_vdi_by_uuid(vbd_struct['VDI'])
  55.106 +        if not vdi:
  55.107 +            return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
  55.108 +
  55.109 +        # new VBD via VDI/SR
  55.110 +        vdi_image = vdi.get_location()
  55.111 +
  55.112          try:
  55.113 -            # new VBD via VDI/SR
  55.114 -            vdi_ref = vbd_struct.get('VDI')
  55.115 -            vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
  55.116 -            if not vdi:
  55.117 -                return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
  55.118 -            vdi_image = vdi.get_location()
  55.119              vbd_ref = XendTask.log_progress(0, 100,
  55.120                                              dom.create_vbd,
  55.121                                              vbd_struct, vdi_image)
  55.122 -        except XendError:
  55.123 -            return xen_api_todo()
  55.124 +        except XendError, e:
  55.125 +            log.exception("Error in VBD_create")
  55.126 +            return xen_api_error(['INTERNAL_ERROR', str(e)]) 
  55.127 +            
  55.128 +        vdi.addVBD(vbd_ref)
  55.129  
  55.130          xendom.managed_config_save(dom)
  55.131          return xen_api_success(vbd_ref)
  55.132 @@ -1612,7 +1647,14 @@ class XendAPI(object):
  55.133          if not vm:
  55.134              return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
  55.135  
  55.136 +        vdi_ref = XendDomain.instance()\
  55.137 +                  .get_dev_property_by_uuid('vbd', vbd_ref, "VDI")
  55.138 +        vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
  55.139 +
  55.140          XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
  55.141 +
  55.142 +        vdi.removeVBD(vbd_ref)
  55.143 +        
  55.144          return xen_api_success_void()
  55.145  
  55.146      def _VBD_get(self, vbd_ref, prop):
  55.147 @@ -1624,6 +1666,24 @@ class XendAPI(object):
  55.148      def VBD_get_metrics(self, _, vbd_ref):
  55.149          return xen_api_success(vbd_ref)
  55.150  
  55.151 +    def VBD_get_runtime_properties(self, _, vbd_ref):
  55.152 +        xendom = XendDomain.instance()
  55.153 +        dominfo = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
  55.154 +        device = dominfo.get_dev_config_by_uuid('vbd', vbd_ref)
  55.155 +
  55.156 +        try:
  55.157 +            devid = int(device['id'])
  55.158 +            device_sxps = dominfo.getDeviceSxprs('vbd')
  55.159 +            device_dicts  = [dict(device_sxp[1][1:]) for device_sxp in device_sxps]
  55.160 +            device_dict = [device_dict
  55.161 +                           for device_dict in device_dicts
  55.162 +                           if int(device_dict['virtual-device']) == devid][0]
  55.163 +
  55.164 +            return xen_api_success(device_dict)
  55.165 +        except Exception, exn:
  55.166 +            log.exception(exn)
  55.167 +            return xen_api_success({})
  55.168 +
  55.169      # attributes (rw)
  55.170      def VBD_get_VM(self, session, vbd_ref):
  55.171          return self._VBD_get(vbd_ref, 'VM')
  55.172 @@ -1684,7 +1744,8 @@ class XendAPI(object):
  55.173      # Xen API: Class VIF
  55.174      # ----------------------------------------------------------------
  55.175  
  55.176 -    VIF_attr_ro = ['metrics']
  55.177 +    VIF_attr_ro = ['metrics',
  55.178 +                   'runtime_properties']
  55.179      VIF_attr_rw = ['device',
  55.180                     'network',
  55.181                     'VM',
  55.182 @@ -1721,18 +1782,17 @@ class XendAPI(object):
  55.183      # class methods
  55.184      def VIF_create(self, session, vif_struct):
  55.185          xendom = XendDomain.instance()
  55.186 -        if xendom.is_valid_vm(vif_struct['VM']):
  55.187 -            dom = xendom.get_vm_by_uuid(vif_struct['VM'])
  55.188 -            try:
  55.189 -                vif_ref = dom.create_vif(vif_struct)
  55.190 -                xendom.managed_config_save(dom)                
  55.191 -                return xen_api_success(vif_ref)
  55.192 -            except XendError:
  55.193 -                return xen_api_error(XEND_ERROR_TODO)
  55.194 -        else:
  55.195 +        if not xendom.is_valid_vm(vif_struct['VM']):
  55.196              return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
  55.197  
  55.198 -
  55.199 +        dom = xendom.get_vm_by_uuid(vif_struct['VM'])
  55.200 +        try:
  55.201 +            vif_ref = dom.create_vif(vif_struct)
  55.202 +            xendom.managed_config_save(dom)
  55.203 +            return xen_api_success(vif_ref)
  55.204 +        except XendError:
  55.205 +            return xen_api_error(XEND_ERROR_TODO)
  55.206 +          
  55.207      def VIF_destroy(self, session, vif_ref):
  55.208          xendom = XendDomain.instance()
  55.209          vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
  55.210 @@ -1770,6 +1830,27 @@ class XendAPI(object):
  55.211          vifs = reduce(lambda x, y: x + y, vifs)
  55.212          return xen_api_success(vifs)
  55.213  
  55.214 +    def VIF_get_runtime_properties(self, _, vif_ref):
  55.215 +        xendom = XendDomain.instance()
  55.216 +        dominfo = xendom.get_vm_with_dev_uuid('vif', vif_ref)
  55.217 +        device = dominfo.get_dev_config_by_uuid('vif', vif_ref)
  55.218 +        
  55.219 +        try:
  55.220 +            devid = int(device['id'])
  55.221 +        
  55.222 +            device_sxps = dominfo.getDeviceSxprs('vif')
  55.223 +            device_dicts = [dict(device_sxp[1][1:])
  55.224 +                            for device_sxp in device_sxps]
  55.225 +            
  55.226 +            device_dict = [device_dict
  55.227 +                       for device_dict in device_dicts
  55.228 +                       if int(device_dict['handle']) == devid][0]
  55.229 +            
  55.230 +            return xen_api_success(device_dict)
  55.231 +        
  55.232 +        except Exception, exn:
  55.233 +            log.exception(exn)
  55.234 +            return xen_api_success({})
  55.235      
  55.236      # Xen API: Class VIF_metrics
  55.237      # ----------------------------------------------------------------
  55.238 @@ -1799,13 +1880,13 @@ class XendAPI(object):
  55.239      VDI_attr_ro = ['SR',
  55.240                     'VBDs',
  55.241                     'physical_utilisation',
  55.242 -                   'sector_size',
  55.243                     'type']
  55.244      VDI_attr_rw = ['name_label',
  55.245                     'name_description',
  55.246                     'virtual_size',
  55.247                     'sharable',
  55.248 -                   'read_only']
  55.249 +                   'read_only',
  55.250 +                   'other_config']
  55.251      VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
  55.252  
  55.253      VDI_methods = [('snapshot', 'VDI')]
  55.254 @@ -1816,14 +1897,12 @@ class XendAPI(object):
  55.255          return XendNode.instance().get_vdi_by_uuid(ref)
  55.256      
  55.257      def VDI_get_VBDs(self, session, vdi_ref):
  55.258 -        return xen_api_todo()
  55.259 +        vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
  55.260 +        return xen_api_success(vdi.getVBDs())
  55.261      
  55.262      def VDI_get_physical_utilisation(self, session, vdi_ref):
  55.263          return xen_api_success(self._get_VDI(vdi_ref).
  55.264 -                               get_physical_utilisation())        
  55.265 -    
  55.266 -    def VDI_get_sector_size(self, session, vdi_ref):
  55.267 -        return xen_api_success(self._get_VDI(vdi_ref).sector_size)        
  55.268 +                               get_physical_utilisation())              
  55.269      
  55.270      def VDI_get_type(self, session, vdi_ref):
  55.271          return xen_api_success(self._get_VDI(vdi_ref).type)
  55.272 @@ -1865,6 +1944,14 @@ class XendAPI(object):
  55.273          self._get_VDI(vdi_ref).read_only = bool(value)
  55.274          return xen_api_success_void()
  55.275  
  55.276 +    def VDI_get_other_config(self, session, vdi_ref):
  55.277 +        return xen_api_success(
  55.278 +            self._get_VDI(vdi_ref).other_config)
  55.279 +
  55.280 +    def VDI_set_other_config(self, session, vdi_ref, other_config):
  55.281 +        self._get_VDI(vdi_ref).other_config = other_config
  55.282 +        return xen_api_success_void()
  55.283 +
  55.284      # Object Methods
  55.285      def VDI_snapshot(self, session, vdi_ref):
  55.286          return xen_api_todo()
  55.287 @@ -1881,13 +1968,13 @@ class XendAPI(object):
  55.288              'name_label': image.name_label,
  55.289              'name_description': image.name_description,
  55.290              'SR': image.sr_uuid,
  55.291 -            'VBDs': [], # TODO
  55.292 +            'VBDs': image.getVBDs(),
  55.293              'virtual_size': image.virtual_size,
  55.294              'physical_utilisation': image.physical_utilisation,
  55.295 -            'sector_size': image.sector_size,
  55.296              'type': image.type,
  55.297              'sharable': image.sharable,
  55.298              'read_only': image.read_only,
  55.299 +            'other_config': image.other_config
  55.300              })
  55.301  
  55.302      # Class Functions    
    56.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Tue Mar 20 10:07:11 2007 -0600
    56.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Tue Mar 20 15:19:38 2007 -0600
    56.3 @@ -193,8 +193,8 @@ def restore(xd, fd, dominfo = None, paus
    56.4      is_hvm = dominfo.info.is_hvm()
    56.5      if is_hvm:
    56.6          hvm  = dominfo.info['memory_static_min']
    56.7 -        apic = dominfo.info['platform'].get('apic', 0)
    56.8 -        pae  = dominfo.info['platform'].get('pae',  0)
    56.9 +        apic = int(dominfo.info['platform'].get('apic', 0))
   56.10 +        pae  = int(dominfo.info['platform'].get('pae',  0))
   56.11          log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d",
   56.12                   dominfo.domid, hvm, apic, pae)
   56.13      else:
    57.1 --- a/tools/python/xen/xend/XendConfig.py	Tue Mar 20 10:07:11 2007 -0600
    57.2 +++ b/tools/python/xen/xend/XendConfig.py	Tue Mar 20 15:19:38 2007 -0600
    57.3 @@ -28,7 +28,7 @@ from xen.xend.PrettyPrint import prettyp
    57.4  from xen.xend.XendConstants import DOM_STATE_HALTED
    57.5  
    57.6  log = logging.getLogger("xend.XendConfig")
    57.7 -log.setLevel(logging.DEBUG)
    57.8 +log.setLevel(logging.WARN)
    57.9  
   57.10  
   57.11  """
   57.12 @@ -105,8 +105,6 @@ XENAPI_CFG_TO_LEGACY_CFG = {
   57.13      'uuid': 'uuid',
   57.14      'vcpus_number': 'vcpus',
   57.15      'cpus': 'cpus',
   57.16 -    'memory_static_min': 'memory',
   57.17 -    'memory_static_max': 'maxmem',
   57.18      'name_label': 'name',
   57.19      'actions_after_shutdown': 'on_poweroff',
   57.20      'actions_after_reboot': 'on_reboot',
   57.21 @@ -136,11 +134,10 @@ XENAPI_CFG_TYPES = {
   57.22      'user_version': str,
   57.23      'is_a_template': bool0,
   57.24      'resident_on': str,
   57.25 -    'memory_static_min': int,
   57.26 +    'memory_static_min': int,  # note these are stored in bytes, not KB!
   57.27      'memory_static_max': int,
   57.28      'memory_dynamic_min': int,
   57.29      'memory_dynamic_max': int,
   57.30 -    'memory_actual': int,
   57.31      'cpus': list,
   57.32      'vcpus_policy': str,
   57.33      'vcpus_params': dict,
   57.34 @@ -314,7 +311,6 @@ class XendConfig(dict):
   57.35              'shadow_memory': 0,
   57.36              'memory_static_max': 0,
   57.37              'memory_dynamic_max': 0,
   57.38 -            'memory_actual': 0,
   57.39              'devices': {},
   57.40              'security': None,
   57.41              'on_xend_start': 'ignore',
   57.42 @@ -334,20 +330,39 @@ class XendConfig(dict):
   57.43          
   57.44          return defaults
   57.45  
   57.46 +    #
   57.47 +    # Here we assume these values exist in the dict.
   57.48 +    # If they don't we have a bigger problem, lets not
   57.49 +    # try and 'fix it up' but acutually fix the cause ;-)
   57.50 +    #
   57.51      def _memory_sanity_check(self):
   57.52 -        if self['memory_static_min'] == 0:
   57.53 -            self['memory_static_min'] = self['memory_dynamic_min']
   57.54 -
   57.55 -        # If the static max is not set, let's set it to dynamic max.
   57.56 -        # If the static max is smaller than static min, then fix it!
   57.57 -        self['memory_static_max'] = max(self['memory_static_max'],
   57.58 -                                        self['memory_dynamic_max'],
   57.59 -                                        self['memory_static_min'])
   57.60 -
   57.61 -        for mem_type in ('memory_static_min', 'memory_static_max'):
   57.62 -            if self[mem_type] <= 0:
   57.63 -                raise XendConfigError('Memory value too low for %s: %d' %
   57.64 -                                      (mem_type, self[mem_type]))
   57.65 +        log.debug("_memory_sanity_check memory_static_min: %s, "
   57.66 +                      "memory_static_max: %i, "
   57.67 +                      "memory_dynamic_min: %i, " 
   57.68 +                      "memory_dynamic_max: %i",
   57.69 +                      self["memory_static_min"],
   57.70 +                      self["memory_static_max"],
   57.71 +                      self["memory_dynamic_min"],
   57.72 +                      self["memory_dynamic_max"])
   57.73 +        
   57.74 +        if not self["memory_static_min"] <= self["memory_static_max"]:
   57.75 +            raise XendConfigError("memory_static_min must be less " \
   57.76 +                                  "than or equal to memory_static_max") 
   57.77 +        if not self["memory_dynamic_min"] <= self["memory_dynamic_max"]:
   57.78 +            raise XendConfigError("memory_dynamic_min must be less " \
   57.79 +                                  "than or equal to memory_dynamic_max")
   57.80 +        if not self["memory_static_min"] <= self["memory_dynamic_min"]:
   57.81 +            raise XendConfigError("memory_static_min must be less " \
   57.82 +                                  "than or equal to memory_dynamic_min")
   57.83 +        if not self["memory_dynamic_max"] <= self["memory_static_max"]:
   57.84 +            raise XendConfigError("memory_dynamic_max must be less " \
   57.85 +                                  "than or equal to memory_static_max")
   57.86 +        if not self["memory_dynamic_max"] > 0:
   57.87 +            raise XendConfigError("memory_dynamic_max must be greater " \
   57.88 +                                  "than zero")
   57.89 +        if not self["memory_static_max"] > 0:
   57.90 +            raise XendConfigError("memory_static_max must be greater " \
   57.91 +                                  "than zero")
   57.92  
   57.93      def _actions_sanity_check(self):
   57.94          for event in ['shutdown', 'reboot', 'crash']:
   57.95 @@ -392,8 +407,12 @@ class XendConfig(dict):
   57.96          self['domid'] = dominfo['domid']
   57.97          self['online_vcpus'] = dominfo['online_vcpus']
   57.98          self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
   57.99 -        self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
  57.100 -        self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
  57.101 +
  57.102 +        self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
  57.103 +        self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
  57.104 +        self['memory_static_min'] = 0
  57.105 +        self['memory_static_max'] = dominfo['maxmem_kb'] * 1024
  57.106 +
  57.107          self['cpu_time'] = dominfo['cpu_time']/1e9
  57.108          # TODO: i don't know what the security stuff expects here
  57.109          if dominfo.get('ssidref'):
  57.110 @@ -447,6 +466,13 @@ class XendConfig(dict):
  57.111                  log.warn('Ignoring unrecognised value for deprecated option:'
  57.112                           'restart = \'%s\'', restart)
  57.113  
  57.114 +        # Handle memory, passed in as MiB
  57.115 +
  57.116 +        if sxp.child_value(sxp_cfg, "memory") != None:
  57.117 +            cfg["memory"] = int(sxp.child_value(sxp_cfg, "memory"))
  57.118 +        if sxp.child_value(sxp_cfg, "maxmem") != None:
  57.119 +            cfg["maxmem"] = int(sxp.child_value(sxp_cfg, "maxmem"))
  57.120 +            
  57.121          # Only extract options we know about.
  57.122          extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG
  57.123          extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values()
  57.124 @@ -616,6 +642,21 @@ class XendConfig(dict):
  57.125              except KeyError:
  57.126                  pass
  57.127  
  57.128 +        # Lets try and handle memory correctly
  57.129 +
  57.130 +        MiB = 1024 * 1024
  57.131 +
  57.132 +        if "memory" in cfg:
  57.133 +            self["memory_static_min"] = 0
  57.134 +            self["memory_static_max"] = int(cfg["memory"]) * MiB
  57.135 +            self["memory_dynamic_min"] = int(cfg["memory"]) * MiB
  57.136 +            self["memory_dynamic_max"] = int(cfg["memory"]) * MiB
  57.137 +            
  57.138 +            if "maxmem" in cfg:
  57.139 +                self["memory_static_max"] = int(cfg["maxmem"]) * MiB
  57.140 +
  57.141 +        self._memory_sanity_check()
  57.142 +
  57.143          def update_with(n, o):
  57.144              if not self.get(n):
  57.145                  self[n] = cfg.get(o, '')
  57.146 @@ -632,13 +673,6 @@ class XendConfig(dict):
  57.147              if key in cfg:
  57.148                  self['platform'][key] = cfg[key]
  57.149  
  57.150 -        # make sure a sane maximum is set
  57.151 -        if self['memory_static_max'] <= 0:
  57.152 -            self['memory_static_max'] = self['memory_static_min']
  57.153 -            
  57.154 -        self['memory_dynamic_max'] = self['memory_static_max']
  57.155 -        self['memory_dynamic_min'] = self['memory_static_min']
  57.156 -
  57.157          # set device references in the configuration
  57.158          self['devices'] = cfg.get('devices', {})
  57.159          self['console_refs'] = cfg.get('console_refs', [])
  57.160 @@ -812,6 +846,21 @@ class XendConfig(dict):
  57.161                  else:
  57.162                      sxpr.append([legacy, self[xenapi]])
  57.163  
  57.164 +        MiB = 1024*1024
  57.165 +
  57.166 +        sxpr.append(["maxmem", int(self["memory_static_max"])/MiB])
  57.167 +        sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
  57.168 +
  57.169 +        if not legacy_only:
  57.170 +            sxpr.append(['memory_dynamic_min',
  57.171 +                     int(self.get('memory_dynamic_min'))])
  57.172 +            sxpr.append(['memory_dynamic_max',
  57.173 +                     int(self.get('memory_dynamic_max'))])
  57.174 +            sxpr.append(['memory_static_max',
  57.175 +                     int(self.get('memory_static_max'))])
  57.176 +            sxpr.append(['memory_static_min',
  57.177 +                     int(self.get('memory_static_min'))])
  57.178 +
  57.179          for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
  57.180              if legacy in ('domid', 'uuid'): # skip these
  57.181                  continue
  57.182 @@ -820,8 +869,6 @@ class XendConfig(dict):
  57.183  
  57.184          sxpr.append(['image', self.image_sxpr()])
  57.185          sxpr.append(['status', domain.state])
  57.186 -        sxpr.append(['memory_dynamic_min',  self.get('memory_dynamic_min')])
  57.187 -        sxpr.append(['memory_dynamic_max',  self.get('memory_dynamic_max')])
  57.188  
  57.189          if domain.getDomid() is not None:
  57.190              sxpr.append(['state', self._get_old_state_string()])
    58.1 --- a/tools/python/xen/xend/XendDomain.py	Tue Mar 20 10:07:11 2007 -0600
    58.2 +++ b/tools/python/xen/xend/XendDomain.py	Tue Mar 20 15:19:38 2007 -0600
    58.3 @@ -674,7 +674,7 @@ class XendDomain:
    58.4                  else:
    58.5                      return domid
    58.6              
    58.7 -            raise XendInvalidDomain("Domain does not exist")
    58.8 +            raise XendInvalidDomain(vm_uuid)
    58.9          finally:
   58.10              self.domains_lock.release()
   58.11          
    59.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Mar 20 10:07:11 2007 -0600
    59.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Mar 20 15:19:38 2007 -0600
    59.3 @@ -34,7 +34,7 @@ from types import StringTypes
    59.4  
    59.5  import xen.lowlevel.xc
    59.6  from xen.util import asserts
    59.7 -from xen.util.blkif import blkdev_uname_to_file
    59.8 +from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
    59.9  from xen.util import security
   59.10  
   59.11  from xen.xend import balloon, sxp, uuid, image, arch, osdep
   59.12 @@ -576,12 +576,14 @@ class XendDomainInfo:
   59.13          if target <= 0:
   59.14              raise XendError('Invalid memory size')
   59.15          
   59.16 -        self.info['memory_static_min'] = target
   59.17 +        MiB = 1024 * 1024
   59.18 +        self.info['memory_dynamic_min'] = target * MiB
   59.19 +        self.info['memory_dynamic_max'] = target * MiB
   59.20 +
   59.21          if self.domid >= 0:
   59.22              self.storeVm("memory", target)
   59.23              self.storeDom("memory/target", target << 10)
   59.24          else:
   59.25 -            self.info['memory_dynamic_min'] = target
   59.26              xen.xend.XendDomain.instance().managed_config_save(self)
   59.27  
   59.28      def setMemoryMaximum(self, limit):
   59.29 @@ -664,6 +666,10 @@ class XendDomainInfo:
   59.30                  if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
   59.31                      xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
   59.32                      self.info[xapiarg] = val
   59.33 +                elif arg == "memory":
   59.34 +                    self.info["static_memory_min"] = val
   59.35 +                elif arg == "maxmem":
   59.36 +                    self.info["static_memory_max"] = val
   59.37                  else:
   59.38                      self.info[arg] = val
   59.39  
   59.40 @@ -780,7 +786,7 @@ class XendDomainInfo:
   59.41              'vm':                 self.vmpath,
   59.42              'name':               self.info['name_label'],
   59.43              'console/limit':      str(xoptions.get_console_limit() * 1024),
   59.44 -            'memory/target':      str(self.info['memory_static_min'] * 1024),
   59.45 +            'memory/target':      str(self.info['memory_dynamic_max'] / 1024),
   59.46              }
   59.47  
   59.48          def f(n, v):
   59.49 @@ -864,7 +870,15 @@ class XendDomainInfo:
   59.50                  xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
   59.51                  if val != None and val != self.info[xapiarg]:
   59.52                      self.info[xapiarg] = val
   59.53 -                    changed= True
   59.54 +                    changed = True
   59.55 +            elif arg == "memory":
   59.56 +                if val != None and val != self.info["static_memory_min"]:
   59.57 +                    self.info["static_memory_min"] = val
   59.58 +                    changed = True
   59.59 +            elif arg == "maxmem":
   59.60 +                if val != None and val != self.info["static_memory_max"]:
   59.61 +                    self.info["static_memory_max"] = val
   59.62 +                    changed = True
   59.63  
   59.64          # Check whether image definition has been updated
   59.65          image_sxp = self._readVm('image')
   59.66 @@ -969,11 +983,12 @@ class XendDomainInfo:
   59.67  
   59.68      def getMemoryTarget(self):
   59.69          """Get this domain's target memory size, in KB."""
   59.70 -        return self.info['memory_static_min'] * 1024
   59.71 +        return self.info['memory_dynamic_max'] / 1024
   59.72  
   59.73      def getMemoryMaximum(self):
   59.74          """Get this domain's maximum memory size, in KB."""
   59.75 -        return self.info['memory_static_max'] * 1024
   59.76 +        # remember, info now stores memory in bytes
   59.77 +        return self.info['memory_static_max'] / 1024
   59.78  
   59.79      def getResume(self):
   59.80          return str(self._resume)
   59.81 @@ -1455,13 +1470,14 @@ class XendDomainInfo:
   59.82              # Use architecture- and image-specific calculations to determine
   59.83              # the various headrooms necessary, given the raw configured
   59.84              # values. maxmem, memory, and shadow are all in KiB.
   59.85 +            # but memory_static_max etc are all stored in bytes now.
   59.86              memory = self.image.getRequiredAvailableMemory(
   59.87 -                self.info['memory_static_min'] * 1024)
   59.88 +                self.info['memory_dynamic_max'] / 1024)
   59.89              maxmem = self.image.getRequiredAvailableMemory(
   59.90 -                self.info['memory_static_max'] * 1024)
   59.91 +                self.info['memory_static_max'] / 1024)
   59.92              shadow = self.image.getRequiredShadowMemory(
   59.93 -                self.info['shadow_memory'] * 1024,
   59.94 -                self.info['memory_static_max'] * 1024)
   59.95 +                self.info['shadow_memory'] / 1024,
   59.96 +                self.info['memory_static_max'] / 1024)
   59.97  
   59.98              log.debug("_initDomain:shadow_memory=0x%x, memory_static_max=0x%x, memory_static_min=0x%x.", self.info['shadow_memory'], self.info['memory_static_max'], self.info['memory_static_min'],)
   59.99              # Round shadow up to a multiple of a MiB, as shadow_mem_control
  59.100 @@ -1650,7 +1666,18 @@ class XendDomainInfo:
  59.101              log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
  59.102  
  59.103          from xen.xend import XendDomain
  59.104 -        XendDomain.instance().remove_domain(self)
  59.105 +
  59.106 +        if "transient" in self.info["other_config"]\
  59.107 +           and bool(self.info["other_config"]["transient"]):
  59.108 +            xendDomainInstance = XendDomain.instance()
  59.109 +            
  59.110 +            xendDomainInstance.domains_lock.acquire()
  59.111 +            xendDomainInstance._refresh(refresh_shutdown = False)
  59.112 +            xendDomainInstance.domains_lock.release()
  59.113 +            
  59.114 +            xendDomainInstance.domain_delete(self.info["name_label"])
  59.115 +        else:
  59.116 +            XendDomain.instance().remove_domain(self)
  59.117  
  59.118          self.cleanupDomain()
  59.119          self._cleanup_phantom_devs(paths)
  59.120 @@ -1759,7 +1786,8 @@ class XendDomainInfo:
  59.121              disk = devinfo[1]['uname']
  59.122  
  59.123              fn = blkdev_uname_to_file(disk)
  59.124 -            mounted = devtype == 'tap' and not os.stat(fn).st_rdev
  59.125 +            taptype = blkdev_uname_to_taptype(disk)
  59.126 +            mounted = devtype == 'tap' and taptype != 'aio' and taptype != 'sync' and not os.stat(fn).st_rdev
  59.127              if mounted:
  59.128                  # This is a file, not a device.  pygrub can cope with a
  59.129                  # file if it's raw, but if it's QCOW or other such formats
  59.130 @@ -1775,7 +1803,7 @@ class XendDomainInfo:
  59.131  
  59.132                  from xen.xend import XendDomain
  59.133                  dom0 = XendDomain.instance().privilegedDomain()
  59.134 -                dom0._waitForDeviceUUID(dom0.create_vbd(vbd, fn))
  59.135 +                dom0._waitForDeviceUUID(dom0.create_vbd(vbd, disk))
  59.136                  fn = BOOTLOADER_LOOPBACK_DEVICE
  59.137  
  59.138              try:
  59.139 @@ -1833,7 +1861,7 @@ class XendDomainInfo:
  59.140              # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
  59.141              # the minimum that Xen would allocate if no value were given.
  59.142              overhead_kb = self.info['vcpus_number'] * 1024 + \
  59.143 -                          self.info['memory_static_max'] * 4
  59.144 +                          (self.info['memory_static_max'] / 1024 / 1024) * 4
  59.145              overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
  59.146              # The domain might already have some shadow memory
  59.147              overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
  59.148 @@ -1899,6 +1927,11 @@ class XendDomainInfo:
  59.149              if self._infoIsSet(info_key):
  59.150                  to_store[key] = str(self.info[info_key])
  59.151  
  59.152 +        if self._infoIsSet("static_memory_min"):
  59.153 +            to_store["memory"] = str(self.info["static_memory_min"])
  59.154 +        if self._infoIsSet("static_memory_max"):
  59.155 +            to_store["maxmem"] = str(self.info["static_memory_max"])
  59.156 +
  59.157          image_sxpr = self.info.image_sxpr()
  59.158          if image_sxpr:
  59.159              to_store['image'] = sxp.to_string(image_sxpr)
  59.160 @@ -1988,7 +2021,11 @@ class XendDomainInfo:
  59.161              info = dom_get(self.domid)
  59.162              if not info:
  59.163                  return
  59.164 -            
  59.165 +
  59.166 +        if info["maxmem_kb"] < 0:
  59.167 +            info["maxmem_kb"] = XendNode.instance() \
  59.168 +                                .physinfo_dict()['total_memory'] * 1024
  59.169 +
  59.170          #manually update ssidref / security fields
  59.171          if security.on() and info.has_key('ssidref'):
  59.172              if (info['ssidref'] != 0) and self.info.has_key('security'):
  59.173 @@ -2249,8 +2286,6 @@ class XendDomainInfo:
  59.174          @return: uuid of the device
  59.175          """
  59.176          xenapi_vbd['image'] = vdi_image_path
  59.177 -        log.debug('create_vbd: %s' % xenapi_vbd)
  59.178 -        dev_uuid = ''
  59.179          if vdi_image_path.startswith('tap'):
  59.180              dev_uuid = self.info.device_add('tap', cfg_xenapi = xenapi_vbd)
  59.181          else:
  59.182 @@ -2260,16 +2295,25 @@ class XendDomainInfo:
  59.183              raise XendError('Failed to create device')
  59.184  
  59.185          if self.state == XEN_API_VM_POWER_STATE_RUNNING:
  59.186 +            
  59.187              _, config = self.info['devices'][dev_uuid]
  59.188 -            dev_control = None
  59.189              
  59.190              if vdi_image_path.startswith('tap'):
  59.191 -                dev_control =  self.getDeviceController('tap')
  59.192 +                dev_control = self.getDeviceController('tap')
  59.193              else:
  59.194                  dev_control = self.getDeviceController('vbd')
  59.195 -                
  59.196 -            config['devid'] = dev_control.createDevice(config)
  59.197 -
  59.198 +
  59.199 +            try:
  59.200 +                devid = dev_control.createDevice(config)
  59.201 +                dev_control.waitForDevice(devid)
  59.202 +                self.info.device_update(dev_uuid,
  59.203 +                                        cfg_xenapi = {'devid': devid})
  59.204 +            except Exception, exn:
  59.205 +                log.exception(exn)
  59.206 +                del self.info['devices'][dev_uuid]
  59.207 +                self.info['vbd_refs'].remove(dev_uuid)
  59.208 +                raise
  59.209 +            
  59.210          return dev_uuid
  59.211  
  59.212      def create_phantom_vbd_with_vdi(self, xenapi_vbd, vdi_image_path):
  59.213 @@ -2303,9 +2347,21 @@ class XendDomainInfo:
  59.214              raise XendError('Failed to create device')
  59.215          
  59.216          if self.state == XEN_API_VM_POWER_STATE_RUNNING:
  59.217 +
  59.218              _, config = self.info['devices'][dev_uuid]
  59.219 -            config['devid'] = self.getDeviceController('vif').createDevice(config)
  59.220 -
  59.221 +            dev_control = self.getDeviceController('vif')
  59.222 +
  59.223 +            try:
  59.224 +                devid = dev_control.createDevice(config)
  59.225 +                dev_control.waitForDevice(devid)
  59.226 +                self.info.device_update(dev_uuid,
  59.227 +                                        cfg_xenapi = {'devid': devid})
  59.228 +            except Exception, exn:
  59.229 +                log.exception(exn)
  59.230 +                del self.info['devices'][dev_uuid]
  59.231 +                self.info['vif_refs'].remove(dev_uuid)
  59.232 +                raise            
  59.233 + 
  59.234          return dev_uuid
  59.235  
  59.236      def create_vtpm(self, xenapi_vtpm):
  59.237 @@ -2372,7 +2428,7 @@ class XendDomainInfo:
  59.238      def __str__(self):
  59.239          return '<domain id=%s name=%s memory=%s state=%s>' % \
  59.240                 (str(self.domid), self.info['name_label'],
  59.241 -                str(self.info['memory_static_min']), DOM_STATES[self.state])
  59.242 +                str(self.info['memory_dynamic_max']), DOM_STATES[self.state])
  59.243  
  59.244      __repr__ = __str__
  59.245  
    60.1 --- a/tools/python/xen/xend/XendLogging.py	Tue Mar 20 10:07:11 2007 -0600
    60.2 +++ b/tools/python/xen/xend/XendLogging.py	Tue Mar 20 15:19:38 2007 -0600
    60.3 @@ -59,6 +59,18 @@ if 'TRACE' not in logging.__dict__:
    60.4                      return filename, frame[2]
    60.5      logging.Logger.findCaller = findCaller
    60.6  
    60.7 +    # Work around a bug in Python's inspect module: findsource is supposed to
    60.8 +    # raise IOError if it fails, with other functions in that module coping
    60.9 +    # with that, but some people are seeing IndexError raised from there.
   60.10 +    if hasattr(inspect, 'findsource'):
   60.11 +        real_findsource = getattr(inspect, 'findsource')
   60.12 +        def findsource(*args, **kwargs):
   60.13 +            try:
   60.14 +                return real_findsource(*args, **kwargs)
   60.15 +            except IndexError, exn:
   60.16 +                raise IOError(exn)
   60.17 +        inspect.findsource = findsource
   60.18 +
   60.19  
   60.20  log = logging.getLogger("xend")
   60.21  
    61.1 --- a/tools/python/xen/xend/XendNode.py	Tue Mar 20 10:07:11 2007 -0600
    61.2 +++ b/tools/python/xen/xend/XendNode.py	Tue Mar 20 15:19:38 2007 -0600
    61.3 @@ -530,7 +530,8 @@ class XendNode:
    61.4                             info['cores_per_socket'] *
    61.5                             info['threads_per_core'])
    61.6          info['cpu_mhz'] = info['cpu_khz'] / 1000
    61.7 -        # physinfo is in KiB
    61.8 +        
    61.9 +        # physinfo is in KiB, need it in MiB
   61.10          info['total_memory'] = info['total_memory'] / 1024
   61.11          info['free_memory']  = info['free_memory'] / 1024
   61.12  
    62.1 --- a/tools/python/xen/xend/XendVDI.py	Tue Mar 20 10:07:11 2007 -0600
    62.2 +++ b/tools/python/xen/xend/XendVDI.py	Tue Mar 20 15:19:38 2007 -0600
    62.3 @@ -54,7 +54,6 @@ class XendVDI(AutoSaveObject):
    62.4      
    62.5      SAVED_CFG = ['name_label',
    62.6                   'name_description',
    62.7 -                 'sector_size',
    62.8                   'virtual_size',
    62.9                   'physical_utilisation',
   62.10                   'sharable',
   62.11 @@ -67,13 +66,22 @@ class XendVDI(AutoSaveObject):
   62.12          self.sr_uuid = sr_uuid
   62.13          self.name_label = ""
   62.14          self.name_description = ""
   62.15 -        self.sector_size = 1024
   62.16          self.virtual_size = 0
   62.17          self.physical_utilisation = 0
   62.18          self.sharable = False
   62.19          self.read_only = False
   62.20          self.type = "system"
   62.21 -        self.location = ''
   62.22 +        self.other_config = {}
   62.23 +        self.vbds = []
   62.24 +
   62.25 +    def addVBD(self, vbd_ref):
   62.26 +        self.vbds.append(vbd_ref)
   62.27 +
   62.28 +    def removeVBD(self, vbd_ref):
   62.29 +        self.vbds.remove(vbd_ref)
   62.30 +
   62.31 +    def getVBDs(self):
   62.32 +        return self.vbds
   62.33  
   62.34      def load_config_dict(self, cfg):
   62.35          """Loads configuration into the object from a dict.
   62.36 @@ -144,11 +152,10 @@ class XendVDI(AutoSaveObject):
   62.37                  'name_description': self.name_description,
   62.38                  'virtual_size': self.virtual_size,
   62.39                  'physical_utilisation': self.physical_utilisation,
   62.40 -                'sector_size': self.sector_size,
   62.41                  'sharable': False,
   62.42                  'readonly': False,
   62.43                  'SR': self.sr_uuid,
   62.44 -                'location': self.get_location(),
   62.45 +                'other_config': self.other_config,
   62.46                  'VBDs': []}
   62.47  
   62.48      def get_location(self):
   62.49 @@ -163,12 +170,11 @@ class XendQCoWVDI(XendVDI):
   62.50          self.cfg_path = cfg_path
   62.51          self.physical_utilisation = psize
   62.52          self.virtual_size = vsize
   62.53 -        self.sector_size = 512
   62.54          self.auto_save = True
   62.55 -        self.location = 'tap:qcow:%s' % self.qcow_path
   62.56 +        self.other_config['location'] = 'tap:qcow:%s' % self.qcow_path
   62.57  
   62.58      def get_location(self):
   62.59 -        return self.location
   62.60 +        return self.other_config['location']
   62.61  
   62.62  class XendLocalVDI(XendVDI):
   62.63      def __init__(self, vdi_struct):
   62.64 @@ -182,11 +188,10 @@ class XendLocalVDI(XendVDI):
   62.65          self.name_description = vdi_struct.get('name_description', '')
   62.66          self.physical_utilisation = 0
   62.67          self.virtual_size = 0
   62.68 -        self.sector_size = 0
   62.69          self.type = vdi_struct.get('type', '')
   62.70          self.sharable = vdi_struct.get('sharable', False)
   62.71          self.read_only = vdi_struct.get('read_only', False)
   62.72 -        self.location = vdi_struct.get('location', 'file:/dev/null')
   62.73 +        self.other_config = vdi_struct.get('other_config', {})
   62.74  
   62.75      def get_location(self):
   62.76 -        return self.location
   62.77 +        return self.other_config['location']
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/tools/python/xen/xm/create.dtd	Tue Mar 20 15:19:38 2007 -0600
    63.3 @@ -0,0 +1,118 @@
    63.4 +<!ENTITY % HTMLlat1 PUBLIC 
    63.5 +   "-//W3C//ENTITIES Latin 1 for XHTML//EN" 
    63.6 +   "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"> 
    63.7 +%HTMLlat1; 
    63.8 +<!ENTITY % HTMLsymbol PUBLIC 
    63.9 +   "-//W3C//ENTITIES Symbols for XHTML//EN" 
   63.10 +   "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"> 
   63.11 +%HTMLsymbol; 
   63.12 +<!ENTITY % HTMLspecial PUBLIC 
   63.13 +   "-//W3C//ENTITIES Special for XHTML//EN" 
   63.14 +   "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"> 
   63.15 +%HTMLspecial; 
   63.16 +<!-- a Uniform Resource Identifier, see [RFC2396] --> 
   63.17 +<!ENTITY % URI "CDATA"> 
   63.18 +<!ENTITY % NAMEID "name ID #REQUIRED"> 
   63.19 +<!ENTITY % CRASH_BEHAVIOUR "( destroy 
   63.20 +                            | coredump_and_destroy
   63.21 +                            | restart
   63.22 +                            | coredump_and_restart
   63.23 +                            | preserve
   63.24 +                            | rename_restart )">
   63.25 +<!ENTITY % NORMAL_EXIT     "( destroy | restart )">
   63.26 +<!ENTITY % VDI_TYPE        "( system
   63.27 +                            | user
   63.28 +                            | ephemeral
   63.29 +                            | suspend
   63.30 +                            | crashdump )">
   63.31 +
   63.32 +<!ELEMENT xm (vm*, 
   63.33 +              vdi*)> 
   63.34 +
   63.35 +<!ELEMENT version (#PCDATA)>
   63.36 + 
   63.37 +<!ELEMENT vm    (name,
   63.38 +                 version,
   63.39 +                 (pv|hvm), 
   63.40 +                 memory,
   63.41 +                 vbd*,
   63.42 +                 vif*,
   63.43 +                 vcpu_param*,
   63.44 +                 other_config*)> 
   63.45 +<!ATTLIST vm     is_a_template          CDATA #REQUIRED
   63.46 +                 auto_power_on          CDATA #REQUIRED
   63.47 +                 vcpus_max              CDATA #REQUIRED
   63.48 +                 vcpus_at_startup       CDATA #REQUIRED
   63.49 +                 actions_after_shutdown %NORMAL_EXIT; #REQUIRED 
   63.50 +                 actions_after_reboot   %NORMAL_EXIT; #REQUIRED
   63.51 +                 actions_after_crash    %CRASH_BEHAVIOUR; #REQUIRED
   63.52 +                 platform_std_VGA       CDATA #REQUIRED
   63.53 +                 platform_serial        CDATA #REQUIRED
   63.54 +                 platform_localtime     CDATA #REQUIRED 
   63.55 +                 platform_clock_offet   CDATA #REQUIRED
   63.56 +                 platform_enable_audio  CDATA #REQUIRED
   63.57 +                 PCI_bus                CDATA #REQUIRED> 
   63.58 +
   63.59 +<!ELEMENT memory EMPTY> 
   63.60 +<!ATTLIST memory static_min      CDATA #REQUIRED
   63.61 +                 static_max      CDATA #REQUIRED
   63.62 +                 dynamic_min     CDATA #REQUIRED 
   63.63 +                 dynamic_max     CDATA #REQUIRED> 
   63.64 +
   63.65 +<!ELEMENT vbd    (qos_algorithm_param*)> 
   63.66 +<!ATTLIST vbd    %NAMEID; 
   63.67 +                 mode            (RO | RW)   #REQUIRED 
   63.68 +                 vdi             IDREF       #REQUIRED
   63.69 +                 device          CDATA       #REQUIRED
   63.70 +                 bootable        CDATA       #REQUIRED
   63.71 +                 type            (CD | disk) #REQUIRED
   63.72 +                 qos_algorithm_type CDATA #REQUIRED> 
   63.73 +
   63.74 +<!ELEMENT vif    (qos_algorithm_param*)>
   63.75 +<!ATTLIST vif    %NAMEID; 
   63.76 +                 mac             CDATA       #REQUIRED 
   63.77 +                 mtu             CDATA       #REQUIRED
   63.78 +                 device          CDATA       #REQUIRED
   63.79 +                 qos_algorithm_type CDATA    #REQUIRED
   63.80 +                 bridge          CDATA       #IMPLIED
   63.81 +                 network         CDATA       #IMPLIED> 
   63.82 +
   63.83 +<!ELEMENT pv     EMPTY>
   63.84 +<!ATTLIST pv     kernel          CDATA #REQUIRED
   63.85 +                 bootloader      CDATA #REQUIRED
   63.86 +                 ramdisk         CDATA #REQUIRED
   63.87 +                 args            CDATA #REQUIRED
   63.88 +                 bootloader_args CDATA #REQUIRED>
   63.89 +
   63.90 +<!ELEMENT hvm    (boot_param*)>
   63.91 +<!ATTLIST hvm    boot_policy     CDATA #REQUIRED>
   63.92 +
   63.93 +<!ELEMENT boot_param EMPTY>
   63.94 +<!ATTLIST boot_param key         CDATA #REQUIRED
   63.95 +                     value       CDATA #REQUIRED>
   63.96 +
   63.97 +<!ELEMENT vdi    (name)> 
   63.98 +<!ATTLIST vdi    %NAMEID; 
   63.99 +                 src             %URI; #REQUIRED
  63.100 +                 type            %VDI_TYPE; #REQUIRED
  63.101 +                 size            CDATA #REQUIRED
  63.102 +                 shareable       CDATA #REQUIRED
  63.103 +                 read_only       CDATA #REQUIRED>
  63.104 +
  63.105 +<!ELEMENT name   (label, 
  63.106 +                  description)> 
  63.107 +
  63.108 +<!ELEMENT label  (#PCDATA)> 
  63.109 +<!ELEMENT description (#PCDATA)>
  63.110 +
  63.111 +<!ELEMENT vcpu_param EMPTY>
  63.112 +<!ATTLIST vcpu_param key   CDATA #REQUIRED
  63.113 +                     value CDATA #REQUIRED>
  63.114 +
  63.115 +<!ELEMENT other_config EMPTY>
  63.116 +<!ATTLIST other_config key   CDATA #REQUIRED
  63.117 +                      value CDATA #REQUIRED>
  63.118 +
  63.119 +<!ELEMENT qos_algorithm_param EMPTY>
  63.120 +<!ATTLIST qos_algorithm_param key   CDATA #REQUIRED
  63.121 +                              value CDATA #REQUIRED>
    64.1 --- a/tools/python/xen/xm/create.py	Tue Mar 20 10:07:11 2007 -0600
    64.2 +++ b/tools/python/xen/xm/create.py	Tue Mar 20 15:19:38 2007 -0600
    64.3 @@ -28,12 +28,13 @@ import time
    64.4  import xmlrpclib
    64.5  
    64.6  from xen.xend import sxp
    64.7 -from xen.xend import PrettyPrint
    64.8 +from xen.xend import PrettyPrint as SXPPrettyPrint
    64.9  from xen.xend import osdep
   64.10  import xen.xend.XendClient
   64.11  from xen.xend.XendBootloader import bootloader
   64.12  from xen.util import blkif
   64.13  from xen.util import security
   64.14 +from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
   64.15  
   64.16  from xen.xm.opts import *
   64.17  
   64.18 @@ -98,6 +99,11 @@ gopts.opt('dryrun', short='n',
   64.19            use="Dry run - prints the resulting configuration in SXP but "
   64.20            "does not create the domain.")
   64.21  
   64.22 +gopts.opt('xmldryrun', short='x',
   64.23 +          fn=set_true, default=0,
   64.24 +          use="XML dry run - prints the resulting configuration in XML but "
   64.25 +          "does not create the domain.")
   64.26 +
   64.27  gopts.opt('paused', short='p',
   64.28            fn=set_true, default=0,
   64.29            use='Leave the domain paused after it is created.')
   64.30 @@ -1241,34 +1247,59 @@ def main(argv):
   64.31          except IOError, exn:
   64.32              raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
   64.33  
   64.34 +    if serverType == SERVER_XEN_API:
   64.35 +        from xen.xm.xenapi_create import sxp2xml
   64.36 +        sxp2xml_inst = sxp2xml()
   64.37 +        doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
   64.38 +
   64.39      if opts.vals.dryrun:
   64.40 -        PrettyPrint.prettyprint(config)
   64.41 +        SXPPrettyPrint.prettyprint(config)
   64.42 +
   64.43 +    if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
   64.44 +        from xml.dom.ext import PrettyPrint as XMLPrettyPrint
   64.45 +        XMLPrettyPrint(doc)
   64.46 +
   64.47 +    if opts.vals.dryrun or opts.vals.xmldryrun:
   64.48 +        return                                               
   64.49 +
   64.50 +    if opts.vals.console_autoconnect:
   64.51 +        do_console(sxp.child_value(config, 'name', -1))
   64.52 +    
   64.53 +    if serverType == SERVER_XEN_API:        
   64.54 +        from xen.xm.xenapi_create import xenapi_create
   64.55 +        xenapi_create_inst = xenapi_create()
   64.56 +        vm_refs = xenapi_create_inst.create(document = doc)
   64.57 +
   64.58 +        map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
   64.59      else:
   64.60          if not create_security_check(config):
   64.61 -            raise security.ACMError('Security Configuration prevents domain from starting')
   64.62 -        else:
   64.63 -            if opts.vals.console_autoconnect:
   64.64 -                cpid = os.fork() 
   64.65 -                if cpid != 0:
   64.66 -                    for i in range(10):
   64.67 -                        # Catch failure of the create process 
   64.68 -                        time.sleep(1)
   64.69 -                        (p, rv) = os.waitpid(cpid, os.WNOHANG)
   64.70 -                        if os.WIFEXITED(rv):
   64.71 -                            if os.WEXITSTATUS(rv) != 0:
   64.72 -                                sys.exit(os.WEXITSTATUS(rv))
   64.73 -                        try:
   64.74 -                            # Acquire the console of the created dom
   64.75 -                            name = sxp.child_value(config, 'name', -1)
   64.76 -                            dom = server.xend.domain(name)
   64.77 -                            domid = int(sxp.child_value(dom, 'domid', '-1'))
   64.78 -                            console.execConsole(domid)
   64.79 -                        except:
   64.80 -                            pass
   64.81 -                    print("Could not start console\n");
   64.82 -                    sys.exit(0)
   64.83 -            dom = make_domain(opts, config)
   64.84 -
   64.85 +            raise security.ACMError(
   64.86 +                'Security Configuration prevents domain from starting')
   64.87 +        dom = make_domain(opts, config)
   64.88 +        
   64.89 +def do_console(domain_name):
   64.90 +    cpid = os.fork() 
   64.91 +    if cpid != 0:
   64.92 +        for i in range(10):
   64.93 +            # Catch failure of the create process 
   64.94 +            time.sleep(1)
   64.95 +            (p, rv) = os.waitpid(cpid, os.WNOHANG)
   64.96 +            if os.WIFEXITED(rv):
   64.97 +                if os.WEXITSTATUS(rv) != 0:
   64.98 +                    sys.exit(os.WEXITSTATUS(rv))
   64.99 +            try:
  64.100 +                # Acquire the console of the created dom
  64.101 +                if serverType == SERVER_XEN_API:
  64.102 +                    domid = server.xenapi.VM.get_domid(
  64.103 +                               get_single_vm(domain_name))
  64.104 +                else:
  64.105 +                    dom = server.xend.domain(domain_name)
  64.106 +                    domid = int(sxp.child_value(dom, 'domid', '-1'))
  64.107 +                console.execConsole(domid)
  64.108 +            except:
  64.109 +                pass
  64.110 +        print("Could not start console\n");
  64.111 +        sys.exit(0)
  64.112  
  64.113  if __name__ == '__main__':
  64.114      main(sys.argv)
    65.1 --- a/tools/python/xen/xm/main.py	Tue Mar 20 10:07:11 2007 -0600
    65.2 +++ b/tools/python/xen/xm/main.py	Tue Mar 20 15:19:38 2007 -0600
    65.3 @@ -33,11 +33,11 @@ import getopt
    65.4  import socket
    65.5  import traceback
    65.6  import xmlrpclib
    65.7 -import traceback
    65.8  import time
    65.9  import datetime
   65.10  from select import select
   65.11  import xml.dom.minidom
   65.12 +from xen.util.blkif import blkdev_name_to_number
   65.13  
   65.14  import warnings
   65.15  warnings.filterwarnings('ignore', category=FutureWarning)
   65.16 @@ -49,18 +49,19 @@ from xen.xend.XendConstants import *
   65.17  
   65.18  from xen.xm.opts import OptionError, Opts, wrap, set_true
   65.19  from xen.xm import console
   65.20 -from xen.util import security
   65.21  from xen.util.xmlrpclib2 import ServerProxy
   65.22  
   65.23  import XenAPI
   65.24  
   65.25 +
   65.26  # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
   65.27  # getopt.getopt if gnu_getopt is not available.  This will mean that options
   65.28  # may only be specified before positional arguments.
   65.29  if not hasattr(getopt, 'gnu_getopt'):
   65.30      getopt.gnu_getopt = getopt.getopt
   65.31  
   65.32 -XM_CONFIG_FILE = '/etc/xen/xm-config.xml'
   65.33 +XM_CONFIG_FILE_ENVVAR = 'XM_CONFIG_FILE'
   65.34 +XM_CONFIG_FILE_DEFAULT = '/etc/xen/xm-config.xml'
   65.35  
   65.36  # Supported types of server
   65.37  SERVER_LEGACY_XMLRPC = 'LegacyXMLRPC'
   65.38 @@ -351,13 +352,14 @@ all_commands = (domain_commands + host_c
   65.39  # Configuration File Parsing
   65.40  ##
   65.41  
   65.42 +xmConfigFile = os.getenv(XM_CONFIG_FILE_ENVVAR, XM_CONFIG_FILE_DEFAULT)
   65.43  config = None
   65.44 -if os.path.isfile(XM_CONFIG_FILE):
   65.45 +if os.path.isfile(xmConfigFile):
   65.46      try:
   65.47 -        config = xml.dom.minidom.parse(XM_CONFIG_FILE)
   65.48 +        config = xml.dom.minidom.parse(xmConfigFile)
   65.49      except:
   65.50          print >>sys.stderr, ('Ignoring invalid configuration file %s.' %
   65.51 -                             XM_CONFIG_FILE)
   65.52 +                             xmConfigFile)
   65.53  
   65.54  def parseServer():
   65.55      if config:
   65.56 @@ -491,6 +493,18 @@ def usage(cmd = None):
   65.57  #
   65.58  ####################################################################
   65.59  
   65.60 +def get_default_SR():
   65.61 +    return [sr_ref
   65.62 +            for sr_ref in server.xenapi.SR.get_all()
   65.63 +            if server.xenapi.SR.get_type(sr_ref) == "local"][0]
   65.64 +
   65.65 +def get_default_Network():
   65.66 +    return [network_ref
   65.67 +            for network_ref in server.xenapi.network.get_all()][0]
   65.68 +
   65.69 +def map2sxp(m):
   65.70 +    return [[k, m[k]] for k in m.keys()]
   65.71 +
   65.72  def arg_check(args, name, lo, hi = -1):
   65.73      n = len([i for i in args if i != '--'])
   65.74      
   65.75 @@ -673,10 +687,41 @@ def xm_restore(args):
   65.76  
   65.77  
   65.78  def getDomains(domain_names, state, full = 0):
   65.79 -    if domain_names:
   65.80 -        return [server.xend.domain(dom, full) for dom in domain_names]
   65.81 +    if serverType == SERVER_XEN_API:
   65.82 +        doms_sxp = []
   65.83 +        doms_dict = []
   65.84 +        dom_refs = server.xenapi.VM.get_all()
   65.85 +        for dom_ref in dom_refs:
   65.86 +            dom_rec = server.xenapi.VM.get_record(dom_ref)
   65.87 +            dom_metrics_ref = server.xenapi.VM.get_metrics(dom_ref)
   65.88 +            dom_metrics = server.xenapi.VM_metrics.get_record(dom_metrics_ref)
   65.89 +            dom_rec.update({'name':     dom_rec['name_label'],
   65.90 +                            'memory_actual': int(dom_metrics['memory_actual'])/1024,
   65.91 +                            'vcpus':    dom_metrics['vcpus_number'],
   65.92 +                            'state':    '-----',
   65.93 +                            'cpu_time': dom_metrics['vcpus_utilisation']})
   65.94 +			
   65.95 +            doms_sxp.append(['domain'] + map2sxp(dom_rec))
   65.96 +            doms_dict.append(dom_rec)
   65.97 +            
   65.98 +        if domain_names:
   65.99 +            doms = [['domain'] + map2sxp(dom) for dom in doms_dict
  65.100 +                    if dom["name"] in domain_names]
  65.101 +            
  65.102 +            if len(doms) > 0:
  65.103 +                return doms
  65.104 +            else:
  65.105 +                print "Error: no domain%s named %s" % \
  65.106 +                      (len(domain_names) > 1 and 's' or '',
  65.107 +                       ', '.join(domain_names))
  65.108 +                sys.exit(-1)
  65.109 +        else:
  65.110 +            return doms_sxp
  65.111      else:
  65.112 -        return server.xend.domains_with_state(True, state, full)
  65.113 +        if domain_names:
  65.114 +            return [server.xend.domain(dom, full) for dom in domain_names]
  65.115 +        else:
  65.116 +            return server.xend.domains_with_state(True, state, full)
  65.117  
  65.118  
  65.119  def xm_list(args):
  65.120 @@ -735,20 +780,39 @@ def parse_doms_info(info):
  65.121      else:
  65.122          up_time = time.time() - start_time
  65.123  
  65.124 -    return {
  65.125 +    parsed_info = {
  65.126          'domid'    : get_info('domid',              str,   ''),
  65.127          'name'     : get_info('name',               str,   '??'),
  65.128 -        'mem'      : get_info('memory_dynamic_min', int,   0),
  65.129          'state'    : get_info('state',              str,   ''),
  65.130 -        'cpu_time' : get_info('cpu_time',           float, 0.0),
  65.131 +
  65.132          # VCPUs is the number online when the VM is up, or the number
  65.133          # configured otherwise.
  65.134          'vcpus'    : get_info('online_vcpus', int,
  65.135                                get_info('vcpus', int, 0)),
  65.136 -        'up_time'  : up_time,
  65.137 -        'seclabel' : security.get_security_printlabel(info),
  65.138 +        'up_time'  : up_time
  65.139          }
  65.140  
  65.141 +    # We're not supporting security stuff just yet via XenAPI
  65.142 +
  65.143 +    if serverType != SERVER_XEN_API:
  65.144 +        from xen.util import security
  65.145 +        parsed_info['seclabel'] = security.get_security_printlabel(info)
  65.146 +    else:
  65.147 +        parsed_info['seclabel'] = ""
  65.148 +
  65.149 +    if serverType == SERVER_XEN_API:
  65.150 +        parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
  65.151 +        cpu_times = get_info('cpu_time', lambda x : (x), 0.0)
  65.152 +        if sum(cpu_times.values()) > 0:
  65.153 +            parsed_info['cpu_time'] = sum(cpu_times.values()) / float(len(cpu_times.values()))
  65.154 +        else:
  65.155 +            parsed_info['cpu_time'] = 0
  65.156 +    else:
  65.157 +        parsed_info['mem'] = get_info('memory', int,0)
  65.158 +        parsed_info['cpu_time'] = get_info('cpu_time', float, 0.0)
  65.159 +
  65.160 +    return parsed_info
  65.161 +
  65.162  def check_sched_type(sched):
  65.163      if serverType == SERVER_XEN_API:
  65.164          current = server.xenapi.host.get_sched_policy(server.xenapi.session.get_this_host())
  65.165 @@ -797,17 +861,22 @@ def xm_label_list(doms):
  65.166      output = []
  65.167      format = '%(name)-32s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
  65.168               '%(cpu_time)8.1f %(seclabel)9s'
  65.169 -    
  65.170 -    for dom in doms:
  65.171 -        d = parse_doms_info(dom)
  65.172 -        if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
  65.173 -            if not d['seclabel']:
  65.174 -                d['seclabel'] = 'ERROR'
  65.175 -        elif security.active_policy in ['DEFAULT']:
  65.176 -            d['seclabel'] = 'DEFAULT'
  65.177 -        else:
  65.178 -            d['seclabel'] = 'INACTIVE'
  65.179 -        output.append((format % d, d['seclabel']))
  65.180 +
  65.181 +    if serverType != SERVER_XEN_API:
  65.182 +        from xen.util import security
  65.183 +        
  65.184 +        for dom in doms:
  65.185 +            d = parse_doms_info(dom)
  65.186 +
  65.187 +            if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
  65.188 +                if not d['seclabel']:
  65.189 +                    d['seclabel'] = 'ERROR'
  65.190 +                elif security.active_policy in ['DEFAULT']:
  65.191 +                    d['seclabel'] = 'DEFAULT'
  65.192 +                else:
  65.193 +                    d['seclabel'] = 'INACTIVE'
  65.194 +
  65.195 +            output.append((format % d, d['seclabel']))
  65.196          
  65.197      #sort by labels
  65.198      output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
  65.199 @@ -816,7 +885,6 @@ def xm_label_list(doms):
  65.200  
  65.201  
  65.202  def xm_vcpu_list(args):
  65.203 -
  65.204      if args:
  65.205          dominfo = map(server.xend.domain.getVCPUInfo, args)
  65.206      else:
  65.207 @@ -1112,7 +1180,7 @@ def xm_mem_set(args):
  65.208      dom = args[0]
  65.209  
  65.210      if serverType == SERVER_XEN_API:
  65.211 -        mem_target = int_unit(args[1], 'k') * 1024
  65.212 +        mem_target = int_unit(args[1], 'm') * 1024 * 1024
  65.213          server.xenapi.VM.set_memory_dynamic_max(get_single_vm(dom), mem_target)
  65.214          server.xenapi.VM.set_memory_dynamic_min(get_single_vm(dom), mem_target)
  65.215      else:
  65.216 @@ -1464,7 +1532,10 @@ def xm_sysrq(args):
  65.217      arg_check(args, "sysrq", 2)
  65.218      dom = args[0]
  65.219      req = args[1]
  65.220 -    server.xend.domain.send_sysrq(dom, req)    
  65.221 +    if serverType == SERVER_XEN_API:
  65.222 +        server.xenapi.VM.send_sysrq(get_single_vm(dom), req)
  65.223 +    else:
  65.224 +        server.xend.domain.send_sysrq(dom, req)
  65.225  
  65.226  def xm_trigger(args):
  65.227      vcpu = 0
  65.228 @@ -1474,12 +1545,23 @@ def xm_trigger(args):
  65.229      trigger = args[1]
  65.230      if len(args) == 3:
  65.231          vcpu = int(args[2])
  65.232 -    
  65.233 -    server.xend.domain.send_trigger(dom, trigger, vcpu)
  65.234 +        
  65.235 +    if serverType == SERVER_XEN_API:
  65.236 +        server.xenapi.VM.send_trigger(get_single_vm(dom), trigger, vcpu)
  65.237 +    else:
  65.238 +        server.xend.domain.send_trigger(dom, trigger, vcpu)
  65.239  
  65.240  def xm_debug_keys(args):
  65.241      arg_check(args, "debug-keys", 1)
  65.242 -    server.xend.node.send_debug_keys(str(args[0]))
  65.243 +
  65.244 +    keys = str(args[0])
  65.245 +    
  65.246 +    if serverType == SERVER_XEN_API:
  65.247 +        server.xenapi.host.send_debug_keys(
  65.248 +            server.xenapi.session.get_this_host(),
  65.249 +            keys)
  65.250 +    else:
  65.251 +        server.xend.node.send_debug_keys(keys)
  65.252  
  65.253  def xm_top(args):
  65.254      arg_check(args, "top", 0)
  65.255 @@ -1605,12 +1687,21 @@ def xm_network_list(args):
  65.256      (use_long, params) = arg_check_for_resource_list(args, "network-list")
  65.257  
  65.258      dom = params[0]
  65.259 +
  65.260 +    if serverType == SERVER_XEN_API:
  65.261 +        vif_refs = server.xenapi.VM.get_VIFs(get_single_vm(dom))
  65.262 +        vif_properties = \
  65.263 +            map(server.xenapi.VIF.get_runtime_properties, vif_refs)
  65.264 +        devs = map(lambda (handle, properties): [handle, map2sxp(properties)],
  65.265 +                   zip(range(len(vif_properties)), vif_properties))
  65.266 +    else:
  65.267 +        devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
  65.268 +        
  65.269      if use_long:
  65.270 -        devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
  65.271          map(PrettyPrint.prettyprint, devs)
  65.272      else:
  65.273          hdr = 0
  65.274 -        for x in server.xend.domain.getDeviceSxprs(dom, 'vif'):
  65.275 +        for x in devs:
  65.276              if hdr == 0:
  65.277                  print 'Idx BE     MAC Addr.     handle state evt-ch tx-/rx-ring-ref BE-path'
  65.278                  hdr = 1
  65.279 @@ -1630,12 +1721,25 @@ def xm_block_list(args):
  65.280      (use_long, params) = arg_check_for_resource_list(args, "block-list")
  65.281  
  65.282      dom = params[0]
  65.283 +
  65.284 +    if serverType == SERVER_XEN_API:
  65.285 +        vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
  65.286 +        vbd_properties = \
  65.287 +            map(server.xenapi.VBD.get_runtime_properties, vbd_refs)
  65.288 +        vbd_devs = \
  65.289 +            map(server.xenapi.VBD.get_device, vbd_refs)
  65.290 +        vbd_devids = \
  65.291 +            map(blkdev_name_to_number, vbd_devs)
  65.292 +        devs = map(lambda (devid, prop): [devid, map2sxp(prop)],
  65.293 +                   zip(vbd_devids, vbd_properties))
  65.294 +    else:
  65.295 +        devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
  65.296 +
  65.297      if use_long:
  65.298 -        devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
  65.299          map(PrettyPrint.prettyprint, devs)
  65.300      else:
  65.301          hdr = 0
  65.302 -        for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
  65.303 +        for x in devs:
  65.304              if hdr == 0:
  65.305                  print 'Vdev  BE handle state evt-ch ring-ref BE-path'
  65.306                  hdr = 1
  65.307 @@ -1690,13 +1794,17 @@ def parse_block_configuration(args):
  65.308      if len(args) == 5:
  65.309          vbd.append(['backend', args[4]])
  65.310  
  65.311 -    # verify that policy permits attaching this resource
  65.312 -    if security.on():
  65.313 -        dominfo = server.xend.domain(dom)
  65.314 -        label = security.get_security_printlabel(dominfo)
  65.315 -    else:
  65.316 -        label = None
  65.317 -    security.res_security_check(args[1], label)
  65.318 +    if serverType != SERVER_XEN_API:
  65.319 +        # verify that policy permits attaching this resource
  65.320 +        from xen.util import security
  65.321 +    
  65.322 +        if security.on():
  65.323 +            dominfo = server.xend.domain(dom)
  65.324 +            label = security.get_security_printlabel(dominfo)
  65.325 +        else:
  65.326 +            label = None
  65.327 +
  65.328 +        security.res_security_check(args[1], label)
  65.329  
  65.330      return (dom, vbd)
  65.331  
  65.332 @@ -1704,8 +1812,45 @@ def parse_block_configuration(args):
  65.333  def xm_block_attach(args):
  65.334      arg_check(args, 'block-attach', 4, 5)
  65.335  
  65.336 -    (dom, vbd) = parse_block_configuration(args)
  65.337 -    server.xend.domain.device_create(dom, vbd)
  65.338 +    if serverType == SERVER_XEN_API:
  65.339 +        dom   = args[0]
  65.340 +        uname = args[1]
  65.341 +        dev   = args[2]
  65.342 +        mode  = args[3]
  65.343 +
  65.344 +        # First create new VDI
  65.345 +        vdi_record = {
  65.346 +            "name_label":       "vdi" + str(uname.__hash__()),   
  65.347 +            "name_description": "",
  65.348 +            "SR":               get_default_SR(),
  65.349 +            "virtual_size":     0,
  65.350 +            "sector_size":      512,
  65.351 +            "type":             "system",
  65.352 +            "sharable":         False,
  65.353 +            "read_only":        mode!="w",
  65.354 +            "other_config":     {"location": uname}
  65.355 +        }
  65.356 +
  65.357 +        vdi_ref = server.xenapi.VDI.create(vdi_record)
  65.358 +
  65.359 +        # Now create new VBD
  65.360 +
  65.361 +        vbd_record = {
  65.362 +            "VM":               get_single_vm(dom),
  65.363 +            "VDI":              vdi_ref,
  65.364 +            "device":           dev,
  65.365 +            "bootable":         True,
  65.366 +            "mode":             mode=="w" and "RW" or "RO",
  65.367 +            "type":             "Disk",
  65.368 +            "qos_algorithm_type": "",
  65.369 +            "qos_algorithm_params": {}
  65.370 +        }
  65.371 +
  65.372 +        server.xenapi.VBD.create(vbd_record)
  65.373 +        
  65.374 +    else:
  65.375 +        (dom, vbd) = parse_block_configuration(args)
  65.376 +        server.xend.domain.device_create(dom, vbd)
  65.377  
  65.378  
  65.379  def xm_block_configure(args):
  65.380 @@ -1723,15 +1868,65 @@ def xm_network_attach(args):
  65.381      vif_params = ['type', 'mac', 'bridge', 'ip', 'script', \
  65.382                    'backend', 'vifname', 'rate', 'model']
  65.383  
  65.384 -    for a in args[1:]:
  65.385 -        vif_param = a.split("=")
  65.386 -        if len(vif_param) != 2 or vif_param[1] == '' or \
  65.387 -           vif_param[0] not in vif_params:
  65.388 -            err("Invalid argument: %s" % a)
  65.389 -            usage('network-attach')
  65.390 -        vif.append(vif_param)
  65.391 +    if serverType == SERVER_XEN_API:     
  65.392 +        vif_record = {
  65.393 +            "device":               "eth0",
  65.394 +            "network":              get_default_Network(),
  65.395 +            "VM":                   get_single_vm(dom),
  65.396 +            "MAC":                  "",
  65.397 +            "MTU":                  "",
  65.398 +            "qos_algorithm_type":   "",
  65.399 +            "qos_algorithm_params": {},
  65.400 +            "other_config":         {}
  65.401 +            }
  65.402  
  65.403 -    server.xend.domain.device_create(dom, vif)
  65.404 +        def set(keys, val):
  65.405 +            record = vif_record
  65.406 +            for key in keys[:-1]:
  65.407 +                record = record[key]
  65.408 +            record[keys[-1]] = val 
  65.409 +         
  65.410 +        vif_conv = {
  65.411 +            'type':
  65.412 +                lambda x: None,
  65.413 +            'mac':
  65.414 +                lambda x: set(['MAC'], x),
  65.415 +            'bridge':
  65.416 +                lambda x: set(['network'], get_net_from_bridge(x)),
  65.417 +            'ip':
  65.418 +                lambda x: set(['other_config', 'ip'], x),
  65.419 +            'script':
  65.420 +                lambda x: set(['other_config', 'script'], x),
  65.421 +            'backend':
  65.422 +                lambda x: set(['other_config', 'backend'], x),
  65.423 +            'vifname':
  65.424 +                lambda x: set(['device'], x),
  65.425 +            'rate':
  65.426 +                lambda x: set(['qos_algorithm_params', 'rate'], x),
  65.427 +            'model':
  65.428 +                lambda x: None
  65.429 +            }
  65.430 +            
  65.431 +        for a in args[1:]:
  65.432 +            vif_param = a.split("=")
  65.433 +            if len(vif_param) != 2 or vif_param[1] == '' or \
  65.434 +                   vif_param[0] not in vif_params:
  65.435 +                err("Invalid argument: %s" % a)
  65.436 +                usage('network-attach')   
  65.437 +            else:
  65.438 +                vif_conv[vif_param[0]](vif_param[1])
  65.439 +
  65.440 +        print str(vif_record)
  65.441 +        server.xenapi.VIF.create(vif_record)
  65.442 +    else:
  65.443 +        for a in args[1:]:
  65.444 +            vif_param = a.split("=")
  65.445 +            if len(vif_param) != 2 or vif_param[1] == '' or \
  65.446 +                   vif_param[0] not in vif_params:
  65.447 +                err("Invalid argument: %s" % a)
  65.448 +                usage('network-attach')
  65.449 +            vif.append(vif_param)
  65.450 +        server.xend.domain.device_create(dom, vif)
  65.451  
  65.452  
  65.453  def detach(args, command, deviceClass):
  65.454 @@ -1751,16 +1946,49 @@ def detach(args, command, deviceClass):
  65.455  
  65.456  
  65.457  def xm_block_detach(args):
  65.458 -    try:
  65.459 -        detach(args, 'block-detach', 'vbd')
  65.460 -        return
  65.461 -    except:
  65.462 -        pass
  65.463 -    detach(args, 'block-detach', 'tap')
  65.464 +    if serverType == SERVER_XEN_API:
  65.465 +        arg_check(args, "xm_block_detach", 2, 3)
  65.466 +        dom = args[0]
  65.467 +        dev = args[1]
  65.468 +        vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
  65.469 +        vbd_refs = [vbd_ref for vbd_ref in vbd_refs
  65.470 +                    if server.xenapi.VBD.get_device(vbd_ref) == dev]
  65.471 +        if len(vbd_refs) > 0:
  65.472 +            vbd_ref = vbd_refs[0]
  65.473 +            vdi_ref = server.xenapi.VBD.get_VDI(vbd_ref)
  65.474 +
  65.475 +            server.xenapi.VBD.destroy(vbd_ref)
  65.476  
  65.477 +            if len(server.xenapi.VDI.get_VBDs(vdi_ref)) <= 0:
  65.478 +                server.xenapi.VDI.destroy(vdi_ref)
  65.479 +        else:
  65.480 +            raise OptionError("Cannot find device '%s' in domain '%s'"
  65.481 +                              % (dev,dom))
  65.482 +    else:
  65.483 +        try:
  65.484 +            detach(args, 'block-detach', 'vbd')
  65.485 +            return
  65.486 +        except:
  65.487 +            pass
  65.488 +        detach(args, 'block-detach', 'tap')
  65.489  
  65.490  def xm_network_detach(args):
  65.491 -    detach(args, 'network-detach', 'vif')
  65.492 +    if serverType == SERVER_XEN_API:
  65.493 +        arg_check(args, "xm_block_detach", 2, 3)
  65.494 +        dom = args[0]
  65.495 +        devid = args[1]
  65.496 +        vif_refs = server.xenapi.VM.get_VIFs(get_single_vm(dom))
  65.497 +        vif_refs = [vif_ref for vif_ref in vif_refs
  65.498 +                    if server.xenapi.VIF.\
  65.499 +                    get_runtime_properties(vif_ref)["handle"] == devid]
  65.500 +        if len(vif_refs) > 0:
  65.501 +            vif_ref = vif_refs[0]
  65.502 +            
  65.503 +            server.xenapi.VIF.destroy(vif_ref)
  65.504 +        else:
  65.505 +            print "Cannot find device '%s' in domain '%s'" % (devid,dom)
  65.506 +    else:
  65.507 +        detach(args, 'network-detach', 'vif')
  65.508  
  65.509  
  65.510  def xm_vnet_list(args):
  65.511 @@ -2001,13 +2229,17 @@ def _run_cmd(cmd, cmd_name, args):
  65.512          err(str(e))
  65.513          _usage(cmd_name)
  65.514          print e.usage
  65.515 -    except security.ACMError, e:
  65.516 -        err(str(e))
  65.517 -    except:
  65.518 -        print "Unexpected error:", sys.exc_info()[0]
  65.519 -        print
  65.520 -        print "Please report to xen-devel@lists.xensource.com"
  65.521 -        raise
  65.522 +    except Exception, e:
  65.523 +        if serverType != SERVER_XEN_API:
  65.524 +           from xen.util import security
  65.525 +           if isinstance(e, security.ACMError):
  65.526 +               err(str(e))
  65.527 +               return False, 1
  65.528 +        else:
  65.529 +            print "Unexpected error:", sys.exc_info()[0]
  65.530 +            print
  65.531 +            print "Please report to xen-devel@lists.xensource.com"
  65.532 +            raise
  65.533  
  65.534      return False, 1
  65.535  
    66.1 --- a/tools/python/xen/xm/new.py	Tue Mar 20 10:07:11 2007 -0600
    66.2 +++ b/tools/python/xen/xm/new.py	Tue Mar 20 15:19:38 2007 -0600
    66.3 @@ -22,6 +22,9 @@ from xen.xend import PrettyPrint
    66.4  from xen.xend import sxp
    66.5  from xen.xend import XendClient
    66.6  
    66.7 +from xen.xm.main import serverType, SERVER_XEN_API
    66.8 +from xen.xm.xenapi_create import *
    66.9 +
   66.10  from opts import *
   66.11  from create import *
   66.12  
   66.13 @@ -65,7 +68,15 @@ def main(argv):
   66.14  
   66.15      if opts.vals.dryrun:
   66.16          PrettyPrint.prettyprint(config)
   66.17 -    else:
   66.18 +        return
   66.19 +    
   66.20 +    if serverType == SERVER_XEN_API:
   66.21 +        sxp2xml_inst = sxp2xml()
   66.22 +        doc = sxp2xml_inst.convert_sxp_to_xml(config) 
   66.23 +        
   66.24 +        xenapi_create_inst = xenapi_create()
   66.25 +        vm_refs = xenapi_create_inst.create(document = doc)
   66.26 +    else:       
   66.27          make_unstarted_domain(opts, config)
   66.28          
   66.29  if __name__ == '__main__':
    67.1 --- a/tools/python/xen/xm/shutdown.py	Tue Mar 20 10:07:11 2007 -0600
    67.2 +++ b/tools/python/xen/xm/shutdown.py	Tue Mar 20 15:19:38 2007 -0600
    67.3 @@ -51,7 +51,7 @@ gopts.opt('reboot', short='R',
    67.4  
    67.5  def wait_reboot(opts, doms, rcs):
    67.6      if serverType == SERVER_XEN_API:
    67.7 -	    opts.err("Cannot wait for reboot w/ XenAPI (yet)")
    67.8 +        opts.err("Cannot wait for reboot w/ XenAPI (yet)")
    67.9  
   67.10      while doms:
   67.11          alive = server.xend.domains(0)
   67.12 @@ -73,7 +73,7 @@ def wait_reboot(opts, doms, rcs):
   67.13  def wait_shutdown(opts, doms):
   67.14      while doms:
   67.15          if serverType == SERVER_XEN_API:
   67.16 -		    alive = [dom for dom in server.xenapi.VM.get_all()
   67.17 +            alive = [dom for dom in server.xenapi.VM.get_all()
   67.18                       if server.xenapi.VM.get_power_state(dom) ==
   67.19                       XEN_API_VM_POWER_STATE[XEN_API_VM_POWER_STATE_RUNNING]]
   67.20          else:
   67.21 @@ -91,16 +91,16 @@ def wait_shutdown(opts, doms):
   67.22  def shutdown(opts, doms, mode, wait):
   67.23      rcs = {}
   67.24      for d in doms:
   67.25 -		if serverType == SERVER_XEN_API:
   67.26 -			if mode == 'halt':
   67.27 -				server.xenapi.VM.clean_shutdown(d)
   67.28 -			if mode == 'reboot':
   67.29 -				server.xenapi.VM.clean_reboot(d)
   67.30 -			if mode == 'poweroff':
   67.31 -				server.xenapi.VM.clean_shutdown(d)				
   67.32 -		else:
   67.33 -			rcs[d] = server.xend.domain.getRestartCount(d)
   67.34 -			server.xend.domain.shutdown(d, mode)
   67.35 +        if serverType == SERVER_XEN_API:
   67.36 +            if mode == 'halt':
   67.37 +                server.xenapi.VM.clean_shutdown(d)
   67.38 +            if mode == 'reboot':
   67.39 +                server.xenapi.VM.clean_reboot(d)
   67.40 +            if mode == 'poweroff':
   67.41 +                server.xenapi.VM.clean_shutdown(d)
   67.42 +        else:
   67.43 +            rcs[d] = server.xend.domain.getRestartCount(d)
   67.44 +            server.xend.domain.shutdown(d, mode)
   67.45  
   67.46      if wait:
   67.47          if mode == 'reboot':
   67.48 @@ -135,7 +135,7 @@ def main_dom(opts, args):
   67.49      if len(args) >  1: opts.err('No multiple domain parameters allowed')
   67.50      dom = args[0]
   67.51      if serverType == SERVER_XEN_API:
   67.52 -		dom = get_single_vm(dom)
   67.53 +        dom = get_single_vm(dom)
   67.54      mode = shutdown_mode(opts)  
   67.55      shutdown(opts, [ dom ], mode, opts.vals.wait)
   67.56      
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/tools/python/xen/xm/xenapi_create.py	Tue Mar 20 15:19:38 2007 -0600
    68.3 @@ -0,0 +1,636 @@
    68.4 +#!/usr/bin/python
    68.5 +#============================================================================
    68.6 +# This library is free software; you can redistribute it and/or
    68.7 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    68.8 +# License as published by the Free Software Foundation.
    68.9 +#
   68.10 +# This library is distributed in the hope that it will be useful,
   68.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   68.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   68.13 +# Lesser General Public License for more details.
   68.14 +#
   68.15 +# You should have received a copy of the GNU Lesser General Public
   68.16 +# License along with this library; if not, write to the Free Software
   68.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   68.18 +#============================================================================
   68.19 +# Copyright (C) 2007 Tom Wilkie <tom.wilkie@gmail.com>
   68.20 +#============================================================================
   68.21 +"""Domain creation using new XenAPI
   68.22 +"""
   68.23 +
   68.24 +from xen.xm.main import server, get_default_SR
   68.25 +from xml.dom.minidom import parse, getDOMImplementation
   68.26 +from xml.dom.ext import PrettyPrint
   68.27 +from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
   68.28 +from xen.xend import sxp
   68.29 +from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
   68.30 +     XEN_API_ON_CRASH_BEHAVIOUR
   68.31 +
   68.32 +
   68.33 +import sys
   68.34 +import os
   68.35 +import traceback
   68.36 +
   68.37 +def log(_, msg):
   68.38 +    #print "> " + msg
   68.39 +    pass
   68.40 +
   68.41 +DEBUG = 0
   68.42 +
   68.43 +def get_name_label(node):
   68.44 +    name_node = node.getElementsByTagName("name")[0]
   68.45 +    label_node = name_node.getElementsByTagName("label")[0]
   68.46 +    return " ".join([child.nodeValue for child in label_node.childNodes])
   68.47 +
   68.48 +def get_name_description(node):
   68.49 +    name_node = node.getElementsByTagName("name")[0]
   68.50 +    description_node = name_node.getElementsByTagName("description")[0]
   68.51 +    return " ".join([child.nodeValue for child in description_node.childNodes])
   68.52 +
   68.53 +def get_text_in_child_node(node, child):
   68.54 +    tag_node = node.getElementsByTagName(child)[0]
   68.55 +    return tag_node.nodeValue
   68.56 +
   68.57 +def get_child_node_attribute(node, child, attribute):
   68.58 +    tag_node = node.getElementsByTagName(child)[0]
   68.59 +    return tag_node.attributes[attribute].value
   68.60 +
   68.61 +def get_child_nodes_as_dict(node, child_name,
   68.62 +                            key_attribute_name,
   68.63 +                            value_attribute_name):
   68.64 +    return dict([(child.attributes[key_attribute_name].value,
   68.65 +                  child.attributes[value_attribute_name].value)
   68.66 +                 for child in node.getElementsByTagName(child_name)])
   68.67 +
   68.68 +def try_quietly(fn, *args):
   68.69 +    try:
   68.70 +        return fn(*args)
   68.71 +    except:
   68.72 +        return None
   68.73 +
   68.74 +class xenapi_create:
   68.75 +
   68.76 +    def __init__(self):
   68.77 +        self.DEFAULT_STORAGE_REPOSITORY = get_default_SR()
   68.78 +
   68.79 +        self.dtd = "/usr/lib/python/xen/xm/create.dtd"
   68.80 +
   68.81 +    def create(self, filename=None, document=None):
   68.82 +        """
   68.83 +        Create a domain from an XML file or DOM tree
   68.84 +        """
   68.85 +        if filename is not None:
   68.86 +            self.check_dtd(file)
   68.87 +            document = parse(file)
   68.88 +        elif document is not None:
   68.89 +            self.check_dom_against_dtd(document)
   68.90 +
   68.91 +        self.check_doc(document)
   68.92 +
   68.93 +        vdis = document.getElementsByTagName("vdi")
   68.94 +        vdi_refs_dict = self.create_vdis(vdis)
   68.95 +        
   68.96 +        try:    
   68.97 +            vms = document.getElementsByTagName("vm")
   68.98 +            return self.create_vms(vms, vdi_refs_dict)
   68.99 +        except Exception, exn:
  68.100 +            try_quietly(self.cleanup_vdis(vdi_refs_dict))
  68.101 +            raise exn
  68.102 +
  68.103 +    # Methods to check xml file
  68.104 +    # try to use dtd to check where possible
  68.105 +    def check_dtd(self, file):
  68.106 +        """
  68.107 +        Check file against DTD.
  68.108 +        Use this if possible as it gives nice
  68.109 +        error messages
  68.110 +        """
  68.111 +        dtd = xmldtd.load_dtd(self.dtd)
  68.112 +        parser = xmlproc.XMLProcessor()
  68.113 +        parser.set_application(xmlval.ValidatingApp(dtd, parser))
  68.114 +        parser.dtd = dtd
  68.115 +        parser.ent = dtd
  68.116 +        parser.parse_resource(file)
  68.117 +
  68.118 +    def check_dom_against_dtd(self, dom):
  68.119 +        """
  68.120 +        Check DOM again DTD.
  68.121 +        Doesn't give as nice error messages.
  68.122 +        (no location info)
  68.123 +        """
  68.124 +        dtd = xmldtd.load_dtd(self.dtd)
  68.125 +        app = xmlval.ValidatingApp(dtd, self)
  68.126 +        app.set_locator(self)
  68.127 +        self.dom2sax(dom, app)
  68.128 +
  68.129 +    # Get errors back from ValidatingApp       
  68.130 +    def report_error(self, number, args=None):
  68.131 +        self.errors = xmlproc.errors.english
  68.132 +        try:
  68.133 +            msg = self.errors[number]
  68.134 +            if args != None:
  68.135 +                msg = msg % args
  68.136 +        except KeyError:
  68.137 +            msg = self.errors[4002] % number # Unknown err msg :-)
  68.138 +        print msg 
  68.139 +        sys.exit(-1)
  68.140 +
  68.141 +    # Here for compatibility with ValidatingApp
  68.142 +    def get_line(self):
  68.143 +        return -1
  68.144 +
  68.145 +    def get_column(self):
  68.146 +        return -1
  68.147 +
  68.148 +    def dom2sax(self, dom, app):
  68.149 +        """
  68.150 +        Take a dom tree and tarverse it,
  68.151 +        issuing SAX calls to app.
  68.152 +        """
  68.153 +        for child in dom.childNodes:
  68.154 +            if child.nodeType == child.TEXT_NODE:
  68.155 +                data = child.nodeValue
  68.156 +                app.handle_data(data, 0, len(data))
  68.157 +            else:
  68.158 +                app.handle_start_tag(
  68.159 +                    child.nodeName,
  68.160 +                    self.attrs_to_dict(child.attributes))
  68.161 +                self.dom2sax(child, app)
  68.162 +                app.handle_end_tag(child.nodeName)
  68.163 +
  68.164 +    def attrs_to_dict(self, attrs):
  68.165 +        return dict(attrs.items())     
  68.166 +
  68.167 +    #
  68.168 +    # Checks which cannot be done with dtd
  68.169 +    #
  68.170 +    def check_doc(self, doc):
  68.171 +        vms = doc.getElementsByTagName("vm")
  68.172 +        self.check_vms(vms)
  68.173 +
  68.174 +    def check_vms(self, vms):
  68.175 +        map(self.check_vm, vms)
  68.176 +
  68.177 +    def check_vm(self, vm):
  68.178 +        vifs = vm.getElementsByTagName("vif")
  68.179 +        self.check_vifs(vifs)
  68.180 +
  68.181 +    def check_vifs(self, vifs):
  68.182 +        map(self.check_vif, vifs)
  68.183 +
  68.184 +    def check_vif(self, vif):
  68.185 +        """
  68.186 +        Check that the vif has
  68.187 +        either a bridge or network
  68.188 +        name but not both
  68.189 +        """
  68.190 +        if "bridge" in vif.attributes.keys() \
  68.191 +               and "network" in vif.attributes.keys():
  68.192 +            raise "You cannot specify both a bridge and\
  68.193 +                   a network name."
  68.194 +
  68.195 +    # Cleanup methods here
  68.196 +    def cleanup_vdis(self, vdi_refs_dict):
  68.197 +        map(self.cleanup_vdi, vdi_refs_dict.values())
  68.198 +
  68.199 +    def cleanup_vdi(self, vdi_ref):
  68.200 +        server.xenapi.VDI.destroy(vdi_ref)
  68.201 +
  68.202 +    def cleanup_vms(self, vm_refs):
  68.203 +        map(self.cleanup_vm, vm_refs)
  68.204 +
  68.205 +    def cleanup_vm(self, vm_ref):
  68.206 +        server.xenapi.VM.destroy(vm_ref)
  68.207 +
  68.208 +    # Create methods here
  68.209 +    def create_vdis(self, vdis):
  68.210 +        log(DEBUG, "create_vdis")
  68.211 +        return dict(map(self.create_vdi, vdis))
  68.212 +
  68.213 +    def create_vdi(self, vdi):
  68.214 +        log(DEBUG, "create_vdi")
  68.215 +
  68.216 +        vdi_record = {
  68.217 +            "name_label":       get_name_label(vdi),
  68.218 +            "name_description": get_name_description(vdi),
  68.219 +            "SR":               self.DEFAULT_STORAGE_REPOSITORY,  
  68.220 +            "virtual_size":     vdi.attributes["size"].value,
  68.221 +            "type":             vdi.attributes["type"].value,
  68.222 +            "shareable":        vdi.attributes["shareable"].value,
  68.223 +            "read_only":        vdi.attributes["read_only"].value,
  68.224 +            "other_config":     {"location":
  68.225 +                vdi.attributes["src"].value}
  68.226 +            }
  68.227 +
  68.228 +        key = vdi.attributes["name"].value
  68.229 +        value = server.xenapi.VDI.create(vdi_record)
  68.230 +        
  68.231 +        return (key, value)
  68.232 +
  68.233 +    def create_vms(self, vms, vdis):
  68.234 +        log(DEBUG, "create_vms")
  68.235 +        return map(lambda vm: self.create_vm(vm, vdis), vms)
  68.236 +
  68.237 +    def create_vm(self, vm, vdis):
  68.238 +        log(DEBUG, "create_vm")
  68.239 +
  68.240 +        vm_record = {
  68.241 +            "name_label":
  68.242 +                get_name_label(vm),
  68.243 +            "name_description":
  68.244 +                get_name_description(vm),
  68.245 +            "user_version":
  68.246 +                get_text_in_child_node(vm, "version"),
  68.247 +            "is_a_template":
  68.248 +                vm.attributes["is_a_template"].value,
  68.249 +            "auto_power_on":
  68.250 +                vm.attributes["auto_power_on"].value,
  68.251 +            "memory_static_max":
  68.252 +                get_child_node_attribute(vm, "memory", "static_max"),
  68.253 +            "memory_static_min":
  68.254 +                get_child_node_attribute(vm, "memory", "static_min"),
  68.255 +            "memory_dynamic_max":
  68.256 +                get_child_node_attribute(vm, "memory", "dynamic_max"),
  68.257 +            "memory_dynamic_min":
  68.258 +                get_child_node_attribute(vm, "memory", "dynamic_min"),
  68.259 +            "vcpus_params":
  68.260 +                get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
  68.261 +            "vcpus_max":
  68.262 +                vm.attributes["vcpus_max"].value,
  68.263 +            "vcpus_at_startup":
  68.264 +                vm.attributes["vcpus_at_startup"].value,
  68.265 +            "actions_after_shutdown":
  68.266 +                vm.attributes["actions_after_shutdown"].value,
  68.267 +            "actions_after_reboot":
  68.268 +                vm.attributes["actions_after_reboot"].value,
  68.269 +            "actions_after_crash":
  68.270 +                vm.attributes["actions_after_crash"].value,
  68.271 +            "platform_std_VGA":
  68.272 +                vm.attributes["platform_std_VGA"].value,
  68.273 +            "platform_serial":
  68.274 +                vm.attributes["platform_serial"].value,
  68.275 +            "platform_localtime":
  68.276 +                vm.attributes["platform_localtime"].value,
  68.277 +            "platform_clock_offet":
  68.278 +                vm.attributes["platform_clock_offet"].value,
  68.279 +            "platform_enable_audio":
  68.280 +                vm.attributes["platform_enable_audio"].value,
  68.281 +            "PCI_bus":
  68.282 +                vm.attributes["platform_enable_audio"].value,
  68.283 +            "other_config":
  68.284 +                get_child_nodes_as_dict(vm, "other_config", "key", "value")
  68.285 +            }
  68.286 +
  68.287 +        if len(vm.getElementsByTagName("pv")) > 0:
  68.288 +            vm_record.update({
  68.289 +                "PV_bootloader":
  68.290 +                    get_child_node_attribute(vm, "pv", "bootloader"),
  68.291 +                "PV_kernel":
  68.292 +                    get_child_node_attribute(vm, "pv", "kernel"),
  68.293 +                "PV_ramdisk":
  68.294 +                    get_child_node_attribute(vm, "pv", "ramdisk"),
  68.295 +                "PV_args":
  68.296 +                    get_child_node_attribute(vm, "pv", "args"),
  68.297 +                "PV_bootloader_args":
  68.298 +                    get_child_node_attribute(vm, "pv", "bootloader_args")
  68.299 +                })
  68.300 +        else:
  68.301 +            hvm = vm.getElementsByTagName("hvm")[0]
  68.302 +            vm_record.update({
  68.303 +                "HVM_boot_policy":
  68.304 +                    get_child_node_attribute(vm, "hvm", "boot_policy"),
  68.305 +                "HVM_boot_params":
  68.306 +                    get_child_nodes_as_dict(hvm, "boot_params", "key", "value")
  68.307 +                })
  68.308 +        try:
  68.309 +            vm_ref = server.xenapi.VM.create(vm_record)
  68.310 +        except:
  68.311 +            traceback.print_exc()
  68.312 +            sys.exit(-1)
  68.313 +
  68.314 +        # Now create vbds
  68.315 +
  68.316 +        vbds = vm.getElementsByTagName("vbd")
  68.317 +
  68.318 +        self.create_vbds(vm_ref, vbds, vdis)
  68.319 +
  68.320 +        # Now create vifs
  68.321 +
  68.322 +        vifs = vm.getElementsByTagName("vif")
  68.323 +
  68.324 +        self.create_vifs(vm_ref, vifs)
  68.325 +
  68.326 +        return vm_ref
  68.327 +        
  68.328 +    def create_vbds(self, vm_ref, vbds, vdis):
  68.329 +        log(DEBUG, "create_vbds")
  68.330 +        return map(lambda vbd: self.create_vbd(vm_ref, vbd, vdis), vbds)
  68.331 +
  68.332 +    def create_vbd(self, vm_ref, vbd, vdis):
  68.333 +        log(DEBUG, "create_vbd")
  68.334 +
  68.335 +        vbd_record = {
  68.336 +            "VM":
  68.337 +                vm_ref,
  68.338 +            "VDI":
  68.339 +                vdis[vbd.attributes["vdi"].value],
  68.340 +            "device":
  68.341 +                vbd.attributes["device"].value,
  68.342 +            "bootable":
  68.343 +                vbd.attributes["bootable"].value,
  68.344 +            "mode":
  68.345 +                vbd.attributes["mode"].value,
  68.346 +            "type":
  68.347 +                vbd.attributes["type"].value,
  68.348 +            "qos_algorithm_type":
  68.349 +                vbd.attributes["qos_algorithm_type"].value,
  68.350 +            "qos_algorithm_params":
  68.351 +                get_child_nodes_as_dict(vbd,
  68.352 +                  "qos_algorithm_param", "key", "value")
  68.353 +            }
  68.354 +
  68.355 +        return server.xenapi.VBD.create(vbd_record)
  68.356 +
  68.357 +    def create_vifs(self, vm_ref, vifs):
  68.358 +        log(DEBUG, "create_vifs")
  68.359 +        return map(lambda vif: self.create_vif(vm_ref, vif), vifs)
  68.360 +
  68.361 +    def create_vif(self, vm_ref, vif):
  68.362 +        log(DEBUG, "create_vif")
  68.363 +
  68.364 +        if "bridge" in vif.attributes.keys():
  68.365 +            raise "Not allowed to add by bridge just yet"
  68.366 +        elif "network" in vif.attributes.keys():
  68.367 +            network = [network_ref
  68.368 +                for network_ref in server.xenapi.network.get_all()
  68.369 +                if server.xenapi.network.get_name_label(network_ref)
  68.370 +                       == vif.attributes["network"].value][0]
  68.371 +        else:
  68.372 +            network = self._get_network_ref()
  68.373 +
  68.374 +        vif_record = {
  68.375 +            "device":
  68.376 +                vif.attributes["device"].value,
  68.377 +            "network":
  68.378 +                network,
  68.379 +            "VM":
  68.380 +                vm_ref,
  68.381 +            "MAC":
  68.382 +                vif.attributes["mac"].value,
  68.383 +            "MTU":
  68.384 +                vif.attributes["mtu"].value,
  68.385 +            "qos_algorithm_type":
  68.386 +                vif.attributes["qos_algorithm_type"].value,
  68.387 +            "qos_algorithm_params":
  68.388 +                get_child_nodes_as_dict(vif,
  68.389 +                    "qos_algorithm_param", "key", "value")
  68.390 +        }
  68.391 +
  68.392 +        return server.xenapi.VIF.create(vif_record)
  68.393 +
  68.394 +    _network_refs = []
  68.395 +
  68.396 +    def _get_network_ref(self):
  68.397 +        try:
  68.398 +            return self._network_refs.pop(0)
  68.399 +        except IndexError:
  68.400 +            self._network_refs = server.xenapi.network.get_all()
  68.401 +            return self._network_refs.pop(0)
  68.402 +
  68.403 +def get_child_by_name(exp, childname, default = None):
  68.404 +    try:
  68.405 +        return [child for child in sxp.children(exp)
  68.406 +                if child[0] == childname][0][1]
  68.407 +    except:
  68.408 +        return default
  68.409 +
  68.410 +# Convert old sxp into new xml
  68.411 +
  68.412 +class sxp2xml:
  68.413 +
  68.414 +    def convert_sxp_to_xml(self, config, transient=False):
  68.415 +       
  68.416 +        devices = [child for child in sxp.children(config)
  68.417 +                   if len(child) > 0 and child[0] == "device"]
  68.418 +                   
  68.419 +        vbds_sxp = map(lambda x: x[1], [device for device in devices
  68.420 +                                        if device[1][0] == "vbd"])
  68.421 +
  68.422 +        vifs_sxp = map(lambda x: x[1], [device for device in devices
  68.423 +                                        if device[1][0] == "vif"])
  68.424 +        # Create XML Document
  68.425 +        
  68.426 +        impl = getDOMImplementation()
  68.427 +
  68.428 +        document = impl.createDocument(None, "xm", None)
  68.429 +
  68.430 +        # Lets make the VM tag..
  68.431 +
  68.432 +        vm = document.createElement("vm")
  68.433 +
  68.434 +        # Some string compatibility
  68.435 +
  68.436 +        actions_after_shutdown \
  68.437 +            = get_child_by_name(config, "on_poweroff", "destroy")
  68.438 +        actions_after_reboot \
  68.439 +            = get_child_by_name(config, "on_reboot", "restart")
  68.440 +        actions_after_crash \
  68.441 +            = get_child_by_name(config, "on_crash", "restart")
  68.442 +
  68.443 +        def conv_chk(val, vals):
  68.444 +            val.replace("-", "_")
  68.445 +            if val not in vals:
  68.446 +                raise "Invalid value: " + val
  68.447 +            else:
  68.448 +                return val
  68.449 +
  68.450 +        actions_after_shutdown = conv_chk(actions_after_shutdown,\
  68.451 +                                          XEN_API_ON_NORMAL_EXIT)
  68.452 +        actions_after_reboot   = conv_chk(actions_after_reboot, \
  68.453 +                                          XEN_API_ON_NORMAL_EXIT)
  68.454 +        actions_after_crash    = conv_chk(actions_after_crash, \
  68.455 +                                          XEN_API_ON_CRASH_BEHAVIOUR)
  68.456 +        # Flesh out tag attributes            
  68.457 +
  68.458 +        vm.attributes["is_a_template"] = "false"
  68.459 +        vm.attributes["auto_power_on"] = "false"
  68.460 +        vm.attributes["actions_after_shutdown"] \
  68.461 +            = actions_after_shutdown              
  68.462 +        vm.attributes["actions_after_reboot"] \
  68.463 +            = actions_after_reboot
  68.464 +        vm.attributes["actions_after_crash"] \
  68.465 +            = actions_after_crash
  68.466 +        vm.attributes["platform_std_VGA"] = "false"
  68.467 +        vm.attributes["platform_serial"] = ""
  68.468 +        vm.attributes["platform_localtime"] = ""
  68.469 +        vm.attributes["platform_clock_offet"] = ""
  68.470 +        vm.attributes["platform_enable_audio"] = ""
  68.471 +        vm.attributes["PCI_bus"] = ""
  68.472 +
  68.473 +        vm.attributes["vcpus_max"] \
  68.474 +            = str(get_child_by_name(config, "vcpus", 1))
  68.475 +        vm.attributes["vcpus_at_startup"] \
  68.476 +            = str(get_child_by_name(config, "vcpus", 1))
  68.477 +
  68.478 +        # Make the name tag
  68.479 +
  68.480 +        vm.appendChild(self.make_name_tag(
  68.481 +            get_child_by_name(config, "name"), document))
  68.482 +
  68.483 +        # Make version tag
  68.484 +
  68.485 +        version = document.createElement("version")
  68.486 +        version.appendChild(document.createTextNode("1.0"))
  68.487 +        vm.appendChild(version)
  68.488 +        
  68.489 +        # Make pv or hvm tag
  68.490 +
  68.491 +        image = get_child_by_name(config, "image")
  68.492 +
  68.493 +        if image[0] == "linux":
  68.494 +            pv = document.createElement("pv")
  68.495 +            pv.attributes["kernel"] \
  68.496 +                = get_child_by_name(image, "kernel", "")
  68.497 +            pv.attributes["bootloader"] = ""
  68.498 +            pv.attributes["ramdisk"] \
  68.499 +                = get_child_by_name(image, "ramdisk", "")
  68.500 +            pv.attributes["args"] \
  68.501 +                = "root=" + get_child_by_name(image, "root", "") \
  68.502 +                + " " + get_child_by_name(image, "args", "")
  68.503 +            pv.attributes["bootloader_args"] = ""
  68.504 +
  68.505 +            vm.appendChild(pv)
  68.506 +        elif image[0] == "hvm":
  68.507 +            hvm = document.createElement("hvm")
  68.508 +            hvm.attributes["boot_policy"] = ""
  68.509 +
  68.510 +            vm.appendChild(hvm)
  68.511 +
  68.512 +        # Make memory tag
  68.513 +
  68.514 +        memory = document.createElement("memory")
  68.515 +
  68.516 +        memory_str = str(int(
  68.517 +            get_child_by_name(config, "memory"))*1024*1024)
  68.518 +
  68.519 +        memory.attributes["static_min"] = str(0)
  68.520 +        memory.attributes["static_max"] = memory_str
  68.521 +        memory.attributes["dynamic_min"] = memory_str
  68.522 +        memory.attributes["dynamic_max"] = memory_str
  68.523 +
  68.524 +        if get_child_by_name(config, "maxmem"):
  68.525 +            memory.attributes["static_max"] = \
  68.526 +               str(int(get_child_by_name(config, "maxmem")*1024*1024))
  68.527 +
  68.528 +        vm.appendChild(memory)
  68.529 +
  68.530 +        # And now the vbds
  68.531 +
  68.532 +        vbds = map(lambda vbd: self.extract_vbd(vbd, document), vbds_sxp)
  68.533 +
  68.534 +        map(vm.appendChild, vbds)
  68.535 +
  68.536 +        # And now the vifs
  68.537 +
  68.538 +        vifs = map(lambda vif: self.extract_vif(vif, document), vifs_sxp)
  68.539 +
  68.540 +        map(vm.appendChild, vifs)
  68.541 +
  68.542 +        # transient?
  68.543 +
  68.544 +        if transient:
  68.545 +            other_config = document.createElement("other_config")
  68.546 +            other_config.attributes["key"] = "transient"
  68.547 +            other_config.attributes["value"] = "True"
  68.548 +            vm.appendChild(other_config)
  68.549 +        
  68.550 +        # Add it to doc_root
  68.551 +
  68.552 +        document.documentElement.appendChild(vm)
  68.553 +        
  68.554 +        # We want to pull out vdis
  68.555 +
  68.556 +        vdis = map(lambda vdb: self.extract_vdi(vdb, document), vbds_sxp)
  68.557 +
  68.558 +        map(document.documentElement.appendChild, vdis)
  68.559 +
  68.560 +        return document
  68.561 +
  68.562 +    def make_name_tag(self, label_text, document):
  68.563 +        name = document.createElement("name")
  68.564 +
  68.565 +        label = document.createElement("label")
  68.566 +        label.appendChild(document.createTextNode(str(label_text)))
  68.567 +        name.appendChild(label)
  68.568 +
  68.569 +        description = document.createElement("description")
  68.570 +        description.appendChild(document.createTextNode(" "))
  68.571 +        name.appendChild(description)
  68.572 +
  68.573 +        return name
  68.574 +
  68.575 +    def extract_vbd(self, vbd_sxp, document):
  68.576 +        src = get_child_by_name(vbd_sxp, "uname")
  68.577 +        name = str(src.__hash__())
  68.578 +
  68.579 +        vbd = document.createElement("vbd")
  68.580 +
  68.581 +        vbd.attributes["name"] = "vdb" + name
  68.582 +        vbd.attributes["vdi"] = "vdi" + name
  68.583 +        vbd.attributes["mode"] \
  68.584 +            = get_child_by_name(vbd_sxp, "mode") != "w" \
  68.585 +              and "RO" or "RW"
  68.586 +        vbd.attributes["device"] \
  68.587 +            = get_child_by_name(vbd_sxp, "dev")
  68.588 +        vbd.attributes["bootable"] = "1"
  68.589 +        vbd.attributes["type"] = "disk"
  68.590 +        vbd.attributes["qos_algorithm_type"] = ""
  68.591 +
  68.592 +        return vbd
  68.593 +
  68.594 +    def extract_vdi(self, vbd_sxp, document):
  68.595 +        src = get_child_by_name(vbd_sxp, "uname")
  68.596 +        name = "vdi" + str(src.__hash__())
  68.597 +        path = src[src.find(":")+1:]
  68.598 +
  68.599 +        vdi = document.createElement("vdi")
  68.600 +
  68.601 +        vdi.attributes["src"] = src
  68.602 +        vdi.attributes["read_only"] \
  68.603 +            = (get_child_by_name(vbd_sxp, "mode") != "w") \
  68.604 +               and "true" or "false"
  68.605 +        vdi.attributes["size"] \
  68.606 +            = str(os.path.getsize(path))
  68.607 +        vdi.attributes["type"] = "system"
  68.608 +        vdi.attributes["shareable"] = "false"
  68.609 +        vdi.attributes["name"] = name
  68.610 +
  68.611 +        vdi.appendChild(self.make_name_tag(name, document))
  68.612 +
  68.613 +        return vdi
  68.614 +
  68.615 +    def extract_vif(self, vif_sxp, document):
  68.616 +
  68.617 +        vif = document.createElement("vif")
  68.618 +
  68.619 +        dev = get_child_by_name(vif_sxp, "vifname", "eth0")
  68.620 +
  68.621 +        vif.attributes["name"] \
  68.622 +            = "vif" + str(dev.__hash__())
  68.623 +        vif.attributes["mac"] \
  68.624 +            = get_child_by_name(vif_sxp, "mac", "")               
  68.625 +        vif.attributes["mtu"] \
  68.626 +            = get_child_by_name(vif_sxp, "mtu", "")  
  68.627 +        vif.attributes["device"] = dev
  68.628 +        vif.attributes["qos_algorithm_type"] = ""
  68.629 +
  68.630 +        if get_child_by_name(vif_sxp, "bridge") is not None:
  68.631 +            vif.attributes["bridge"] \
  68.632 +                = get_child_by_name(vif_sxp, "bridge")
  68.633 +        
  68.634 +        return vif
  68.635 +
  68.636 +
  68.637 +
  68.638 +
  68.639 +
    69.1 --- a/tools/xcutils/Makefile	Tue Mar 20 10:07:11 2007 -0600
    69.2 +++ b/tools/xcutils/Makefile	Tue Mar 20 15:19:38 2007 -0600
    69.3 @@ -13,7 +13,7 @@ include $(XEN_ROOT)/tools/Rules.mk
    69.4  
    69.5  PROGRAMS_INSTALL_DIR = /usr/$(LIBDIR)/xen/bin
    69.6  
    69.7 -INCLUDES += -I $(XEN_LIBXC)
    69.8 +INCLUDES += -I $(XEN_LIBXC) -I $(XEN_XENSTORE)
    69.9  
   69.10  CFLAGS += -Werror -fno-strict-aliasing
   69.11  CFLAGS += $(INCLUDES)
   69.12 @@ -22,9 +22,9 @@ CFLAGS += $(INCLUDES)
   69.13  CFLAGS += -Wp,-MD,.$(@F).d
   69.14  PROG_DEP = .*.d
   69.15  
   69.16 -PROGRAMS		= xc_restore xc_save readnotes
   69.17 +PROGRAMS = xc_restore xc_save readnotes
   69.18  
   69.19 -LDLIBS			= -L$(XEN_LIBXC) -lxenguest -lxenctrl
   69.20 +LDLIBS   = -L$(XEN_LIBXC) -L$(XEN_XENSTORE) -lxenguest -lxenctrl -lxenstore
   69.21  
   69.22  .PHONY: all
   69.23  all: build
    70.1 --- a/tools/xcutils/xc_save.c	Tue Mar 20 10:07:11 2007 -0600
    70.2 +++ b/tools/xcutils/xc_save.c	Tue Mar 20 15:19:38 2007 -0600
    70.3 @@ -12,7 +12,13 @@
    70.4  #include <stdint.h>
    70.5  #include <string.h>
    70.6  #include <stdio.h>
    70.7 +#include <sys/ipc.h>
    70.8 +#include <sys/shm.h>
    70.9 +#include <sys/types.h>
   70.10 +#include <sys/stat.h>
   70.11 +#include <fcntl.h>
   70.12  
   70.13 +#include <xs.h>
   70.14  #include <xenctrl.h>
   70.15  #include <xenguest.h>
   70.16  
   70.17 @@ -31,6 +37,123 @@ static int suspend(int domid)
   70.18              !strncmp(ans, "done\n", 5));
   70.19  }
   70.20  
   70.21 +/* For HVM guests, there are two sources of dirty pages: the Xen shadow
   70.22 + * log-dirty bitmap, which we get with a hypercall, and qemu's version.
   70.23 + * The protocol for getting page-dirtying data from qemu uses a
   70.24 + * double-buffered shared memory interface directly between xc_save and
   70.25 + * qemu-dm. 
   70.26 + *
   70.27 + * xc_save calculates the size of the bitmaps and notifies qemu-dm 
   70.28 + * through the store that it wants to share the bitmaps.  qemu-dm then 
   70.29 + * starts filling in the 'active' buffer. 
   70.30 + *
   70.31 + * To change the buffers over, xc_save writes the other buffer number to
   70.32 + * the store and waits for qemu to acknowledge that it is now writing to
   70.33 + * the new active buffer.  xc_save can then process and clear the old
   70.34 + * active buffer. */
   70.35 +
   70.36 +static char *qemu_active_path;
   70.37 +static char *qemu_next_active_path;
   70.38 +static struct xs_handle *xs;
   70.39 +
   70.40 +/* Get qemu to change buffers. */
   70.41 +static void qemu_flip_buffer(int domid, int next_active)
   70.42 +{
   70.43 +    char digit = '0' + next_active;
   70.44 +    unsigned int len;
   70.45 +    char *active_str, **watch;
   70.46 +    struct timeval tv;
   70.47 +    fd_set fdset;
   70.48 +
   70.49 +    /* Tell qemu that we want it to start writing log-dirty bits to the
   70.50 +     * other buffer */
   70.51 +    if (!xs_write(xs, XBT_NULL, qemu_next_active_path, &digit, 1)) {
   70.52 +        errx(1, "can't write next-active to store path (%s)\n", 
   70.53 +              qemu_next_active_path);
   70.54 +        exit(1);
   70.55 +    }
   70.56 +
   70.57 +    /* Wait a while for qemu to signal that it has switched to the new 
   70.58 +     * active buffer */
   70.59 + read_again: 
   70.60 +    tv.tv_sec = 5;
   70.61 +    tv.tv_usec = 0;
   70.62 +    FD_ZERO(&fdset);
   70.63 +    FD_SET(xs_fileno(xs), &fdset);
   70.64 +    if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) {
   70.65 +        errx(1, "timed out waiting for qemu to switch buffers\n");
   70.66 +        exit(1);
   70.67 +    }
   70.68 +    watch = xs_read_watch(xs, &len);
   70.69 +    free(watch);
   70.70 +    
   70.71 +    active_str = xs_read(xs, XBT_NULL, qemu_active_path, &len);
   70.72 +    if (active_str == NULL || active_str[0] - '0' != next_active) 
   70.73 +        /* Watch fired but value is not yet right */
   70.74 +        goto read_again;
   70.75 +}
   70.76 +
   70.77 +static void * init_qemu_maps(int domid, unsigned int bitmap_size)
   70.78 +{
   70.79 +    key_t key;
   70.80 +    char key_ascii[17] = {0,};
   70.81 +    int shmid = -1;
   70.82 +    void *seg; 
   70.83 +    char *path, *p;
   70.84 +
   70.85 +    /* Make a shared-memory segment */
   70.86 +    while (shmid == -1)
   70.87 +    {
   70.88 +        key = rand(); /* No security, just a sequence of numbers */
   70.89 +        shmid = shmget(key, 2 * bitmap_size, 
   70.90 +                       IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
   70.91 +        if (shmid == -1 && errno != EEXIST)
   70.92 +            errx(1, "can't get shmem to talk to qemu-dm");
   70.93 +    }
   70.94 +
   70.95 +    /* Map it into our address space */
   70.96 +    seg = shmat(shmid, NULL, 0);
   70.97 +    if (seg == (void *) -1) 
   70.98 +        errx(1, "can't map shmem to talk to qemu-dm");
   70.99 +    memset(seg, 0, 2 * bitmap_size);
  70.100 +
  70.101 +    /* Write the size of it into the first 32 bits */
  70.102 +    *(uint32_t *)seg = bitmap_size;
  70.103 +
  70.104 +    /* Tell qemu about it */
  70.105 +    if ((xs = xs_daemon_open()) == NULL)
  70.106 +        errx(1, "Couldn't contact xenstore");
  70.107 +    if (!(path = xs_get_domain_path(xs, domid)))
  70.108 +        errx(1, "can't get domain path in store");
  70.109 +    if (!(path = realloc(path, strlen(path) 
  70.110 +                         + strlen("/logdirty/next-active") + 1))) 
  70.111 +        errx(1, "no memory for constructing xenstore path");
  70.112 +    strcat(path, "/logdirty/");
  70.113 +    p = path + strlen(path);
  70.114 +
  70.115 +    strcpy(p, "key");
  70.116 +    snprintf(key_ascii, 17, "%16.16llx", (unsigned long long) key);
  70.117 +    if (!xs_write(xs, XBT_NULL, path, key_ascii, 16))
  70.118 +        errx(1, "can't write key (%s) to store path (%s)\n", key_ascii, path);
  70.119 +
  70.120 +    /* Watch for qemu's indication of the active buffer, and request it 
  70.121 +     * to start writing to buffer 0 */
  70.122 +    strcpy(p, "active");
  70.123 +    if (!xs_watch(xs, path, "qemu-active-buffer"))
  70.124 +        errx(1, "can't set watch in store (%s)\n", path);
  70.125 +    if (!(qemu_active_path = strdup(path)))
  70.126 +        errx(1, "no memory for copying xenstore path");
  70.127 +
  70.128 +    strcpy(p, "next-active");
  70.129 +    if (!(qemu_next_active_path = strdup(path)))
  70.130 +        errx(1, "no memory for copying xenstore path");
  70.131 +
  70.132 +    qemu_flip_buffer(domid, 0);
  70.133 +
  70.134 +    free(path);
  70.135 +    return seg;
  70.136 +}
  70.137 +
  70.138  
  70.139  int
  70.140  main(int argc, char **argv)
  70.141 @@ -52,9 +175,11 @@ main(int argc, char **argv)
  70.142      flags = atoi(argv[5]);
  70.143  
  70.144      if (flags & XCFLAGS_HVM)
  70.145 -        ret = xc_hvm_save(xc_fd, io_fd, domid, maxit, max_f, flags, &suspend);
  70.146 +        ret = xc_hvm_save(xc_fd, io_fd, domid, maxit, max_f, flags, 
  70.147 +                          &suspend, &init_qemu_maps, &qemu_flip_buffer);
  70.148      else 
  70.149 -        ret = xc_linux_save(xc_fd, io_fd, domid, maxit, max_f, flags, &suspend);
  70.150 +        ret = xc_linux_save(xc_fd, io_fd, domid, maxit, max_f, flags, 
  70.151 +                            &suspend);
  70.152  
  70.153      xc_interface_close(xc_fd);
  70.154  
    71.1 --- a/tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py	Tue Mar 20 10:07:11 2007 -0600
    71.2 +++ b/tools/xm-test/tests/block-create/07_block_attach_baddevice_neg.py	Tue Mar 20 15:19:38 2007 -0600
    71.3 @@ -32,10 +32,10 @@ except ConsoleError, e:
    71.4  
    71.5  status, output = traceCommand("xm block-attach %s phy:NOT-EXIST xvda1 w" % domain.getName())
    71.6  eyecatcher = "Error"
    71.7 -where = output.find(eyecatcher)
    71.8 +where = re.compile(eyecatcher, re.IGNORECASE).search(output)
    71.9  if status == 0:
   71.10      FAIL("xm block-attach returned bad status, expected non 0, status is: %i" % status )
   71.11 -elif where == -1:
   71.12 +elif where is None:
   71.13      FAIL("xm block-attach returned bad output, expected Error, output is: %s" % output )
   71.14  
   71.15  try:
    72.1 --- a/tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py	Tue Mar 20 10:07:11 2007 -0600
    72.2 +++ b/tools/xm-test/tests/block-create/08_block_attach_bad_filedevice_neg.py	Tue Mar 20 15:19:38 2007 -0600
    72.3 @@ -31,10 +31,10 @@ except ConsoleError, e:
    72.4  
    72.5  status, output = traceCommand("xm block-attach %s file:/dev/NOT-EXIST xvda1 w" % domain.getName())
    72.6  eyecatcher = "Error"
    72.7 -where = output.find(eyecatcher)
    72.8 +where = re.compile(eyecatcher, re.IGNORECASE).search(output)
    72.9  if status == 0:
   72.10      FAIL("xm block-attach returned bad status, expected non 0, status is: %i" % status )
   72.11 -elif where == -1:
   72.12 +elif where is None:
   72.13      FAIL("xm block-attach returned bad output, expected Error, output is: %s" % output )
   72.14      
   72.15  try:
    73.1 --- a/tools/xm-test/tests/network-attach/network_utils.py	Tue Mar 20 10:07:11 2007 -0600
    73.2 +++ b/tools/xm-test/tests/network-attach/network_utils.py	Tue Mar 20 15:19:38 2007 -0600
    73.3 @@ -12,6 +12,18 @@ def count_eth(console):
    73.4          FAIL(str(e))
    73.5      return len(run['output'].splitlines())
    73.6  
    73.7 +def get_state(domain_name, number):
    73.8 +    s, o = traceCommand("xm network-list %s | awk '/^%d/ {print $5}'" %
    73.9 +                        (domain_name, number))
   73.10 +    print o
   73.11 +    
   73.12 +    if s != 0:
   73.13 +        FAIL("network-list failed")
   73.14 +    if o == "":
   73.15 +        return 0
   73.16 +    else:
   73.17 +        return int(o)
   73.18 +
   73.19  def network_attach(domain_name, console):
   73.20      eths_before = count_eth(console)
   73.21      status, output = traceCommand("xm network-attach %s" % domain_name)
   73.22 @@ -30,6 +42,13 @@ def network_detach(domain_name, console,
   73.23      if status != 0:
   73.24          return -1, "xm network-detach returned invalid %i != 0" % status
   73.25  
   73.26 +    for i in range(10):
   73.27 +        if get_state(domain_name, num) == 0:
   73.28 +            break
   73.29 +        time.sleep(1)
   73.30 +    else:
   73.31 +        FAIL("network-detach failed: device did not disappear")
   73.32 +
   73.33      eths_after = count_eth(console)
   73.34      if eths_after != (eths_before-1):
   73.35      	return -2, "Network device was not actually disconnected from domU"
    74.1 --- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c	Tue Mar 20 10:07:11 2007 -0600
    74.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c	Tue Mar 20 15:19:38 2007 -0600
    74.3 @@ -167,7 +167,8 @@ EXPORT_SYMBOL(notify_remote_via_irq);
    74.4  irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    74.5  {
    74.6  	unsigned int l1i, port;
    74.7 -	int cpu = smp_processor_id();
    74.8 +	/* XXX: All events are bound to vcpu0 but irq may be redirected. */
    74.9 +	int cpu = 0; /*smp_processor_id();*/
   74.10  	irqreturn_t(*handler) (int, void *, struct pt_regs *);
   74.11  	shared_info_t *s = shared_info_area;
   74.12  	vcpu_info_t *v = &s->vcpu_info[cpu];
    75.1 --- a/xen/arch/x86/Rules.mk	Tue Mar 20 10:07:11 2007 -0600
    75.2 +++ b/xen/arch/x86/Rules.mk	Tue Mar 20 15:19:38 2007 -0600
    75.3 @@ -58,19 +58,7 @@ HDRS += $(wildcard $(BASEDIR)/include/as
    75.4  HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/svm/*.h)
    75.5  HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/vmx/*.h)
    75.6  
    75.7 -# Test for at least GCC v3.2.x.
    75.8 -gcc-ver = $(shell $(CC) -dumpversion | sed -e 's/^\(.\)\.\(.\)\.\(.\)/\$(1)/')
    75.9 -ifeq ($(call gcc-ver,1),1)
   75.10 -$(error gcc-1.x.x unsupported - upgrade to at least gcc-3.2.x)
   75.11 -endif
   75.12 -ifeq ($(call gcc-ver,1),2)
   75.13 -$(error gcc-2.x.x unsupported - upgrade to at least gcc-3.2.x)
   75.14 +# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
   75.15 +ifneq ($(call cc-ver,$(CC),0x030400),y)
   75.16 +$(error Xen requires at least gcc-3.4)
   75.17  endif
   75.18 -ifeq ($(call gcc-ver,1),3)
   75.19 -ifeq ($(call gcc-ver,2),0)
   75.20 -$(error gcc-3.0.x unsupported - upgrade to at least gcc-3.2.x)
   75.21 -endif
   75.22 -ifeq ($(call gcc-ver,2),1)
   75.23 -$(error gcc-3.1.x unsupported - upgrade to at least gcc-3.2.x)
   75.24 -endif
   75.25 -endif
    76.1 --- a/xen/arch/x86/hvm/hpet.c	Tue Mar 20 10:07:11 2007 -0600
    76.2 +++ b/xen/arch/x86/hvm/hpet.c	Tue Mar 20 15:19:38 2007 -0600
    76.3 @@ -29,6 +29,10 @@
    76.4  #define S_TO_NS  1000000000ULL           /* 1s  = 10^9  ns */
    76.5  #define S_TO_FS  1000000000000000ULL     /* 1s  = 10^15 fs */
    76.6  
    76.7 +/* Frequency_of_TSC / frequency_of_HPET = 32 */
    76.8 +#define TSC_PER_HPET_TICK 32
    76.9 +#define guest_time_hpet(v) (hvm_get_guest_time(v) / TSC_PER_HPET_TICK)
   76.10 +
   76.11  #define HPET_ID         0x000
   76.12  #define HPET_PERIOD     0x004
   76.13  #define HPET_CFG        0x010
   76.14 @@ -67,7 +71,9 @@
   76.15  #define HPET_TN_INT_ROUTE_CAP_MASK (0xffffffffULL \
   76.16                      << HPET_TN_INT_ROUTE_CAP_SHIFT)
   76.17  
   76.18 -#define hpet_tick_to_ns(h, tick) ((s_time_t)(tick)*S_TO_NS/h->tsc_freq)
   76.19 +#define hpet_tick_to_ns(h, tick) ((s_time_t)(tick)* \
   76.20 +                                  (S_TO_NS*TSC_PER_HPET_TICK)/h->tsc_freq)
   76.21 +
   76.22  #define timer_config(h, n)       (h->hpet.timers[n].config)
   76.23  #define timer_enabled(h, n)      (timer_config(h, n) & HPET_TN_ENABLE)
   76.24  #define timer_is_periodic(h, n)  (timer_config(h, n) & HPET_TN_PERIODIC)
   76.25 @@ -108,7 +114,7 @@ static inline int hpet_check_access_leng
   76.26  static inline uint64_t hpet_read_maincounter(HPETState *h)
   76.27  {
   76.28      if ( hpet_enabled(h) )
   76.29 -        return hvm_get_guest_time(h->vcpu) + h->mc_offset;
   76.30 +        return guest_time_hpet(h->vcpu) + h->mc_offset;
   76.31      else 
   76.32          return h->hpet.mc64;
   76.33  }
   76.34 @@ -144,7 +150,7 @@ static void hpet_stop_timer(HPETState *h
   76.35  
   76.36  /* the number of HPET tick that stands for
   76.37   * 1/(2^10) second, namely, 0.9765625 milliseconds */
   76.38 -#define  HPET_TINY_TIME_SPAN  (h->tsc_freq >> 10)
   76.39 +#define  HPET_TINY_TIME_SPAN  ((h->tsc_freq >> 10) / TSC_PER_HPET_TICK)
   76.40  
   76.41  static void hpet_set_timer(HPETState *h, unsigned int tn)
   76.42  {
   76.43 @@ -225,14 +231,14 @@ static void hpet_write(
   76.44          if ( !(old_val & HPET_CFG_ENABLE) && (new_val & HPET_CFG_ENABLE) )
   76.45          {
   76.46              /* Enable main counter and interrupt generation. */
   76.47 -            h->mc_offset = h->hpet.mc64 - hvm_get_guest_time(h->vcpu);
   76.48 +            h->mc_offset = h->hpet.mc64 - guest_time_hpet(h->vcpu);
   76.49              for ( i = 0; i < HPET_TIMER_NUM; i++ )
   76.50                  hpet_set_timer(h, i); 
   76.51          }
   76.52          else if ( (old_val & HPET_CFG_ENABLE) && !(new_val & HPET_CFG_ENABLE) )
   76.53          {
   76.54              /* Halt main counter and disable interrupt generation. */
   76.55 -            h->hpet.mc64 = h->mc_offset + hvm_get_guest_time(h->vcpu);
   76.56 +            h->hpet.mc64 = h->mc_offset + guest_time_hpet(h->vcpu);
   76.57              for ( i = 0; i < HPET_TIMER_NUM; i++ )
   76.58                  hpet_stop_timer(h, i);
   76.59          }
   76.60 @@ -384,7 +390,7 @@ static int hpet_save(struct domain *d, h
   76.61      HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
   76.62  
   76.63      /* Write the proper value into the main counter */
   76.64 -    hp->hpet.mc64 = hp->mc_offset + hvm_get_guest_time(hp->vcpu);
   76.65 +    hp->hpet.mc64 = hp->mc_offset + guest_time_hpet(hp->vcpu);
   76.66  
   76.67      /* Save the HPET registers */
   76.68      return hvm_save_entry(HPET, 0, h, &hp->hpet);
   76.69 @@ -400,7 +406,7 @@ static int hpet_load(struct domain *d, h
   76.70          return -EINVAL;
   76.71      
   76.72      /* Recalculate the offset between the main counter and guest time */
   76.73 -    hp->mc_offset = hp->hpet.mc64 - hvm_get_guest_time(hp->vcpu);
   76.74 +    hp->mc_offset = hp->hpet.mc64 - guest_time_hpet(hp->vcpu);
   76.75                  
   76.76      /* Restart the timers */
   76.77      for ( i = 0; i < HPET_TIMER_NUM; i++ )
   76.78 @@ -425,8 +431,8 @@ void hpet_init(struct vcpu *v)
   76.79      h->hpet.capability = 0x8086A201ULL;
   76.80  
   76.81      /* This is the number of femptoseconds per HPET tick. */
   76.82 -    /* Here we define HPET's frequency to be the same as the TSC's. */
   76.83 -    h->hpet.capability |= ((S_TO_FS/h->tsc_freq) << 32);
   76.84 +    /* Here we define HPET's frequency to be 1/32 of the TSC's */
   76.85 +    h->hpet.capability |= ((S_TO_FS*TSC_PER_HPET_TICK/h->tsc_freq) << 32);
   76.86  
   76.87      for ( i = 0; i < HPET_TIMER_NUM; i++ )
   76.88      {
    77.1 --- a/xen/arch/x86/hvm/platform.c	Tue Mar 20 10:07:11 2007 -0600
    77.2 +++ b/xen/arch/x86/hvm/platform.c	Tue Mar 20 15:19:38 2007 -0600
    77.3 @@ -415,6 +415,17 @@ static int mmio_decode(int address_bytes
    77.4          GET_OP_SIZE_FOR_NONEBYTE(*op_size);
    77.5          return mem_reg(*op_size, opcode, mmio_op, rex);
    77.6  
    77.7 +    case 0x08: /* or r8, m8 */	
    77.8 +        mmio_op->instr = INSTR_OR;
    77.9 +        *op_size = BYTE;
   77.10 +        GET_OP_SIZE_FOR_BYTE(size_reg);
   77.11 +        return reg_mem(size_reg, opcode, mmio_op, rex);
   77.12 +
   77.13 +    case 0x09: /* or r32/16, m32/16 */
   77.14 +        mmio_op->instr = INSTR_OR;
   77.15 +        GET_OP_SIZE_FOR_NONEBYTE(*op_size);
   77.16 +        return reg_mem(*op_size, opcode, mmio_op, rex);
   77.17 +
   77.18      case 0x0A: /* or m8, r8 */
   77.19          mmio_op->instr = INSTR_OR;
   77.20          *op_size = BYTE;
    78.1 --- a/xen/arch/x86/hvm/svm/svm.c	Tue Mar 20 10:07:11 2007 -0600
    78.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Tue Mar 20 15:19:38 2007 -0600
    78.3 @@ -449,6 +449,9 @@ int svm_vmcb_restore(struct vcpu *v, str
    78.4      vmcb->rflags = c->eflags;
    78.5  
    78.6      v->arch.hvm_svm.cpu_shadow_cr0 = c->cr0;
    78.7 +    vmcb->cr0 = c->cr0 | X86_CR0_WP | X86_CR0_ET;
    78.8 +    if ( !paging_mode_hap(v->domain) ) 
    78.9 +        vmcb->cr0 |= X86_CR0_PG;
   78.10  
   78.11  #ifdef HVM_DEBUG_SUSPEND
   78.12      printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
   78.13 @@ -482,7 +485,6 @@ int svm_vmcb_restore(struct vcpu *v, str
   78.14           * first.
   78.15           */
   78.16          HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %"PRIx64"", c->cr3);
   78.17 -        /* current!=vcpu as not called by arch_vmx_do_launch */
   78.18          mfn = gmfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT);
   78.19          if( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) ) 
   78.20              goto bad_cr3;
   78.21 @@ -566,7 +568,7 @@ void svm_save_cpu_state(struct vcpu *v, 
   78.22      data->msr_star         = vmcb->star;
   78.23      data->msr_cstar        = vmcb->cstar;
   78.24      data->msr_syscall_mask = vmcb->sfmask;
   78.25 -    data->msr_efer         = vmcb->efer;
   78.26 +    data->msr_efer         = v->arch.hvm_svm.cpu_shadow_efer;
   78.27  
   78.28      data->tsc = hvm_get_guest_time(v);
   78.29  }
   78.30 @@ -581,7 +583,12 @@ void svm_load_cpu_state(struct vcpu *v, 
   78.31      vmcb->star       = data->msr_star;
   78.32      vmcb->cstar      = data->msr_cstar;
   78.33      vmcb->sfmask     = data->msr_syscall_mask;
   78.34 -    vmcb->efer       = data->msr_efer;
   78.35 +    v->arch.hvm_svm.cpu_shadow_efer = data->msr_efer;
   78.36 +    vmcb->efer       = data->msr_efer | EFER_SVME;
   78.37 +    /* VMCB's EFER.LME isn't set unless we're actually in long mode
   78.38 +     * (see long_mode_do_msr_write()) */
   78.39 +    if ( !(vmcb->efer & EFER_LMA) )
   78.40 +        vmcb->efer &= ~EFER_LME;
   78.41  
   78.42      hvm_set_guest_time(v, data->tsc);
   78.43  }
   78.44 @@ -741,6 +748,14 @@ static void svm_set_tsc_offset(struct vc
   78.45  static void svm_init_ap_context(
   78.46      struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
   78.47  {
   78.48 +    struct vcpu *v;
   78.49 +    cpu_user_regs_t *regs;
   78.50 +    u16 cs_sel;
   78.51 +
   78.52 +    /* We know this is safe because hvm_bringup_ap() does it */
   78.53 +    v = current->domain->vcpu[vcpuid];
   78.54 +    regs = &v->arch.guest_context.user_regs;
   78.55 +
   78.56      memset(ctxt, 0, sizeof(*ctxt));
   78.57  
   78.58      /*
   78.59 @@ -748,8 +763,19 @@ static void svm_init_ap_context(
   78.60       * passed to us is page alligned and is the physicall frame number for
   78.61       * the code. We will execute this code in real mode. 
   78.62       */
   78.63 +    cs_sel = trampoline_vector << 8;
   78.64      ctxt->user_regs.eip = 0x0;
   78.65 -    ctxt->user_regs.cs = (trampoline_vector << 8);
   78.66 +    ctxt->user_regs.cs = cs_sel;
   78.67 +
   78.68 +    /*
   78.69 +     * This is the launch of an AP; set state so that we begin executing
   78.70 +     * the trampoline code in real-mode.
   78.71 +     */
   78.72 +    svm_do_vmmcall_reset_to_realmode(v, regs);  
   78.73 +    /* Adjust the vmcb's hidden register state. */
   78.74 +    v->arch.hvm_svm.vmcb->rip = 0;
   78.75 +    v->arch.hvm_svm.vmcb->cs.sel = cs_sel;
   78.76 +    v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
   78.77  }
   78.78  
   78.79  static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
   78.80 @@ -894,32 +920,6 @@ static void svm_load_cpu_guest_regs(
   78.81      svm_load_cpu_user_regs(v, regs);
   78.82  }
   78.83  
   78.84 -static void arch_svm_do_launch(struct vcpu *v) 
   78.85 -{
   78.86 -    svm_do_launch(v);
   78.87 -
   78.88 -    if ( paging_mode_hap(v->domain) ) {
   78.89 -        v->arch.hvm_svm.vmcb->h_cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
   78.90 -    }
   78.91 -
   78.92 -    if ( v->vcpu_id != 0 )
   78.93 -    {
   78.94 -        cpu_user_regs_t *regs = &current->arch.guest_context.user_regs;
   78.95 -        u16 cs_sel = regs->cs;
   78.96 -        /*
   78.97 -         * This is the launch of an AP; set state so that we begin executing
   78.98 -         * the trampoline code in real-mode.
   78.99 -         */
  78.100 -        svm_do_vmmcall_reset_to_realmode(v, regs);  
  78.101 -        /* Adjust the state to execute the trampoline code.*/
  78.102 -        v->arch.hvm_svm.vmcb->rip = 0;
  78.103 -        v->arch.hvm_svm.vmcb->cs.sel= cs_sel;
  78.104 -        v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
  78.105 -    }
  78.106 -      
  78.107 -    reset_stack_and_jump(svm_asm_do_launch);
  78.108 -}
  78.109 -
  78.110  static void svm_ctxt_switch_from(struct vcpu *v)
  78.111  {
  78.112      svm_save_dr(v);
  78.113 @@ -941,16 +941,30 @@ static void svm_ctxt_switch_to(struct vc
  78.114      svm_restore_dr(v);
  78.115  }
  78.116  
  78.117 +static void arch_svm_do_resume(struct vcpu *v) 
  78.118 +{
  78.119 +    if ( v->arch.hvm_svm.launch_core != smp_processor_id() )
  78.120 +    {
  78.121 +        v->arch.hvm_svm.launch_core = smp_processor_id();
  78.122 +        hvm_migrate_timers(v);
  78.123 +    }
  78.124 +
  78.125 +    hvm_do_resume(v);
  78.126 +    reset_stack_and_jump(svm_asm_do_resume);
  78.127 +}
  78.128 +
  78.129  static int svm_vcpu_initialise(struct vcpu *v)
  78.130  {
  78.131      int rc;
  78.132  
  78.133 -    v->arch.schedule_tail    = arch_svm_do_launch;
  78.134 +    v->arch.schedule_tail    = arch_svm_do_resume;
  78.135      v->arch.ctxt_switch_from = svm_ctxt_switch_from;
  78.136      v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
  78.137  
  78.138      v->arch.hvm_svm.saved_irq_vector = -1;
  78.139  
  78.140 +    v->arch.hvm_svm.launch_core = -1;
  78.141 +
  78.142      if ( (rc = svm_create_vmcb(v)) != 0 )
  78.143      {
  78.144          dprintk(XENLOG_WARNING,
  78.145 @@ -1014,10 +1028,12 @@ void svm_npt_detect(void)
  78.146  
  78.147      /* check CPUID for nested paging support */
  78.148      cpuid(0x8000000A, &eax, &ebx, &ecx, &edx);
  78.149 -    if ( edx & 0x01 ) { /* nested paging */
  78.150 +    if ( edx & 0x01 ) /* nested paging */
  78.151 +    {
  78.152          hap_capable_system = 1;
  78.153      }
  78.154 -    else if ( opt_hap_enabled ) {
  78.155 +    else if ( opt_hap_enabled )
  78.156 +    {
  78.157          printk(" nested paging is not supported by this CPU.\n");
  78.158          hap_capable_system = 0; /* no nested paging, we disable flag. */
  78.159      }
  78.160 @@ -1075,24 +1091,6 @@ int start_svm(void)
  78.161      return 1;
  78.162  }
  78.163  
  78.164 -void arch_svm_do_resume(struct vcpu *v) 
  78.165 -{
  78.166 -    /* pinning VCPU to a different core? */
  78.167 -    if ( v->arch.hvm_svm.launch_core == smp_processor_id()) {
  78.168 -        hvm_do_resume( v );
  78.169 -        reset_stack_and_jump( svm_asm_do_resume );
  78.170 -    }
  78.171 -    else {
  78.172 -        if (svm_dbg_on)
  78.173 -            printk("VCPU core pinned: %d to %d\n", 
  78.174 -                   v->arch.hvm_svm.launch_core, smp_processor_id() );
  78.175 -        v->arch.hvm_svm.launch_core = smp_processor_id();
  78.176 -        hvm_migrate_timers( v );
  78.177 -        hvm_do_resume( v );
  78.178 -        reset_stack_and_jump( svm_asm_do_resume );
  78.179 -    }
  78.180 -}
  78.181 -
  78.182  static int svm_do_nested_pgfault(paddr_t gpa, struct cpu_user_regs *regs)
  78.183  {
  78.184      if (mmio_space(gpa)) {
    79.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Tue Mar 20 10:07:11 2007 -0600
    79.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Tue Mar 20 15:19:38 2007 -0600
    79.3 @@ -196,11 +196,13 @@ static int construct_vmcb(struct vcpu *v
    79.4  
    79.5      arch_svm->vmcb->exception_intercepts = MONITOR_DEFAULT_EXCEPTION_BITMAP;
    79.6  
    79.7 -    if ( paging_mode_hap(v->domain) ) {
    79.8 +    if ( paging_mode_hap(v->domain) )
    79.9 +    {
   79.10          vmcb->cr0 = arch_svm->cpu_shadow_cr0;
   79.11          vmcb->np_enable = 1; /* enable nested paging */
   79.12          vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */
   79.13          vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_PG;
   79.14 +        vmcb->h_cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
   79.15      }
   79.16  
   79.17      return 0;
   79.18 @@ -247,16 +249,6 @@ void svm_destroy_vmcb(struct vcpu *v)
   79.19      arch_svm->vmcb = NULL;
   79.20  }
   79.21  
   79.22 -void svm_do_launch(struct vcpu *v)
   79.23 -{
   79.24 -    hvm_stts(v);
   79.25 -
   79.26 -    /* current core is the one we intend to perform the VMRUN on */
   79.27 -    v->arch.hvm_svm.launch_core = smp_processor_id();
   79.28 -
   79.29 -    v->arch.schedule_tail = arch_svm_do_resume;
   79.30 -}
   79.31 -
   79.32  static void svm_dump_sel(char *name, svm_segment_register_t *s)
   79.33  {
   79.34      printk("%s: sel=0x%04x, attr=0x%04x, limit=0x%08x, base=0x%016llx\n", 
    80.1 --- a/xen/arch/x86/hvm/svm/x86_32/exits.S	Tue Mar 20 10:07:11 2007 -0600
    80.2 +++ b/xen/arch/x86/hvm/svm/x86_32/exits.S	Tue Mar 20 15:19:38 2007 -0600
    80.3 @@ -80,15 +80,24 @@
    80.4          popl %eax;  \
    80.5          addl $(NR_SKIPPED_REGS*4), %esp
    80.6  
    80.7 -        ALIGN
    80.8 -
    80.9  #define VMRUN  .byte 0x0F,0x01,0xD8
   80.10  #define VMLOAD .byte 0x0F,0x01,0xDA
   80.11  #define VMSAVE .byte 0x0F,0x01,0xDB
   80.12  #define STGI   .byte 0x0F,0x01,0xDC
   80.13  #define CLGI   .byte 0x0F,0x01,0xDD
   80.14  
   80.15 -ENTRY(svm_asm_do_launch)
   80.16 +ENTRY(svm_asm_do_resume)
   80.17 +        GET_CURRENT(%ebx)
   80.18 +        xorl %ecx,%ecx
   80.19 +        notl %ecx
   80.20 +        cli                             # tests must not race interrupts
   80.21 +        movl VCPU_processor(%ebx),%eax
   80.22 +        shl  $IRQSTAT_shift,%eax
   80.23 +        test %ecx,irq_stat(%eax,1)
   80.24 +        jnz  svm_process_softirqs
   80.25 +        call svm_intr_assist
   80.26 +        call svm_load_cr2
   80.27 +
   80.28          CLGI                
   80.29          sti
   80.30          GET_CURRENT(%ebx)
   80.31 @@ -135,30 +144,7 @@ svm_stgi_label:
   80.32          jmp  svm_asm_do_resume
   80.33  
   80.34          ALIGN
   80.35 -
   80.36 -ENTRY(svm_asm_do_resume)
   80.37 -svm_test_all_events:
   80.38 -        GET_CURRENT(%ebx)
   80.39 -/*test_all_events:*/
   80.40 -        xorl %ecx,%ecx
   80.41 -        notl %ecx
   80.42 -        cli                             # tests must not race interrupts
   80.43 -/*test_softirqs:*/  
   80.44 -        movl VCPU_processor(%ebx),%eax
   80.45 -        shl  $IRQSTAT_shift,%eax
   80.46 -        test %ecx,irq_stat(%eax,1)
   80.47 -        jnz  svm_process_softirqs
   80.48 -svm_restore_all_guest:
   80.49 -        call svm_intr_assist
   80.50 -        call svm_load_cr2
   80.51 -        /* 
   80.52 -         * Check if we are going back to AMD-V based VM
   80.53 -         * By this time, all the setups in the VMCB must be complete.
   80.54 -         */
   80.55 -        jmp svm_asm_do_launch
   80.56 -
   80.57 -        ALIGN
   80.58  svm_process_softirqs:
   80.59          sti       
   80.60          call do_softirq
   80.61 -        jmp  svm_test_all_events
   80.62 +        jmp  svm_asm_do_resume
    81.1 --- a/xen/arch/x86/hvm/svm/x86_64/exits.S	Tue Mar 20 10:07:11 2007 -0600
    81.2 +++ b/xen/arch/x86/hvm/svm/x86_64/exits.S	Tue Mar 20 15:19:38 2007 -0600
    81.3 @@ -98,7 +98,17 @@
    81.4  #define STGI   .byte 0x0F,0x01,0xDC
    81.5  #define CLGI   .byte 0x0F,0x01,0xDD
    81.6  
    81.7 -ENTRY(svm_asm_do_launch)
    81.8 +ENTRY(svm_asm_do_resume)
    81.9 +        GET_CURRENT(%rbx)
   81.10 +        cli                             # tests must not race interrupts
   81.11 +        movl VCPU_processor(%rbx),%eax
   81.12 +        shl  $IRQSTAT_shift, %rax
   81.13 +        leaq irq_stat(%rip), %rdx
   81.14 +        testl $~0, (%rdx, %rax, 1)
   81.15 +        jnz  svm_process_softirqs
   81.16 +        call svm_intr_assist
   81.17 +        call svm_load_cr2
   81.18 +
   81.19          CLGI                
   81.20          sti
   81.21          GET_CURRENT(%rbx)
   81.22 @@ -150,28 +160,8 @@ svm_stgi_label:
   81.23          call svm_vmexit_handler
   81.24          jmp  svm_asm_do_resume
   81.25  
   81.26 -ENTRY(svm_asm_do_resume)
   81.27 -svm_test_all_events:
   81.28 -        GET_CURRENT(%rbx)
   81.29 -/*test_all_events:*/
   81.30 -        cli                             # tests must not race interrupts
   81.31 -/*test_softirqs:*/
   81.32 -        movl  VCPU_processor(%rbx),%eax
   81.33 -        shl   $IRQSTAT_shift, %rax
   81.34 -        leaq  irq_stat(%rip), %rdx
   81.35 -        testl $~0, (%rdx, %rax, 1)
   81.36 -        jnz   svm_process_softirqs
   81.37 -svm_restore_all_guest:
   81.38 -        call svm_intr_assist
   81.39 -        call svm_load_cr2
   81.40 -        /*
   81.41 -         * Check if we are going back to AMD-V based VM
   81.42 -         * By this time, all the setups in the VMCB must be complete.
   81.43 -         */
   81.44 -        jmp svm_asm_do_launch
   81.45 -
   81.46          ALIGN
   81.47  svm_process_softirqs:
   81.48          sti
   81.49          call do_softirq
   81.50 -        jmp  svm_test_all_events
   81.51 +        jmp  svm_asm_do_resume
    82.1 --- a/xen/arch/x86/hvm/vpic.c	Tue Mar 20 10:07:11 2007 -0600
    82.2 +++ b/xen/arch/x86/hvm/vpic.c	Tue Mar 20 15:19:38 2007 -0600
    82.3 @@ -54,8 +54,8 @@ static int vpic_get_priority(struct hvm_
    82.4      if ( mask == 0 )
    82.5          return VPIC_PRIO_NONE;
    82.6  
    82.7 -    /* prio = ffs(mask ROL vpic->priority_add); */
    82.8 -    asm ( "rol %%cl,%b1 ; bsf %1,%0"
    82.9 +    /* prio = ffs(mask ROR vpic->priority_add); */
   82.10 +    asm ( "ror %%cl,%b1 ; bsf %1,%0"
   82.11            : "=r" (prio) : "r" ((uint32_t)mask), "c" (vpic->priority_add) );
   82.12      return prio;
   82.13  }
    83.1 --- a/xen/arch/x86/mm.c	Tue Mar 20 10:07:11 2007 -0600
    83.2 +++ b/xen/arch/x86/mm.c	Tue Mar 20 15:19:38 2007 -0600
    83.3 @@ -108,6 +108,7 @@
    83.4  #include <asm/x86_emulate.h>
    83.5  #include <asm/e820.h>
    83.6  #include <asm/hypercall.h>
    83.7 +#include <asm/shared.h>
    83.8  #include <public/memory.h>
    83.9  
   83.10  #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
   83.11 @@ -246,6 +247,11 @@ int memory_is_conventional_ram(paddr_t p
   83.12      return 0;
   83.13  }
   83.14  
   83.15 +unsigned long domain_get_maximum_gpfn(struct domain *d)
   83.16 +{
   83.17 +    return is_hvm_domain(d) ? d->arch.p2m.max_mapped_pfn : arch_get_max_pfn(d);
   83.18 +}
   83.19 +
   83.20  void share_xen_page_with_guest(
   83.21      struct page_info *page, struct domain *d, int readonly)
   83.22  {
    84.1 --- a/xen/arch/x86/mm/shadow/common.c	Tue Mar 20 10:07:11 2007 -0600
    84.2 +++ b/xen/arch/x86/mm/shadow/common.c	Tue Mar 20 15:19:38 2007 -0600
    84.3 @@ -36,7 +36,6 @@
    84.4  #include <asm/current.h>
    84.5  #include <asm/flushtlb.h>
    84.6  #include <asm/shadow.h>
    84.7 -#include <asm/shared.h>
    84.8  #include "private.h"
    84.9  
   84.10  
   84.11 @@ -2672,7 +2671,7 @@ sh_alloc_log_dirty_bitmap(struct domain 
   84.12  {
   84.13      ASSERT(d->arch.paging.shadow.dirty_bitmap == NULL);
   84.14      d->arch.paging.shadow.dirty_bitmap_size =
   84.15 -        (arch_get_max_pfn(d) + (BITS_PER_LONG - 1)) &
   84.16 +        (domain_get_maximum_gpfn(d) + (BITS_PER_LONG - 1)) &
   84.17          ~(BITS_PER_LONG - 1);
   84.18      d->arch.paging.shadow.dirty_bitmap =
   84.19          xmalloc_array(unsigned long,
   84.20 @@ -2682,7 +2681,8 @@ sh_alloc_log_dirty_bitmap(struct domain 
   84.21          d->arch.paging.shadow.dirty_bitmap_size = 0;
   84.22          return -ENOMEM;
   84.23      }
   84.24 -    memset(d->arch.paging.shadow.dirty_bitmap, 0, d->arch.paging.shadow.dirty_bitmap_size/8);
   84.25 +    memset(d->arch.paging.shadow.dirty_bitmap, 0,
   84.26 +           d->arch.paging.shadow.dirty_bitmap_size/8);
   84.27  
   84.28      return 0;
   84.29  }
    85.1 --- a/xen/arch/x86/x86_64/asm-offsets.c	Tue Mar 20 10:07:11 2007 -0600
    85.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c	Tue Mar 20 15:19:38 2007 -0600
    85.3 @@ -59,6 +59,7 @@ void __dummy__(void)
    85.4      OFFSET(VCPU_domain, struct vcpu, domain);
    85.5      OFFSET(VCPU_vcpu_info, struct vcpu, vcpu_info);
    85.6      OFFSET(VCPU_trap_bounce, struct vcpu, arch.trap_bounce);
    85.7 +    OFFSET(VCPU_int80_bounce, struct vcpu, arch.int80_bounce);
    85.8      OFFSET(VCPU_thread_flags, struct vcpu, arch.flags);
    85.9      OFFSET(VCPU_event_addr, struct vcpu,
   85.10             arch.guest_context.event_callback_eip);
    86.1 --- a/xen/arch/x86/x86_64/compat/entry.S	Tue Mar 20 10:07:11 2007 -0600
    86.2 +++ b/xen/arch/x86/x86_64/compat/entry.S	Tue Mar 20 15:19:38 2007 -0600
    86.3 @@ -187,6 +187,10 @@ ENTRY(compat_post_handle_exception)
    86.4          call  compat_create_bounce_frame
    86.5          jmp   compat_test_all_events
    86.6  
    86.7 +ENTRY(compat_int80_direct_trap)
    86.8 +        call  compat_create_bounce_frame
    86.9 +        jmp   compat_restore_all_guest
   86.10 +
   86.11  /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
   86.12  /*   {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]}                             */
   86.13  /* %rdx: trap_bounce, %rbx: struct vcpu                                  */
    87.1 --- a/xen/arch/x86/x86_64/compat/traps.c	Tue Mar 20 10:07:11 2007 -0600
    87.2 +++ b/xen/arch/x86/x86_64/compat/traps.c	Tue Mar 20 15:19:38 2007 -0600
    87.3 @@ -1,6 +1,7 @@
    87.4  #ifdef CONFIG_COMPAT
    87.5  
    87.6  #include <xen/event.h>
    87.7 +#include <asm/regs.h>
    87.8  #include <compat/callback.h>
    87.9  #include <compat/arch-x86_32.h>
   87.10  
   87.11 @@ -291,6 +292,9 @@ int compat_set_trap_table(XEN_GUEST_HAND
   87.12  
   87.13          XLAT_trap_info(dst + cur.vector, &cur);
   87.14  
   87.15 +        if ( cur.vector == 0x80 )
   87.16 +            init_int80_direct_trap(current);
   87.17 +
   87.18          guest_handle_add_offset(traps, 1);
   87.19      }
   87.20  
    88.1 --- a/xen/arch/x86/x86_64/entry.S	Tue Mar 20 10:07:11 2007 -0600
    88.2 +++ b/xen/arch/x86/x86_64/entry.S	Tue Mar 20 15:19:38 2007 -0600
    88.3 @@ -222,6 +222,35 @@ bad_hypercall:
    88.4          movq $-ENOSYS,UREGS_rax(%rsp)
    88.5          jmp  test_all_events
    88.6  
    88.7 +ENTRY(int80_direct_trap)
    88.8 +        pushq $0
    88.9 +        SAVE_ALL
   88.10 +
   88.11 +        GET_CURRENT(%rbx)
   88.12 +
   88.13 +        /* Check that the callback is non-null. */
   88.14 +        leaq  VCPU_int80_bounce(%rbx),%rdx
   88.15 +        cmp   $0, TRAPBOUNCE_flags(%rdx)
   88.16 +        jz    int80_slow_path
   88.17 +
   88.18 +        movq  VCPU_domain(%rbx),%rax
   88.19 +        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
   88.20 +        jc    compat_int80_direct_trap
   88.21 +
   88.22 +        call  create_bounce_frame
   88.23 +        jmp   restore_all_guest
   88.24 +
   88.25 +int80_slow_path:
   88.26 +        /* 
   88.27 +         * Setup entry vector and error code as if this was a GPF caused by an
   88.28 +         * IDT entry with DPL==0.
   88.29 +         */
   88.30 +        movl  $((0x80 << 3) | 0x2),UREGS_error_code(%rsp)
   88.31 +        movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
   88.32 +        /* A GPF wouldn't have incremented the instruction pointer. */
   88.33 +        sub   $2,UREGS_rip(%rsp)
   88.34 +        jmp   handle_exception_saved
   88.35 +
   88.36  /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK:                     */
   88.37  /*   { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS }   */
   88.38  /* %rdx: trap_bounce, %rbx: struct vcpu                           */
   88.39 @@ -359,6 +388,7 @@ ENTRY(ret_from_intr)
   88.40  /* No special register assumptions. */
   88.41  ENTRY(handle_exception)
   88.42          SAVE_ALL
   88.43 +handle_exception_saved:
   88.44          testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp)
   88.45          jz    exception_with_ints_disabled
   88.46          sti
    89.1 --- a/xen/arch/x86/x86_64/traps.c	Tue Mar 20 10:07:11 2007 -0600
    89.2 +++ b/xen/arch/x86/x86_64/traps.c	Tue Mar 20 15:19:38 2007 -0600
    89.3 @@ -247,6 +247,7 @@ unsigned long do_iret(void)
    89.4  
    89.5  asmlinkage void syscall_enter(void);
    89.6  asmlinkage void compat_hypercall(void);
    89.7 +asmlinkage void int80_direct_trap(void);
    89.8  void __init percpu_traps_init(void)
    89.9  {
   89.10      char *stack_bottom, *stack;
   89.11 @@ -262,6 +263,7 @@ void __init percpu_traps_init(void)
   89.12  #ifdef CONFIG_COMPAT
   89.13          /* The hypercall entry vector is only accessible from ring 1. */
   89.14          _set_gate(idt_table+HYPERCALL_VECTOR, 15, 1, &compat_hypercall);
   89.15 +        _set_gate(idt_table+0x80, 15, 3, &int80_direct_trap);
   89.16  #endif
   89.17      }
   89.18  
   89.19 @@ -346,6 +348,22 @@ void __init percpu_traps_init(void)
   89.20      wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
   89.21  }
   89.22  
   89.23 +void init_int80_direct_trap(struct vcpu *v)
   89.24 +{
   89.25 +    struct trap_info *ti = &v->arch.guest_context.trap_ctxt[0x80];
   89.26 +    struct trap_bounce *tb = &v->arch.int80_bounce;
   89.27 +
   89.28 +    if ( !guest_gate_selector_okay(v->domain, ti->cs) )
   89.29 +         return;
   89.30 +
   89.31 +    tb->flags = TBF_EXCEPTION;
   89.32 +    tb->cs    = ti->cs;
   89.33 +    tb->eip   = ti->address;
   89.34 +
   89.35 +    if ( null_trap_bounce(v, tb) )
   89.36 +        tb->flags = 0;
   89.37 +}
   89.38 +
   89.39  static long register_guest_callback(struct callback_register *reg)
   89.40  {
   89.41      long ret = 0;
    90.1 --- a/xen/common/compat/memory.c	Tue Mar 20 10:07:11 2007 -0600
    90.2 +++ b/xen/common/compat/memory.c	Tue Mar 20 15:19:38 2007 -0600
    90.3 @@ -170,6 +170,7 @@ int compat_memory_op(unsigned int cmd, X
    90.4  
    90.5          case XENMEM_current_reservation:
    90.6          case XENMEM_maximum_reservation:
    90.7 +        case XENMEM_maximum_gpfn:
    90.8          {
    90.9  #define xen_domid_t domid_t
   90.10  #define compat_domid_t domid_compat_t
   90.11 @@ -325,6 +326,7 @@ int compat_memory_op(unsigned int cmd, X
   90.12          case XENMEM_maximum_ram_page:
   90.13          case XENMEM_current_reservation:
   90.14          case XENMEM_maximum_reservation:
   90.15 +        case XENMEM_maximum_gpfn:
   90.16              break;
   90.17  
   90.18          case XENMEM_translate_gpfn_list:
    91.1 --- a/xen/common/memory.c	Tue Mar 20 10:07:11 2007 -0600
    91.2 +++ b/xen/common/memory.c	Tue Mar 20 15:19:38 2007 -0600
    91.3 @@ -584,6 +584,7 @@ long do_memory_op(unsigned long cmd, XEN
    91.4  
    91.5      case XENMEM_current_reservation:
    91.6      case XENMEM_maximum_reservation:
    91.7 +    case XENMEM_maximum_gpfn:
    91.8          if ( copy_from_guest(&domid, arg, 1) )
    91.9              return -EFAULT;
   91.10  
   91.11 @@ -594,7 +595,19 @@ long do_memory_op(unsigned long cmd, XEN
   91.12          else if ( (d = rcu_lock_domain_by_id(domid)) == NULL )
   91.13              return -ESRCH;
   91.14  
   91.15 -        rc = (op == XENMEM_current_reservation) ? d->tot_pages : d->max_pages;
   91.16 +        switch ( op )
   91.17 +        {
   91.18 +        case XENMEM_current_reservation:
   91.19 +            rc = d->tot_pages;
   91.20 +            break;
   91.21 +        case XENMEM_maximum_reservation:
   91.22 +            rc = d->max_pages;
   91.23 +            break;
   91.24 +        default:
   91.25 +            ASSERT(op == XENMEM_maximum_gpfn);
   91.26 +            rc = domain_get_maximum_gpfn(d);
   91.27 +            break;
   91.28 +        }
   91.29  
   91.30          if ( unlikely(domid != DOMID_SELF) )
   91.31              rcu_unlock_domain(d);
    92.1 --- a/xen/common/perfc.c	Tue Mar 20 10:07:11 2007 -0600
    92.2 +++ b/xen/common/perfc.c	Tue Mar 20 15:19:38 2007 -0600
    92.3 @@ -136,8 +136,8 @@ static xen_sysctl_perfc_desc_t perfc_d[N
    92.4  static xen_sysctl_perfc_val_t *perfc_vals;
    92.5  static int               perfc_nbr_vals;
    92.6  static int               perfc_init = 0;
    92.7 -static int perfc_copy_info(XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc,
    92.8 -                           XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val)
    92.9 +static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
   92.10 +                           XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val)
   92.11  {
   92.12      unsigned int i, j;
   92.13      unsigned int v = 0;
   92.14 @@ -217,29 +217,20 @@ static int perfc_copy_info(XEN_GUEST_HAN
   92.15  int perfc_control(xen_sysctl_perfc_op_t *pc)
   92.16  {
   92.17      static DEFINE_SPINLOCK(lock);
   92.18 -    XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc;
   92.19 -    XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val;
   92.20      int rc;
   92.21  
   92.22 -    /*
   92.23 -     * 64 bit guest handles cannot be passed as parameters to
   92.24 -     * functions so cast to a regular guest handle.
   92.25 -     */
   92.26 -    desc = guest_handle_cast(pc->desc, xen_sysctl_perfc_desc_t);
   92.27 -    val = guest_handle_cast(pc->val, xen_sysctl_perfc_val_t);
   92.28 -
   92.29      spin_lock(&lock);
   92.30  
   92.31      switch ( pc->cmd )
   92.32      {
   92.33      case XEN_SYSCTL_PERFCOP_reset:
   92.34 -        perfc_copy_info(desc, val);
   92.35 +        perfc_copy_info(pc->desc, pc->val);
   92.36          perfc_reset(0);
   92.37          rc = 0;
   92.38          break;
   92.39  
   92.40      case XEN_SYSCTL_PERFCOP_query:
   92.41 -        perfc_copy_info(desc, val);
   92.42 +        perfc_copy_info(pc->desc, pc->val);
   92.43          rc = 0;
   92.44          break;
   92.45  
    93.1 --- a/xen/include/asm-ia64/mm.h	Tue Mar 20 10:07:11 2007 -0600
    93.2 +++ b/xen/include/asm-ia64/mm.h	Tue Mar 20 15:19:38 2007 -0600
    93.3 @@ -511,4 +511,6 @@ int steal_page(
    93.4  
    93.5  #define domain_clamp_alloc_bitsize(d, b) (b)
    93.6  
    93.7 +#define domain_get_maximum_gpfn(d) (-ENOSYS)
    93.8 +
    93.9  #endif /* __ASM_IA64_MM_H__ */
    94.1 --- a/xen/include/asm-powerpc/mm.h	Tue Mar 20 10:07:11 2007 -0600
    94.2 +++ b/xen/include/asm-powerpc/mm.h	Tue Mar 20 15:19:38 2007 -0600
    94.3 @@ -278,4 +278,6 @@ extern int steal_page(struct domain *d, 
    94.4  
    94.5  #define domain_clamp_alloc_bitsize(d, b) (b)
    94.6  
    94.7 +#define domain_get_maximum_gpfn(d) (-ENOSYS)
    94.8 +
    94.9  #endif
    95.1 --- a/xen/include/asm-x86/domain.h	Tue Mar 20 10:07:11 2007 -0600
    95.2 +++ b/xen/include/asm-x86/domain.h	Tue Mar 20 15:19:38 2007 -0600
    95.3 @@ -248,6 +248,9 @@ struct arch_vcpu
    95.4  #ifdef CONFIG_X86_32
    95.5      struct desc_struct int80_desc;
    95.6  #endif
    95.7 +#ifdef CONFIG_X86_64
    95.8 +    struct trap_bounce int80_bounce;
    95.9 +#endif
   95.10  
   95.11      /* Virtual Machine Extensions */
   95.12      struct hvm_vcpu hvm_vcpu;
    96.1 --- a/xen/include/asm-x86/hvm/svm/svm.h	Tue Mar 20 10:07:11 2007 -0600
    96.2 +++ b/xen/include/asm-x86/hvm/svm/svm.h	Tue Mar 20 15:19:38 2007 -0600
    96.3 @@ -29,8 +29,6 @@
    96.4  #include <asm/i387.h>
    96.5  
    96.6  extern void svm_dump_vmcb(const char *from, struct vmcb_struct *vmcb);
    96.7 -extern void svm_do_launch(struct vcpu *v);
    96.8 -extern void arch_svm_do_resume(struct vcpu *v);
    96.9  
   96.10  extern u64 root_vmcb_pa[NR_CPUS];
   96.11  
    97.1 --- a/xen/include/asm-x86/hvm/svm/vmcb.h	Tue Mar 20 10:07:11 2007 -0600
    97.2 +++ b/xen/include/asm-x86/hvm/svm/vmcb.h	Tue Mar 20 15:19:38 2007 -0600
    97.3 @@ -447,7 +447,7 @@ struct arch_svm_struct {
    97.4      u32                 *msrpm;
    97.5      u64                 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
    97.6      int                 saved_irq_vector;
    97.7 -    u32                 launch_core;
    97.8 +    int                 launch_core;
    97.9      
   97.10      unsigned long       flags;            /* VMCB flags */
   97.11      unsigned long       cpu_shadow_cr0;   /* Guest value for CR0 */
    98.1 --- a/xen/include/asm-x86/mm.h	Tue Mar 20 10:07:11 2007 -0600
    98.2 +++ b/xen/include/asm-x86/mm.h	Tue Mar 20 15:19:38 2007 -0600
    98.3 @@ -404,5 +404,6 @@ unsigned int domain_clamp_alloc_bitsize(
    98.4  # define domain_clamp_alloc_bitsize(d, b) (b)
    98.5  #endif
    98.6  
    98.7 +unsigned long domain_get_maximum_gpfn(struct domain *d);
    98.8  
    98.9  #endif /* __ASM_X86_MM_H__ */
    99.1 --- a/xen/include/asm-x86/processor.h	Tue Mar 20 10:07:11 2007 -0600
    99.2 +++ b/xen/include/asm-x86/processor.h	Tue Mar 20 15:19:38 2007 -0600
    99.3 @@ -455,16 +455,16 @@ extern idt_entry_t *idt_tables[];
    99.4  
    99.5  extern struct tss_struct init_tss[NR_CPUS];
    99.6  
    99.7 -#ifdef CONFIG_X86_32
    99.8 +extern void init_int80_direct_trap(struct vcpu *v);
    99.9  
   99.10 -extern void init_int80_direct_trap(struct vcpu *v);
   99.11 +#if defined(CONFIG_X86_32)
   99.12 +
   99.13  #define set_int80_direct_trap(_ed)                  \
   99.14      (memcpy(idt_tables[(_ed)->processor] + 0x80,    \
   99.15              &((_ed)->arch.int80_desc), 8))
   99.16  
   99.17  #else
   99.18  
   99.19 -#define init_int80_direct_trap(_ed) ((void)0)
   99.20  #define set_int80_direct_trap(_ed)  ((void)0)
   99.21  
   99.22  #endif
   100.1 --- a/xen/include/public/arch-x86/xen-x86_32.h	Tue Mar 20 10:07:11 2007 -0600
   100.2 +++ b/xen/include/public/arch-x86/xen-x86_32.h	Tue Mar 20 15:19:38 2007 -0600
   100.3 @@ -103,7 +103,7 @@
   100.4           (hnd).p = val;                                     \
   100.5      } while ( 0 )
   100.6  #define uint64_aligned_t uint64_t __attribute__((aligned(8)))
   100.7 -#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name __attribute__((aligned(8)))
   100.8 +#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
   100.9  #endif
  100.10  
  100.11  #ifndef __ASSEMBLY__
   101.1 --- a/xen/include/public/foreign/Makefile	Tue Mar 20 10:07:11 2007 -0600
   101.2 +++ b/xen/include/public/foreign/Makefile	Tue Mar 20 15:19:38 2007 -0600
   101.3 @@ -18,7 +18,7 @@ check-headers: checker
   101.4  	./checker > $(XEN_TARGET_ARCH).size
   101.5  	diff -u reference.size $(XEN_TARGET_ARCH).size
   101.6  checker: checker.c $(headers)
   101.7 -	$(HOSTCC) $(CFLAGS) -o $@ $<
   101.8 +	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
   101.9  else
  101.10  check-headers:
  101.11  	@echo "cross build: skipping check"
   102.1 --- a/xen/include/public/memory.h	Tue Mar 20 10:07:11 2007 -0600
   102.2 +++ b/xen/include/public/memory.h	Tue Mar 20 15:19:38 2007 -0600
   102.3 @@ -129,6 +129,11 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_excha
   102.4  #define XENMEM_maximum_reservation  4
   102.5  
   102.6  /*
   102.7 + * Returns the maximum GPFN in use by the guest, or -ve errcode on failure.
   102.8 + */
   102.9 +#define XENMEM_maximum_gpfn         14
  102.10 +
  102.11 +/*
  102.12   * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
  102.13   * mapping table. Architectures which do not have a m2p table do not implement
  102.14   * this command.
   103.1 --- a/xen/include/xen/trace.h	Tue Mar 20 10:07:11 2007 -0600
   103.2 +++ b/xen/include/xen/trace.h	Tue Mar 20 15:19:38 2007 -0600
   103.3 @@ -41,11 +41,11 @@ void trace(u32 event, unsigned long d1, 
   103.4      do {                                 \
   103.5          if ( unlikely(tb_init_done) )    \
   103.6              trace(e,                     \
   103.7 -                 (unsigned long)d1,      \
   103.8 -                 (unsigned long)d2,      \
   103.9 -                 (unsigned long)d3,      \
  103.10 -                 (unsigned long)d4,      \
  103.11 -                 (unsigned long)d5);     \
  103.12 +                  (unsigned long)(d1),   \
  103.13 +                  (unsigned long)(d2),   \
  103.14 +                  (unsigned long)(d3),   \
  103.15 +                  (unsigned long)(d4),   \
  103.16 +                  (unsigned long)(d5));  \
  103.17      } while ( 0 )
  103.18  
  103.19  /* Convenience macros for calling the trace function. */