# HG changeset patch
# User smh22@xxxxxxxxxxxxxxxxxxxx
# Node ID e023e37b3c7aca1d5702715eed4b586e267a75ee
# Parent 980967b0b161aa2a0d77066c5c43afa1c4e3a14c
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@xxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 980967b0b161 -r e023e37b3c7a
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Fri Nov 11 16:56:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Fri Nov 11 18:02:49 2005
@@ -398,14 +398,14 @@
{
pte_t *pte = virt_to_ptep(va);
set_pte(pte, pte_wrprotect(*pte));
- if ( (unsigned long)va >= (unsigned long)high_memory )
- {
- unsigned long phys;
- phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
+ if ((unsigned long)va >= (unsigned long)high_memory) {
+ unsigned long pfn;
+ pfn = pte_pfn(*pte);
#ifdef CONFIG_HIGHMEM
- if ( (phys >> PAGE_SHIFT) < highstart_pfn )
+ if (pfn < highstart_pfn)
#endif
- make_lowmem_page_readonly(phys_to_virt(phys));
+ make_lowmem_page_readonly(
+ phys_to_virt(pfn << PAGE_SHIFT));
}
}
@@ -413,21 +413,20 @@
{
pte_t *pte = virt_to_ptep(va);
set_pte(pte, pte_mkwrite(*pte));
- if ( (unsigned long)va >= (unsigned long)high_memory )
- {
- unsigned long phys;
- phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
+ if ((unsigned long)va >= (unsigned long)high_memory) {
+ unsigned long pfn;
+ pfn = pte_pfn(*pte);
#ifdef CONFIG_HIGHMEM
- if ( (phys >> PAGE_SHIFT) < highstart_pfn )
+ if (pfn < highstart_pfn)
#endif
- make_lowmem_page_writable(phys_to_virt(phys));
+ make_lowmem_page_writable(
+ phys_to_virt(pfn << PAGE_SHIFT));
}
}
void make_pages_readonly(void *va, unsigned int nr)
{
- while ( nr-- != 0 )
- {
+ while (nr-- != 0) {
make_page_readonly(va);
va = (void *)((unsigned long)va + PAGE_SIZE);
}
@@ -435,8 +434,7 @@
void make_pages_writable(void *va, unsigned int nr)
{
- while ( nr-- != 0 )
- {
+ while (nr-- != 0) {
make_page_writable(va);
va = (void *)((unsigned long)va + PAGE_SIZE);
}
diff -r 980967b0b161 -r e023e37b3c7a xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Nov 11 16:56:02 2005
+++ b/xen/arch/x86/x86_32/traps.c Fri Nov 11 18:02:49 2005
@@ -84,32 +84,37 @@
void show_page_walk(unsigned long addr)
{
- unsigned long pfn = read_cr3() >> PAGE_SHIFT;
+ unsigned long mfn = read_cr3() >> PAGE_SHIFT;
intpte_t *ptab, ent;
+ unsigned long pfn;
printk("Pagetable walk from %08lx:\n", addr);
#ifdef CONFIG_X86_PAE
- ptab = map_domain_page(pfn);
- ent = ptab[l3_table_offset(addr)];
- printk(" L3 = %"PRIpte"\n", ent);
+ ptab = map_domain_page(mfn);
+ ent = ptab[l3_table_offset(addr)];
+ pfn = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)];
+ printk(" L3 = %"PRIpte" %08lx\n", ent, pfn);
unmap_domain_page(ptab);
if ( !(ent & _PAGE_PRESENT) )
return;
- pfn = ent >> PAGE_SHIFT;
+ mfn = ent >> PAGE_SHIFT;
#endif
- ptab = map_domain_page(pfn);
- ent = ptab[l2_table_offset(addr)];
- printk(" L2 = %"PRIpte" %s\n", ent, (ent & _PAGE_PSE) ? "(PSE)" : "");
+ ptab = map_domain_page(mfn);
+ ent = ptab[l2_table_offset(addr)];
+ pfn = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)];
+ printk(" L2 = %"PRIpte" %08lx %s\n", ent, pfn,
+ (ent & _PAGE_PSE) ? "(PSE)" : "");
unmap_domain_page(ptab);
if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
return;
- pfn = ent >> PAGE_SHIFT;
+ mfn = ent >> PAGE_SHIFT;
ptab = map_domain_page(ent >> PAGE_SHIFT);
- ent = ptab[l2_table_offset(addr)];
- printk(" L1 = %"PRIpte"\n", ent);
+ ent = ptab[l1_table_offset(addr)];
+ pfn = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)];
+ printk(" L1 = %"PRIpte" %08lx\n", ent, pfn);
unmap_domain_page(ptab);
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|