direct-io.hg

changeset 7771:e023e37b3c7a

Fix make_page_readonly/make_page_writeable on PAE guests - previous behaviour
was incorrect when machine address > 4GB. We believe this fixes bugzilla #267.

Also tidy up and fix show_page_walk.


Signed-off-by: Steven Hand <steven@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author smh22@firebug.cl.cam.ac.uk
date Fri Nov 11 19:02:49 2005 +0100 (2005-11-11)
parents 980967b0b161
children 995e94c4802e
files linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c xen/arch/x86/x86_32/traps.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Fri Nov 11 17:56:02 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Fri Nov 11 19:02:49 2005 +0100
     1.3 @@ -398,14 +398,14 @@ void make_page_readonly(void *va)
     1.4  {
     1.5  	pte_t *pte = virt_to_ptep(va);
     1.6  	set_pte(pte, pte_wrprotect(*pte));
     1.7 -	if ( (unsigned long)va >= (unsigned long)high_memory )
     1.8 -	{
     1.9 -		unsigned long phys;
    1.10 -		phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
    1.11 +	if ((unsigned long)va >= (unsigned long)high_memory) {
    1.12 +		unsigned long pfn; 
    1.13 +		pfn = pte_pfn(*pte); 
    1.14  #ifdef CONFIG_HIGHMEM
    1.15 -		if ( (phys >> PAGE_SHIFT) < highstart_pfn )
    1.16 +		if (pfn < highstart_pfn)
    1.17  #endif
    1.18 -			make_lowmem_page_readonly(phys_to_virt(phys));
    1.19 +			make_lowmem_page_readonly(
    1.20 +				phys_to_virt(pfn << PAGE_SHIFT)); 
    1.21  	}
    1.22  }
    1.23  
    1.24 @@ -413,21 +413,20 @@ void make_page_writable(void *va)
    1.25  {
    1.26  	pte_t *pte = virt_to_ptep(va);
    1.27  	set_pte(pte, pte_mkwrite(*pte));
    1.28 -	if ( (unsigned long)va >= (unsigned long)high_memory )
    1.29 -	{
    1.30 -		unsigned long phys;
    1.31 -		phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
    1.32 +	if ((unsigned long)va >= (unsigned long)high_memory) {
    1.33 +		unsigned long pfn; 
    1.34 +		pfn = pte_pfn(*pte); 
    1.35  #ifdef CONFIG_HIGHMEM
    1.36 -		if ( (phys >> PAGE_SHIFT) < highstart_pfn )
    1.37 +		if (pfn < highstart_pfn)
    1.38  #endif
    1.39 -			make_lowmem_page_writable(phys_to_virt(phys));
    1.40 +			make_lowmem_page_writable(
    1.41 +				phys_to_virt(pfn << PAGE_SHIFT)); 
    1.42  	}
    1.43  }
    1.44  
    1.45  void make_pages_readonly(void *va, unsigned int nr)
    1.46  {
    1.47 -	while ( nr-- != 0 )
    1.48 -	{
    1.49 +	while (nr-- != 0) {
    1.50  		make_page_readonly(va);
    1.51  		va = (void *)((unsigned long)va + PAGE_SIZE);
    1.52  	}
    1.53 @@ -435,8 +434,7 @@ void make_pages_readonly(void *va, unsig
    1.54  
    1.55  void make_pages_writable(void *va, unsigned int nr)
    1.56  {
    1.57 -	while ( nr-- != 0 )
    1.58 -	{
    1.59 +	while (nr-- != 0) {
    1.60  		make_page_writable(va);
    1.61  		va = (void *)((unsigned long)va + PAGE_SIZE);
    1.62  	}
     2.1 --- a/xen/arch/x86/x86_32/traps.c	Fri Nov 11 17:56:02 2005 +0100
     2.2 +++ b/xen/arch/x86/x86_32/traps.c	Fri Nov 11 19:02:49 2005 +0100
     2.3 @@ -84,32 +84,37 @@ void show_registers(struct cpu_user_regs
     2.4  
     2.5  void show_page_walk(unsigned long addr)
     2.6  {
     2.7 -    unsigned long pfn = read_cr3() >> PAGE_SHIFT;
     2.8 +    unsigned long mfn = read_cr3() >> PAGE_SHIFT;
     2.9      intpte_t *ptab, ent;
    2.10 +    unsigned long pfn; 
    2.11  
    2.12      printk("Pagetable walk from %08lx:\n", addr);
    2.13  
    2.14  #ifdef CONFIG_X86_PAE
    2.15 -    ptab = map_domain_page(pfn);
    2.16 -    ent = ptab[l3_table_offset(addr)];
    2.17 -    printk(" L3 = %"PRIpte"\n", ent);
    2.18 +    ptab = map_domain_page(mfn);
    2.19 +    ent  = ptab[l3_table_offset(addr)];
    2.20 +    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
    2.21 +    printk(" L3 = %"PRIpte" %08lx\n", ent, pfn);
    2.22      unmap_domain_page(ptab);
    2.23      if ( !(ent & _PAGE_PRESENT) )
    2.24          return;
    2.25 -    pfn = ent >> PAGE_SHIFT;
    2.26 +    mfn = ent >> PAGE_SHIFT;
    2.27  #endif
    2.28  
    2.29 -    ptab = map_domain_page(pfn);
    2.30 -    ent = ptab[l2_table_offset(addr)];
    2.31 -    printk("  L2 = %"PRIpte" %s\n", ent, (ent & _PAGE_PSE) ? "(PSE)" : "");
    2.32 +    ptab = map_domain_page(mfn);
    2.33 +    ent  = ptab[l2_table_offset(addr)];
    2.34 +    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
    2.35 +    printk("  L2 = %"PRIpte" %08lx %s\n", ent, pfn, 
    2.36 +           (ent & _PAGE_PSE) ? "(PSE)" : "");
    2.37      unmap_domain_page(ptab);
    2.38      if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
    2.39          return;
    2.40 -    pfn = ent >> PAGE_SHIFT;
    2.41 +    mfn = ent >> PAGE_SHIFT;
    2.42  
    2.43      ptab = map_domain_page(ent >> PAGE_SHIFT);
    2.44 -    ent = ptab[l2_table_offset(addr)];
    2.45 -    printk("   L1 = %"PRIpte"\n", ent);
    2.46 +    ent  = ptab[l1_table_offset(addr)];
    2.47 +    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
    2.48 +    printk("   L1 = %"PRIpte" %08lx\n", ent, pfn);
    2.49      unmap_domain_page(ptab);
    2.50  }
    2.51