ia64/xen-unstable

changeset 4244:688480d39d96

bitkeeper revision 1.1251 (423ef939YAuSbyU77UivO6Ybvl5Yzw)

Merge with Rolf's tree

Signed-off-by: michael.fetterman@cl.cam.ac.uk
author mafetter@fleming.research
date Mon Mar 21 16:41:29 2005 +0000 (2005-03-21)
parents 105bb57fc414 e113e917d480
children dcf6c3ab8a7b
files linux-2.6.10-xen-sparse/arch/xen/Kconfig linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ldt.c linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/io.h linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h xen/arch/x86/audit.c xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/extable.c xen/arch/x86/mm.c xen/arch/x86/shadow.c xen/arch/x86/traps.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/arch/x86/x86_32/domain_page.c xen/arch/x86/x86_32/traps.c xen/common/page_alloc.c xen/include/asm-x86/domain.h xen/include/asm-x86/mm.h xen/include/asm-x86/shadow.h xen/include/asm-x86/vmx_platform.h xen/include/asm-x86/x86_32/domain_page.h xen/include/public/arch-x86_32.h xen/include/xen/perfc.h xen/include/xen/perfc_defn.h xen/include/xen/sched.h
line diff
     2.1 --- a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig	Wed Mar 16 19:30:47 2005 +0000
     2.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig	Mon Mar 21 16:41:29 2005 +0000
     2.3 @@ -12,14 +12,15 @@ CONFIG_NO_IDLE_HZ=y
     2.4  #
     2.5  CONFIG_XEN_PRIVILEGED_GUEST=y
     2.6  CONFIG_XEN_PHYSDEV_ACCESS=y
     2.7 -CONFIG_XEN_BLKDEV_BACKEND=y
     2.8 +# CONFIG_XEN_BLKDEV_BACKEND is not set
     2.9  # CONFIG_XEN_BLKDEV_TAP_BE is not set
    2.10 -CONFIG_XEN_NETDEV_BACKEND=y
    2.11 +# CONFIG_XEN_NETDEV_BACKEND is not set
    2.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    2.13  CONFIG_XEN_NETDEV_FRONTEND=y
    2.14  # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
    2.15  # CONFIG_XEN_BLKDEV_TAP is not set
    2.16  CONFIG_XEN_WRITABLE_PAGETABLES=y
    2.17 +CONFIG_XEN_SHADOW_MODE=y
    2.18  CONFIG_XEN_SCRUB_PAGES=y
    2.19  CONFIG_X86=y
    2.20  # CONFIG_X86_64 is not set
     3.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Wed Mar 16 19:30:47 2005 +0000
     3.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Mon Mar 21 16:41:29 2005 +0000
     3.3 @@ -512,7 +512,11 @@ void __init cpu_gdt_init(struct Xgt_desc
     3.4  	for (va = gdt_descr->address, f = 0;
     3.5  	     va < gdt_descr->address + gdt_descr->size;
     3.6  	     va += PAGE_SIZE, f++) {
     3.7 +#ifndef CONFIG_XEN_SHADOW_MODE
     3.8  		frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
     3.9 +#else /* CONFIG_XEN_SHADOW_MODE */
    3.10 +		frames[f] = __vms_virt_to_machine(va) >> PAGE_SHIFT;
    3.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
    3.12  		make_page_readonly((void *)va);
    3.13  	}
    3.14  	flush_page_update_queue();
     4.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ldt.c	Wed Mar 16 19:30:47 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ldt.c	Mon Mar 21 16:41:29 2005 +0000
     4.3 @@ -61,8 +61,10 @@ static int alloc_ldt(mm_context_t *pc, i
     4.4  		cpumask_t mask;
     4.5  		preempt_disable();
     4.6  #endif
     4.7 +#ifndef CONFIG_XEN_SHADOW_MODE
     4.8  		make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
     4.9  				    PAGE_SIZE);
    4.10 +#endif /* CONFIG_XEN_SHADOW_MODE */
    4.11  		load_LDT(pc);
    4.12  		flush_page_update_queue();
    4.13  #ifdef CONFIG_SMP
    4.14 @@ -73,8 +75,10 @@ static int alloc_ldt(mm_context_t *pc, i
    4.15  #endif
    4.16  	}
    4.17  	if (oldsize) {
    4.18 +#ifndef CONFIG_XEN_SHADOW_MODE
    4.19  		make_pages_writable(oldldt, (oldsize * LDT_ENTRY_SIZE) /
    4.20  			PAGE_SIZE);
    4.21 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
    4.22  		flush_page_update_queue();
    4.23  		if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
    4.24  			vfree(oldldt);
    4.25 @@ -90,8 +94,10 @@ static inline int copy_ldt(mm_context_t 
    4.26  	if (err < 0)
    4.27  		return err;
    4.28  	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
    4.29 +#ifndef CONFIG_XEN_SHADOW_MODE
    4.30  	make_pages_readonly(new->ldt, (new->size * LDT_ENTRY_SIZE) /
    4.31  			    PAGE_SIZE);
    4.32 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
    4.33  	flush_page_update_queue();
    4.34  	return 0;
    4.35  }
    4.36 @@ -124,9 +130,11 @@ void destroy_context(struct mm_struct *m
    4.37  	if (mm->context.size) {
    4.38  		if (mm == current->active_mm)
    4.39  			clear_LDT();
    4.40 +#ifndef CONFIG_XEN_SHADOW_MODE
    4.41  		make_pages_writable(mm->context.ldt, 
    4.42  				    (mm->context.size * LDT_ENTRY_SIZE) /
    4.43  				    PAGE_SIZE);
    4.44 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
    4.45  		flush_page_update_queue();
    4.46  		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
    4.47  			vfree(mm->context.ldt);
    4.48 @@ -222,7 +230,11 @@ static int write_ldt(void __user * ptr, 
    4.49  	}
    4.50  
    4.51  	lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
    4.52 +#ifndef CONFIG_XEN_SHADOW_MODE
    4.53  	mach_lp = arbitrary_virt_to_machine(lp);
    4.54 +#else /* CONFIG_XEN_SHADOW_MODE */
    4.55 +	mach_lp = arbitrary_virt_to_phys(lp);
    4.56 +#endif /* CONFIG_XEN_SHADOW_MODE */
    4.57  
    4.58     	/* Allow LDTs to be cleared by the user. */
    4.59     	if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
     5.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Wed Mar 16 19:30:47 2005 +0000
     5.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Mon Mar 21 16:41:29 2005 +0000
     5.3 @@ -30,6 +30,7 @@ struct dma_coherent_mem {
     5.4  static void
     5.5  xen_contig_memory(unsigned long vstart, unsigned int order)
     5.6  {
     5.7 +#ifndef CONFIG_XEN_SHADOW_MODE
     5.8  	/*
     5.9  	 * Ensure multi-page extents are contiguous in machine memory.
    5.10  	 * This code could be cleaned up some, and the number of
    5.11 @@ -76,6 +77,7 @@ xen_contig_memory(unsigned long vstart, 
    5.12  	xen_tlb_flush();
    5.13  
    5.14          balloon_unlock(flags);
    5.15 +#endif /* CONFIG_XEN_SHADOW_MODE */
    5.16  }
    5.17  
    5.18  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
     6.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c	Wed Mar 16 19:30:47 2005 +0000
     6.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c	Mon Mar 21 16:41:29 2005 +0000
     6.3 @@ -514,17 +514,23 @@ struct task_struct fastcall * __switch_t
     6.4  	 * Load the per-thread Thread-Local Storage descriptor.
     6.5  	 * This is load_TLS(next, cpu) with multicalls.
     6.6  	 */
     6.7 +#ifndef CONFIG_XEN_SHADOW_MODE
     6.8 +#define C_VIRT_TO_MACH virt_to_machine
     6.9 +#else /* CONFIG_XEN_SHADOW_MODE */
    6.10 +#define C_VIRT_TO_MACH virt_to_phys
    6.11 +#endif
    6.12  #define C(i) do {							    \
    6.13  	if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||	    \
    6.14  		     next->tls_array[i].b != prev->tls_array[i].b))	    \
    6.15  		queue_multicall3(__HYPERVISOR_update_descriptor,	    \
    6.16 -				 virt_to_machine(&get_cpu_gdt_table(cpu)    \
    6.17 +				 C_VIRT_TO_MACH(&get_cpu_gdt_table(cpu)     \
    6.18  						 [GDT_ENTRY_TLS_MIN + i]),  \
    6.19  				 ((u32 *)&next->tls_array[i])[0],	    \
    6.20  				 ((u32 *)&next->tls_array[i])[1]);	    \
    6.21  } while (0)
    6.22  	C(0); C(1); C(2);
    6.23  #undef C
    6.24 +#undef C_VIRT_TO_MACH
    6.25  
    6.26  	if (xen_start_info.flags & SIF_PRIVILEGED) {
    6.27  		op.cmd           = DOM0_IOPL;
     7.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c	Wed Mar 16 19:30:47 2005 +0000
     7.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c	Mon Mar 21 16:41:29 2005 +0000
     7.3 @@ -345,8 +345,13 @@ static void __init probe_roms(void)
     7.4  shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
     7.5  EXPORT_SYMBOL(HYPERVISOR_shared_info);
     7.6  
     7.7 +#ifndef CONFIG_XEN_SHADOW_MODE
     7.8  unsigned int *phys_to_machine_mapping, *pfn_to_mfn_frame_list;
     7.9  EXPORT_SYMBOL(phys_to_machine_mapping);
    7.10 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.11 +unsigned int *__vms_phys_to_machine_mapping, *__vms_pfn_to_mfn_frame_list;
    7.12 +EXPORT_SYMBOL(__vms_phys_to_machine_mapping);
    7.13 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.14  
    7.15  DEFINE_PER_CPU(multicall_entry_t, multicall_list[8]);
    7.16  DEFINE_PER_CPU(int, nr_multicall_ents);
    7.17 @@ -1142,7 +1147,11 @@ static unsigned long __init setup_memory
    7.18  	}
    7.19  #endif
    7.20  
    7.21 +#ifndef CONFIG_XEN_SHADOW_MODE
    7.22  	phys_to_machine_mapping = (unsigned int *)xen_start_info.mfn_list;
    7.23 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.24 +	__vms_phys_to_machine_mapping = (unsigned int *)xen_start_info.mfn_list;
    7.25 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.26  
    7.27  	return max_low_pfn;
    7.28  }
    7.29 @@ -1437,11 +1446,23 @@ void __init setup_arch(char **cmdline_p)
    7.30  
    7.31  	/* Make sure we have a large enough P->M table. */
    7.32  	if (max_pfn > xen_start_info.nr_pages) {
    7.33 +#ifndef CONFIG_XEN_SHADOW_MODE
    7.34  		phys_to_machine_mapping = alloc_bootmem_low_pages(
    7.35 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.36 +		__vms_phys_to_machine_mapping = alloc_bootmem_low_pages(
    7.37 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.38  			max_pfn * sizeof(unsigned long));
    7.39 +#ifndef CONFIG_XEN_SHADOW_MODE
    7.40  		memset(phys_to_machine_mapping, ~0,
    7.41 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.42 +		memset(__vms_phys_to_machine_mapping, ~0,
    7.43 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.44  			max_pfn * sizeof(unsigned long));
    7.45 +#ifndef CONFIG_XEN_SHADOW_MODE
    7.46  		memcpy(phys_to_machine_mapping,
    7.47 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.48 +		memcpy(__vms_phys_to_machine_mapping,
    7.49 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.50  			(unsigned long *)xen_start_info.mfn_list,
    7.51  			xen_start_info.nr_pages * sizeof(unsigned long));
    7.52  		free_bootmem(
    7.53 @@ -1450,14 +1471,27 @@ void __init setup_arch(char **cmdline_p)
    7.54  			sizeof(unsigned long))));
    7.55  	}
    7.56  
    7.57 +#ifndef CONFIG_XEN_SHADOW_MODE
    7.58  	pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
    7.59 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.60 +	__vms_pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
    7.61 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.62  	for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
    7.63  	{	
    7.64 +#ifndef CONFIG_XEN_SHADOW_MODE
    7.65  	     pfn_to_mfn_frame_list[j] = 
    7.66  		  virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
    7.67 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.68 +	     __vms_pfn_to_mfn_frame_list[j] = 
    7.69 +		  __vms_virt_to_machine(&__vms_phys_to_machine_mapping[i]) >> PAGE_SHIFT;
    7.70 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.71  	}
    7.72  	HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
    7.73 +#ifndef CONFIG_XEN_SHADOW_MODE
    7.74  	     virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
    7.75 +#else /* CONFIG_XEN_SHADOW_MODE */
    7.76 +	     __vms_virt_to_machine(__vms_pfn_to_mfn_frame_list) >> PAGE_SHIFT;
    7.77 +#endif /* CONFIG_XEN_SHADOW_MODE */
    7.78  
    7.79  
    7.80  	/*
     8.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c	Wed Mar 16 19:30:47 2005 +0000
     8.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c	Mon Mar 21 16:41:29 2005 +0000
     8.3 @@ -473,8 +473,13 @@ no_context:
     8.4  	printk("%08lx\n", regs->eip);
     8.5  	page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id()))
     8.6  	    [address >> 22];
     8.7 +#ifndef CONFIG_XEN_SHADOW_MODE
     8.8  	printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page,
     8.9  	       machine_to_phys(page));
    8.10 +#else /* CONFIG_XEN_SHADOW_MODE */
    8.11 +	printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n",
    8.12 +	       __vms_phys_to_machine(page), page);
    8.13 +#endif /* CONFIG_XEN_SHADOW_MODE */
    8.14  	/*
    8.15  	 * We must not directly access the pte in the highpte
    8.16  	 * case, the page table might be allocated in highmem.
    8.17 @@ -485,10 +490,17 @@ no_context:
    8.18  	if (page & 1) {
    8.19  		page &= PAGE_MASK;
    8.20  		address &= 0x003ff000;
    8.21 +#ifndef CONFIG_XEN_SHADOW_MODE
    8.22  		page = machine_to_phys(page);
    8.23 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
    8.24  		page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
    8.25 +#ifndef CONFIG_XEN_SHADOW_MODE
    8.26  		printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page,
    8.27  		       machine_to_phys(page));
    8.28 +#else /* CONFIG_XEN_SHADOW_MODE */
    8.29 +		printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n",
    8.30 +		       __vms_phys_to_machine(page), page);
    8.31 +#endif /* CONFIG_XEN_SHADOW_MODE */
    8.32  	}
    8.33  #endif
    8.34  	show_trace(NULL, (unsigned long *)&regs[1]);
     9.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c	Wed Mar 16 19:30:47 2005 +0000
     9.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c	Mon Mar 21 16:41:29 2005 +0000
     9.3 @@ -56,7 +56,11 @@ static spinlock_t update_lock = SPIN_LOC
     9.4  #ifdef CONFIG_SMP
     9.5  #define QUEUE_SIZE 1
     9.6  #else
     9.7 +#ifndef CONFIG_XEN_SHADOW_MODE
     9.8  #define QUEUE_SIZE 128
     9.9 +#else /* CONFIG_XEN_SHADOW_MODE */
    9.10 +#define QUEUE_SIZE 1
    9.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.12  #endif
    9.13  #endif
    9.14  
    9.15 @@ -139,9 +143,8 @@ void queue_l1_entry_update(pte_t *ptr, u
    9.16  #endif
    9.17      spin_unlock_irqrestore(&update_lock, flags);
    9.18  #else
    9.19 -    _flush_page_update_queue();
    9.20 -    *(unsigned long *)ptr = val;
    9.21 -#endif
    9.22 +    set_pte(ptr, __pte(val));
    9.23 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.24  }
    9.25  
    9.26  void queue_l2_entry_update(pmd_t *ptr, unsigned long val)
    9.27 @@ -157,9 +160,8 @@ void queue_l2_entry_update(pmd_t *ptr, u
    9.28      increment_index();
    9.29      spin_unlock_irqrestore(&update_lock, flags);
    9.30  #else
    9.31 -    _flush_page_update_queue();
    9.32 -    *(unsigned long *)ptr = val;
    9.33 -#endif
    9.34 +    set_pmd(ptr, __pmd(val));
    9.35 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.36  }
    9.37  
    9.38  void queue_pt_switch(unsigned long ptr)
    9.39 @@ -169,7 +171,11 @@ void queue_pt_switch(unsigned long ptr)
    9.40      unsigned long flags;
    9.41      spin_lock_irqsave(&update_lock, flags);
    9.42      idx = per_cpu(mmu_update_queue_idx, cpu);
    9.43 +#ifndef CONFIG_XEN_SHADOW_MODE
    9.44      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
    9.45 +#else /* CONFIG_XEN_SHADOW_MODE */
    9.46 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
    9.47 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.48      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
    9.49      per_cpu(update_queue[idx], cpu).val  = MMUEXT_NEW_BASEPTR;
    9.50      increment_index();
    9.51 @@ -203,56 +209,88 @@ void queue_invlpg(unsigned long ptr)
    9.52      spin_unlock_irqrestore(&update_lock, flags);
    9.53  }
    9.54  
    9.55 +#ifndef CONFIG_XEN_SHADOW_MODE
    9.56  void queue_pgd_pin(unsigned long ptr)
    9.57 +#else /* CONFIG_XEN_SHADOW_MODE */
    9.58 +void __vms_queue_pgd_pin(unsigned long ptr)
    9.59 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.60  {
    9.61      int cpu = smp_processor_id();
    9.62      int idx;
    9.63      unsigned long flags;
    9.64      spin_lock_irqsave(&update_lock, flags);
    9.65      idx = per_cpu(mmu_update_queue_idx, cpu);
    9.66 +#ifndef CONFIG_XEN_SHADOW_MODE
    9.67      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
    9.68 +#else /* CONFIG_XEN_SHADOW_MODE */
    9.69 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
    9.70 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.71      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
    9.72      per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L2_TABLE;
    9.73      increment_index();
    9.74      spin_unlock_irqrestore(&update_lock, flags);
    9.75  }
    9.76  
    9.77 +#ifndef CONFIG_XEN_SHADOW_MODE
    9.78  void queue_pgd_unpin(unsigned long ptr)
    9.79 +#else /* CONFIG_XEN_SHADOW_MODE */
    9.80 +void __vms_queue_pgd_unpin(unsigned long ptr)
    9.81 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.82  {
    9.83      int cpu = smp_processor_id();
    9.84      int idx;
    9.85      unsigned long flags;
    9.86      spin_lock_irqsave(&update_lock, flags);
    9.87      idx = per_cpu(mmu_update_queue_idx, cpu);
    9.88 +#ifndef CONFIG_XEN_SHADOW_MODE
    9.89      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
    9.90 +#else /* CONFIG_XEN_SHADOW_MODE */
    9.91 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
    9.92 +#endif /* CONFIG_XEN_SHADOW_MODE */
    9.93      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
    9.94      per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
    9.95      increment_index();
    9.96      spin_unlock_irqrestore(&update_lock, flags);
    9.97  }
    9.98  
    9.99 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.100  void queue_pte_pin(unsigned long ptr)
   9.101 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.102 +void __vms_queue_pte_pin(unsigned long ptr)
   9.103 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.104  {
   9.105      int cpu = smp_processor_id();
   9.106      int idx;
   9.107      unsigned long flags;
   9.108      spin_lock_irqsave(&update_lock, flags);
   9.109      idx = per_cpu(mmu_update_queue_idx, cpu);
   9.110 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.111      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
   9.112 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.113 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
   9.114 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.115      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
   9.116      per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L1_TABLE;
   9.117      increment_index();
   9.118      spin_unlock_irqrestore(&update_lock, flags);
   9.119  }
   9.120  
   9.121 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.122  void queue_pte_unpin(unsigned long ptr)
   9.123 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.124 +void __vms_queue_pte_unpin(unsigned long ptr)
   9.125 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.126  {
   9.127      int cpu = smp_processor_id();
   9.128      int idx;
   9.129      unsigned long flags;
   9.130      spin_lock_irqsave(&update_lock, flags);
   9.131      idx = per_cpu(mmu_update_queue_idx, cpu);
   9.132 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.133      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
   9.134 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.135 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
   9.136 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.137      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
   9.138      per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
   9.139      increment_index();
   9.140 @@ -299,8 +337,8 @@ void xen_l1_entry_update(pte_t *ptr, uns
   9.141      increment_index_and_flush();
   9.142      spin_unlock_irqrestore(&update_lock, flags);
   9.143  #else
   9.144 -    *(unsigned long *)ptr = val;
   9.145 -#endif
   9.146 +    set_pte(ptr, __pte(val));
   9.147 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.148  }
   9.149  
   9.150  void xen_l2_entry_update(pmd_t *ptr, unsigned long val)
   9.151 @@ -316,8 +354,8 @@ void xen_l2_entry_update(pmd_t *ptr, uns
   9.152      increment_index_and_flush();
   9.153      spin_unlock_irqrestore(&update_lock, flags);
   9.154  #else
   9.155 -    *(unsigned long *)ptr = val;
   9.156 -#endif
   9.157 +    set_pmd(ptr, __pmd(val));
   9.158 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.159  }
   9.160  
   9.161  void xen_pt_switch(unsigned long ptr)
   9.162 @@ -327,7 +365,11 @@ void xen_pt_switch(unsigned long ptr)
   9.163      unsigned long flags;
   9.164      spin_lock_irqsave(&update_lock, flags);
   9.165      idx = per_cpu(mmu_update_queue_idx, cpu);
   9.166 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.167      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
   9.168 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.169 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
   9.170 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.171      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
   9.172      per_cpu(update_queue[idx], cpu).val  = MMUEXT_NEW_BASEPTR;
   9.173      increment_index_and_flush();
   9.174 @@ -361,56 +403,88 @@ void xen_invlpg(unsigned long ptr)
   9.175      spin_unlock_irqrestore(&update_lock, flags);
   9.176  }
   9.177  
   9.178 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.179  void xen_pgd_pin(unsigned long ptr)
   9.180 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.181 +void __vms_xen_pgd_pin(unsigned long ptr)
   9.182 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.183  {
   9.184      int cpu = smp_processor_id();
   9.185      int idx;
   9.186      unsigned long flags;
   9.187      spin_lock_irqsave(&update_lock, flags);
   9.188      idx = per_cpu(mmu_update_queue_idx, cpu);
   9.189 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.190      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
   9.191 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.192 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
   9.193 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.194      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
   9.195      per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L2_TABLE;
   9.196      increment_index_and_flush();
   9.197      spin_unlock_irqrestore(&update_lock, flags);
   9.198  }
   9.199  
   9.200 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.201  void xen_pgd_unpin(unsigned long ptr)
   9.202 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.203 +void __vms_xen_pgd_unpin(unsigned long ptr)
   9.204 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.205  {
   9.206      int cpu = smp_processor_id();
   9.207      int idx;
   9.208      unsigned long flags;
   9.209      spin_lock_irqsave(&update_lock, flags);
   9.210      idx = per_cpu(mmu_update_queue_idx, cpu);
   9.211 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.212      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
   9.213 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.214 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
   9.215 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.216      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
   9.217      per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
   9.218      increment_index_and_flush();
   9.219      spin_unlock_irqrestore(&update_lock, flags);
   9.220  }
   9.221  
   9.222 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.223  void xen_pte_pin(unsigned long ptr)
   9.224 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.225 +void __vms_xen_pte_pin(unsigned long ptr)
   9.226 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.227  {
   9.228      int cpu = smp_processor_id();
   9.229      int idx;
   9.230      unsigned long flags;
   9.231      spin_lock_irqsave(&update_lock, flags);
   9.232      idx = per_cpu(mmu_update_queue_idx, cpu);
   9.233 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.234      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
   9.235 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.236 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
   9.237 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.238      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
   9.239      per_cpu(update_queue[idx], cpu).val  = MMUEXT_PIN_L1_TABLE;
   9.240      increment_index_and_flush();
   9.241      spin_unlock_irqrestore(&update_lock, flags);
   9.242  }
   9.243  
   9.244 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.245  void xen_pte_unpin(unsigned long ptr)
   9.246 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.247 +void __vms_xen_pte_unpin(unsigned long ptr)
   9.248 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.249  {
   9.250      int cpu = smp_processor_id();
   9.251      int idx;
   9.252      unsigned long flags;
   9.253      spin_lock_irqsave(&update_lock, flags);
   9.254      idx = per_cpu(mmu_update_queue_idx, cpu);
   9.255 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.256      per_cpu(update_queue[idx], cpu).ptr  = phys_to_machine(ptr);
   9.257 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.258 +    per_cpu(update_queue[idx], cpu).ptr  = __vms_phys_to_machine(ptr);
   9.259 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.260      per_cpu(update_queue[idx], cpu).ptr |= MMU_EXTENDED_COMMAND;
   9.261      per_cpu(update_queue[idx], cpu).val  = MMUEXT_UNPIN_TABLE;
   9.262      increment_index_and_flush();
   9.263 @@ -472,7 +546,11 @@ unsigned long allocate_empty_lowmem_regi
   9.264          pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE))); 
   9.265          pfn_array[i] = pte->pte_low >> PAGE_SHIFT;
   9.266          queue_l1_entry_update(pte, 0);
   9.267 +#ifndef CONFIG_XEN_SHADOW_MODE
   9.268          phys_to_machine_mapping[__pa(vstart)>>PAGE_SHIFT] = INVALID_P2M_ENTRY;
   9.269 +#else /* CONFIG_XEN_SHADOW_MODE */
   9.270 +        __vms_phys_to_machine_mapping[__pa(vstart)>>PAGE_SHIFT] = INVALID_P2M_ENTRY;
   9.271 +#endif /* CONFIG_XEN_SHADOW_MODE */
   9.272      }
   9.273  
   9.274      /* Flush updates through and flush the TLB. */
    10.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c	Wed Mar 16 19:30:47 2005 +0000
    10.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c	Mon Mar 21 16:41:29 2005 +0000
    10.3 @@ -353,12 +353,16 @@ static void __init pagetable_init (void)
    10.4  	memcpy(new_pgd, old_pgd, PTRS_PER_PGD_NO_HV*sizeof(pgd_t));
    10.5  #ifndef CONFIG_XEN_SHADOW_MODE
    10.6  	make_page_readonly(new_pgd);
    10.7 -#endif
    10.8  	queue_pgd_pin(__pa(new_pgd));
    10.9 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   10.10  	load_cr3(new_pgd);
   10.11 +#ifndef CONFIG_XEN_SHADOW_MODE
   10.12  	queue_pgd_unpin(__pa(old_pgd));
   10.13 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   10.14  	__flush_tlb_all(); /* implicit flush */
   10.15 +#ifndef CONFIG_XEN_SHADOW_MODE
   10.16  	make_page_writable(old_pgd);
   10.17 +#endif /* CONFIG_XEN_SHADOW_MODE */
   10.18  	flush_page_update_queue();
   10.19  	free_bootmem(__pa(old_pgd), PAGE_SIZE);
   10.20  
   10.21 @@ -566,18 +570,31 @@ void __init paging_init(void)
   10.22  
   10.23  	/* Switch to the real shared_info page, and clear the dummy page. */
   10.24  	flush_page_update_queue();
   10.25 +#ifndef CONFIG_XEN_SHADOW_MODE
   10.26  	set_fixmap_ma(FIX_SHARED_INFO, xen_start_info.shared_info);
   10.27 +#else /* CONFIG_XEN_SHADOW_MODE */
   10.28 +        printk("xen_start_info.shared_info=%x\n", xen_start_info.shared_info);
   10.29 +	set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info);
   10.30 +#endif /* CONFIG_XEN_SHADOW_MODE */
   10.31  	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   10.32  	memset(empty_zero_page, 0, sizeof(empty_zero_page));
   10.33  
   10.34  #ifdef CONFIG_XEN_PHYSDEV_ACCESS
   10.35  	/* Setup mapping of lower 1st MB */
   10.36  	for (i = 0; i < NR_FIX_ISAMAPS; i++)
   10.37 +#ifndef CONFIG_XEN_SHADOW_MODE
   10.38  		if (xen_start_info.flags & SIF_PRIVILEGED)
   10.39  			set_fixmap_ma(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
   10.40  		else
   10.41  			set_fixmap_ma_ro(FIX_ISAMAP_BEGIN - i,
   10.42  					 virt_to_machine(empty_zero_page));
   10.43 +#else /* CONFIG_XEN_SHADOW_MODE */
   10.44 +		if (xen_start_info.flags & SIF_PRIVILEGED)
   10.45 +			__vms_set_fixmap_ma(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
   10.46 +		else
   10.47 +			__vms_set_fixmap_ma_ro(FIX_ISAMAP_BEGIN - i,
   10.48 +					 __vms_virt_to_machine(empty_zero_page));
   10.49 +#endif /* CONFIG_XEN_SHADOW_MODE */
   10.50  #endif
   10.51  }
   10.52  
    11.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c	Wed Mar 16 19:30:47 2005 +0000
    11.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c	Mon Mar 21 16:41:29 2005 +0000
    11.3 @@ -56,9 +56,14 @@ void __init bt_iounmap(void *addr, unsig
    11.4  static inline int is_local_lowmem(unsigned long address)
    11.5  {
    11.6  	extern unsigned long max_low_pfn;
    11.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    11.8  	unsigned long mfn = address >> PAGE_SHIFT;
    11.9  	unsigned long pfn = mfn_to_pfn(mfn);
   11.10  	return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
   11.11 +#else /* CONFIG_XEN_SHADOW_MODE */
   11.12 +	unsigned long pfn = address >> PAGE_SHIFT;
   11.13 +	return (pfn < max_low_pfn);
   11.14 +#endif /* CONFIG_XEN_SHADOW_MODE */
   11.15  }
   11.16  
   11.17  /*
   11.18 @@ -97,6 +102,7 @@ void __iomem * __ioremap(unsigned long p
   11.19  	/*
   11.20  	 * Don't allow anybody to remap normal RAM that we're using..
   11.21  	 */
   11.22 +#ifndef CONFIG_XEN_SHADOW_MODE
   11.23  	if (is_local_lowmem(phys_addr)) {
   11.24  		char *t_addr, *t_end;
   11.25  		struct page *page;
   11.26 @@ -110,6 +116,7 @@ void __iomem * __ioremap(unsigned long p
   11.27  
   11.28  		domid = DOMID_LOCAL;
   11.29  	}
   11.30 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   11.31  
   11.32  	/*
   11.33  	 * Mappings have to be page-aligned
   11.34 @@ -255,7 +262,11 @@ void __init *bt_ioremap(unsigned long ph
   11.35  	 */
   11.36  	idx = FIX_BTMAP_BEGIN;
   11.37  	while (nrpages > 0) {
   11.38 +#ifndef CONFIG_XEN_SHADOW_MODE
   11.39  		set_fixmap_ma(idx, phys_addr);
   11.40 +#else /* CONFIG_XEN_SHADOW_MODE */
   11.41 +		__vms_set_fixmap_ma(idx, phys_addr);
   11.42 +#endif /* CONFIG_XEN_SHADOW_MODE */
   11.43  		phys_addr += PAGE_SIZE;
   11.44  		--idx;
   11.45  		--nrpages;
   11.46 @@ -312,7 +323,11 @@ static inline void direct_remap_area_pte
   11.47  		BUG();
   11.48  
   11.49  	do {
   11.50 +#ifndef CONFIG_XEN_SHADOW_MODE
   11.51  		(*v)->ptr = virt_to_machine(pte);
   11.52 +#else /* CONFIG_XEN_SHADOW_MODE */
   11.53 +		(*v)->ptr = __vms_virt_to_machine(pte);
   11.54 +#endif /* CONFIG_XEN_SHADOW_MODE */
   11.55  		(*v)++;
   11.56  		address += PAGE_SIZE;
   11.57  		pte++;
   11.58 @@ -386,12 +401,14 @@ int direct_remap_area_pages(struct mm_st
   11.59  	mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
   11.60  
   11.61  	v = w = &u[0];
   11.62 +#ifndef CONFIG_XEN_SHADOW_MODE
   11.63  	if (domid != DOMID_LOCAL) {
   11.64  		u[0].ptr  = MMU_EXTENDED_COMMAND;
   11.65  		u[0].val  = MMUEXT_SET_FOREIGNDOM;
   11.66  		u[0].val |= (unsigned long)domid << 16;
   11.67  		v = w = &u[1];
   11.68  	}
   11.69 +#endif /* CONFIG_XEN_SHADOW_MODE */
   11.70  
   11.71  	start_address = address;
   11.72  
   11.73 @@ -415,8 +432,24 @@ int direct_remap_area_pages(struct mm_st
   11.74  		 * Fill in the machine address: PTE ptr is done later by
   11.75  		 * __direct_remap_area_pages(). 
   11.76  		 */
   11.77 +#ifndef CONFIG_XEN_SHADOW_MODE
   11.78  		v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
   11.79  
   11.80 +#else /* CONFIG_XEN_SHADOW_MODE */
   11.81 +        {
   11.82 +            mmu_update_t update;
   11.83 +            int success = 0;
   11.84 +            unsigned long ppfn;
   11.85 +
   11.86 +            update.ptr = (machine_addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE;
   11.87 +            update.val = -1;
   11.88 +            ppfn = HYPERVISOR_mmu_update(&update, 1, &success);
   11.89 +            if (! success)
   11.90 +                BUG();
   11.91 +                
   11.92 +		v->val = (ppfn << PAGE_SHIFT) | pgprot_val(prot);
   11.93 +        }
   11.94 +#endif /* CONFIG_XEN_SHADOW_MODE */
   11.95  		machine_addr += PAGE_SIZE;
   11.96  		address += PAGE_SIZE; 
   11.97  		v++;
    12.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c	Wed Mar 16 19:30:47 2005 +0000
    12.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c	Mon Mar 21 16:41:29 2005 +0000
    12.3 @@ -119,7 +119,11 @@ static int
    12.4  		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
    12.5  			pte_t old = *kpte;
    12.6  			pte_t standard = mk_pte(page, PAGE_KERNEL); 
    12.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    12.8  			set_pte_batched(kpte, mk_pte(page, prot)); 
    12.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   12.10 +			set_pte_atomic(kpte, mk_pte(page, prot)); 
   12.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   12.12  			if (pte_same(old,standard))
   12.13  				get_page(kpte_page);
   12.14  		} else {
   12.15 @@ -130,7 +134,11 @@ static int
   12.16  			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
   12.17  		}	
   12.18  	} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
   12.19 +#ifndef CONFIG_XEN_SHADOW_MODE
   12.20  		set_pte_batched(kpte, mk_pte(page, PAGE_KERNEL));
   12.21 +#else /* CONFIG_XEN_SHADOW_MODE */
   12.22 +		set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
   12.23 +#endif /* CONFIG_XEN_SHADOW_MODE */
   12.24  		__put_page(kpte_page);
   12.25  	}
   12.26  
   12.27 @@ -171,7 +179,9 @@ int change_page_attr(struct page *page, 
   12.28  		if (err) 
   12.29  			break; 
   12.30  	} 	
   12.31 +#ifndef CONFIG_XEN_SHADOW_MODE
   12.32  	flush_page_update_queue();
   12.33 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   12.34  	spin_unlock_irqrestore(&cpa_lock, flags);
   12.35  	return err;
   12.36  }
    13.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c	Wed Mar 16 19:30:47 2005 +0000
    13.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c	Mon Mar 21 16:41:29 2005 +0000
    13.3 @@ -93,7 +93,11 @@ static void set_pte_pfn(unsigned long va
    13.4   * Associate a virtual page frame with a given physical page frame 
    13.5   * and protection flags for that frame.
    13.6   */ 
    13.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    13.8  static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn,
    13.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   13.10 +static void __vms_set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn,
   13.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   13.12  			   pgprot_t flags)
   13.13  {
   13.14  	pgd_t *pgd;
   13.15 @@ -112,7 +116,22 @@ static void set_pte_pfn_ma(unsigned long
   13.16  	}
   13.17  	pte = pte_offset_kernel(pmd, vaddr);
   13.18  	/* <pfn,flags> stored as-is, to permit clearing entries */
   13.19 +#ifndef CONFIG_XEN_SHADOW_MODE
   13.20  	set_pte(pte, pfn_pte_ma(pfn, flags));
   13.21 +#else /* CONFIG_XEN_SHADOW_MODE */
   13.22 +        {
   13.23 +            mmu_update_t update;
   13.24 +            int success = 0;
   13.25 +            unsigned long ppfn;
   13.26 +
   13.27 +            update.ptr = (pfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
   13.28 +            update.val = -1;
   13.29 +            ppfn = HYPERVISOR_mmu_update(&update, 1, &success);
   13.30 +            if (! success)
   13.31 +                BUG();
   13.32 +            set_pte(pte, pfn_pte(ppfn, flags));
   13.33 +        }
   13.34 +#endif /* CONFIG_XEN_SHADOW_MODE */
   13.35  
   13.36  	/*
   13.37  	 * It's enough to flush this one mapping.
   13.38 @@ -165,7 +184,11 @@ void __set_fixmap (enum fixed_addresses 
   13.39  	set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
   13.40  }
   13.41  
   13.42 +#ifndef CONFIG_XEN_SHADOW_MODE
   13.43  void __set_fixmap_ma (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
   13.44 +#else /* CONFIG_XEN_SHADOW_MODE */
   13.45 +void __vms___set_fixmap_ma (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
   13.46 +#endif /* CONFIG_XEN_SHADOW_MODE */
   13.47  {
   13.48  	unsigned long address = __fix_to_virt(idx);
   13.49  
   13.50 @@ -173,7 +196,11 @@ void __set_fixmap_ma (enum fixed_address
   13.51  		BUG();
   13.52  		return;
   13.53  	}
   13.54 +#ifndef CONFIG_XEN_SHADOW_MODE
   13.55  	set_pte_pfn_ma(address, phys >> PAGE_SHIFT, flags);
   13.56 +#else /* CONFIG_XEN_SHADOW_MODE */
   13.57 +	__vms_set_pte_pfn_ma(address, phys >> PAGE_SHIFT, flags);
   13.58 +#endif /* CONFIG_XEN_SHADOW_MODE */
   13.59  }
   13.60  
   13.61  pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
   13.62 @@ -183,8 +210,8 @@ pte_t *pte_alloc_one_kernel(struct mm_st
   13.63  		clear_page(pte);
   13.64  #ifndef CONFIG_XEN_SHADOW_MODE
   13.65  		make_page_readonly(pte);
   13.66 -#endif
   13.67  		xen_flush_page_update_queue();
   13.68 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   13.69  	}
   13.70  	return pte;
   13.71  }
   13.72 @@ -198,9 +225,9 @@ void pte_ctor(void *pte, kmem_cache_t *c
   13.73  	clear_page(pte);
   13.74  #ifndef CONFIG_XEN_SHADOW_MODE
   13.75  	make_page_readonly(pte);
   13.76 -#endif
   13.77  	queue_pte_pin(__pa(pte));
   13.78  	flush_page_update_queue();
   13.79 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   13.80  }
   13.81  
   13.82  void pte_dtor(void *pte, kmem_cache_t *cache, unsigned long unused)
   13.83 @@ -208,9 +235,11 @@ void pte_dtor(void *pte, kmem_cache_t *c
   13.84  	struct page *page = virt_to_page(pte);
   13.85  	ClearPageForeign(page);
   13.86  
   13.87 +#ifndef CONFIG_XEN_SHADOW_MODE
   13.88  	queue_pte_unpin(__pa(pte));
   13.89  	make_page_writable(pte);
   13.90  	flush_page_update_queue();
   13.91 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   13.92  }
   13.93  
   13.94  struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
   13.95 @@ -243,7 +272,11 @@ void pte_free(struct page *pte)
   13.96  	if (pte < highmem_start_page)
   13.97  #endif
   13.98  		kmem_cache_free(pte_cache,
   13.99 +#ifndef CONFIG_XEN_SHADOW_MODE
  13.100  				phys_to_virt(page_to_pseudophys(pte)));
  13.101 +#else /* CONFIG_XEN_SHADOW_MODE */
  13.102 +				phys_to_virt(__vms_page_to_pseudophys(pte)));
  13.103 +#endif /* CONFIG_XEN_SHADOW_MODE */
  13.104  #ifdef CONFIG_HIGHPTE
  13.105  	else
  13.106  		__free_page(pte);
  13.107 @@ -310,9 +343,11 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
  13.108   out:
  13.109  #ifndef CONFIG_XEN_SHADOW_MODE
  13.110  	make_page_readonly(pgd);
  13.111 -#endif
  13.112  	queue_pgd_pin(__pa(pgd));
  13.113  	flush_page_update_queue();
  13.114 +#else /* CONFIG_XEN_SHADOW_MODE */
  13.115 +	;
  13.116 +#endif /* CONFIG_XEN_SHADOW_MODE */
  13.117  }
  13.118  
  13.119  /* never called when PTRS_PER_PMD > 1 */
  13.120 @@ -320,9 +355,11 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
  13.121  {
  13.122  	unsigned long flags; /* can be called from interrupt context */
  13.123  
  13.124 +#ifndef CONFIG_XEN_SHADOW_MODE
  13.125  	queue_pgd_unpin(__pa(pgd));
  13.126  	make_page_writable(pgd);
  13.127  	flush_page_update_queue();
  13.128 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
  13.129  
  13.130  	if (PTRS_PER_PMD > 1)
  13.131  		return;
  13.132 @@ -389,6 +426,7 @@ void make_page_readonly(void *va)
  13.133  	pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
  13.134  	pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
  13.135  	queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
  13.136 +#ifndef CONFIG_XEN_SHADOW_MODE
  13.137  	if ( (unsigned long)va >= (unsigned long)high_memory )
  13.138  	{
  13.139  		unsigned long phys;
  13.140 @@ -398,6 +436,7 @@ void make_page_readonly(void *va)
  13.141  #endif
  13.142  			make_lowmem_page_readonly(phys_to_virt(phys));
  13.143  	}
  13.144 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
  13.145  }
  13.146  
  13.147  void make_page_writable(void *va)
  13.148 @@ -409,7 +448,11 @@ void make_page_writable(void *va)
  13.149  	if ( (unsigned long)va >= (unsigned long)high_memory )
  13.150  	{
  13.151  		unsigned long phys;
  13.152 +#ifndef CONFIG_XEN_SHADOW_MODE
  13.153  		phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
  13.154 +#else /* CONFIG_XEN_SHADOW_MODE */
  13.155 +		phys = __vms_machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
  13.156 +#endif /* CONFIG_XEN_SHADOW_MODE */
  13.157  #ifdef CONFIG_HIGHMEM
  13.158  		if ( (phys >> PAGE_SHIFT) < highstart_pfn )
  13.159  #endif
    14.1 --- a/linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c	Wed Mar 16 19:30:47 2005 +0000
    14.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c	Mon Mar 21 16:41:29 2005 +0000
    14.3 @@ -80,7 +80,11 @@ static void __do_suspend(void)
    14.4      extern void time_suspend(void);
    14.5      extern void time_resume(void);
    14.6      extern unsigned long max_pfn;
    14.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    14.8      extern unsigned int *pfn_to_mfn_frame_list;
    14.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   14.10 +    extern unsigned int *__vms_pfn_to_mfn_frame_list;
   14.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   14.12  
   14.13      suspend_record = (suspend_record_t *)__get_free_page(GFP_KERNEL);
   14.14      if ( suspend_record == NULL )
   14.15 @@ -105,7 +109,11 @@ static void __do_suspend(void)
   14.16  
   14.17      memcpy(&suspend_record->resume_info, &xen_start_info, sizeof(xen_start_info));
   14.18  
   14.19 +#ifndef CONFIG_XEN_SHADOW_MODE
   14.20      HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
   14.21 +#else /* CONFIG_XEN_SHADOW_MODE */
   14.22 +    HYPERVISOR_suspend(__vms_virt_to_machine(suspend_record) >> PAGE_SHIFT);
   14.23 +#endif /* CONFIG_XEN_SHADOW_MODE */
   14.24  
   14.25      HYPERVISOR_vm_assist(VMASST_CMD_enable,
   14.26  			 VMASST_TYPE_4gb_segments);
   14.27 @@ -118,7 +126,7 @@ static void __do_suspend(void)
   14.28  
   14.29      memcpy(&xen_start_info, &suspend_record->resume_info, sizeof(xen_start_info));
   14.30  
   14.31 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   14.32 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && !defined(CONFIG_XEN_SHADOW_MODE)
   14.33      set_fixmap_ma(FIX_SHARED_INFO, xen_start_info.shared_info);
   14.34  #else
   14.35      set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info);
   14.36 @@ -130,11 +138,20 @@ static void __do_suspend(void)
   14.37  
   14.38      for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
   14.39      {
   14.40 +#ifndef CONFIG_XEN_SHADOW_MODE
   14.41          pfn_to_mfn_frame_list[j] = 
   14.42              virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
   14.43 +#else /* CONFIG_XEN_SHADOW_MODE */
   14.44 +        __vms_pfn_to_mfn_frame_list[j] = 
   14.45 +            __vms_virt_to_machine(&__vms_phys_to_machine_mapping[i]) >> PAGE_SHIFT;
   14.46 +#endif /* CONFIG_XEN_SHADOW_MODE */
   14.47      }
   14.48      HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
   14.49 +#ifndef CONFIG_XEN_SHADOW_MODE
   14.50          virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
   14.51 +#else /* CONFIG_XEN_SHADOW_MODE */
   14.52 +        __vms_virt_to_machine(__vms_pfn_to_mfn_frame_list) >> PAGE_SHIFT;
   14.53 +#endif /* CONFIG_XEN_SHADOW_MODE */
   14.54  
   14.55  
   14.56      irq_resume();
    15.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c	Wed Mar 16 19:30:47 2005 +0000
    15.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c	Mon Mar 21 16:41:29 2005 +0000
    15.3 @@ -206,11 +206,19 @@ static void balloon_process(void *unused
    15.4                  BUG();
    15.5  
    15.6              pfn = page - mem_map;
    15.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    15.8              if ( phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY )
    15.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   15.10 +            if ( __vms_phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY )
   15.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   15.12                  BUG();
   15.13  
   15.14              /* Update P->M and M->P tables. */
   15.15 +#ifndef CONFIG_XEN_SHADOW_MODE
   15.16              phys_to_machine_mapping[pfn] = mfn_list[i];
   15.17 +#else /* CONFIG_XEN_SHADOW_MODE */
   15.18 +            __vms_phys_to_machine_mapping[pfn] = mfn_list[i];
   15.19 +#endif /* CONFIG_XEN_SHADOW_MODE */
   15.20              queue_machphys_update(mfn_list[i], pfn);
   15.21              
   15.22              /* Link back into the page tables if it's not a highmem page. */
   15.23 @@ -244,8 +252,13 @@ static void balloon_process(void *unused
   15.24              }
   15.25  
   15.26              pfn = page - mem_map;
   15.27 +#ifndef CONFIG_XEN_SHADOW_MODE
   15.28              mfn_list[i] = phys_to_machine_mapping[pfn];
   15.29              phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
   15.30 +#else /* CONFIG_XEN_SHADOW_MODE */
   15.31 +            mfn_list[i] = __vms_phys_to_machine_mapping[pfn];
   15.32 +            __vms_phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
   15.33 +#endif /* CONFIG_XEN_SHADOW_MODE */
   15.34  
   15.35              if ( !PageHighMem(page) )
   15.36              {
    16.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c	Wed Mar 16 19:30:47 2005 +0000
    16.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c	Mon Mar 21 16:41:29 2005 +0000
    16.3 @@ -444,7 +444,11 @@ static void dispatch_rw_block_io(blkif_t
    16.4  #else
    16.5          mcl[i].args[3] = blkif->domid;
    16.6  #endif
    16.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    16.8          phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
    16.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   16.10 +        __vms_phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] =
   16.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   16.12              FOREIGN_FRAME(phys_seg[i].buffer >> PAGE_SHIFT);
   16.13      }
   16.14  
    17.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c	Wed Mar 16 19:30:47 2005 +0000
    17.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c	Mon Mar 21 16:41:29 2005 +0000
    17.3 @@ -129,7 +129,11 @@ static inline void translate_req_to_pfn(
    17.4      xreq->sector_number = req->sector_number;
    17.5  
    17.6      for ( i = 0; i < req->nr_segments; i++ )
    17.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    17.8          xreq->frame_and_sects[i] = machine_to_phys(req->frame_and_sects[i]);
    17.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   17.10 +        xreq->frame_and_sects[i] = __vms_machine_to_phys(req->frame_and_sects[i]);
   17.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   17.12  }
   17.13  
   17.14  static inline void translate_req_to_mfn(blkif_request_t *xreq,
   17.15 @@ -144,7 +148,11 @@ static inline void translate_req_to_mfn(
   17.16      xreq->sector_number = req->sector_number;
   17.17  
   17.18      for ( i = 0; i < req->nr_segments; i++ )
   17.19 +#ifndef CONFIG_XEN_SHADOW_MODE
   17.20          xreq->frame_and_sects[i] = phys_to_machine(req->frame_and_sects[i]);
   17.21 +#else /* CONFIG_XEN_SHADOW_MODE */
   17.22 +        xreq->frame_and_sects[i] = __vms_phys_to_machine(req->frame_and_sects[i]);
   17.23 +#endif /* CONFIG_XEN_SHADOW_MODE */
   17.24  }
   17.25  
   17.26  
   17.27 @@ -1091,7 +1099,11 @@ static void blkif_send_interface_connect
   17.28      blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
   17.29      
   17.30      msg->handle      = 0;
   17.31 +#ifndef CONFIG_XEN_SHADOW_MODE
   17.32      msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
   17.33 +#else /* CONFIG_XEN_SHADOW_MODE */
   17.34 +    msg->shmem_frame = (__vms_virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
   17.35 +#endif /* CONFIG_XEN_SHADOW_MODE */
   17.36      
   17.37      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   17.38  }
   17.39 @@ -1401,7 +1413,11 @@ void blkif_completion(blkif_request_t *r
   17.40          for ( i = 0; i < req->nr_segments; i++ )
   17.41          {
   17.42              unsigned long pfn = req->frame_and_sects[i] >> PAGE_SHIFT;
   17.43 +#ifndef CONFIG_XEN_SHADOW_MODE
   17.44              unsigned long mfn = phys_to_machine_mapping[pfn];
   17.45 +#else /* CONFIG_XEN_SHADOW_MODE */
   17.46 +            unsigned long mfn = __vms_phys_to_machine_mapping[pfn];
   17.47 +#endif /* CONFIG_XEN_SHADOW_MODE */
   17.48              xen_machphys_update(mfn, pfn);
   17.49          }
   17.50          break;
    18.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c	Wed Mar 16 19:30:47 2005 +0000
    18.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c	Mon Mar 21 16:41:29 2005 +0000
    18.3 @@ -112,7 +112,11 @@ static int xlvbd_get_vbd_info(vdisk_t *d
    18.4      memset(&req, 0, sizeof(req));
    18.5      req.operation   = BLKIF_OP_PROBE;
    18.6      req.nr_segments = 1;
    18.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    18.8      req.frame_and_sects[0] = virt_to_machine(buf) | 7;
    18.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   18.10 +    req.frame_and_sects[0] = __vms_virt_to_machine(buf) | 7;
   18.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   18.12  
   18.13      blkif_control_send(&req, &rsp);
   18.14  
    19.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c	Wed Mar 16 19:30:47 2005 +0000
    19.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c	Mon Mar 21 16:41:29 2005 +0000
    19.3 @@ -207,7 +207,11 @@ static void net_rx_action(unsigned long 
    19.4      {
    19.5          netif   = netdev_priv(skb->dev);
    19.6          vdata   = (unsigned long)skb->data;
    19.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    19.8          mdata   = virt_to_machine(vdata);
    19.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   19.10 +        mdata   = __vms_virt_to_machine(vdata);
   19.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   19.12  
   19.13          /* Memory squeeze? Back off for an arbitrary while. */
   19.14          if ( (new_mfn = alloc_mfn()) == 0 )
   19.15 @@ -223,7 +227,11 @@ static void net_rx_action(unsigned long 
   19.16           * Set the new P2M table entry before reassigning the old data page.
   19.17           * Heed the comment in pgtable-2level.h:pte_page(). :-)
   19.18           */
   19.19 +#ifndef CONFIG_XEN_SHADOW_MODE
   19.20          phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn;
   19.21 +#else /* CONFIG_XEN_SHADOW_MODE */
   19.22 +        __vms_phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn;
   19.23 +#endif /* CONFIG_XEN_SHADOW_MODE */
   19.24          
   19.25          mmu[0].ptr  = (new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
   19.26          mmu[0].val  = __pa(vdata) >> PAGE_SHIFT;  
   19.27 @@ -590,7 +598,11 @@ static void net_tx_action(unsigned long 
   19.28              continue;
   19.29          }
   19.30  
   19.31 +#ifndef CONFIG_XEN_SHADOW_MODE
   19.32          phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
   19.33 +#else /* CONFIG_XEN_SHADOW_MODE */
   19.34 +        __vms_phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
   19.35 +#endif /* CONFIG_XEN_SHADOW_MODE */
   19.36              FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT);
   19.37  
   19.38          data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size;
    20.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Wed Mar 16 19:30:47 2005 +0000
    20.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Mon Mar 21 16:41:29 2005 +0000
    20.3 @@ -375,10 +375,18 @@ static void network_alloc_rx_buffers(str
    20.4          
    20.5          np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
    20.6          
    20.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    20.8          rx_pfn_array[i] = virt_to_machine(skb->head) >> PAGE_SHIFT;
    20.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   20.10 +        rx_pfn_array[i] = __vms_virt_to_machine(skb->head) >> PAGE_SHIFT;
   20.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   20.12  
   20.13  	/* Remove this page from pseudo phys map before passing back to Xen. */
   20.14 +#ifndef CONFIG_XEN_SHADOW_MODE
   20.15  	phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] 
   20.16 +#else /* CONFIG_XEN_SHADOW_MODE */
   20.17 +	__vms_phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] 
   20.18 +#endif /* CONFIG_XEN_SHADOW_MODE */
   20.19  	    = INVALID_P2M_ENTRY;
   20.20  
   20.21          rx_mcl[i].op = __HYPERVISOR_update_va_mapping;
   20.22 @@ -464,7 +472,11 @@ static int network_start_xmit(struct sk_
   20.23      tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req;
   20.24  
   20.25      tx->id   = id;
   20.26 +#ifndef CONFIG_XEN_SHADOW_MODE
   20.27      tx->addr = virt_to_machine(skb->data);
   20.28 +#else /* CONFIG_XEN_SHADOW_MODE */
   20.29 +    tx->addr = __vms_virt_to_machine(skb->data);
   20.30 +#endif /* CONFIG_XEN_SHADOW_MODE */
   20.31      tx->size = skb->len;
   20.32  
   20.33      wmb(); /* Ensure that backend will see the request. */
   20.34 @@ -579,7 +591,11 @@ static int netif_poll(struct net_device 
   20.35          mcl->args[2] = 0;
   20.36          mcl++;
   20.37  
   20.38 +#ifndef CONFIG_XEN_SHADOW_MODE
   20.39          phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = 
   20.40 +#else /* CONFIG_XEN_SHADOW_MODE */
   20.41 +        __vms_phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = 
   20.42 +#endif /* CONFIG_XEN_SHADOW_MODE */
   20.43              rx->addr >> PAGE_SHIFT;
   20.44  
   20.45          __skb_queue_tail(&rxq, skb);
   20.46 @@ -736,7 +752,11 @@ static void network_connect(struct net_d
   20.47                  tx = &np->tx->ring[requeue_idx++].req;
   20.48                  
   20.49                  tx->id   = i;
   20.50 +#ifndef CONFIG_XEN_SHADOW_MODE
   20.51                  tx->addr = virt_to_machine(skb->data);
   20.52 +#else /* CONFIG_XEN_SHADOW_MODE */
   20.53 +                tx->addr = __vms_virt_to_machine(skb->data);
   20.54 +#endif /* CONFIG_XEN_SHADOW_MODE */
   20.55                  tx->size = skb->len;
   20.56                  
   20.57                  np->stats.tx_bytes += skb->len;
   20.58 @@ -799,8 +819,13 @@ static void send_interface_connect(struc
   20.59      netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
   20.60  
   20.61      msg->handle = np->handle;
   20.62 +#ifndef CONFIG_XEN_SHADOW_MODE
   20.63      msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT);
   20.64      msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT);
   20.65 +#else /* CONFIG_XEN_SHADOW_MODE */
   20.66 +    msg->tx_shmem_frame = (__vms_virt_to_machine(np->tx) >> PAGE_SHIFT);
   20.67 +    msg->rx_shmem_frame = (__vms_virt_to_machine(np->rx) >> PAGE_SHIFT);
   20.68 +#endif /* CONFIG_XEN_SHADOW_MODE */
   20.69          
   20.70      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   20.71  }
    21.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c	Wed Mar 16 19:30:47 2005 +0000
    21.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c	Mon Mar 21 16:41:29 2005 +0000
    21.3 @@ -174,7 +174,11 @@ static int privcmd_ioctl(struct inode *i
    21.4  
    21.5      case IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN:
    21.6      {
    21.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    21.8          unsigned long m2pv = (unsigned long)machine_to_phys_mapping;
    21.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   21.10 +        unsigned long m2pv = (unsigned long)__vms_machine_to_phys_mapping;
   21.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   21.12          pgd_t *pgd = pgd_offset_k(m2pv);
   21.13          pmd_t *pmd = pmd_offset(pgd, m2pv);
   21.14          unsigned long m2p_start_mfn = pmd_val(*pmd) >> PAGE_SHIFT;
    22.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h	Wed Mar 16 19:30:47 2005 +0000
    22.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h	Mon Mar 21 16:41:29 2005 +0000
    22.3 @@ -89,7 +89,11 @@ static inline void set_ldt_desc(unsigned
    22.4  
    22.5  static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
    22.6  {
    22.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    22.8  #define C(i) HYPERVISOR_update_descriptor(virt_to_machine(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]), ((u32 *)&t->tls_array[i])[0], ((u32 *)&t->tls_array[i])[1])
    22.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   22.10 +#define C(i) HYPERVISOR_update_descriptor(__pa(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]), ((u32 *)&t->tls_array[i])[0], ((u32 *)&t->tls_array[i])[1])
   22.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   22.12  	C(0); C(1); C(2);
   22.13  #undef C
   22.14  }
    23.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Wed Mar 16 19:30:47 2005 +0000
    23.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Mon Mar 21 16:41:29 2005 +0000
    23.3 @@ -101,15 +101,26 @@ enum fixed_addresses {
    23.4  
    23.5  extern void __set_fixmap (enum fixed_addresses idx,
    23.6  					unsigned long phys, pgprot_t flags);
    23.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    23.8  extern void __set_fixmap_ma (enum fixed_addresses idx,
    23.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   23.10 +extern void __vms___set_fixmap_ma (enum fixed_addresses idx,
   23.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   23.12  					unsigned long mach, pgprot_t flags);
   23.13  
   23.14  #define set_fixmap(idx, phys) \
   23.15  		__set_fixmap(idx, phys, PAGE_KERNEL)
   23.16 +#ifndef CONFIG_XEN_SHADOW_MODE
   23.17  #define set_fixmap_ma(idx, phys) \
   23.18  		__set_fixmap_ma(idx, phys, PAGE_KERNEL)
   23.19  #define set_fixmap_ma_ro(idx, phys) \
   23.20  		__set_fixmap_ma(idx, phys, PAGE_KERNEL_RO)
   23.21 +#else /* CONFIG_XEN_SHADOW_MODE */
   23.22 +#define __vms_set_fixmap_ma(idx, phys) \
   23.23 +		__vms___set_fixmap_ma(idx, phys, PAGE_KERNEL)
   23.24 +#define __vms_set_fixmap_ma_ro(idx, phys) \
   23.25 +		__vms___set_fixmap_ma(idx, phys, PAGE_KERNEL_RO)
   23.26 +#endif /* CONFIG_XEN_SHADOW_MODE */
   23.27  /*
   23.28   * Some hardware wants to get fixmapped without caching.
   23.29   */
    24.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/io.h	Wed Mar 16 19:30:47 2005 +0000
    24.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/io.h	Mon Mar 21 16:41:29 2005 +0000
    24.3 @@ -89,18 +89,44 @@ static inline void * phys_to_virt(unsign
    24.4  /*
    24.5   * Change "struct page" to physical address.
    24.6   */
    24.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    24.8  #define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
    24.9  #define page_to_phys(page)	 (phys_to_machine(page_to_pseudophys(page)))
   24.10 +#else /* CONFIG_XEN_SHADOW_MODE */
   24.11 +#define __vms_page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
   24.12 +#define __vms_page_to_machphys(page) (__vms_phys_to_machine(__vms_page_to_pseudophys(page)))
   24.13 +#define page_to_phys(page)	 (__vms_page_to_machphys(page))
   24.14 +#endif /* CONFIG_XEN_SHADOW_MODE */
   24.15  
   24.16 +#ifndef CONFIG_XEN_SHADOW_MODE
   24.17  #define bio_to_pseudophys(bio)	 (page_to_pseudophys(bio_page((bio))) + \
   24.18  				  (unsigned long) bio_offset((bio)))
   24.19 +#else /* CONFIG_XEN_SHADOW_MODE */
   24.20 +#define __vms_bio_to_pseudophys(bio)	 (__vms_page_to_pseudophys(bio_page((bio))) + \
   24.21 +				  (unsigned long) bio_offset((bio)))
   24.22 +#endif /* CONFIG_XEN_SHADOW_MODE */
   24.23 +
   24.24 +#ifndef CONFIG_XEN_SHADOW_MODE
   24.25  #define bvec_to_pseudophys(bv)	 (page_to_pseudophys((bv)->bv_page) + \
   24.26  				  (unsigned long) (bv)->bv_offset)
   24.27 +#else /* CONFIG_XEN_SHADOW_MODE */
   24.28 +#define __vms_bvec_to_pseudophys(bv)	 (__vms_page_to_pseudophys((bv)->bv_page) + \
   24.29 +				  (unsigned long) (bv)->bv_offset)
   24.30 +#define __vms_bvec_to_machphys(bv)	 (__vms_page_to_machphys((bv)->bv_page) + \
   24.31 +				  (unsigned long) (bv)->bv_offset)
   24.32 +#endif /* CONFIG_XEN_SHADOW_MODE */
   24.33  
   24.34 +#ifndef CONFIG_XEN_SHADOW_MODE
   24.35  #define BIOVEC_PHYS_MERGEABLE(vec1, vec2)	\
   24.36  	(((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) && \
   24.37  	 ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \
   24.38  	  bvec_to_pseudophys((vec2))))
   24.39 +#else /* CONFIG_XEN_SHADOW_MODE */
   24.40 +#define BIOVEC_PHYS_MERGEABLE(vec1, vec2)	\
   24.41 +	(((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) && \
   24.42 +	 ((__vms_bvec_to_machphys((vec1)) + (vec1)->bv_len) == \
   24.43 +	  __vms_bvec_to_machphys((vec2))))
   24.44 +#endif /* CONFIG_XEN_SHADOW_MODE */
   24.45  
   24.46  extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
   24.47  
   24.48 @@ -149,8 +175,13 @@ extern void bt_iounmap(void *addr, unsig
   24.49   *
   24.50   * Allow them on x86 for legacy drivers, though.
   24.51   */
   24.52 +#ifndef CONFIG_XEN_SHADOW_MODE
   24.53  #define virt_to_bus(_x) phys_to_machine(__pa(_x))
   24.54  #define bus_to_virt(_x) __va(machine_to_phys(_x))
   24.55 +#else /* CONFIG_XEN_SHADOW_MODE */
   24.56 +#define virt_to_bus(_x) __vms_phys_to_machine(__pa(_x))
   24.57 +#define bus_to_virt(_x) ({ BUG(); __va((_x)); })
   24.58 +#endif /* CONFIG_XEN_SHADOW_MODE */
   24.59  
   24.60  /*
   24.61   * readX/writeX() are used to access memory mapped devices. On some
    25.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h	Wed Mar 16 19:30:47 2005 +0000
    25.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h	Mon Mar 21 16:41:29 2005 +0000
    25.3 @@ -12,6 +12,10 @@
    25.4  #ifdef __KERNEL__
    25.5  #ifndef __ASSEMBLY__
    25.6  
    25.7 +#ifdef CONFIG_XEN_SHADOW_MODE
    25.8 +#include <asm/bug.h>
    25.9 +#endif /* CONFIG_XEN_SHADOW_MODE */
   25.10 +
   25.11  #include <linux/config.h>
   25.12  #include <linux/string.h>
   25.13  #include <linux/types.h>
   25.14 @@ -55,18 +59,37 @@
   25.15  #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
   25.16  
   25.17  /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
   25.18 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.19  extern unsigned int *phys_to_machine_mapping;
   25.20  #define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
   25.21  #define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
   25.22  static inline unsigned long phys_to_machine(unsigned long phys)
   25.23 +#else /* CONFIG_XEN_SHADOW_MODE */
   25.24 +extern unsigned int *__vms_phys_to_machine_mapping;
   25.25 +#define __vms_pfn_to_mfn(_pfn) ((unsigned long)(__vms_phys_to_machine_mapping[(_pfn)]))
   25.26 +#define __vms_mfn_to_pfn(_mfn) ({ BUG(); ((unsigned long)(__vms_machine_to_phys_mapping[(_mfn)])); })
   25.27 +static inline unsigned long __vms_phys_to_machine(unsigned long phys)
   25.28 +#endif /* CONFIG_XEN_SHADOW_MODE */
   25.29  {
   25.30 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.31  	unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
   25.32 +#else /* CONFIG_XEN_SHADOW_MODE */
   25.33 +	unsigned long machine = __vms_pfn_to_mfn(phys >> PAGE_SHIFT);
   25.34 +#endif /* CONFIG_XEN_SHADOW_MODE */
   25.35  	machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
   25.36  	return machine;
   25.37  }
   25.38 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.39  static inline unsigned long machine_to_phys(unsigned long machine)
   25.40 +#else /* CONFIG_XEN_SHADOW_MODE */
   25.41 +static inline unsigned long __vms_machine_to_phys(unsigned long machine)
   25.42 +#endif /* CONFIG_XEN_SHADOW_MODE */
   25.43  {
   25.44 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.45  	unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT);
   25.46 +#else /* CONFIG_XEN_SHADOW_MODE */
   25.47 +	unsigned long phys = __vms_mfn_to_pfn(machine >> PAGE_SHIFT);
   25.48 +#endif /* CONFIG_XEN_SHADOW_MODE */
   25.49  	phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
   25.50  	return phys;
   25.51  }
   25.52 @@ -89,9 +112,14 @@ typedef struct { unsigned long pmd; } pm
   25.53  typedef struct { unsigned long pgd; } pgd_t;
   25.54  typedef struct { unsigned long pgprot; } pgprot_t;
   25.55  #define boot_pte_t pte_t /* or would you rather have a typedef */
   25.56 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.57  #define pte_val(x)	(((x).pte_low & 1) ? machine_to_phys((x).pte_low) : \
   25.58  			 (x).pte_low)
   25.59  #define pte_val_ma(x)	((x).pte_low)
   25.60 +#else /* CONFIG_XEN_SHADOW_MODE */
   25.61 +#define pte_val(x)	((x).pte_low)
   25.62 +#define __vms_pte_val_ma(x)	((x).pte_low)
   25.63 +#endif /* CONFIG_XEN_SHADOW_MODE */
   25.64  #define HPAGE_SHIFT	22
   25.65  #endif
   25.66  #define PTE_MASK	PAGE_MASK
   25.67 @@ -106,22 +134,32 @@ typedef struct { unsigned long pgprot; }
   25.68  
   25.69  static inline unsigned long pmd_val(pmd_t x)
   25.70  {
   25.71 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.72  	unsigned long ret = x.pmd;
   25.73  	if (ret) ret = machine_to_phys(ret);
   25.74  	return ret;
   25.75 +#else /* CONFIG_XEN_SHADOW_MODE */
   25.76 +	return x.pmd;
   25.77 +#endif /* CONFIG_XEN_SHADOW_MODE */
   25.78  }
   25.79  #define pgd_val(x)	({ BUG(); (unsigned long)0; })
   25.80  #define pgprot_val(x)	((x).pgprot)
   25.81  
   25.82  static inline pte_t __pte(unsigned long x)
   25.83  {
   25.84 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.85  	if (x & 1) x = phys_to_machine(x);
   25.86 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   25.87  	return ((pte_t) { (x) });
   25.88  }
   25.89 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.90  #define __pte_ma(x)	((pte_t) { (x) } )
   25.91 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   25.92  static inline pmd_t __pmd(unsigned long x)
   25.93  {
   25.94 +#ifndef CONFIG_XEN_SHADOW_MODE
   25.95  	if ((x & 1)) x = phys_to_machine(x);
   25.96 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   25.97  	return ((pmd_t) { (x) });
   25.98  }
   25.99  #define __pgd(x)	({ BUG(); (pgprot_t) { 0 }; })
  25.100 @@ -199,8 +237,13 @@ extern int sysctl_legacy_va_layout;
  25.101  		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
  25.102  
  25.103  /* VIRT <-> MACHINE conversion */
  25.104 +#ifndef CONFIG_XEN_SHADOW_MODE
  25.105  #define virt_to_machine(_a)	(phys_to_machine(__pa(_a)))
  25.106  #define machine_to_virt(_m)	(__va(machine_to_phys(_m)))
  25.107 +#else /* CONFIG_XEN_SHADOW_MODE */
  25.108 +#define __vms_virt_to_machine(_a)	(__vms_phys_to_machine(__pa(_a)))
  25.109 +#define __vms_machine_to_virt(_m)	(__va(__vms_machine_to_phys(_m)))
  25.110 +#endif /* CONFIG_XEN_SHADOW_MODE */
  25.111  
  25.112  #endif /* __KERNEL__ */
  25.113  
    26.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Wed Mar 16 19:30:47 2005 +0000
    26.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h	Mon Mar 21 16:41:29 2005 +0000
    26.3 @@ -16,7 +16,9 @@ static inline void pmd_populate(struct m
    26.4  	set_pmd(pmd, __pmd(_PAGE_TABLE +
    26.5  		((unsigned long long)page_to_pfn(pte) <<
    26.6  			(unsigned long long) PAGE_SHIFT)));
    26.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    26.8  	flush_page_update_queue();
    26.9 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   26.10  }
   26.11  /*
   26.12   * Allocate and free page tables.
   26.13 @@ -31,8 +33,10 @@ extern struct page *pte_alloc_one(struct
   26.14  static inline void pte_free_kernel(pte_t *pte)
   26.15  {
   26.16  	free_page((unsigned long)pte);
   26.17 +#ifndef CONFIG_XEN_SHADOW_MODE
   26.18  	make_page_writable(pte);
   26.19  	flush_page_update_queue();
   26.20 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   26.21  }
   26.22  
   26.23  extern void pte_free(struct page *pte);
    27.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Wed Mar 16 19:30:47 2005 +0000
    27.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h	Mon Mar 21 16:41:29 2005 +0000
    27.3 @@ -58,7 +58,11 @@ do { \
    27.4   * (pmds are folded into pgds so this doesn't get actually called,
    27.5   * but the define is needed for a generic inline function.)
    27.6   */
    27.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    27.8  #define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval).pmd)
    27.9 +#else /* CONFIG_XEN_SHADOW_MODE */
   27.10 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
   27.11 +#endif /* CONFIG_XEN_SHADOW_MODE */
   27.12  #define set_pgd(pgdptr, pgdval) ((void)0)
   27.13  
   27.14  #define pgd_page(pgd) \
   27.15 @@ -82,7 +86,11 @@ static inline pte_t ptep_get_and_clear(p
   27.16  {
   27.17  	pte_t pte = *xp;
   27.18  	if (pte.pte_low)
   27.19 +#ifndef CONFIG_XEN_SHADOW_MODE
   27.20  		set_pte(xp, __pte_ma(0));
   27.21 +#else /* CONFIG_XEN_SHADOW_MODE */
   27.22 +		set_pte(xp, __pte(0));
   27.23 +#endif /* CONFIG_XEN_SHADOW_MODE */
   27.24  	return pte;
   27.25  }
   27.26  
   27.27 @@ -109,6 +117,7 @@ static inline pte_t ptep_get_and_clear(p
   27.28   */
   27.29  #define INVALID_P2M_ENTRY (~0U)
   27.30  #define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
   27.31 +#ifndef CONFIG_XEN_SHADOW_MODE
   27.32  #define pte_pfn(_pte)							\
   27.33  ({									\
   27.34  	unsigned long mfn = (_pte).pte_low >> PAGE_SHIFT;		\
   27.35 @@ -117,12 +126,17 @@ static inline pte_t ptep_get_and_clear(p
   27.36  		pfn = max_mapnr; /* special: force !pfn_valid() */	\
   27.37  	pfn;								\
   27.38  })
   27.39 +#else /* CONFIG_XEN_SHADOW_MODE */
   27.40 +#define pte_pfn(_pte)		((_pte).pte_low >> PAGE_SHIFT)
   27.41 +#endif /* CONFIG_XEN_SHADOW_MODE */
   27.42  
   27.43  #define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
   27.44  
   27.45  #define pte_none(x)		(!(x).pte_low)
   27.46  #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
   27.47 +#ifndef CONFIG_XEN_SHADOW_MODE
   27.48  #define pfn_pte_ma(pfn, prot)	__pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
   27.49 +#endif /* ! CONFIG_XEN_SHADOW_MODE */
   27.50  #define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
   27.51  
   27.52  /*
    28.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Wed Mar 16 19:30:47 2005 +0000
    28.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Mon Mar 21 16:41:29 2005 +0000
    28.3 @@ -319,10 +319,16 @@ static inline pte_t pte_modify(pte_t pte
    28.4  #define pmd_page_kernel(pmd) \
    28.5  ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
    28.6  
    28.7 -#define pmd_clear(xp)	do {					\
    28.8 +#ifndef CONFIG_XEN_SHADOW_MODE
    28.9 +#define pmd_clear(xp) do {					\
   28.10  	set_pmd(xp, __pmd(0));					\
   28.11  	xen_flush_page_update_queue();				\
   28.12  } while (0)
   28.13 +#else /* CONFIG_XEN_SHADOW_MODE */
   28.14 +#define pmd_clear(xp)	do {					\
   28.15 +	set_pmd(xp, __pmd(0));					\
   28.16 +} while (0)
   28.17 +#endif /* CONFIG_XEN_SHADOW_MODE */
   28.18  
   28.19  #ifndef CONFIG_DISCONTIGMEM
   28.20  #define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
   28.21 @@ -460,6 +466,7 @@ void make_page_writable(void *va);
   28.22  void make_pages_readonly(void *va, unsigned int nr);
   28.23  void make_pages_writable(void *va, unsigned int nr);
   28.24  
   28.25 +#ifndef CONFIG_XEN_SHADOW_MODE
   28.26  #define arbitrary_virt_to_machine(__va)					\
   28.27  ({									\
   28.28  	pgd_t *__pgd = pgd_offset_k((unsigned long)(__va));		\
   28.29 @@ -468,6 +475,27 @@ void make_pages_writable(void *va, unsig
   28.30  	unsigned long __pa = (*(unsigned long *)__pte) & PAGE_MASK;	\
   28.31  	__pa | ((unsigned long)(__va) & (PAGE_SIZE-1));			\
   28.32  })
   28.33 +#else /* CONFIG_XEN_SHADOW_MODE */
   28.34 +#define __vms_arbitrary_virt_to_machine(__va)					\
   28.35 +({									\
   28.36 +	pgd_t *__pgd = pgd_offset_k((unsigned long)(__va));		\
   28.37 +	pmd_t *__pmd = pmd_offset(__pgd, (unsigned long)(__va));	\
   28.38 +	pte_t *__pte = pte_offset_kernel(__pmd, (unsigned long)(__va));	\
   28.39 +	unsigned long __pa = (*(unsigned long *)__pte) & PAGE_MASK;	\
   28.40 +	__vms_phys_to_machine(__pa) | ((unsigned long)(__va) & (PAGE_SIZE-1)); \
   28.41 +})
   28.42 +#endif /* CONFIG_XEN_SHADOW_MODE */
   28.43 +
   28.44 +#ifdef CONFIG_XEN_SHADOW_MODE
   28.45 +#define arbitrary_virt_to_phys(__va)					\
   28.46 +({									\
   28.47 +	pgd_t *__pgd = pgd_offset_k((unsigned long)(__va));		\
   28.48 +	pmd_t *__pmd = pmd_offset(__pgd, (unsigned long)(__va));	\
   28.49 +	pte_t *__pte = pte_offset_kernel(__pmd, (unsigned long)(__va));	\
   28.50 +	unsigned long __pa = (*(unsigned long *)__pte) & PAGE_MASK;	\
   28.51 +	(__pa) | ((unsigned long)(__va) & (PAGE_SIZE-1));               \
   28.52 +})
   28.53 +#endif /* CONFIG_XEN_SHADOW_MODE */
   28.54  
   28.55  #endif /* !__ASSEMBLY__ */
   28.56  
    29.1 --- a/xen/arch/x86/audit.c	Wed Mar 16 19:30:47 2005 +0000
    29.2 +++ b/xen/arch/x86/audit.c	Mon Mar 21 16:41:29 2005 +0000
    29.3 @@ -36,6 +36,7 @@ static int ttot=0, ctot=0, io_mappings=0
    29.4  static int l1, l2, oos_count, page_count;
    29.5  
    29.6  #define FILE_AND_LINE 0
    29.7 +//#define MFN2_TO_WATCH 0x1d8
    29.8  
    29.9  #if FILE_AND_LINE
   29.10  #define adjust(_p, _a) _adjust((_p), (_a), __FILE__, __LINE__)
   29.11 @@ -51,9 +52,17 @@ int audit_adjust_pgtables(struct domain 
   29.12  {
   29.13      int errors = 0;
   29.14      int shadow_enabled = shadow_mode_enabled(d) ? 1 : 0;
   29.15 +    int l2limit;
   29.16  
   29.17      void _adjust(struct pfn_info *page, int adjtype ADJUST_EXTRA_ARGS)
   29.18      {
   29.19 +#ifdef MFN2_TO_WATCH
   29.20 +        if (page_to_pfn(page) == MFN2_TO_WATCH)
   29.21 +        {
   29.22 +            APRINTK("adjust(mfn=%p, dir=%d, adjtype=%d)",
   29.23 +                    page_to_pfn(page), dir, adjtype);
   29.24 +        }
   29.25 +#endif
   29.26          if ( adjtype )
   29.27          {
   29.28              // adjust the type count
   29.29 @@ -97,7 +106,7 @@ int audit_adjust_pgtables(struct domain 
   29.30  
   29.31          if ( count < 0 )
   29.32          {
   29.33 -            APRINTK("Audit %d: general count went below zero pfn=%x t=%x ot=%x",
   29.34 +            APRINTK("Audit %d: general count went below zero mfn=%x t=%x ot=%x",
   29.35                      d->id, page-frame_table,
   29.36                      page->u.inuse.type_info,
   29.37                      page->tlbflush_timestamp);
   29.38 @@ -105,7 +114,7 @@ int audit_adjust_pgtables(struct domain 
   29.39          }
   29.40          else if ( (count & ~PGT_count_mask) != 0 )
   29.41          {
   29.42 -            APRINTK("Audit %d: general count overflowed pfn=%x t=%x ot=%x",
   29.43 +            APRINTK("Audit %d: general count overflowed mfn=%x t=%x ot=%x",
   29.44                      d->id, page-frame_table,
   29.45                      page->u.inuse.type_info,
   29.46                      page->tlbflush_timestamp);
   29.47 @@ -115,17 +124,12 @@ int audit_adjust_pgtables(struct domain 
   29.48              page->count_info += dir;
   29.49      }
   29.50  
   29.51 -    void adjust_l2_page(unsigned long mfn, int adjtype)
   29.52 +    void adjust_l2_page(unsigned long mfn)
   29.53      {
   29.54          unsigned long *pt = map_domain_mem(mfn << PAGE_SHIFT);
   29.55 -        int i, limit;
   29.56 +        int i;
   29.57  
   29.58 -        if ( shadow_mode_external(d) )
   29.59 -            limit = L2_PAGETABLE_ENTRIES;
   29.60 -        else
   29.61 -            limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
   29.62 -
   29.63 -        for ( i = 0; i < limit; i++ )
   29.64 +        for ( i = 0; i < l2limit; i++ )
   29.65          {
   29.66              if ( pt[i] & _PAGE_PRESENT )
   29.67              {
   29.68 @@ -180,7 +184,61 @@ int audit_adjust_pgtables(struct domain 
   29.69                      }
   29.70                  }
   29.71  
   29.72 -                adjust(l1page, adjtype);
   29.73 +                adjust(l1page, !shadow_enabled);
   29.74 +            }
   29.75 +        }
   29.76 +
   29.77 +        if ( shadow_mode_translate(d) && !shadow_mode_external(d) )
   29.78 +        {
   29.79 +            unsigned long hl2mfn =
   29.80 +                pt[l2_table_offset(LINEAR_PT_VIRT_START)] >> PAGE_SHIFT;
   29.81 +            struct pfn_info *hl2page = pfn_to_page(hl2mfn);
   29.82 +            adjust(hl2page, 0);
   29.83 +        }
   29.84 +
   29.85 +        unmap_domain_mem(pt);
   29.86 +    }
   29.87 +
   29.88 +    void adjust_hl2_page(unsigned long hl2mfn)
   29.89 +    {
   29.90 +        unsigned long *pt = map_domain_mem(hl2mfn << PAGE_SHIFT);
   29.91 +        int i;
   29.92 +
   29.93 +        for ( i = 0; i < l2limit; i++ )
   29.94 +        {
   29.95 +            if ( pt[i] & _PAGE_PRESENT )
   29.96 +            {
   29.97 +                unsigned long gmfn = pt[i] >> PAGE_SHIFT;
   29.98 +                struct pfn_info *gpage = pfn_to_page(gmfn);
   29.99 +
  29.100 +                if ( gmfn < 0x100 )
  29.101 +                {
  29.102 +                    lowmem_mappings++;
  29.103 +                    continue;
  29.104 +                }
  29.105 +
  29.106 +                if ( gmfn > max_page )
  29.107 +                {
  29.108 +                    io_mappings++;
  29.109 +                    continue;
  29.110 +                }
  29.111 +
  29.112 +                if ( noisy )
  29.113 +                {
  29.114 +                    if ( page_get_owner(gpage) != d )
  29.115 +                    {
  29.116 +                        printk("Audit %d: [hl2mfn=%p,i=%x] Skip foreign page "
  29.117 +                               "dom=%p (id=%d) mfn=%p c=%08x t=%08x\n",
  29.118 +                               d->id, hl2mfn, i,
  29.119 +                               page_get_owner(gpage),
  29.120 +                               page_get_owner(gpage)->id,
  29.121 +                               gmfn,
  29.122 +                               gpage->count_info,
  29.123 +                               gpage->u.inuse.type_info);
  29.124 +                        continue;
  29.125 +                    }
  29.126 +                }
  29.127 +                adjust(gpage, 0);
  29.128              }
  29.129          }
  29.130  
  29.131 @@ -275,19 +333,27 @@ int audit_adjust_pgtables(struct domain 
  29.132                  smfn = a->smfn;
  29.133                  page = &frame_table[smfn];
  29.134  
  29.135 -                adjust(pfn_to_page(gmfn), 0);
  29.136 -
  29.137                  switch ( a->gpfn_and_flags & PGT_type_mask ) {
  29.138 +                case PGT_writable_pred:
  29.139 +                    break;
  29.140                  case PGT_snapshot:
  29.141 +                    adjust(pfn_to_page(gmfn), 0);
  29.142                      break;
  29.143                  case PGT_l1_shadow:
  29.144 -                case PGT_hl2_shadow:
  29.145 +                    adjust(pfn_to_page(gmfn), 0);
  29.146                      adjust_l1_page(smfn);
  29.147                      if ( page->u.inuse.type_info & PGT_pinned )
  29.148                          adjust(page, 0);
  29.149                      break;
  29.150 +                case PGT_hl2_shadow:
  29.151 +                    adjust(pfn_to_page(gmfn), 0);
  29.152 +                    adjust_hl2_page(smfn);
  29.153 +                    if ( page->u.inuse.type_info & PGT_pinned )
  29.154 +                        adjust(page, 0);
  29.155 +                    break;
  29.156                  case PGT_l2_shadow:
  29.157 -                    adjust_l2_page(smfn, 0);
  29.158 +                    adjust(pfn_to_page(gmfn), 0);
  29.159 +                    adjust_l2_page(smfn);
  29.160                      if ( page->u.inuse.type_info & PGT_pinned )
  29.161                          adjust(page, 0);
  29.162                      break;
  29.163 @@ -317,6 +383,9 @@ int audit_adjust_pgtables(struct domain 
  29.164              if ( !(oos->writable_pl1e & (sizeof(l1_pgentry_t)-1)) )
  29.165                  adjust(pfn_to_page(oos->writable_pl1e >> PAGE_SHIFT), 0);
  29.166  
  29.167 +            if ( oos->snapshot_mfn != SHADOW_SNAPSHOT_ELSEWHERE )
  29.168 +                adjust(pfn_to_page(oos->snapshot_mfn), 0);
  29.169 +
  29.170              oos = oos->next;
  29.171              oos_count++;
  29.172          }
  29.173 @@ -400,7 +469,7 @@ int audit_adjust_pgtables(struct domain 
  29.174                      adjust(page, 1);
  29.175  
  29.176                  if ( page->u.inuse.type_info & PGT_validated )
  29.177 -                    adjust_l2_page(mfn, 1);
  29.178 +                    adjust_l2_page(mfn);
  29.179  
  29.180                  break;
  29.181  
  29.182 @@ -468,6 +537,11 @@ int audit_adjust_pgtables(struct domain 
  29.183          }
  29.184      }
  29.185  
  29.186 +    if ( shadow_mode_external(d) )
  29.187 +        l2limit = L2_PAGETABLE_ENTRIES;
  29.188 +    else
  29.189 +        l2limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
  29.190 +
  29.191      adjust_for_pgtbase();
  29.192  
  29.193      adjust_guest_pages();
  29.194 @@ -478,13 +552,16 @@ int audit_adjust_pgtables(struct domain 
  29.195          adjust_shadow_tables();
  29.196      }
  29.197  
  29.198 +    //printk("d->shared_info=%p __pa()=%p\n", d->shared_info, __pa(d->shared_info));
  29.199 +    adjust(virt_to_page(d->shared_info), 1);
  29.200 +
  29.201      return errors;
  29.202  }
  29.203  
  29.204  
  29.205  #ifndef NDEBUG
  29.206  
  29.207 -void _audit_domain(struct domain *d, int flags, const char *file, int line)
  29.208 +void _audit_domain(struct domain *d, int flags)
  29.209  {
  29.210      void scan_for_pfn_in_mfn(struct domain *d, unsigned long xmfn,
  29.211                               unsigned long mfn)
  29.212 @@ -546,6 +623,7 @@ void _audit_domain(struct domain *d, int
  29.213                          scan_for_pfn_in_mfn(d, xmfn, a->smfn);
  29.214                          break;
  29.215                      case PGT_snapshot:
  29.216 +                    case PGT_writable_pred:
  29.217                          break;
  29.218                      default:
  29.219                          BUG();
  29.220 @@ -569,6 +647,14 @@ void _audit_domain(struct domain *d, int
  29.221      struct pfn_info *page;
  29.222      int errors = 0;
  29.223  
  29.224 +    if ( (d != current->domain) && shadow_mode_translate(d) )
  29.225 +    {
  29.226 +        printk("skipping audit domain of translated domain %d "
  29.227 +               "from other context\n",
  29.228 +               d->id);
  29.229 +        return;
  29.230 +    }
  29.231 +
  29.232      if ( d != current->domain )
  29.233          domain_pause(d);
  29.234      synchronise_pagetables(~0UL);
  29.235 @@ -740,11 +826,10 @@ void _audit_domain(struct domain *d, int
  29.236                  page_type = a->gpfn_and_flags & PGT_type_mask;
  29.237  
  29.238                  switch ( page_type ) {
  29.239 -                case PGT_snapshot:
  29.240 -                    // XXX -- what should we check here?
  29.241 -                    break;
  29.242                  case PGT_l1_shadow:
  29.243                  case PGT_l2_shadow:
  29.244 +                case PGT_hl2_shadow:
  29.245 +                case PGT_snapshot:
  29.246                      if ( ((page->u.inuse.type_info & PGT_type_mask) != page_type ) ||
  29.247                           (page->count_info != 0) )
  29.248                      {
  29.249 @@ -755,8 +840,10 @@ void _audit_domain(struct domain *d, int
  29.250                          errors++;
  29.251                      }
  29.252                      break;
  29.253 +                case PGT_writable_pred:
  29.254 +                    // XXX - nothing to check?
  29.255 +                    break;
  29.256  
  29.257 -                case PGT_hl2_shadow: // haven't thought about this case yet.
  29.258                  default:
  29.259                      BUG();
  29.260                      break;
  29.261 @@ -781,9 +868,9 @@ void _audit_domain(struct domain *d, int
  29.262      spin_unlock(&d->page_alloc_lock);
  29.263  
  29.264      if ( !(flags & AUDIT_QUIET) )
  29.265 -        printk("Audit dom%d (%s:%d) Done. "
  29.266 +        printk("Audit dom%d Done. "
  29.267                 "pages=%d oos=%d l1=%d l2=%d ctot=%d ttot=%d\n",
  29.268 -               d->id, file, line, page_count, oos_count, l1, l2, ctot, ttot );
  29.269 +               d->id, page_count, oos_count, l1, l2, ctot, ttot);
  29.270  
  29.271      if ( !(flags & AUDIT_ALREADY_LOCKED) )
  29.272          shadow_unlock(d);
    30.1 --- a/xen/arch/x86/domain.c	Wed Mar 16 19:30:47 2005 +0000
    30.2 +++ b/xen/arch/x86/domain.c	Mon Mar 21 16:41:29 2005 +0000
    30.3 @@ -238,7 +238,7 @@ void arch_do_createdomain(struct exec_do
    30.4          d->shared_info = (void *)alloc_xenheap_page();
    30.5          memset(d->shared_info, 0, PAGE_SIZE);
    30.6          ed->vcpu_info = &d->shared_info->vcpu_data[ed->eid];
    30.7 -        SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
    30.8 +        SHARE_PFN_WITH_DOMAIN2(virt_to_page(d->shared_info), d);
    30.9          machine_to_phys_mapping[virt_to_phys(d->shared_info) >> 
   30.10                                 PAGE_SHIFT] = INVALID_M2P_ENTRY;
   30.11  
   30.12 @@ -344,8 +344,6 @@ static int vmx_final_setup_guest(struct 
   30.13          shadow_mode_enable(ed->domain, SHM_enable|SHM_translate|SHM_external);
   30.14      }
   30.15  
   30.16 -    update_pagetables(ed);
   30.17 -
   30.18      return 0;
   30.19  
   30.20  out:
   30.21 @@ -416,7 +414,7 @@ int arch_final_setup_guest(
   30.22      ed->arch.failsafe_address  = c->failsafe_callback_eip;
   30.23  
   30.24      phys_basetab = c->pt_base;
   30.25 -    ed->arch.guest_table = ed->arch.phys_table = mk_pagetable(phys_basetab);
   30.26 +    ed->arch.guest_table = mk_pagetable(phys_basetab);
   30.27  
   30.28      if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, 
   30.29                              PGT_base_page_table) )
   30.30 @@ -435,8 +433,22 @@ int arch_final_setup_guest(
   30.31      }
   30.32  
   30.33  #ifdef CONFIG_VMX
   30.34 -    if (c->flags & ECF_VMX_GUEST)
   30.35 -        return vmx_final_setup_guest(ed, c);
   30.36 +    if ( c->flags & ECF_VMX_GUEST )
   30.37 +    {
   30.38 +        int error;
   30.39 +
   30.40 +        // VMX uses the initially provided page tables as the P2M map.
   30.41 +        //
   30.42 +        // XXX: This creates a security issue -- Xen can't necessarily
   30.43 +        //      trust the VMX domain builder.  Xen should validate this
   30.44 +        //      page table, and/or build the table itself, or ???
   30.45 +        //
   30.46 +        if ( !pagetable_val(d->arch.phys_table) )
   30.47 +            d->arch.phys_table = ed->arch.guest_table;
   30.48 +
   30.49 +        if ( (error = vmx_final_setup_guest(ed, c)) )
   30.50 +            return error;
   30.51 +    }
   30.52  #endif
   30.53  
   30.54      update_pagetables(ed);
    31.1 --- a/xen/arch/x86/domain_build.c	Wed Mar 16 19:30:47 2005 +0000
    31.2 +++ b/xen/arch/x86/domain_build.c	Mon Mar 21 16:41:29 2005 +0000
    31.3 @@ -84,6 +84,8 @@ int construct_dom0(struct domain *d,
    31.4      l2_pgentry_t *l2tab = NULL, *l2start = NULL;
    31.5      l1_pgentry_t *l1tab = NULL, *l1start = NULL;
    31.6  
    31.7 +    int translate_dom0 = 1; // HACK ALERT !!  Force dom0 to run in shadow translate mode
    31.8 +
    31.9      /*
   31.10       * This fully describes the memory layout of the initial domain. All 
   31.11       * *_start address are page-aligned, except v_start (and v_end) which are 
   31.12 @@ -106,6 +108,7 @@ int construct_dom0(struct domain *d,
   31.13      unsigned long mpt_alloc;
   31.14  
   31.15      extern void physdev_init_dom0(struct domain *);
   31.16 +    extern void translate_l2pgtable(struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
   31.17  
   31.18      /* Sanity! */
   31.19      if ( d->id != 0 ) 
   31.20 @@ -422,7 +425,7 @@ int construct_dom0(struct domain *d,
   31.21          d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
   31.22      d->shared_info->n_vcpu = smp_num_cpus;
   31.23  
   31.24 -    /* Set up shadow and monitor tables. */
   31.25 +    /* setup monitor table */
   31.26      update_pagetables(ed);
   31.27  
   31.28      /* Install the new page tables. */
   31.29 @@ -441,12 +444,22 @@ int construct_dom0(struct domain *d,
   31.30          init_domheap_pages(
   31.31              _initrd_start, (_initrd_start+initrd_len+PAGE_SIZE-1) & PAGE_MASK);
   31.32      }
   31.33 -    
   31.34 +
   31.35 +    d->next_io_page = d->max_pages;
   31.36 +
   31.37      /* Set up start info area. */
   31.38      si = (start_info_t *)vstartinfo_start;
   31.39      memset(si, 0, PAGE_SIZE);
   31.40      si->nr_pages     = nr_pages;
   31.41 +#define NASTY_HACK
   31.42 +#ifdef NASTY_HACK
   31.43 +    si->shared_info  = d->next_io_page << PAGE_SHIFT;
   31.44 +    set_machinetophys(virt_to_phys(d->shared_info) >> PAGE_SHIFT,
   31.45 +                      d->next_io_page);
   31.46 +    d->next_io_page++;
   31.47 +#else
   31.48      si->shared_info  = virt_to_phys(d->shared_info);
   31.49 +#endif
   31.50      si->flags        = SIF_PRIVILEGED | SIF_INITDOMAIN;
   31.51      si->pt_base      = vpt_start;
   31.52      si->nr_pt_frames = nr_pt_pages;
   31.53 @@ -456,11 +469,13 @@ int construct_dom0(struct domain *d,
   31.54      for ( pfn = 0; pfn < d->tot_pages; pfn++ )
   31.55      {
   31.56          mfn = pfn + (alloc_start>>PAGE_SHIFT);
   31.57 +#if 0
   31.58  #ifndef NDEBUG
   31.59  #define REVERSE_START ((v_end - dsi.v_start) >> PAGE_SHIFT)
   31.60          if ( pfn > REVERSE_START )
   31.61              mfn = (alloc_end>>PAGE_SHIFT) - (pfn - REVERSE_START);
   31.62  #endif
   31.63 +#endif
   31.64          ((u32 *)vphysmap_start)[pfn] = mfn;
   31.65          machine_to_phys_mapping[mfn] = pfn;
   31.66      }
   31.67 @@ -520,9 +535,27 @@ int construct_dom0(struct domain *d,
   31.68  
   31.69      new_thread(ed, dsi.v_kernentry, vstack_end, vstartinfo_start);
   31.70  
   31.71 -    if ( opt_dom0_shadow )
   31.72 +    if ( opt_dom0_shadow || translate_dom0 )
   31.73      {
   31.74 -        shadow_mode_enable(d, SHM_enable); 
   31.75 +        shadow_mode_enable(d, (translate_dom0
   31.76 +                               ? SHM_enable | SHM_translate
   31.77 +                               : SHM_enable));
   31.78 +        if ( translate_dom0 )
   31.79 +        {
   31.80 +            // map this domain's p2m table into current page table,
   31.81 +            // so that we can easily access it.
   31.82 +            //
   31.83 +            ASSERT( root_pgentry_val(idle_pg_table[1]) == 0 );
   31.84 +            ASSERT( pagetable_val(d->arch.phys_table) );
   31.85 +            idle_pg_table[1] = mk_root_pgentry(
   31.86 +                pagetable_val(d->arch.phys_table) | __PAGE_HYPERVISOR);
   31.87 +            translate_l2pgtable(d, (l1_pgentry_t *)(1u << L2_PAGETABLE_SHIFT),
   31.88 +                                pagetable_val(ed->arch.guest_table)
   31.89 +                                >> PAGE_SHIFT);
   31.90 +            idle_pg_table[1] = mk_root_pgentry(0);
   31.91 +            local_flush_tlb();
   31.92 +        }
   31.93 +
   31.94          update_pagetables(ed); /* XXX SMP */
   31.95      }
   31.96  
    32.1 --- a/xen/arch/x86/extable.c	Wed Mar 16 19:30:47 2005 +0000
    32.2 +++ b/xen/arch/x86/extable.c	Mon Mar 21 16:41:29 2005 +0000
    32.3 @@ -3,6 +3,11 @@
    32.4  #include <xen/spinlock.h>
    32.5  #include <asm/uaccess.h>
    32.6  
    32.7 +#ifdef PERF_COUNTERS
    32.8 +#include <xen/sched.h>
    32.9 +#include <xen/perfc.h>
   32.10 +#endif
   32.11 +
   32.12  extern struct exception_table_entry __start___ex_table[];
   32.13  extern struct exception_table_entry __stop___ex_table[];
   32.14  extern struct exception_table_entry __start___pre_ex_table[];
   32.15 @@ -69,5 +74,9 @@ search_pre_exception_table(struct xen_re
   32.16      unsigned long fixup = search_one_table(
   32.17          __start___pre_ex_table, __stop___pre_ex_table-1, addr);
   32.18      DPRINTK("Pre-exception: %p -> %p\n", addr, fixup);
   32.19 +#ifdef PERF_COUNTERS
   32.20 +    if ( fixup )
   32.21 +        perfc_incrc(exception_fixed);
   32.22 +#endif
   32.23      return fixup;
   32.24  }
    33.1 --- a/xen/arch/x86/mm.c	Wed Mar 16 19:30:47 2005 +0000
    33.2 +++ b/xen/arch/x86/mm.c	Mon Mar 21 16:41:29 2005 +0000
    33.3 @@ -262,13 +262,13 @@ int map_ldt_shadow_page(unsigned int off
    33.4  
    33.5      gpfn = l1_pgentry_to_pfn(mk_l1_pgentry(l1e));
    33.6      gmfn = __gpfn_to_mfn(d, gpfn);
    33.7 -    if ( unlikely(!gmfn) )
    33.8 +    if ( unlikely(!VALID_MFN(gmfn)) )
    33.9          return 0;
   33.10  
   33.11      if ( unlikely(shadow_mode_enabled(d)) )
   33.12      {
   33.13          shadow_lock(d);
   33.14 -        shadow_remove_all_write_access(d, PGT_l1_shadow, PGT_l1_shadow, gpfn);
   33.15 +        shadow_remove_all_write_access(d, gpfn, gmfn);
   33.16      }
   33.17  
   33.18      res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
   33.19 @@ -1088,7 +1088,7 @@ void free_page_type(struct pfn_info *pag
   33.20  }
   33.21  
   33.22  
   33.23 -void put_page_type(struct pfn_info *page)
   33.24 +void _put_page_type(struct pfn_info *page)
   33.25  {
   33.26      u32 nx, x, y = page->u.inuse.type_info;
   33.27  
   33.28 @@ -1143,7 +1143,7 @@ void put_page_type(struct pfn_info *page
   33.29  }
   33.30  
   33.31  
   33.32 -int get_page_type(struct pfn_info *page, u32 type)
   33.33 +int _get_page_type(struct pfn_info *page, u32 type)
   33.34  {
   33.35      u32 nx, x, y = page->u.inuse.type_info;
   33.36  
   33.37 @@ -1286,8 +1286,7 @@ static int do_extended_command(unsigned 
   33.38      unsigned int cmd = val & MMUEXT_CMD_MASK, type;
   33.39      struct exec_domain *ed = current;
   33.40      struct domain *d = ed->domain, *e;
   33.41 -    unsigned long gpfn = ptr >> PAGE_SHIFT;
   33.42 -    unsigned long mfn = __gpfn_to_mfn(d, gpfn);
   33.43 +    unsigned long mfn = ptr >> PAGE_SHIFT;
   33.44      struct pfn_info *page = &frame_table[mfn];
   33.45      u32 x, y, _d, _nd;
   33.46      domid_t domid;
   33.47 @@ -1304,15 +1303,6 @@ static int do_extended_command(unsigned 
   33.48          type = PGT_l1_page_table | PGT_va_mutable;
   33.49  
   33.50      pin_page:
   33.51 -        if ( unlikely(percpu_info[cpu].foreign &&
   33.52 -                      (shadow_mode_translate(d) ||
   33.53 -                       shadow_mode_translate(percpu_info[cpu].foreign))) )
   33.54 -        {
   33.55 -            // oops -- we should be using the foreign domain's P2M
   33.56 -            mfn = __gpfn_to_mfn(FOREIGNDOM, gpfn);
   33.57 -            page = &frame_table[mfn];
   33.58 -        }
   33.59 -
   33.60          if ( shadow_mode_enabled(FOREIGNDOM) )
   33.61              type = PGT_writable_page;
   33.62  
   33.63 @@ -1349,15 +1339,6 @@ static int do_extended_command(unsigned 
   33.64  #endif /* __x86_64__ */
   33.65  
   33.66      case MMUEXT_UNPIN_TABLE:
   33.67 -        if ( unlikely(percpu_info[cpu].foreign &&
   33.68 -                      (shadow_mode_translate(d) ||
   33.69 -                       shadow_mode_translate(percpu_info[cpu].foreign))) )
   33.70 -        {
   33.71 -            // oops -- we should be using the foreign domain's P2M
   33.72 -            mfn = __gpfn_to_mfn(FOREIGNDOM, gpfn);
   33.73 -            page = &frame_table[mfn];
   33.74 -        }
   33.75 -
   33.76          if ( unlikely(!(okay = get_page_from_pagenr(mfn, FOREIGNDOM))) )
   33.77          {
   33.78              MEM_LOG("mfn %p bad domain (dom=%p)",
   33.79 @@ -1723,9 +1704,7 @@ int do_mmu_update(
   33.80      cleanup_writable_pagetable(d);
   33.81  
   33.82      if ( unlikely(shadow_mode_enabled(d)) )
   33.83 -    {
   33.84          check_pagetable(ed, "pre-mmu"); /* debug */
   33.85 -    }
   33.86  
   33.87      /*
   33.88       * If we are resuming after preemption, read how much work we have already
   33.89 @@ -1784,8 +1763,7 @@ int do_mmu_update(
   33.90          }
   33.91  
   33.92          cmd = req.ptr & (sizeof(l1_pgentry_t)-1);
   33.93 -        gpfn = req.ptr >> PAGE_SHIFT;
   33.94 -        mfn = __gpfn_to_mfn(d, gpfn);
   33.95 +        mfn = req.ptr >> PAGE_SHIFT;
   33.96  
   33.97          okay = 0;
   33.98  
   33.99 @@ -1868,6 +1846,8 @@ int do_mmu_update(
  33.100                          if ( shadow_mode_log_dirty(d) )
  33.101                              __mark_dirty(d, mfn);
  33.102  
  33.103 +                        gpfn = __mfn_to_gpfn(d, mfn);
  33.104 +                        ASSERT(gpfn);
  33.105                          if ( page_is_page_table(page) )
  33.106                              shadow_mark_mfn_out_of_sync(ed, gpfn, mfn);
  33.107                      }
  33.108 @@ -1887,6 +1867,21 @@ int do_mmu_update(
  33.109              break;
  33.110  
  33.111          case MMU_MACHPHYS_UPDATE:
  33.112 +
  33.113 +            // HACK ALERT...  This about this later...
  33.114 +            //
  33.115 +            if ( unlikely(shadow_mode_translate(FOREIGNDOM) && IS_PRIV(d)) )
  33.116 +            {
  33.117 +                rc = FOREIGNDOM->next_io_page++;
  33.118 +                printk("privileged guest dom%d requests mfn=%p for dom%d, gets pfn=%p\n",
  33.119 +                       d->id, mfn, FOREIGNDOM->id, rc);
  33.120 +                set_machinetophys(mfn, rc);
  33.121 +                set_p2m_entry(FOREIGNDOM, rc, mfn);
  33.122 +                okay = 1;
  33.123 +                break;
  33.124 +            }
  33.125 +            BUG();
  33.126 +            
  33.127              if ( unlikely(!get_page_from_pagenr(mfn, FOREIGNDOM)) )
  33.128              {
  33.129                  MEM_LOG("Could not get page for mach->phys update");
  33.130 @@ -2251,7 +2246,7 @@ long do_update_descriptor(
  33.131  
  33.132      LOCK_BIGLOCK(dom);
  33.133  
  33.134 -    if ( !(mfn = __gpfn_to_mfn(dom, gpfn)) ) {
  33.135 +    if ( !VALID_MFN(mfn = __gpfn_to_mfn(dom, gpfn)) ) {
  33.136          UNLOCK_BIGLOCK(dom);
  33.137          return -EINVAL;
  33.138      }
    34.1 --- a/xen/arch/x86/shadow.c	Wed Mar 16 19:30:47 2005 +0000
    34.2 +++ b/xen/arch/x86/shadow.c	Mon Mar 21 16:41:29 2005 +0000
    34.3 @@ -48,7 +48,6 @@ static inline int
    34.4  shadow_promote(struct domain *d, unsigned long gpfn, unsigned long gmfn,
    34.5                 unsigned long new_type)
    34.6  {
    34.7 -    unsigned long min_type, max_type;
    34.8      struct pfn_info *page = pfn_to_page(gmfn);
    34.9      int pinned = 0, okay = 1;
   34.10  
   34.11 @@ -61,20 +60,12 @@ shadow_promote(struct domain *d, unsigne
   34.12      }
   34.13  
   34.14      if ( unlikely(page_is_page_table(page)) )
   34.15 -    {
   34.16 -        min_type = shadow_max_pgtable_type(d, gpfn) + PGT_l1_shadow;
   34.17 -        max_type = new_type;
   34.18 -    }
   34.19 -    else
   34.20 -    {
   34.21 -        min_type = PGT_l1_shadow;
   34.22 -        max_type = PGT_l1_shadow;
   34.23 -    }
   34.24 -    FSH_LOG("shadow_promote gpfn=%p gmfn=%p nt=%p min=%p max=%p",
   34.25 -            gmfn, gmfn, new_type, min_type, max_type);
   34.26 -
   34.27 -    if ( min_type <= max_type )
   34.28 -        shadow_remove_all_write_access(d, min_type, max_type, gpfn);
   34.29 +        return 1;
   34.30 +
   34.31 +    FSH_LOG("shadow_promote gpfn=%p gmfn=%p nt=%p", gpfn, gmfn, new_type);
   34.32 +
   34.33 +    if ( !shadow_remove_all_write_access(d, gpfn, gmfn) )
   34.34 +        return 0;
   34.35  
   34.36      // To convert this page to use as a page table, the writable count
   34.37      // should now be zero.  Test this by grabbing the page as an page table,
   34.38 @@ -90,7 +81,7 @@ shadow_promote(struct domain *d, unsigne
   34.39      // shadow_lock() and move the shadow code to BIGLOCK().
   34.40      //
   34.41      if ( unlikely(!get_page(page, d)) )
   34.42 -        BUG();
   34.43 +        BUG(); // XXX -- needs more thought for a graceful failure
   34.44      if ( unlikely(test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info)) )
   34.45      {
   34.46          pinned = 1;
   34.47 @@ -98,8 +89,8 @@ shadow_promote(struct domain *d, unsigne
   34.48      }
   34.49      if ( get_page_type(page, PGT_base_page_table) )
   34.50      {
   34.51 +        set_bit(_PGC_page_table, &page->count_info);
   34.52          put_page_type(page);
   34.53 -        set_bit(_PGC_page_table, &page->count_info);
   34.54      }
   34.55      else
   34.56      {
   34.57 @@ -111,7 +102,7 @@ shadow_promote(struct domain *d, unsigne
   34.58  
   34.59      // Now put the type back to writable...
   34.60      if ( unlikely(!get_page_type(page, PGT_writable_page)) )
   34.61 -        BUG();
   34.62 +        BUG(); // XXX -- needs more thought for a graceful failure
   34.63      if ( unlikely(pinned) )
   34.64      {
   34.65          if ( unlikely(test_and_set_bit(_PGT_pinned,
   34.66 @@ -191,14 +182,6 @@ alloc_shadow_page(struct domain *d,
   34.67      unsigned long smfn;
   34.68      int pin = 0;
   34.69  
   34.70 -    if ( (psh_type != PGT_snapshot) &&
   34.71 -         !shadow_promote(d, gpfn, gmfn, psh_type) )
   34.72 -    {
   34.73 -        FSH_LOG("promotion of pfn=%p mfn=%p failed!  external gnttab refs?\n",
   34.74 -                gpfn, gmfn);
   34.75 -        return 0;
   34.76 -    }
   34.77 -
   34.78      page = alloc_domheap_page(NULL);
   34.79      if ( unlikely(page == NULL) )
   34.80      {
   34.81 @@ -222,11 +205,15 @@ alloc_shadow_page(struct domain *d,
   34.82      switch ( psh_type )
   34.83      {
   34.84      case PGT_l1_shadow:
   34.85 +        if ( !shadow_promote(d, gpfn, gmfn, psh_type) )
   34.86 +            goto fail;
   34.87          perfc_incr(shadow_l1_pages);
   34.88          d->arch.shadow_page_count++;
   34.89          break;
   34.90  
   34.91      case PGT_l2_shadow:
   34.92 +        if ( !shadow_promote(d, gpfn, gmfn, psh_type) )
   34.93 +            goto fail;
   34.94          perfc_incr(shadow_l2_pages);
   34.95          d->arch.shadow_page_count++;
   34.96          if ( PGT_l2_page_table == PGT_root_page_table )
   34.97 @@ -235,13 +222,16 @@ alloc_shadow_page(struct domain *d,
   34.98          break;
   34.99  
  34.100      case PGT_hl2_shadow:
  34.101 +        // Treat an hl2 as an L1 for purposes of promotion.
  34.102 +        // For external mode domains, treat them as an L2 for purposes of
  34.103 +        // pinning.
  34.104 +        //
  34.105 +        if ( !shadow_promote(d, gpfn, gmfn, PGT_l1_shadow) )
  34.106 +            goto fail;
  34.107          perfc_incr(hl2_table_pages);
  34.108          d->arch.hl2_page_count++;
  34.109 -
  34.110 -        // treat an hl2 as an L1 for purposes of promotion,
  34.111 -        // and as an L2 for purposes of pinning.
  34.112 -        //
  34.113 -        if ( PGT_l2_page_table == PGT_root_page_table )
  34.114 +        if ( shadow_mode_external(d) &&
  34.115 +             (PGT_l2_page_table == PGT_root_page_table) )
  34.116              pin = 1;
  34.117  
  34.118          break;
  34.119 @@ -257,12 +247,18 @@ alloc_shadow_page(struct domain *d,
  34.120          break;
  34.121      }
  34.122  
  34.123 -    set_shadow_status(d, gpfn, smfn, psh_type);
  34.124 +    set_shadow_status(d, gpfn, gmfn, smfn, psh_type);
  34.125  
  34.126      if ( pin )
  34.127          shadow_pin(smfn);
  34.128  
  34.129      return smfn;
  34.130 +
  34.131 +  fail:
  34.132 +    FSH_LOG("promotion of pfn=%p mfn=%p failed!  external gnttab refs?\n",
  34.133 +            gpfn, gmfn);
  34.134 +    free_domheap_page(page);
  34.135 +    return 0;
  34.136  }
  34.137  
  34.138  static void inline
  34.139 @@ -280,9 +276,7 @@ free_shadow_l1_table(struct domain *d, u
  34.140  static void inline
  34.141  free_shadow_hl2_table(struct domain *d, unsigned long smfn)
  34.142  {
  34.143 -    printk("free_shadow_hl2_table(smfn=%p)\n", smfn);
  34.144 -
  34.145 -    l1_pgentry_t *pl1e = map_domain_mem(smfn << PAGE_SHIFT);
  34.146 +    l1_pgentry_t *hl2 = map_domain_mem(smfn << PAGE_SHIFT);
  34.147      int i, limit;
  34.148  
  34.149      if ( shadow_mode_external(d) )
  34.150 @@ -291,9 +285,13 @@ free_shadow_hl2_table(struct domain *d, 
  34.151          limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE;
  34.152  
  34.153      for ( i = 0; i < limit; i++ )
  34.154 -        put_page_from_l1e(pl1e[i], d);
  34.155 -
  34.156 -    unmap_domain_mem(pl1e);
  34.157 +    {
  34.158 +        unsigned long hl2e = l1_pgentry_val(hl2[i]);
  34.159 +        if ( hl2e & _PAGE_PRESENT )
  34.160 +            put_page(pfn_to_page(hl2e >> PAGE_SHIFT));
  34.161 +    }
  34.162 +
  34.163 +    unmap_domain_mem(hl2);
  34.164  }
  34.165  
  34.166  static void inline
  34.167 @@ -330,7 +328,7 @@ void free_shadow_page(unsigned long smfn
  34.168  
  34.169      ASSERT( ! IS_INVALID_M2P_ENTRY(gpfn) );
  34.170  
  34.171 -    delete_shadow_status(d, gpfn, type);
  34.172 +    delete_shadow_status(d, gpfn, gmfn, type);
  34.173  
  34.174      switch ( type )
  34.175      {
  34.176 @@ -567,7 +565,7 @@ static void alloc_monitor_pagetable(stru
  34.177  
  34.178      // map the phys_to_machine map into the Read-Only MPT space for this domain
  34.179      mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
  34.180 -        mk_l2_pgentry(pagetable_val(ed->arch.phys_table) | __PAGE_HYPERVISOR);
  34.181 +        mk_l2_pgentry(pagetable_val(d->arch.phys_table) | __PAGE_HYPERVISOR);
  34.182  
  34.183      ed->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
  34.184      ed->arch.monitor_vtable = mpl2e;
  34.185 @@ -607,9 +605,101 @@ void free_monitor_pagetable(struct exec_
  34.186      ed->arch.monitor_vtable = 0;
  34.187  }
  34.188  
  34.189 +int
  34.190 +set_p2m_entry(struct domain *d, unsigned long pfn, unsigned long mfn)
  34.191 +{
  34.192 +    unsigned long phystab = pagetable_val(d->arch.phys_table);
  34.193 +    l2_pgentry_t *l2, l2e;
  34.194 +    l1_pgentry_t *l1;
  34.195 +    struct pfn_info *l1page;
  34.196 +    unsigned long va = pfn << PAGE_SHIFT;
  34.197 +
  34.198 +    ASSERT( phystab );
  34.199 +
  34.200 +#ifdef WATCH_MAP_DOMAIN_CALLERS
  34.201 +    int old_map_domain_mem_noisy = map_domain_mem_noisy;
  34.202 +    map_domain_mem_noisy = 0;
  34.203 +#endif
  34.204 +
  34.205 +    l2 = map_domain_mem(phystab);
  34.206 +    if ( !l2_pgentry_val(l2e = l2[l2_table_offset(va)]) )
  34.207 +    {
  34.208 +        l1page = alloc_domheap_page(NULL);
  34.209 +        if ( !l1page )
  34.210 +            return 0;
  34.211 +
  34.212 +        l1 = map_domain_mem(page_to_pfn(l1page) << PAGE_SHIFT);
  34.213 +        memset(l1, 0, PAGE_SIZE);
  34.214 +        unmap_domain_mem(l1);
  34.215 +
  34.216 +        l2e = l2[l2_table_offset(va)] =
  34.217 +            mk_l2_pgentry((page_to_pfn(l1page) << PAGE_SHIFT) |
  34.218 +                          __PAGE_HYPERVISOR);
  34.219 +    }
  34.220 +    unmap_domain_mem(l2);
  34.221 +
  34.222 +    l1 = map_domain_mem(l2_pgentry_val(l2e) & PAGE_MASK);
  34.223 +    l1[l1_table_offset(va)] = mk_l1_pgentry((mfn << PAGE_SHIFT) |
  34.224 +                                            __PAGE_HYPERVISOR);
  34.225 +    unmap_domain_mem(l1);
  34.226 +
  34.227 +#ifdef WATCH_MAP_DOMAIN_CALLERS
  34.228 +    map_domain_mem_noisy = old_map_domain_mem_noisy;
  34.229 +#endif
  34.230 +
  34.231 +    return 1;
  34.232 +}
  34.233 +
  34.234 +static int
  34.235 +alloc_p2m_table(struct domain *d)
  34.236 +{
  34.237 +    struct list_head *list_ent;
  34.238 +    struct pfn_info *page, *l2page;
  34.239 +    l2_pgentry_t *l2;
  34.240 +    unsigned long mfn, pfn;
  34.241 +
  34.242 +    l2page = alloc_domheap_page(NULL);
  34.243 +    if ( !l2page )
  34.244 +        return 0;
  34.245 +    d->arch.phys_table = mk_pagetable(page_to_pfn(l2page) << PAGE_SHIFT);
  34.246 +    l2 = map_domain_mem(page_to_pfn(l2page) << PAGE_SHIFT);
  34.247 +    memset(l2, 0, PAGE_SIZE);
  34.248 +    unmap_domain_mem(l2);
  34.249 +
  34.250 +    list_ent = d->page_list.next;
  34.251 +    while ( list_ent != &d->page_list )
  34.252 +    {
  34.253 +        page = list_entry(list_ent, struct pfn_info, list);
  34.254 +        mfn = page_to_pfn(page);
  34.255 +        pfn = machine_to_phys_mapping[mfn];
  34.256 +        ASSERT(pfn != INVALID_M2P_ENTRY);
  34.257 +        ASSERT(pfn < (1u<<20));
  34.258 +
  34.259 +        set_p2m_entry(d, pfn, mfn);
  34.260 +
  34.261 +        list_ent = page->list.next;
  34.262 +    }
  34.263 +
  34.264 +    return 1;
  34.265 +}
  34.266 +
  34.267 +static void
  34.268 +free_p2m_table(struct domain *d)
  34.269 +{
  34.270 +    // uh, this needs some work...  :)
  34.271 +    BUG();
  34.272 +}
  34.273 +
  34.274  int __shadow_mode_enable(struct domain *d, unsigned int mode)
  34.275  {
  34.276      struct exec_domain *ed;
  34.277 +    int new_modes = (mode & ~d->arch.shadow_mode);
  34.278 +
  34.279 +    // Gotta be adding something to call this function.
  34.280 +    ASSERT(new_modes);
  34.281 +
  34.282 +    // can't take anything away by calling this function.
  34.283 +    ASSERT(!(d->arch.shadow_mode & ~mode));
  34.284  
  34.285      for_each_exec_domain(d, ed)
  34.286      {
  34.287 @@ -670,8 +760,9 @@ int __shadow_mode_enable(struct domain *
  34.288          }
  34.289      }
  34.290  
  34.291 -    if ( !d->arch.shadow_ht )
  34.292 +    if ( new_modes & SHM_enable )
  34.293      {
  34.294 +        ASSERT( !d->arch.shadow_ht );
  34.295          d->arch.shadow_ht = xmalloc_array(struct shadow_status, shadow_ht_buckets);
  34.296          if ( d->arch.shadow_ht == NULL )
  34.297              goto nomem;
  34.298 @@ -680,8 +771,9 @@ int __shadow_mode_enable(struct domain *
  34.299             shadow_ht_buckets * sizeof(struct shadow_status));
  34.300      }
  34.301  
  34.302 -    if ( shadow_mode_log_dirty(d) && !d->arch.shadow_dirty_bitmap )
  34.303 +    if ( new_modes & SHM_log_dirty )
  34.304      {
  34.305 +        ASSERT( !d->arch.shadow_dirty_bitmap );
  34.306          d->arch.shadow_dirty_bitmap_size = (d->max_pages + 63) & ~63;
  34.307          d->arch.shadow_dirty_bitmap = 
  34.308              xmalloc_array(unsigned long, d->arch.shadow_dirty_bitmap_size /
  34.309 @@ -695,8 +787,28 @@ int __shadow_mode_enable(struct domain *
  34.310                 d->arch.shadow_dirty_bitmap_size/8);
  34.311      }
  34.312  
  34.313 +    if ( new_modes & SHM_translate )
  34.314 +    {
  34.315 +        if ( !(new_modes & SHM_external) )
  34.316 +        {
  34.317 +            ASSERT( !pagetable_val(d->arch.phys_table) );
  34.318 +            if ( !alloc_p2m_table(d) )
  34.319 +            {
  34.320 +                printk("alloc_p2m_table failed (out-of-memory?)\n");
  34.321 +                goto nomem;
  34.322 +            }
  34.323 +        }
  34.324 +        else
  34.325 +        {
  34.326 +            // external guests provide their own memory for their P2M maps.
  34.327 +            //
  34.328 +            ASSERT( d == page_get_owner(&frame_table[pagetable_val(
  34.329 +                                        d->arch.phys_table)>>PAGE_SHIFT]) );
  34.330 +        }
  34.331 +    }
  34.332 +
  34.333      printk("audit1\n");
  34.334 -    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK, __FILE__, __LINE__);
  34.335 +    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK);
  34.336      printk("audit1 done\n");
  34.337  
  34.338      // Get rid of any shadow pages from any previous shadow mode.
  34.339 @@ -704,11 +816,12 @@ int __shadow_mode_enable(struct domain *
  34.340      free_shadow_pages(d);
  34.341  
  34.342      printk("audit2\n");
  34.343 -    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK, __FILE__, __LINE__);
  34.344 +    _audit_domain(d, AUDIT_ALREADY_LOCKED | AUDIT_ERRORS_OK);
  34.345      printk("audit2 done\n");
  34.346  
  34.347      // Turn off writable page tables.
  34.348      // It doesn't mix with shadow mode.
  34.349 +    // And shadow mode offers a superset of functionality.
  34.350      //
  34.351      vm_assist(d, VMASST_CMD_disable, VMASST_TYPE_writable_pagetables);
  34.352  
  34.353 @@ -749,15 +862,27 @@ int __shadow_mode_enable(struct domain *
  34.354      audit_adjust_pgtables(d, 1, 1);
  34.355  
  34.356      printk("audit3\n");
  34.357 -    _audit_domain(d, AUDIT_ALREADY_LOCKED, __FILE__, __LINE__);
  34.358 +    _audit_domain(d, AUDIT_ALREADY_LOCKED);
  34.359      printk("audit3 done\n");
  34.360  
  34.361      return 0;
  34.362  
  34.363   nomem:
  34.364 -    if ( d->arch.shadow_ht != NULL )
  34.365 +    if ( (new_modes & SHM_enable) && (d->arch.shadow_ht != NULL) )
  34.366 +    {
  34.367          xfree(d->arch.shadow_ht);
  34.368 -    d->arch.shadow_ht = NULL;
  34.369 +        d->arch.shadow_ht = NULL;
  34.370 +    }
  34.371 +    if ( (new_modes & SHM_log_dirty) && (d->arch.shadow_dirty_bitmap != NULL) )
  34.372 +    {
  34.373 +        xfree(d->arch.shadow_dirty_bitmap);
  34.374 +        d->arch.shadow_dirty_bitmap = NULL;
  34.375 +    }
  34.376 +    if ( (new_modes & SHM_translate) && !(new_modes & SHM_external) &&
  34.377 +         pagetable_val(d->arch.phys_table) )
  34.378 +    {
  34.379 +        free_p2m_table(d);
  34.380 +    }
  34.381      return -ENOMEM;
  34.382  }
  34.383  
  34.384 @@ -770,6 +895,57 @@ int shadow_mode_enable(struct domain *d,
  34.385      return rc;
  34.386  }
  34.387  
  34.388 +static void
  34.389 +translate_l1pgtable(struct domain *d, l1_pgentry_t *p2m, unsigned long l1mfn)
  34.390 +{
  34.391 +    int i;
  34.392 +    l1_pgentry_t *l1;
  34.393 +
  34.394 +    l1 = map_domain_mem(l1mfn << PAGE_SHIFT);
  34.395 +    for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
  34.396 +    {
  34.397 +        if ( is_guest_l1_slot(i) &&
  34.398 +             (l1_pgentry_val(l1[i]) & _PAGE_PRESENT) )
  34.399 +        {
  34.400 +            unsigned long mfn = l1_pgentry_val(l1[i]) >> PAGE_SHIFT;
  34.401 +            unsigned long gpfn = __mfn_to_gpfn(d, mfn);
  34.402 +            ASSERT((l1_pgentry_val(p2m[gpfn]) >> PAGE_SHIFT) == mfn);
  34.403 +            l1[i] = mk_l1_pgentry((gpfn << PAGE_SHIFT) |
  34.404 +                                  (l1_pgentry_val(l1[i]) & ~PAGE_MASK));
  34.405 +        }
  34.406 +    }
  34.407 +    unmap_domain_mem(l1);
  34.408 +}
  34.409 +
  34.410 +// This is not general enough to handle arbitrary pagetables
  34.411 +// with shared L1 pages, etc., but it is sufficient for bringing
  34.412 +// up dom0.
  34.413 +//
  34.414 +void
  34.415 +translate_l2pgtable(struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn)
  34.416 +{
  34.417 +    int i;
  34.418 +    l2_pgentry_t *l2;
  34.419 +
  34.420 +    ASSERT(shadow_mode_translate(d) && !shadow_mode_external(d));
  34.421 +
  34.422 +    l2 = map_domain_mem(l2mfn << PAGE_SHIFT);
  34.423 +    for (i = 0; i < L2_PAGETABLE_ENTRIES; i++)
  34.424 +    {
  34.425 +        if ( is_guest_l2_slot(i) &&
  34.426 +             (l2_pgentry_val(l2[i]) & _PAGE_PRESENT) )
  34.427 +        {
  34.428 +            unsigned long mfn = l2_pgentry_val(l2[i]) >> PAGE_SHIFT;
  34.429 +            unsigned long gpfn = __mfn_to_gpfn(d, mfn);
  34.430 +            ASSERT((l1_pgentry_val(p2m[gpfn]) >> PAGE_SHIFT) == mfn);
  34.431 +            l2[i] = mk_l2_pgentry((gpfn << PAGE_SHIFT) |
  34.432 +                                  (l2_pgentry_val(l2[i]) & ~PAGE_MASK));
  34.433 +            translate_l1pgtable(d, p2m, mfn);
  34.434 +        }
  34.435 +    }
  34.436 +    unmap_domain_mem(l2);
  34.437 +}
  34.438 +
  34.439  static void free_shadow_ht_entries(struct domain *d)
  34.440  {
  34.441      struct shadow_status *x, *n;
  34.442 @@ -1018,6 +1194,42 @@ void vmx_shadow_clear_state(struct domai
  34.443      shadow_unlock(d);
  34.444  }
  34.445  
  34.446 +unsigned long
  34.447 +gpfn_to_mfn_safe(struct domain *d, unsigned long gpfn)
  34.448 +{
  34.449 +    ASSERT( shadow_mode_translate(d) );
  34.450 +
  34.451 +    perfc_incrc(gpfn_to_mfn_safe);
  34.452 +
  34.453 +    unsigned long va = gpfn << PAGE_SHIFT;
  34.454 +    unsigned long phystab = pagetable_val(d->arch.phys_table);
  34.455 +    l2_pgentry_t *l2 = map_domain_mem(phystab);
  34.456 +    l2_pgentry_t l2e = l2[l2_table_offset(va)];
  34.457 +    unmap_domain_mem(l2);
  34.458 +    if ( !(l2_pgentry_val(l2e) & _PAGE_PRESENT) )
  34.459 +    {
  34.460 +        printk("gpfn_to_mfn_safe(d->id=%d, gpfn=%p) => 0 l2e=%p\n",
  34.461 +               d->id, gpfn, l2_pgentry_val(l2e));
  34.462 +        return INVALID_MFN;
  34.463 +    }
  34.464 +    unsigned long l1tab = l2_pgentry_val(l2e) & PAGE_MASK;
  34.465 +    l1_pgentry_t *l1 = map_domain_mem(l1tab);
  34.466 +    l1_pgentry_t l1e = l1[l1_table_offset(va)];
  34.467 +    unmap_domain_mem(l1);
  34.468 +
  34.469 +    printk("gpfn_to_mfn_safe(d->id=%d, gpfn=%p) => %p phystab=%p l2e=%p l1tab=%p, l1e=%p\n",
  34.470 +           d->id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, phystab, l2e, l1tab, l1e);
  34.471 +
  34.472 +    if ( !(l1_pgentry_val(l1e) & _PAGE_PRESENT) )
  34.473 +    {
  34.474 +        printk("gpfn_to_mfn_safe(d->id=%d, gpfn=%p) => 0 l1e=%p\n",
  34.475 +               d->id, gpfn, l1_pgentry_val(l1e));
  34.476 +        return INVALID_MFN;
  34.477 +    }
  34.478 +
  34.479 +    return l1_pgentry_val(l1e) >> PAGE_SHIFT;
  34.480 +}
  34.481 +
  34.482  static unsigned long
  34.483  shadow_hl2_table(struct domain *d, unsigned long gpfn, unsigned long gmfn,
  34.484                  unsigned long smfn)
  34.485 @@ -1037,9 +1249,7 @@ shadow_hl2_table(struct domain *d, unsig
  34.486  
  34.487      perfc_incrc(shadow_hl2_table_count);
  34.488  
  34.489 -    ASSERT( pagetable_val(current->arch.guest_table) == (gmfn << PAGE_SHIFT) );
  34.490 -    gl2 = current->arch.guest_vtable;
  34.491 -
  34.492 +    gl2 = map_domain_mem(gmfn << PAGE_SHIFT);
  34.493      hl2 = map_domain_mem(hl2mfn << PAGE_SHIFT);
  34.494  
  34.495      if ( shadow_mode_external(d) )
  34.496 @@ -1050,16 +1260,15 @@ shadow_hl2_table(struct domain *d, unsig
  34.497      for ( i = 0; i < limit; i++ )
  34.498      {
  34.499          unsigned long gl2e = l2_pgentry_val(gl2[i]);
  34.500 -        unsigned long mfn;
  34.501 -
  34.502 -        if ( gl2e & _PAGE_PRESENT )
  34.503 -        {
  34.504 -            mfn = __gpfn_to_mfn(d, gl2e >> PAGE_SHIFT);
  34.505 -            hl2[i] = mk_l1_pgentry((mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  34.506 -            get_page(pfn_to_page(mfn), d);
  34.507 -        }
  34.508 -        else
  34.509 -            hl2[i] = mk_l1_pgentry(0);
  34.510 +        unsigned long hl2e;
  34.511 +
  34.512 +        hl2e_propagate_from_guest(d, gl2e, &hl2e);
  34.513 +
  34.514 +        if ( (hl2e & _PAGE_PRESENT) &&
  34.515 +             !get_page(pfn_to_page(hl2e >> PAGE_SHIFT), d) )
  34.516 +            hl2e = 0;
  34.517 +
  34.518 +        hl2[i] = mk_l1_pgentry(hl2e);
  34.519      }
  34.520  
  34.521      if ( !shadow_mode_external(d) )
  34.522 @@ -1078,6 +1287,7 @@ shadow_hl2_table(struct domain *d, unsig
  34.523      }
  34.524  
  34.525      unmap_domain_mem(hl2);
  34.526 +    unmap_domain_mem(gl2);
  34.527  
  34.528      return hl2mfn;
  34.529  }
  34.530 @@ -1122,10 +1332,23 @@ static unsigned long shadow_l2_table(
  34.531                 &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
  34.532                 HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
  34.533  
  34.534 +        spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
  34.535 +            mk_l2_pgentry((smfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  34.536 +
  34.537 +        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
  34.538 +            mk_l2_pgentry(__pa(page_get_owner(
  34.539 +                &frame_table[gmfn])->arch.mm_perdomain_pt) |
  34.540 +                          __PAGE_HYPERVISOR);
  34.541 +
  34.542          if ( shadow_mode_translate(d) ) // NB: not external
  34.543          {
  34.544              unsigned long hl2mfn;
  34.545 -            if ( unlikely(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow)) )
  34.546 +
  34.547 +            spl2e[l2_table_offset(RO_MPT_VIRT_START)] =
  34.548 +                mk_l2_pgentry(pagetable_val(d->arch.phys_table) |
  34.549 +                              __PAGE_HYPERVISOR);
  34.550 +
  34.551 +            if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
  34.552                  hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
  34.553  
  34.554              // shadow_mode_translate (but not external) sl2 tables hold a
  34.555 @@ -1140,14 +1363,6 @@ static unsigned long shadow_l2_table(
  34.556          else
  34.557              spl2e[l2_table_offset(LINEAR_PT_VIRT_START)] =
  34.558                  mk_l2_pgentry((gmfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  34.559 -
  34.560 -        spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
  34.561 -            mk_l2_pgentry((smfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  34.562 -
  34.563 -        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
  34.564 -            mk_l2_pgentry(__pa(page_get_owner(
  34.565 -                &frame_table[gmfn])->arch.mm_perdomain_pt) |
  34.566 -                          __PAGE_HYPERVISOR);
  34.567      }
  34.568      else
  34.569      {
  34.570 @@ -1177,7 +1392,7 @@ void shadow_map_l1_into_current_l2(unsig
  34.571          SH_VVLOG("4a: l1 not shadowed");
  34.572  
  34.573          gl1mfn = __gpfn_to_mfn(d, gl1pfn);
  34.574 -        if ( unlikely(!gl1mfn) )
  34.575 +        if ( unlikely(!VALID_MFN(gl1mfn)) )
  34.576          {
  34.577              // Attempt to use an invalid pfn as an L1 page.
  34.578              // XXX this needs to be more graceful!
  34.579 @@ -1304,7 +1519,7 @@ shadow_alloc_oos_entry(struct domain *d)
  34.580      return f;
  34.581  }
  34.582  
  34.583 -static unsigned long
  34.584 +static inline unsigned long
  34.585  shadow_make_snapshot(
  34.586      struct domain *d, unsigned long gpfn, unsigned long gmfn)
  34.587  {
  34.588 @@ -1502,7 +1717,7 @@ int __shadow_out_of_sync(struct exec_dom
  34.589      l1mfn = __gpfn_to_mfn(d, l2e >> PAGE_SHIFT);
  34.590  
  34.591      // If the l1 pfn is invalid, it can't be out of sync...
  34.592 -    if ( !l1mfn )
  34.593 +    if ( !VALID_MFN(l1mfn) )
  34.594          return 0;
  34.595  
  34.596      if ( page_out_of_sync(&frame_table[l1mfn]) &&
  34.597 @@ -1512,92 +1727,194 @@ int __shadow_out_of_sync(struct exec_dom
  34.598      return 0;
  34.599  }
  34.600  
  34.601 +#define GPFN_TO_GPTEPAGE(_gpfn) ((_gpfn) / (PAGE_SIZE / sizeof(l1_pgentry_t)))
  34.602 +static inline unsigned long
  34.603 +predict_writable_pte_page(struct domain *d, unsigned long gpfn)
  34.604 +{
  34.605 +    return __shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), PGT_writable_pred);
  34.606 +}
  34.607 +
  34.608 +static inline void
  34.609 +increase_writable_pte_prediction(struct domain *d, unsigned long gpfn, unsigned long prediction)
  34.610 +{
  34.611 +    unsigned long score = prediction & PGT_score_mask;
  34.612 +    int create = (score == 0);
  34.613 +
  34.614 +    // saturating addition
  34.615 +    score = (score + (1u << PGT_score_shift)) & PGT_score_mask;
  34.616 +    score = score ? score : PGT_score_mask;
  34.617 +
  34.618 +    prediction = (prediction & PGT_mfn_mask) | score;
  34.619 +
  34.620 +    //printk("increase gpfn=%p pred=%p create=%d\n", gpfn, prediction, create);
  34.621 +    set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, PGT_writable_pred);
  34.622 +
  34.623 +    if ( create )
  34.624 +        perfc_incr(writable_pte_predictions);
  34.625 +}
  34.626 +
  34.627 +static inline void
  34.628 +decrease_writable_pte_prediction(struct domain *d, unsigned long gpfn, unsigned long prediction)
  34.629 +{
  34.630 +    unsigned long score = prediction & PGT_score_mask;
  34.631 +    ASSERT(score);
  34.632 +
  34.633 +    // divide score by 2...  We don't like bad predictions.
  34.634 +    //
  34.635 +    score = (score >> 1) & PGT_score_mask;
  34.636 +
  34.637 +    prediction = (prediction & PGT_mfn_mask) | score;
  34.638 +
  34.639 +    //printk("decrease gpfn=%p pred=%p score=%p\n", gpfn, prediction, score);
  34.640 +
  34.641 +    if ( score )
  34.642 +        set_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, prediction, PGT_writable_pred);
  34.643 +    else
  34.644 +    {
  34.645 +        delete_shadow_status(d, GPFN_TO_GPTEPAGE(gpfn), 0, PGT_writable_pred);
  34.646 +        perfc_decr(writable_pte_predictions);
  34.647 +    }
  34.648 +}
  34.649 +
  34.650  static u32 remove_all_write_access_in_ptpage(
  34.651 -    struct domain *d, unsigned long pt_mfn, unsigned long readonly_mfn)
  34.652 +    struct domain *d, unsigned long pt_pfn, unsigned long pt_mfn,
  34.653 +    unsigned long readonly_gpfn, unsigned long readonly_gmfn,
  34.654 +    u32 max_refs_to_find, unsigned long prediction)
  34.655  {
  34.656      unsigned long *pt = map_domain_mem(pt_mfn << PAGE_SHIFT);
  34.657      unsigned long match =
  34.658 -        (readonly_mfn << PAGE_SHIFT) | _PAGE_RW | _PAGE_PRESENT;
  34.659 +        (readonly_gmfn << PAGE_SHIFT) | _PAGE_RW | _PAGE_PRESENT;
  34.660      unsigned long mask = PAGE_MASK | _PAGE_RW | _PAGE_PRESENT;
  34.661      int i;
  34.662 -    u32 count = 0;
  34.663 +    u32 found = 0;
  34.664      int is_l1_shadow =
  34.665          ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
  34.666           PGT_l1_shadow);
  34.667  
  34.668 +#define MATCH_ENTRY(_i) (((pt[_i] ^ match) & mask) == 0)
  34.669 +
  34.670 +    // returns true if all refs have been found and fixed.
  34.671 +    //
  34.672 +    int fix_entry(int i)
  34.673 +    {
  34.674 +        unsigned long old = pt[i];
  34.675 +        unsigned long new = old & ~_PAGE_RW;
  34.676 +
  34.677 +        if ( is_l1_shadow && !shadow_get_page_from_l1e(mk_l1_pgentry(new), d) )
  34.678 +            BUG();
  34.679 +        found++;
  34.680 +        pt[i] = new;
  34.681 +        if ( is_l1_shadow )
  34.682 +            put_page_from_l1e(mk_l1_pgentry(old), d);
  34.683 +
  34.684 +#if 0
  34.685 +        printk("removed write access to pfn=%p mfn=%p in smfn=%p entry %x "
  34.686 +               "is_l1_shadow=%d\n",
  34.687 +               readonly_gpfn, readonly_gmfn, pt_mfn, i, is_l1_shadow);
  34.688 +#endif
  34.689 +
  34.690 +        return (found == max_refs_to_find);
  34.691 +    }
  34.692 +
  34.693 +    if ( MATCH_ENTRY(readonly_gpfn & (L1_PAGETABLE_ENTRIES - 1)) &&
  34.694 +         fix_entry(readonly_gpfn & (L1_PAGETABLE_ENTRIES - 1)) )
  34.695 +    {
  34.696 +        perfc_incrc(remove_write_fast_exit);
  34.697 +        increase_writable_pte_prediction(d, readonly_gpfn, prediction);
  34.698 +        unmap_domain_mem(pt);
  34.699 +        return found;
  34.700 +    }
  34.701 + 
  34.702      for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
  34.703      {
  34.704 -        if ( unlikely(((pt[i] ^ match) & mask) == 0) )
  34.705 -        {
  34.706 -            unsigned long old = pt[i];
  34.707 -            unsigned long new = old & ~_PAGE_RW;
  34.708 -
  34.709 -            if ( is_l1_shadow &&
  34.710 -                 !shadow_get_page_from_l1e(mk_l1_pgentry(new), d) )
  34.711 -                BUG();
  34.712 -
  34.713 -            count++;
  34.714 -            pt[i] = new;
  34.715 -
  34.716 -            if ( is_l1_shadow )
  34.717 -                put_page_from_l1e(mk_l1_pgentry(old), d);
  34.718 -
  34.719 -            FSH_LOG("removed write access to mfn=%p in smfn=%p entry %x "
  34.720 -                    "is_l1_shadow=%d",
  34.721 -                    readonly_mfn, pt_mfn, i, is_l1_shadow);
  34.722 -        }
  34.723 +        if ( unlikely(MATCH_ENTRY(i)) && fix_entry(i) )
  34.724 +            break;
  34.725      }
  34.726  
  34.727      unmap_domain_mem(pt);
  34.728  
  34.729 -    return count;
  34.730 +    return found;
  34.731 +#undef MATCH_ENTRY
  34.732  }
  34.733  
  34.734 -u32 shadow_remove_all_write_access(
  34.735 -    struct domain *d, unsigned min_type, unsigned max_type, unsigned long gpfn)
  34.736 +int shadow_remove_all_write_access(
  34.737 +    struct domain *d, unsigned long readonly_gpfn, unsigned long readonly_gmfn)
  34.738  {
  34.739      int i;
  34.740      struct shadow_status *a;
  34.741 -    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
  34.742 -    unsigned long sl1mfn = __shadow_status(d, gpfn, PGT_l1_shadow);
  34.743 -    u32 count = 0;
  34.744 +    u32 found = 0, fixups, write_refs;
  34.745 +    unsigned long prediction, predicted_gpfn, predicted_smfn;
  34.746  
  34.747      ASSERT(spin_is_locked(&d->arch.shadow_lock));
  34.748 -    ASSERT(gmfn);
  34.749 -
  34.750 +    ASSERT(VALID_MFN(readonly_gmfn));
  34.751 +
  34.752 +    perfc_incrc(remove_write_access);
  34.753 +
  34.754 +    // If it's not a writable page, then no writable refs can be outstanding.
  34.755 +    //
  34.756 +    if ( (frame_table[readonly_gmfn].u.inuse.type_info & PGT_type_mask) !=
  34.757 +         PGT_writable_page )
  34.758 +    {
  34.759 +        perfc_incrc(remove_write_not_writable);
  34.760 +        return 1;
  34.761 +    }
  34.762 +
  34.763 +    // How many outstanding writable PTEs for this page are there?
  34.764 +    //
  34.765 +    write_refs = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_count_mask);
  34.766 +    if ( write_refs && (frame_table[readonly_gmfn].u.inuse.type_info & PGT_pinned) )
  34.767 +        write_refs--;
  34.768 +
  34.769 +    if ( write_refs == 0 )
  34.770 +    {
  34.771 +        perfc_incrc(remove_write_no_work);
  34.772 +        return 1;
  34.773 +    }
  34.774 +
  34.775 +    // Before searching all the L1 page tables, check the typical culprit first.
  34.776 +    //
  34.777 +    if ( (prediction = predict_writable_pte_page(d, readonly_gpfn)) )
  34.778 +    {
  34.779 +        predicted_gpfn = prediction & PGT_mfn_mask;
  34.780 +        if ( (predicted_smfn = __shadow_status(d, predicted_gpfn, PGT_l1_shadow)) &&
  34.781 +             (fixups = remove_all_write_access_in_ptpage(d, predicted_gpfn, predicted_smfn, readonly_gpfn, readonly_gmfn, write_refs, prediction)) )
  34.782 +        {
  34.783 +            found += fixups;
  34.784 +            if ( found == write_refs )
  34.785 +            {
  34.786 +                perfc_incrc(remove_write_predicted);
  34.787 +                return 1;
  34.788 +            }
  34.789 +        }
  34.790 +        else
  34.791 +        {
  34.792 +            perfc_incrc(remove_write_bad_prediction);
  34.793 +            decrease_writable_pte_prediction(d, readonly_gpfn, prediction);
  34.794 +        }
  34.795 +    }
  34.796 +
  34.797 +    // Search all the shadow L1 page tables...
  34.798 +    //
  34.799      for (i = 0; i < shadow_ht_buckets; i++)
  34.800      {
  34.801          a = &d->arch.shadow_ht[i];
  34.802          while ( a && a->gpfn_and_flags )
  34.803          {
  34.804 -            if ( ((a->gpfn_and_flags & PGT_type_mask) >= min_type) &&
  34.805 -                 ((a->gpfn_and_flags & PGT_type_mask) <= max_type) )
  34.806 +            if ( (a->gpfn_and_flags & PGT_type_mask) == PGT_l1_shadow )
  34.807              {
  34.808 -                switch ( a->gpfn_and_flags & PGT_type_mask )
  34.809 -                {
  34.810 -                case PGT_l1_shadow:
  34.811 -                    count +=
  34.812 -                        remove_all_write_access_in_ptpage(d, a->smfn, gmfn);
  34.813 -                    break;
  34.814 -                case PGT_l2_shadow:
  34.815 -                    if ( sl1mfn )
  34.816 -                        count +=
  34.817 -                            remove_all_write_access_in_ptpage(d, a->smfn,
  34.818 -                                                              sl1mfn);
  34.819 -                    break;
  34.820 -                case PGT_hl2_shadow:
  34.821 -                    // nothing to do here...
  34.822 -                    break;
  34.823 -                default:
  34.824 -                    // need to flush this out for 4 level page tables.
  34.825 -                    BUG();
  34.826 -                }
  34.827 +                found += remove_all_write_access_in_ptpage(d, a->gpfn_and_flags & PGT_mfn_mask, a->smfn, readonly_gpfn, readonly_gmfn, write_refs - found, a->gpfn_and_flags & PGT_mfn_mask);
  34.828 +                if ( found == write_refs )
  34.829 +                    return 1;
  34.830              }
  34.831 +
  34.832              a = a->next;
  34.833          }
  34.834      }
  34.835  
  34.836 -    return count;
  34.837 +    FSH_LOG("%s: looking for %d refs, found %d refs\n",
  34.838 +            __func__, write_refs, found);
  34.839 +
  34.840 +    return 0;
  34.841  }
  34.842  
  34.843  static u32 remove_all_access_in_page(
  34.844 @@ -1632,7 +1949,7 @@ static u32 remove_all_access_in_page(
  34.845      return count;
  34.846  }
  34.847  
  34.848 -u32 shadow_remove_all_access(struct domain *d, unsigned long gmfn)
  34.849 +u32 shadow_remove_all_access(struct domain *d, unsigned long forbidden_gmfn)
  34.850  {
  34.851      int i;
  34.852      struct shadow_status *a;
  34.853 @@ -1645,11 +1962,23 @@ u32 shadow_remove_all_access(struct doma
  34.854          a = &d->arch.shadow_ht[i];
  34.855          while ( a && a->gpfn_and_flags )
  34.856          {
  34.857 -            if ( ((a->gpfn_and_flags & PGT_type_mask) == PGT_l1_shadow) ||
  34.858 -                 ((a->gpfn_and_flags & PGT_type_mask) == PGT_hl2_shadow) )
  34.859 +            switch (a->gpfn_and_flags & PGT_type_mask)
  34.860              {
  34.861 -                count += remove_all_access_in_page(d, a->smfn, gmfn);
  34.862 +            case PGT_l1_shadow:
  34.863 +            case PGT_l2_shadow:
  34.864 +            case PGT_l3_shadow:
  34.865 +            case PGT_l4_shadow:
  34.866 +            case PGT_hl2_shadow:
  34.867 +                count += remove_all_access_in_page(d, a->smfn, forbidden_gmfn);
  34.868 +                break;
  34.869 +            case PGT_snapshot:
  34.870 +            case PGT_writable_pred:
  34.871 +                // these can't hold refs to the forbidden page
  34.872 +                break;
  34.873 +            default:
  34.874 +                BUG();
  34.875              }
  34.876 +
  34.877              a = a->next;
  34.878          }
  34.879      }
  34.880 @@ -1723,8 +2052,8 @@ static int resync_all(struct domain *d, 
  34.881                  // XXX - This hack works for linux guests.
  34.882                  //       Need a better solution long term.
  34.883                  if ( !(new_pde & _PAGE_PRESENT) && unlikely(new_pde != 0) &&
  34.884 -                     (frame_table[smfn].u.inuse.type_info & PGT_pinned) &&
  34.885 -                     !unshadow )
  34.886 +                     !unshadow &&
  34.887 +                     (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
  34.888                  {
  34.889                      perfc_incrc(unshadow_l2_count);
  34.890                      unshadow = 1;
  34.891 @@ -1732,7 +2061,22 @@ static int resync_all(struct domain *d, 
  34.892              }
  34.893              break;
  34.894          default:
  34.895 -            BUG();
  34.896 +            for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ )
  34.897 +            {
  34.898 +                if ( !is_guest_l2_slot(i) && !external )
  34.899 +                    continue;
  34.900 +
  34.901 +                unsigned new_pde = guest[i];
  34.902 +                if ( new_pde != snapshot[i] )
  34.903 +                {
  34.904 +                    need_flush |= validate_hl2e_change(d, new_pde, &shadow[i]);
  34.905 +
  34.906 +                    // can't update snapshots of linear page tables -- they
  34.907 +                    // are used multiple times...
  34.908 +                    //
  34.909 +                    // snapshot[i] = new_pde;
  34.910 +                }
  34.911 +            }
  34.912              break;
  34.913          }
  34.914  
  34.915 @@ -1865,11 +2209,23 @@ int shadow_fault(unsigned long va, struc
  34.916              return 0;
  34.917          }
  34.918  
  34.919 -        l1pte_write_fault(ed, &gpte, &spte, va);
  34.920 +        if ( !l1pte_write_fault(ed, &gpte, &spte, va) )
  34.921 +        {
  34.922 +            SH_VVLOG("shadow_fault - EXIT: l1pte_write_fault failed");
  34.923 +            perfc_incrc(write_fault_bail);
  34.924 +            shadow_unlock(d);
  34.925 +            return 0;
  34.926 +        }
  34.927      }
  34.928      else
  34.929      {
  34.930 -        l1pte_read_fault(d, &gpte, &spte);
  34.931 +        if ( !l1pte_read_fault(d, &gpte, &spte) )
  34.932 +        {
  34.933 +            SH_VVLOG("shadow_fault - EXIT: l1pte_read_fault failed");
  34.934 +            perfc_incrc(read_fault_bail);
  34.935 +            shadow_unlock(d);
  34.936 +            return 0;
  34.937 +        }
  34.938      }
  34.939  
  34.940      /*
  34.941 @@ -1964,7 +2320,7 @@ void __update_pagetables(struct exec_dom
  34.942      if ( old_smfn )
  34.943          put_shadow_ref(old_smfn);
  34.944  
  34.945 -    SH_VVLOG("0: __update_pagetables(gmfn=%p, smfn=%p)", gmfn, smfn);
  34.946 +    SH_VVLOG("__update_pagetables(gmfn=%p, smfn=%p)", gmfn, smfn);
  34.947  
  34.948      /*
  34.949       * arch.shadow_vtable
  34.950 @@ -2004,6 +2360,8 @@ void __update_pagetables(struct exec_dom
  34.951  
  34.952          ASSERT( shadow_mode_translate(d) );
  34.953  
  34.954 +        BUG(); // ref counts for hl2mfn and smfn need to be maintained!
  34.955 +
  34.956          mpl2e[l2_table_offset(LINEAR_PT_VIRT_START)] =
  34.957              mk_l2_pgentry((hl2mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
  34.958  
  34.959 @@ -2038,10 +2396,10 @@ int shadow_status_noswap;
  34.960  
  34.961  #define FAIL(_f, _a...)                                                      \
  34.962      do {                                                                     \
  34.963 -        printk("XXX %s-FAIL (%d,%d)" _f "\n"                                 \
  34.964 +        printk("XXX %s-FAIL (%d,%d,%d)" _f "\n"                              \
  34.965                 "g=%08lx s=%08lx &g=%08lx &s=%08lx"                           \
  34.966                 " v2m(&g)=%08lx v2m(&s)=%08lx ea=%08lx\n",                    \
  34.967 -               sh_check_name, level, l1_idx, ## _a ,                         \
  34.968 +               sh_check_name, level, l2_idx, l1_idx, ## _a ,                 \
  34.969                 gpte, spte, pgpte, pspte,                                     \
  34.970                 v2m(pgpte), v2m(pspte),                                       \
  34.971                 (l2_idx << L2_PAGETABLE_SHIFT) |                              \
  34.972 @@ -2076,7 +2434,8 @@ static int check_pte(
  34.973      if ( (spte & mask) != (gpte & mask) )
  34.974          FAIL("Corrupt?");
  34.975  
  34.976 -    if ( (spte & _PAGE_DIRTY ) && !(gpte & _PAGE_DIRTY) && !oos_ptes )
  34.977 +    if ( (level == 1) &&
  34.978 +         (spte & _PAGE_DIRTY ) && !(gpte & _PAGE_DIRTY) && !oos_ptes )
  34.979          FAIL("Dirty coherence");
  34.980  
  34.981      if ( (spte & _PAGE_ACCESSED ) && !(gpte & _PAGE_ACCESSED) && !oos_ptes )
  34.982 @@ -2086,27 +2445,35 @@ static int check_pte(
  34.983      gpfn = gpte >> PAGE_SHIFT;
  34.984      gmfn = __gpfn_to_mfn(d, gpfn);
  34.985  
  34.986 +    if ( !VALID_MFN(gmfn) )
  34.987 +        FAIL("invalid gpfn=%p gpte=%p\n", __func__, gpfn, gpte);
  34.988 +
  34.989      page_table_page = mfn_is_page_table(gmfn);
  34.990  
  34.991      if ( (spte & _PAGE_RW ) && !(gpte & _PAGE_RW) && !oos_ptes )
  34.992      {
  34.993 -        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d oos_ptes=%d\n",
  34.994 +        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d "
  34.995 +               "oos_ptes=%d\n",
  34.996                 gpfn, gmfn, smfn,
  34.997                 frame_table[gmfn].u.inuse.type_info,
  34.998                 page_table_page, oos_ptes);
  34.999          FAIL("RW coherence");
 34.1000      }
 34.1001  
 34.1002 -    if ( (spte & _PAGE_RW ) && !((gpte & _PAGE_RW) && (gpte & _PAGE_DIRTY)) && !oos_ptes )
 34.1003 +    if ( (level == 1) &&
 34.1004 +         (spte & _PAGE_RW ) &&
 34.1005 +         !((gpte & _PAGE_RW) && (gpte & _PAGE_DIRTY)) &&
 34.1006 +         !oos_ptes )
 34.1007      {
 34.1008 -        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d oos_ptes=%d\n",
 34.1009 +        printk("gpfn=%p gmfn=%p smfn=%p t=0x%08x page_table_page=%d "
 34.1010 +               "oos_ptes=%d\n",
 34.1011                 gpfn, gmfn, smfn,
 34.1012                 frame_table[gmfn].u.inuse.type_info,
 34.1013                 page_table_page, oos_ptes);
 34.1014          FAIL("RW2 coherence");
 34.1015      }
 34.1016   
 34.1017 -    if ( gpfn == smfn )
 34.1018 +    if ( gmfn == smfn )
 34.1019      {
 34.1020          if ( level > 1 )
 34.1021              FAIL("Linear map ???");    /* XXX this will fail on BSD */
 34.1022 @@ -2272,7 +2639,7 @@ int _check_pagetable(struct exec_domain 
 34.1023      unsigned long ptbase_mfn = 0;
 34.1024      int errors = 0, limit, oos_pdes = 0;
 34.1025  
 34.1026 -    audit_domain(d);
 34.1027 +    _audit_domain(d, AUDIT_QUIET);
 34.1028      shadow_lock(d);
 34.1029  
 34.1030      sh_check_name = s;
 34.1031 @@ -2280,8 +2647,8 @@ int _check_pagetable(struct exec_domain 
 34.1032      sh_l2_present = sh_l1_present = 0;
 34.1033      perfc_incrc(check_pagetable);
 34.1034  
 34.1035 -    ptbase_pfn = gptbase >> PAGE_SHIFT;
 34.1036 -    ptbase_mfn = __gpfn_to_mfn(d, ptbase_pfn);
 34.1037 +    ptbase_mfn = gptbase >> PAGE_SHIFT;
 34.1038 +    ptbase_pfn = __mfn_to_gpfn(d, ptbase_mfn);
 34.1039  
 34.1040      if ( !(smfn = __shadow_status(d, ptbase_pfn, PGT_base_page_table)) )
 34.1041      {
 34.1042 @@ -2372,6 +2739,7 @@ int _check_all_pagetables(struct exec_do
 34.1043                  BUG(); // XXX - ought to fix this...
 34.1044                  break;
 34.1045              case PGT_snapshot:
 34.1046 +            case PGT_writable_ref:
 34.1047                  break;
 34.1048              default:
 34.1049                  errors++;
    35.1 --- a/xen/arch/x86/traps.c	Wed Mar 16 19:30:47 2005 +0000
    35.2 +++ b/xen/arch/x86/traps.c	Mon Mar 21 16:41:29 2005 +0000
    35.3 @@ -298,7 +298,7 @@ asmlinkage int do_page_fault(struct xen_
    35.4      }
    35.5  
    35.6      if ( unlikely(shadow_mode_enabled(d)) &&
    35.7 -         ((addr < PAGE_OFFSET) || shadow_mode_external(d)) &&
    35.8 +         ((addr < HYPERVISOR_VIRT_START) || shadow_mode_external(d)) &&
    35.9           shadow_fault(addr, regs) )
   35.10      {
   35.11          return EXCRET_fault_fixed;
    36.1 --- a/xen/arch/x86/vmx.c	Wed Mar 16 19:30:47 2005 +0000
    36.2 +++ b/xen/arch/x86/vmx.c	Mon Mar 21 16:41:29 2005 +0000
    36.3 @@ -416,8 +416,8 @@ static void mov_to_cr(int gp, int cr, st
    36.4              /*
    36.5               * The guest CR3 must be pointing to the guest physical.
    36.6               */
    36.7 -            if (!(mfn = phys_to_machine_mapping(
    36.8 -                      d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT))) 
    36.9 +            if (!VALID_MFN(mfn = phys_to_machine_mapping(
   36.10 +                               d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)))
   36.11              {
   36.12                  VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value = %lx", 
   36.13                          d->arch.arch_vmx.cpu_cr3);
    37.1 --- a/xen/arch/x86/vmx_io.c	Wed Mar 16 19:30:47 2005 +0000
    37.2 +++ b/xen/arch/x86/vmx_io.c	Mon Mar 21 16:41:29 2005 +0000
    37.3 @@ -391,7 +391,7 @@ void vmx_do_resume(struct exec_domain *d
    37.4          __vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table));
    37.5      else
    37.6          // paging is not enabled in the guest
    37.7 -        __vmwrite(GUEST_CR3, pagetable_val(d->arch.phys_table));
    37.8 +        __vmwrite(GUEST_CR3, pagetable_val(d->domain->arch.phys_table));
    37.9  
   37.10      __vmwrite(HOST_CR3, pagetable_val(d->arch.monitor_table));
   37.11      __vmwrite(HOST_ESP, (unsigned long)get_stack_bottom());
    38.1 --- a/xen/arch/x86/x86_32/domain_page.c	Wed Mar 16 19:30:47 2005 +0000
    38.2 +++ b/xen/arch/x86/x86_32/domain_page.c	Mon Mar 21 16:41:29 2005 +0000
    38.3 @@ -26,6 +26,11 @@ static spinlock_t map_lock = SPIN_LOCK_U
    38.4  /* Use a spare PTE bit to mark entries ready for recycling. */
    38.5  #define READY_FOR_TLB_FLUSH (1<<10)
    38.6  
    38.7 +#ifdef WATCH_MAP_DOMAIN_CALLERS
    38.8 +int map_domain_mem_noisy = 1;
    38.9 +#endif
   38.10 +
   38.11 +
   38.12  static void flush_all_ready_maps(void)
   38.13  {
   38.14      unsigned long *cache = mapcache;
   38.15 @@ -38,8 +43,7 @@ static void flush_all_ready_maps(void)
   38.16      while ( ((unsigned long)(++cache) & ~PAGE_MASK) != 0 );
   38.17  }
   38.18  
   38.19 -
   38.20 -void *map_domain_mem(unsigned long pa)
   38.21 +void *_map_domain_mem(unsigned long pa)
   38.22  {
   38.23      unsigned long va;
   38.24      unsigned int idx, cpu = smp_processor_id();
    39.1 --- a/xen/arch/x86/x86_32/traps.c	Wed Mar 16 19:30:47 2005 +0000
    39.2 +++ b/xen/arch/x86/x86_32/traps.c	Mon Mar 21 16:41:29 2005 +0000
    39.3 @@ -150,6 +150,8 @@ void show_registers(struct xen_regs *reg
    39.4             ds, es, fs, gs, ss, cs);
    39.5  
    39.6      show_stack((unsigned long *)&regs->esp);
    39.7 +    if ( GUEST_MODE(regs) )
    39.8 +        show_guest_stack();
    39.9  } 
   39.10  
   39.11  void show_page_walk(unsigned long addr)
    40.1 --- a/xen/common/page_alloc.c	Wed Mar 16 19:30:47 2005 +0000
    40.2 +++ b/xen/common/page_alloc.c	Mon Mar 21 16:41:29 2005 +0000
    40.3 @@ -350,6 +350,11 @@ void scrub_heap_pages(void)
    40.4  
    40.5      printk("Scrubbing Free RAM: ");
    40.6  
    40.7 +#ifdef WATCH_MAP_DOMAIN_CALLERS
    40.8 +    int old_map_domain_mem_noisy = map_domain_mem_noisy;
    40.9 +    map_domain_mem_noisy = 0;
   40.10 +#endif
   40.11 +
   40.12      for ( pfn = 0; pfn < (bitmap_size * 8); pfn++ )
   40.13      {
   40.14          /* Every 100MB, print a progress dot and appease the watchdog. */
   40.15 @@ -376,6 +381,10 @@ void scrub_heap_pages(void)
   40.16          spin_unlock_irqrestore(&heap_lock, flags);
   40.17      }
   40.18  
   40.19 +#ifdef WATCH_MAP_DOMAIN_CALLERS
   40.20 +    map_domain_mem_noisy = old_map_domain_mem_noisy;
   40.21 +#endif
   40.22 +
   40.23      printk("done.\n");
   40.24  }
   40.25  
    41.1 --- a/xen/include/asm-x86/domain.h	Wed Mar 16 19:30:47 2005 +0000
    41.2 +++ b/xen/include/asm-x86/domain.h	Mon Mar 21 16:41:29 2005 +0000
    41.3 @@ -50,6 +50,8 @@ struct arch_domain
    41.4      struct out_of_sync_entry *out_of_sync_extras;
    41.5      unsigned int out_of_sync_extras_count;
    41.6  
    41.7 +    pagetable_t  phys_table;               /* guest 1:1 pagetable */
    41.8 +
    41.9  } __cacheline_aligned;
   41.10  
   41.11  struct arch_exec_domain
   41.12 @@ -115,8 +117,6 @@ struct arch_exec_domain
   41.13      pagetable_t  shadow_table;          /* (MA) shadow of guest */
   41.14      pagetable_t  monitor_table;         /* (MA) used in hypervisor */
   41.15  
   41.16 -    pagetable_t  phys_table;            /* guest 1:1 pagetable */
   41.17 -
   41.18      l2_pgentry_t *guest_vtable;         /* virtual address of pagetable */
   41.19      l2_pgentry_t *shadow_vtable;        /* virtual address of shadow_table */
   41.20      l2_pgentry_t *monitor_vtable;		/* virtual address of monitor_table */
    42.1 --- a/xen/include/asm-x86/mm.h	Wed Mar 16 19:30:47 2005 +0000
    42.2 +++ b/xen/include/asm-x86/mm.h	Mon Mar 21 16:41:29 2005 +0000
    42.3 @@ -76,6 +76,7 @@ struct pfn_info
    42.4  #define PGT_l4_shadow       PGT_l4_page_table
    42.5  #define PGT_hl2_shadow      (5<<29)
    42.6  #define PGT_snapshot        (6<<29)
    42.7 +#define PGT_writable_pred   (7<<29) /* predicted gpfn with writable ref */
    42.8  
    42.9  #define PGT_type_mask       (7<<29) /* Bits 29-31. */
   42.10  
   42.11 @@ -95,7 +96,10 @@ struct pfn_info
   42.12   /* 17-bit count of uses of this frame as its current type. */
   42.13  #define PGT_count_mask      ((1U<<17)-1)
   42.14  
   42.15 -#define PGT_mfn_mask        ((1U<<21)-1) /* mfn mask for shadow types */
   42.16 +#define PGT_mfn_mask        ((1U<<20)-1) /* mfn mask for shadow types */
   42.17 +
   42.18 +#define PGT_score_shift     20
   42.19 +#define PGT_score_mask      (((1U<<4)-1)<<PGT_score_shift)
   42.20  
   42.21   /* Cleared when the owning guest 'frees' this page. */
   42.22  #define _PGC_allocated      31
   42.23 @@ -144,6 +148,21 @@ static inline u32 pickle_domptr(struct d
   42.24          list_add_tail(&(_pfn)->list, &(_dom)->xenpage_list);                \
   42.25          spin_unlock(&(_dom)->page_alloc_lock);                              \
   42.26      } while ( 0 )
   42.27 +#define SHARE_PFN_WITH_DOMAIN2(_pfn, _dom)                                  \
   42.28 +    do {                                                                    \
   42.29 +        page_set_owner((_pfn), (_dom));                                     \
   42.30 +        /* The incremented type count is intended to pin to 'writable'. */  \
   42.31 +        (_pfn)->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;  \
   42.32 +        wmb(); /* install valid domain ptr before updating refcnt. */       \
   42.33 +        spin_lock(&(_dom)->page_alloc_lock);                                \
   42.34 +        /* _dom holds an allocation reference + writable ref */             \
   42.35 +        ASSERT((_pfn)->count_info == 0);                                    \
   42.36 +        (_pfn)->count_info |= PGC_allocated | 2;                            \
   42.37 +        if ( unlikely((_dom)->xenheap_pages++ == 0) )                       \
   42.38 +            get_knownalive_domain(_dom);                                    \
   42.39 +        list_add_tail(&(_pfn)->list, &(_dom)->page_list);                   \
   42.40 +        spin_unlock(&(_dom)->page_alloc_lock);                              \
   42.41 +    } while ( 0 )
   42.42  
   42.43  extern struct pfn_info *frame_table;
   42.44  extern unsigned long frame_table_size;
   42.45 @@ -153,9 +172,8 @@ void init_frametable(void);
   42.46  int alloc_page_type(struct pfn_info *page, unsigned int type);
   42.47  void free_page_type(struct pfn_info *page, unsigned int type);
   42.48  extern void invalidate_shadow_ldt(struct exec_domain *d);
   42.49 -extern u32 shadow_remove_all_write_access(
   42.50 -    struct domain *d, unsigned min_type, unsigned max_type,
   42.51 -    unsigned long gpfn);
   42.52 +extern int shadow_remove_all_write_access(
   42.53 +    struct domain *d, unsigned long gpfn, unsigned long gmfn);
   42.54  extern u32 shadow_remove_all_access( struct domain *d, unsigned long gmfn);
   42.55  
   42.56  static inline void put_page(struct pfn_info *page)
   42.57 @@ -188,6 +206,7 @@ static inline int get_page(struct pfn_in
   42.58               unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
   42.59               unlikely(d != _domain) )                /* Wrong owner? */
   42.60          {
   42.61 +          if ( !domain->arch.shadow_mode )
   42.62              DPRINTK("Error pfn %p: rd=%p(%d), od=%p(%d), caf=%08x, taf=%08x\n",
   42.63                      page_to_pfn(page), domain, (domain ? domain->id : -1),
   42.64                      page_get_owner(page),
   42.65 @@ -206,8 +225,36 @@ static inline int get_page(struct pfn_in
   42.66      return 1;
   42.67  }
   42.68  
   42.69 -void put_page_type(struct pfn_info *page);
   42.70 -int  get_page_type(struct pfn_info *page, u32 type);
   42.71 +//#define MFN1_TO_WATCH 0x1d8
   42.72 +#ifdef MFN1_TO_WATCH
   42.73 +#define get_page_type(__p, __t) (                                             \
   42.74 +{                                                                             \
   42.75 +    struct pfn_info *_p = (__p);                                              \
   42.76 +    u32 _t = (__t);                                                           \
   42.77 +    if ( page_to_pfn(_p) == MFN1_TO_WATCH )                                   \
   42.78 +        printk("get_page_type(%x) c=%p ot=%p @ %s:%d in %s\n",                \
   42.79 +               MFN1_TO_WATCH, frame_table[MFN1_TO_WATCH].count_info,          \
   42.80 +               frame_table[MFN1_TO_WATCH].u.inuse.type_info,                  \
   42.81 +               __FILE__, __LINE__, __func__);                                 \
   42.82 +    _get_page_type(_p, _t);                                                   \
   42.83 +})
   42.84 +#define put_page_type(__p) (                                                  \
   42.85 +{                                                                             \
   42.86 +    struct pfn_info *_p = (__p);                                              \
   42.87 +    if ( page_to_pfn(_p) == MFN1_TO_WATCH )                                   \
   42.88 +        printk("put_page_type(%x) c=%p ot=%p @ %s:%d in %s\n",                \
   42.89 +               MFN1_TO_WATCH, frame_table[MFN1_TO_WATCH].count_info,          \
   42.90 +               frame_table[MFN1_TO_WATCH].u.inuse.type_info,                  \
   42.91 +               __FILE__, __LINE__, __func__);                                 \
   42.92 +    _put_page_type(_p);                                                       \
   42.93 +})
   42.94 +#else
   42.95 +#define _get_page_type get_page_type
   42.96 +#define _put_page_type put_page_type
   42.97 +#endif
   42.98 +
   42.99 +void _put_page_type(struct pfn_info *page);
  42.100 +int  _get_page_type(struct pfn_info *page, u32 type);
  42.101  int  get_page_from_l1e(l1_pgentry_t l1e, struct domain *d);
  42.102  void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d);
  42.103  
  42.104 @@ -266,6 +313,8 @@ void synchronise_pagetables(unsigned lon
  42.105   * been used by the read-only MPT map.
  42.106   */
  42.107  #define __phys_to_machine_mapping ((unsigned long *)RO_MPT_VIRT_START)
  42.108 +#define INVALID_MFN               (~0UL)
  42.109 +#define VALID_MFN(_mfn)           (!((_mfn) & (1U<<31)))
  42.110  
  42.111  /* Returns the machine physical */
  42.112  static inline unsigned long phys_to_machine_mapping(unsigned long pfn) 
  42.113 @@ -273,10 +322,11 @@ static inline unsigned long phys_to_mach
  42.114      unsigned long mfn;
  42.115      l1_pgentry_t pte;
  42.116  
  42.117 -   if (__get_user(l1_pgentry_val(pte), (__phys_to_machine_mapping + pfn)))
  42.118 -       mfn = 0;
  42.119 +   if ( !__get_user(l1_pgentry_val(pte), (__phys_to_machine_mapping + pfn)) &&
  42.120 +        (l1_pgentry_val(pte) & _PAGE_PRESENT) )
  42.121 +       mfn = l1_pgentry_to_phys(pte) >> PAGE_SHIFT;
  42.122     else
  42.123 -       mfn = l1_pgentry_to_phys(pte) >> PAGE_SHIFT;
  42.124 +       mfn = INVALID_MFN;
  42.125  
  42.126     return mfn; 
  42.127  }
  42.128 @@ -361,15 +411,15 @@ int audit_adjust_pgtables(struct domain 
  42.129  #define AUDIT_ERRORS_OK      ( 1u << 1 )
  42.130  #define AUDIT_QUIET          ( 1u << 2 )
  42.131  
  42.132 -void _audit_domain(struct domain *d, int flags, const char *file, int line);
  42.133 -#define audit_domain(_d) _audit_domain((_d), 0, __FILE__, __LINE__)
  42.134 +void _audit_domain(struct domain *d, int flags);
  42.135 +#define audit_domain(_d) _audit_domain((_d), 0)
  42.136  void audit_domains(void);
  42.137  
  42.138  #else
  42.139  
  42.140 -#define _audit_domain(_d, _f, _file, _line) ((void)0)
  42.141 -#define audit_domain(_d) ((void)0)
  42.142 -#define audit_domains()  ((void)0)
  42.143 +#define _audit_domain(_d, _f) ((void)0)
  42.144 +#define audit_domain(_d)      ((void)0)
  42.145 +#define audit_domains()       ((void)0)
  42.146  
  42.147  #endif
  42.148  
    43.1 --- a/xen/include/asm-x86/shadow.h	Wed Mar 16 19:30:47 2005 +0000
    43.2 +++ b/xen/include/asm-x86/shadow.h	Mon Mar 21 16:41:29 2005 +0000
    43.3 @@ -49,7 +49,7 @@
    43.4       (PERDOMAIN_VIRT_START >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT))))
    43.5  
    43.6  #define shadow_lock_init(_d) spin_lock_init(&(_d)->arch.shadow_lock)
    43.7 -#define shadow_lock(_d)      spin_lock(&(_d)->arch.shadow_lock)
    43.8 +#define shadow_lock(_d)      do { ASSERT(!spin_is_locked(&(_d)->arch.shadow_lock)); spin_lock(&(_d)->arch.shadow_lock); } while (0)
    43.9  #define shadow_unlock(_d)    spin_unlock(&(_d)->arch.shadow_lock)
   43.10  
   43.11  extern void shadow_mode_init(void);
   43.12 @@ -62,6 +62,8 @@ extern struct out_of_sync_entry *shadow_
   43.13  extern void free_monitor_pagetable(struct exec_domain *ed);
   43.14  extern void __shadow_sync_all(struct domain *d);
   43.15  extern int __shadow_out_of_sync(struct exec_domain *ed, unsigned long va);
   43.16 +extern int set_p2m_entry(
   43.17 +    struct domain *d, unsigned long pfn, unsigned long mfn);
   43.18  
   43.19  static inline unsigned long __shadow_status(
   43.20      struct domain *d, unsigned long gpfn, unsigned long stype);
   43.21 @@ -169,15 +171,23 @@ static inline void shadow_mode_disable(s
   43.22  
   43.23  #define __gpfn_to_mfn(_d, gpfn)                        \
   43.24      ( (shadow_mode_translate(_d))                      \
   43.25 -      ? phys_to_machine_mapping(gpfn)                  \
   43.26 +      ? ({ ASSERT(current->domain == (_d));            \
   43.27 +           phys_to_machine_mapping(gpfn); })           \
   43.28        : (gpfn) )
   43.29  
   43.30 +extern unsigned long gpfn_to_mfn_safe(
   43.31 +    struct domain *d, unsigned long gpfn);
   43.32 +
   43.33  /************************************************************************/
   43.34  
   43.35  struct shadow_status {
   43.36      unsigned long gpfn_and_flags; /* Guest pfn plus flags. */
   43.37 -    struct shadow_status *next;   /* Pull-to-front list.   */
   43.38 +    struct shadow_status *next;   /* Pull-to-front list per hash bucket. */
   43.39      unsigned long smfn;           /* Shadow mfn.           */
   43.40 +
   43.41 +    // Pull-to-front list of L1s/L2s from which we check when removing
   43.42 +    // write access to a page.
   43.43 +    //struct list_head next_to_check;
   43.44  };
   43.45  
   43.46  #define shadow_ht_extra_size 128
   43.47 @@ -267,7 +277,7 @@ shadow_get_page_from_l1e(l1_pgentry_t l1
   43.48      if ( unlikely(!res) )
   43.49      {
   43.50          perfc_incrc(shadow_get_page_fail);
   43.51 -        FSH_LOG("%s failed to get ref l1e=%p\n", l1_pgentry_val(l1e));
   43.52 +        FSH_LOG("%s failed to get ref l1e=%p\n", __func__, l1_pgentry_val(l1e));
   43.53      }
   43.54  
   43.55      return res;
   43.56 @@ -310,7 +320,7 @@ static inline void
   43.57          unsigned long old_hl2e =
   43.58              l1_pgentry_val(ed->arch.hl2_vtable[l2_table_offset(va)]);
   43.59          unsigned long new_hl2e =
   43.60 -            (mfn ? ((mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR) : 0);
   43.61 +            (VALID_MFN(mfn) ? ((mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR) : 0);
   43.62  
   43.63          // only do the ref counting if something important changed.
   43.64          //
   43.65 @@ -331,11 +341,36 @@ static inline void
   43.66  
   43.67  /************************************************************************/
   43.68  
   43.69 +//#define MFN3_TO_WATCH 0x1ff6e
   43.70 +#ifdef MFN3_TO_WATCH
   43.71 +#define get_shadow_ref(__s) (                                                 \
   43.72 +{                                                                             \
   43.73 +    unsigned long _s = (__s);                                                 \
   43.74 +    if ( _s == MFN3_TO_WATCH )                                                \
   43.75 +        printk("get_shadow_ref(%x) oc=%d @ %s:%d in %s\n",                    \
   43.76 +               MFN3_TO_WATCH, frame_table[_s].count_info,                     \
   43.77 +               __FILE__, __LINE__, __func__);                                 \
   43.78 +    _get_shadow_ref(_s);                                                      \
   43.79 +})
   43.80 +#define put_shadow_ref(__s) (                                                 \
   43.81 +{                                                                             \
   43.82 +    unsigned long _s = (__s);                                                 \
   43.83 +    if ( _s == MFN3_TO_WATCH )                                                \
   43.84 +        printk("put_shadow_ref(%x) oc=%d @ %s:%d in %s\n",                    \
   43.85 +               MFN3_TO_WATCH, frame_table[_s].count_info,                     \
   43.86 +               __FILE__, __LINE__, __func__);                                 \
   43.87 +    _put_shadow_ref(_s);                                                      \
   43.88 +})
   43.89 +#else
   43.90 +#define _get_shadow_ref get_shadow_ref
   43.91 +#define _put_shadow_ref put_shadow_ref
   43.92 +#endif
   43.93 +
   43.94  /*
   43.95   * Add another shadow reference to smfn.
   43.96   */
   43.97  static inline int
   43.98 -get_shadow_ref(unsigned long smfn)
   43.99 +_get_shadow_ref(unsigned long smfn)
  43.100  {
  43.101      u32 x, nx;
  43.102  
  43.103 @@ -364,7 +399,7 @@ extern void free_shadow_page(unsigned lo
  43.104   * Drop a shadow reference to smfn.
  43.105   */
  43.106  static inline void
  43.107 -put_shadow_ref(unsigned long smfn)
  43.108 +_put_shadow_ref(unsigned long smfn)
  43.109  {
  43.110      u32 x, nx;
  43.111  
  43.112 @@ -419,6 +454,9 @@ static inline int __mark_dirty(struct do
  43.113      ASSERT(spin_is_locked(&d->arch.shadow_lock));
  43.114      ASSERT(d->arch.shadow_dirty_bitmap != NULL);
  43.115  
  43.116 +    if ( !VALID_MFN(mfn) )
  43.117 +        return rc;
  43.118 +
  43.119      pfn = __mfn_to_gpfn(d, mfn);
  43.120  
  43.121      /*
  43.122 @@ -470,7 +508,7 @@ extern void shadow_mark_va_out_of_sync(
  43.123      struct exec_domain *ed, unsigned long gpfn, unsigned long mfn,
  43.124      unsigned long va);
  43.125  
  43.126 -static inline void l1pte_write_fault(
  43.127 +static inline int l1pte_write_fault(
  43.128      struct exec_domain *ed, unsigned long *gpte_p, unsigned long *spte_p,
  43.129      unsigned long va)
  43.130  {
  43.131 @@ -478,34 +516,36 @@ static inline void l1pte_write_fault(
  43.132      unsigned long gpte = *gpte_p;
  43.133      unsigned long spte;
  43.134      unsigned long gpfn = gpte >> PAGE_SHIFT;
  43.135 -    unsigned long mfn = __gpfn_to_mfn(d, gpfn);
  43.136 +    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
  43.137  
  43.138 -    //printk("l1pte_write_fault gmfn=%p\n", mfn);
  43.139 +    //printk("l1pte_write_fault gmfn=%p\n", gmfn);
  43.140  
  43.141 -    if ( unlikely(!mfn) )
  43.142 +    if ( unlikely(!VALID_MFN(gmfn)) )
  43.143      {
  43.144          SH_LOG("l1pte_write_fault: invalid gpfn=%p", gpfn);
  43.145          *spte_p = 0;
  43.146 -        return;
  43.147 +        return 0;
  43.148      }
  43.149  
  43.150      ASSERT(gpte & _PAGE_RW);
  43.151      gpte |= _PAGE_DIRTY | _PAGE_ACCESSED;
  43.152 -    spte = (mfn << PAGE_SHIFT) | (gpte & ~PAGE_MASK);
  43.153 +    spte = (gmfn << PAGE_SHIFT) | (gpte & ~PAGE_MASK);
  43.154  
  43.155      SH_VVLOG("l1pte_write_fault: updating spte=0x%p gpte=0x%p", spte, gpte);
  43.156  
  43.157      if ( shadow_mode_log_dirty(d) )
  43.158 -        __mark_dirty(d, mfn);
  43.159 +        __mark_dirty(d, gmfn);
  43.160  
  43.161 -    if ( mfn_is_page_table(mfn) )
  43.162 -        shadow_mark_va_out_of_sync(ed, gpfn, mfn, va);
  43.163 +    if ( mfn_is_page_table(gmfn) )
  43.164 +        shadow_mark_va_out_of_sync(ed, gpfn, gmfn, va);
  43.165  
  43.166      *gpte_p = gpte;
  43.167      *spte_p = spte;
  43.168 +
  43.169 +    return 1;
  43.170  }
  43.171  
  43.172 -static inline void l1pte_read_fault(
  43.173 +static inline int l1pte_read_fault(
  43.174      struct domain *d, unsigned long *gpte_p, unsigned long *spte_p)
  43.175  { 
  43.176      unsigned long gpte = *gpte_p;
  43.177 @@ -513,11 +553,11 @@ static inline void l1pte_read_fault(
  43.178      unsigned long pfn = gpte >> PAGE_SHIFT;
  43.179      unsigned long mfn = __gpfn_to_mfn(d, pfn);
  43.180  
  43.181 -    if ( unlikely(!mfn) )
  43.182 +    if ( unlikely(!VALID_MFN(mfn)) )
  43.183      {
  43.184          SH_LOG("l1pte_read_fault: invalid gpfn=%p", pfn);
  43.185          *spte_p = 0;
  43.186 -        return;
  43.187 +        return 0;
  43.188      }
  43.189  
  43.190      gpte |= _PAGE_ACCESSED;
  43.191 @@ -532,25 +572,22 @@ static inline void l1pte_read_fault(
  43.192      SH_VVLOG("l1pte_read_fault: updating spte=0x%p gpte=0x%p", spte, gpte);
  43.193      *gpte_p = gpte;
  43.194      *spte_p = spte;
  43.195 +
  43.196 +    return 1;
  43.197  }
  43.198  
  43.199  static inline void l1pte_propagate_from_guest(
  43.200      struct domain *d, unsigned long gpte, unsigned long *spte_p)
  43.201  { 
  43.202      unsigned long pfn = gpte >> PAGE_SHIFT;
  43.203 -    unsigned long mfn = __gpfn_to_mfn(d, pfn);
  43.204 -    unsigned long spte;
  43.205 -
  43.206 -#if SHADOW_VERBOSE_DEBUG
  43.207 -    unsigned long old_spte = *spte_p;
  43.208 -#endif
  43.209 +    unsigned long mfn, spte;
  43.210  
  43.211      spte = 0;
  43.212  
  43.213 -    if ( mfn &&
  43.214 -         ((gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
  43.215 -          (_PAGE_PRESENT|_PAGE_ACCESSED)) ) {
  43.216 -
  43.217 +    if ( ((gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
  43.218 +          (_PAGE_PRESENT|_PAGE_ACCESSED)) &&
  43.219 +         VALID_MFN(mfn = __gpfn_to_mfn(d, pfn)) )
  43.220 +    {
  43.221          spte = (mfn << PAGE_SHIFT) | (gpte & ~PAGE_MASK);
  43.222          
  43.223          if ( shadow_mode_log_dirty(d) ||
  43.224 @@ -561,14 +598,47 @@ static inline void l1pte_propagate_from_
  43.225          }
  43.226      }
  43.227  
  43.228 -#if SHADOW_VERBOSE_DEBUG
  43.229 -    if ( old_spte || spte || gpte )
  43.230 -        SH_VLOG("l1pte_propagate_from_guest: gpte=0x%p, old spte=0x%p, new spte=0x%p", gpte, old_spte, spte);
  43.231 +#if 0
  43.232 +    if ( spte || gpte )
  43.233 +        SH_VVLOG("%s: gpte=%p, new spte=%p", __func__, gpte, spte);
  43.234  #endif
  43.235  
  43.236      *spte_p = spte;
  43.237  }
  43.238  
  43.239 +static inline void hl2e_propagate_from_guest(
  43.240 +    struct domain *d, unsigned long gpde, unsigned long *hl2e_p)
  43.241 +{
  43.242 +    unsigned long pfn = gpde >> PAGE_SHIFT;
  43.243 +    unsigned long mfn, hl2e;
  43.244 +
  43.245 +    hl2e = 0;
  43.246 +
  43.247 +    if ( gpde & _PAGE_PRESENT )
  43.248 +    {
  43.249 +        if ( unlikely((current->domain != d) && !shadow_mode_external(d)) )
  43.250 +        {
  43.251 +            // Can't use __gpfn_to_mfn() if we don't have one of this domain's
  43.252 +            // page tables currently installed.  What a pain in the neck!
  43.253 +            //
  43.254 +            // This isn't common -- it only happens during shadow mode setup
  43.255 +            // and mode changes.
  43.256 +            //
  43.257 +            mfn = gpfn_to_mfn_safe(d, pfn);
  43.258 +        }
  43.259 +        else
  43.260 +            mfn = __gpfn_to_mfn(d, pfn);
  43.261 +
  43.262 +        if ( VALID_MFN(mfn) && (mfn < max_page) )
  43.263 +            hl2e = (mfn << PAGE_SHIFT) | __PAGE_HYPERVISOR;
  43.264 +    }
  43.265 +
  43.266 +    if ( hl2e || gpde )
  43.267 +        SH_VVLOG("%s: gpde=%p hl2e=%p", __func__, gpde, hl2e);
  43.268 +
  43.269 +    *hl2e_p = hl2e;
  43.270 +}
  43.271 +
  43.272  static inline void l2pde_general(
  43.273      struct domain *d,
  43.274      unsigned long *gpde_p,
  43.275 @@ -582,7 +652,7 @@ static inline void l2pde_general(
  43.276      if ( (gpde & _PAGE_PRESENT) && (sl1mfn != 0) )
  43.277      {
  43.278          spde = (gpde & ~PAGE_MASK) | (sl1mfn << PAGE_SHIFT) | 
  43.279 -            _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY;
  43.280 +            _PAGE_RW | _PAGE_ACCESSED;
  43.281          gpde |= _PAGE_ACCESSED; /* N.B. PDEs do not have a dirty bit. */
  43.282  
  43.283          // XXX mafetter: Hmm...
  43.284 @@ -592,6 +662,9 @@ static inline void l2pde_general(
  43.285          *gpde_p = gpde;
  43.286      }
  43.287  
  43.288 +    if ( spde || gpde )
  43.289 +        SH_VVLOG("%s: gpde=%p, new spde=%p", __func__, gpde, spde);
  43.290 +
  43.291      *spde_p = spde;
  43.292  }
  43.293  
  43.294 @@ -649,6 +722,42 @@ validate_pte_change(
  43.295  // returns true if a tlb flush is needed
  43.296  //
  43.297  static int inline
  43.298 +validate_hl2e_change(
  43.299 +    struct domain *d,
  43.300 +    unsigned long new_gpde,
  43.301 +    unsigned long *shadow_hl2e_p)
  43.302 +{
  43.303 +    unsigned long old_hl2e, new_hl2e;
  43.304 +
  43.305 +    perfc_incrc(validate_hl2e_calls);
  43.306 +
  43.307 +    old_hl2e = *shadow_hl2e_p;
  43.308 +    hl2e_propagate_from_guest(d, new_gpde, &new_hl2e);
  43.309 +
  43.310 +    // Only do the ref counting if something important changed.
  43.311 +    //
  43.312 +    if ( ((old_hl2e | new_hl2e) & _PAGE_PRESENT) &&
  43.313 +         ((old_hl2e ^ new_hl2e) & (PAGE_MASK | _PAGE_PRESENT)) )
  43.314 +    {
  43.315 +        perfc_incrc(validate_hl2e_changes);
  43.316 +
  43.317 +        if ( (new_hl2e & _PAGE_PRESENT) &&
  43.318 +             !get_page(pfn_to_page(new_hl2e >> PAGE_SHIFT), d) )
  43.319 +            new_hl2e = 0;
  43.320 +        if ( old_hl2e & _PAGE_PRESENT )
  43.321 +            put_page(pfn_to_page(old_hl2e >> PAGE_SHIFT));
  43.322 +    }
  43.323 +
  43.324 +    *shadow_hl2e_p = new_hl2e;
  43.325 +
  43.326 +    // paranoia rules!
  43.327 +    return 1;
  43.328 +    
  43.329 +}
  43.330 +
  43.331 +// returns true if a tlb flush is needed
  43.332 +//
  43.333 +static int inline
  43.334  validate_pde_change(
  43.335      struct domain *d,
  43.336      unsigned long new_gpde,
  43.337 @@ -733,17 +842,19 @@ static void shadow_audit(struct domain *
  43.338          perfc_value(shadow_l1_pages) +
  43.339          perfc_value(shadow_l2_pages) +
  43.340          perfc_value(hl2_table_pages) +
  43.341 -        perfc_value(snapshot_pages)
  43.342 +        perfc_value(snapshot_pages) +
  43.343 +        perfc_value(writable_pte_predictions)
  43.344          ) - live;
  43.345  #ifdef PERF_COUNTERS
  43.346      if ( (abs < -1) || (abs > 1) )
  43.347      {
  43.348 -        printk("live=%d free=%d l1=%d l2=%d hl2=%d snapshot=%d\n",
  43.349 +        printk("live=%d free=%d l1=%d l2=%d hl2=%d snapshot=%d writable_ptes=%d\n",
  43.350                 live, free,
  43.351                 perfc_value(shadow_l1_pages),
  43.352                 perfc_value(shadow_l2_pages),
  43.353                 perfc_value(hl2_table_pages),
  43.354 -               perfc_value(snapshot_pages));
  43.355 +               perfc_value(snapshot_pages),
  43.356 +               perfc_value(writable_pte_predictions));
  43.357          BUG();
  43.358      }
  43.359  #endif
  43.360 @@ -828,22 +939,34 @@ static inline unsigned long ___shadow_st
  43.361  static inline unsigned long __shadow_status(
  43.362      struct domain *d, unsigned long gpfn, unsigned long stype)
  43.363  {
  43.364 -    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
  43.365 +    unsigned long gmfn = ((current->domain == d)
  43.366 +                          ? __gpfn_to_mfn(d, gpfn)
  43.367 +                          : INVALID_MFN);
  43.368  
  43.369      ASSERT(spin_is_locked(&d->arch.shadow_lock));
  43.370      ASSERT(gpfn == (gpfn & PGT_mfn_mask));
  43.371      ASSERT(stype && !(stype & ~PGT_type_mask));
  43.372  
  43.373 -    if ( gmfn && ((stype != PGT_snapshot)
  43.374 -                  ? !mfn_is_page_table(gmfn)
  43.375 -                  : !mfn_out_of_sync(gmfn)) )
  43.376 +    if ( VALID_MFN(gmfn) && (gmfn < max_page) &&
  43.377 +         (stype != PGT_writable_pred) &&
  43.378 +         ((stype == PGT_snapshot)
  43.379 +          ? !mfn_out_of_sync(gmfn)
  43.380 +          : !mfn_is_page_table(gmfn)) )
  43.381      {
  43.382          perfc_incrc(shadow_status_shortcut);
  43.383 +#ifndef NDEBUG
  43.384          ASSERT(___shadow_status(d, gpfn, stype) == 0);
  43.385 +
  43.386 +        // Undo the affects of the above ASSERT on ___shadow_status()'s perf
  43.387 +        // counters.
  43.388 +        //
  43.389 +        perfc_decrc(shadow_status_calls);
  43.390 +        perfc_decrc(shadow_status_miss);
  43.391 +#endif
  43.392          return 0;
  43.393      }
  43.394  
  43.395 -    return ___shadow_status(d, gmfn, stype);
  43.396 +    return ___shadow_status(d, gpfn, stype);
  43.397  }
  43.398  
  43.399  /*
  43.400 @@ -870,21 +993,26 @@ shadow_max_pgtable_type(struct domain *d
  43.401          {
  43.402              type = x->gpfn_and_flags & PGT_type_mask;
  43.403  
  43.404 -            // Treat an HL2 as if it's an L1
  43.405 -            //
  43.406 -            if ( type == PGT_hl2_shadow )
  43.407 +            switch ( type )
  43.408 +            {
  43.409 +            case PGT_hl2_shadow:
  43.410 +                // Treat an HL2 as if it's an L1
  43.411 +                //
  43.412                  type = PGT_l1_shadow;
  43.413 -
  43.414 -            // Ignore snapshots -- they don't in and of themselves constitute
  43.415 -            // treating a page as a page table
  43.416 -            //
  43.417 -            if ( type == PGT_snapshot )
  43.418 +                break;
  43.419 +            case PGT_snapshot:
  43.420 +            case PGT_writable_pred:
  43.421 +                // Ignore snapshots -- they don't in and of themselves constitute
  43.422 +                // treating a page as a page table
  43.423 +                //
  43.424                  goto next;
  43.425 -
  43.426 -            // Early exit if we found the max possible value
  43.427 -            //
  43.428 -            if ( type == PGT_base_page_table )
  43.429 +            case PGT_base_page_table:
  43.430 +                // Early exit if we found the max possible value
  43.431 +                //
  43.432                  return type;
  43.433 +            default:
  43.434 +                break;
  43.435 +            }
  43.436  
  43.437              if ( type > pttype )
  43.438                  pttype = type;
  43.439 @@ -937,7 +1065,7 @@ static inline void put_shadow_status(str
  43.440  
  43.441  
  43.442  static inline void delete_shadow_status( 
  43.443 -    struct domain *d, unsigned int gpfn, unsigned int stype)
  43.444 +    struct domain *d, unsigned long gpfn, unsigned long gmfn, unsigned int stype)
  43.445  {
  43.446      struct shadow_status *p, *x, *n, *head;
  43.447      unsigned long key = gpfn | stype;
  43.448 @@ -1008,24 +1136,30 @@ static inline void delete_shadow_status(
  43.449  
  43.450   found:
  43.451      // release ref to page
  43.452 -    put_page(pfn_to_page(__gpfn_to_mfn(d, gpfn)));
  43.453 +    if ( stype != PGT_writable_pred )
  43.454 +        put_page(pfn_to_page(gmfn));
  43.455  
  43.456      shadow_audit(d, 0);
  43.457  }
  43.458  
  43.459  static inline void set_shadow_status(
  43.460 -    struct domain *d, unsigned long gpfn,
  43.461 +    struct domain *d, unsigned long gpfn, unsigned long gmfn,
  43.462      unsigned long smfn, unsigned long stype)
  43.463  {
  43.464      struct shadow_status *x, *head, *extra;
  43.465      int i;
  43.466 -    unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
  43.467      unsigned long key = gpfn | stype;
  43.468  
  43.469 +    SH_VVLOG("set gpfn=%p gmfn=%p smfn=%p t=%p", gpfn, gmfn, smfn, stype);
  43.470 +
  43.471      ASSERT(spin_is_locked(&d->arch.shadow_lock));
  43.472 -    ASSERT(gpfn && !(gpfn & ~PGT_mfn_mask));
  43.473 -    ASSERT(pfn_is_ram(gmfn)); // XXX need to be more graceful
  43.474 -    ASSERT(smfn && !(smfn & ~PGT_mfn_mask));
  43.475 +
  43.476 +    ASSERT(shadow_mode_translate(d) || gpfn);
  43.477 +    ASSERT(!(gpfn & ~PGT_mfn_mask));
  43.478 +
  43.479 +    // XXX - need to be more graceful.
  43.480 +    ASSERT(VALID_MFN(gmfn));
  43.481 +
  43.482      ASSERT(stype && !(stype & ~PGT_type_mask));
  43.483  
  43.484      x = head = hash_bucket(d, gpfn);
  43.485 @@ -1037,17 +1171,24 @@ static inline void set_shadow_status(
  43.486      // grab a reference to the guest page to represent the entry in the shadow
  43.487      // hash table
  43.488      //
  43.489 -    get_page(pfn_to_page(gmfn), d);
  43.490 +    // XXX - Should PGT_writable_pred grab a page ref?
  43.491 +    //     - Who/how are these hash table entry refs flushed if/when a page
  43.492 +    //       is given away by the domain?
  43.493 +    //
  43.494 +    if ( stype != PGT_writable_pred )
  43.495 +        get_page(pfn_to_page(gmfn), d);
  43.496  
  43.497      /*
  43.498       * STEP 1. If page is already in the table, update it in place.
  43.499       */
  43.500      do
  43.501      {
  43.502 -        if ( x->gpfn_and_flags == key )
  43.503 +        if ( unlikely(x->gpfn_and_flags == key) )
  43.504          {
  43.505 -            BUG();
  43.506 +            if ( stype != PGT_writable_pred )
  43.507 +                BUG(); // we should never replace entries into the hash table
  43.508              x->smfn = smfn;
  43.509 +            put_page(pfn_to_page(gmfn)); // already had a ref...
  43.510              goto done;
  43.511          }
  43.512  
  43.513 @@ -1109,6 +1250,13 @@ static inline void set_shadow_status(
  43.514  
  43.515   done:
  43.516      shadow_audit(d, 0);
  43.517 +
  43.518 +    if ( stype <= PGT_l4_shadow )
  43.519 +    {
  43.520 +        // add to front of list of pages to check when removing write
  43.521 +        // permissions for a page...
  43.522 +        //
  43.523 +    }
  43.524  }
  43.525  
  43.526  /************************************************************************/
    44.1 --- a/xen/include/asm-x86/vmx_platform.h	Wed Mar 16 19:30:47 2005 +0000
    44.2 +++ b/xen/include/asm-x86/vmx_platform.h	Mon Mar 21 16:41:29 2005 +0000
    44.3 @@ -87,6 +87,7 @@ struct virutal_platform_def {
    44.4  extern void handle_mmio(unsigned long, unsigned long);
    44.5  extern int vmx_setup_platform(struct exec_domain *, execution_context_t *);
    44.6  
    44.7 -#define mmio_space(gpa) (!phys_to_machine_mapping((gpa) >> PAGE_SHIFT))
    44.8 +// XXX - think about this -- maybe use bit 30 of the mfn to signify an MMIO frame.
    44.9 +#define mmio_space(gpa) (!VALID_MFN(phys_to_machine_mapping((gpa) >> PAGE_SHIFT)))
   44.10  
   44.11  #endif
    45.1 --- a/xen/include/asm-x86/x86_32/domain_page.h	Wed Mar 16 19:30:47 2005 +0000
    45.2 +++ b/xen/include/asm-x86/x86_32/domain_page.h	Mon Mar 21 16:41:29 2005 +0000
    45.3 @@ -13,12 +13,28 @@
    45.4  extern unsigned long *mapcache;
    45.5  #define MAPCACHE_ENTRIES        1024
    45.6  
    45.7 +
    45.8 +//#define WATCH_MAP_DOMAIN_CALLERS 1
    45.9 +#ifdef WATCH_MAP_DOMAIN_CALLERS
   45.10 +extern int map_domain_mem_noisy;
   45.11 +#define map_domain_mem(__mdm_pa) (                                            \
   45.12 +{                                                                             \
   45.13 +    unsigned long _mdm_pa = (__mdm_pa);                                       \
   45.14 +    if ( map_domain_mem_noisy )                                               \
   45.15 +        printk("map_domain_mem(%p) @ %s:%d in %s\n",                          \
   45.16 +               _mdm_pa, __FILE__, __LINE__, __func__);                        \
   45.17 +    _map_domain_mem(_mdm_pa);                                                 \
   45.18 +})
   45.19 +#else
   45.20 +#define _map_domain_mem map_domain_mem
   45.21 +#endif
   45.22 +
   45.23  /*
   45.24   * Maps a given physical address, returning corresponding virtual address.
   45.25   * The entire page containing that VA is now accessible until a 
   45.26   * corresponding call to unmap_domain_mem().
   45.27   */
   45.28 -extern void *map_domain_mem(unsigned long pa);
   45.29 +extern void *_map_domain_mem(unsigned long pa);
   45.30  
   45.31  /*
   45.32   * Pass a VA within a page previously mapped with map_domain_mem().
    46.1 --- a/xen/include/public/arch-x86_32.h	Wed Mar 16 19:30:47 2005 +0000
    46.2 +++ b/xen/include/public/arch-x86_32.h	Mon Mar 21 16:41:29 2005 +0000
    46.3 @@ -70,9 +70,15 @@
    46.4   * machine->physical mapping table starts at this address, read-only.
    46.5   */
    46.6  #define HYPERVISOR_VIRT_START (0xFC000000UL)
    46.7 +#ifndef CONFIG_XEN_SHADOW_MODE
    46.8  #ifndef machine_to_phys_mapping
    46.9  #define machine_to_phys_mapping ((u32 *)HYPERVISOR_VIRT_START)
   46.10  #endif
   46.11 +#else /* CONFIG_XEN_SHADOW_MODE */
   46.12 +#ifndef __vms_machine_to_phys_mapping
   46.13 +#define __vms_machine_to_phys_mapping ((u32 *)HYPERVISOR_VIRT_START)
   46.14 +#endif
   46.15 +#endif /* CONFIG_XEN_SHADOW_MODE */
   46.16  
   46.17  #ifndef __ASSEMBLY__
   46.18  
    47.1 --- a/xen/include/xen/perfc.h	Wed Mar 16 19:30:47 2005 +0000
    47.2 +++ b/xen/include/xen/perfc.h	Mon Mar 21 16:41:29 2005 +0000
    47.3 @@ -69,6 +69,7 @@ extern struct perfcounter perfcounters;
    47.4  #define perfc_incr(x)     atomic_inc(&perfcounters.x[0])
    47.5  #define perfc_decr(x)     atomic_dec(&perfcounters.x[0])
    47.6  #define perfc_incrc(x)    atomic_inc(&perfcounters.x[smp_processor_id()])
    47.7 +#define perfc_decrc(x)    atomic_dec(&perfcounters.x[smp_processor_id()])
    47.8  #define perfc_incra(x,y)                                                \
    47.9      do {                                                                \
   47.10          if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
    48.1 --- a/xen/include/xen/perfc_defn.h	Wed Mar 16 19:30:47 2005 +0000
    48.2 +++ b/xen/include/xen/perfc_defn.h	Mon Mar 21 16:41:29 2005 +0000
    48.3 @@ -1,4 +1,3 @@
    48.4 -
    48.5  PERFCOUNTER_CPU (seg_fixups,   "segmentation fixups" )
    48.6  
    48.7  PERFCOUNTER_CPU( irqs,         "#interrupts" )
    49.1 --- a/xen/include/xen/sched.h	Wed Mar 16 19:30:47 2005 +0000
    49.2 +++ b/xen/include/xen/sched.h	Mon Mar 21 16:41:29 2005 +0000
    49.3 @@ -117,6 +117,7 @@ struct domain
    49.4      struct list_head xenpage_list;    /* linked list, of size xenheap_pages */
    49.5      unsigned int     tot_pages;       /* number of pages currently possesed */
    49.6      unsigned int     max_pages;       /* maximum value for tot_pages        */
    49.7 +    unsigned int     next_io_page;    /* next io pfn to give to domain      */
    49.8      unsigned int     xenheap_pages;   /* # pages allocated from Xen heap    */
    49.9  
   49.10      /* Scheduling. */