WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] CONFIG_XEN_COMPAT_030002 broken?

To: Gerd Hoffmann <kraxel@xxxxxxx>
Subject: Re: [Xen-devel] CONFIG_XEN_COMPAT_030002 broken?
From: Gerd Hoffmann <kraxel@xxxxxxx>
Date: Tue, 14 Nov 2006 17:06:23 +0100
Cc: Xen devel list <xen-devel@xxxxxxxxxxxxxxxxxxx>, Keir Fraser <keir@xxxxxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxxxx>
Delivery-date: Tue, 14 Nov 2006 08:06:36 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <4559E236.7080706@xxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <C17F9079.486E%keir@xxxxxxxxxxxxx> <4559E236.7080706@xxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 1.5.0.7 (X11/20060911)
Gerd Hoffmann wrote:
>> So far we have maintained the COMPAT code to be easily entirely strippable.
>> So the change to pmd_bad() should either use kernel_page_user rather than
>> _PAGE_USER, or its definition should be conditional on the COMPAT flag.
> 
> Both ways should have the same effect as kernel_page_user is defined to
> 0 for the non-compat case.

Well, thinko in there, wasn't that simple.  Went with the #ifdef, new
version attached.

cheers,
  Gerd

-- 
Gerd Hoffmann <kraxel@xxxxxxx>
http://www.suse.de/~kraxel/julika-dora.jpeg
---
 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c                |    3 
 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c                 |   51 
+++++++++-
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h |   22 +++-
 3 files changed, 70 insertions(+), 6 deletions(-)

Index: build-64-testing-11774/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
===================================================================
--- build-64-testing-11774.orig/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
+++ build-64-testing-11774/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
@@ -250,6 +250,9 @@ void __iomem * __ioremap(unsigned long p
        area->phys_addr = phys_addr;
        addr = (void __iomem *) area->addr;
        flags |= _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;
+#if defined(__x86_64__)
+       flags |= kernel_page_user;
+#endif
        if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr,
                                     phys_addr>>PAGE_SHIFT,
                                     size, __pgprot(flags), domid)) {
Index: build-64-testing-11774/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
===================================================================
--- build-64-testing-11774.orig/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
+++ build-64-testing-11774/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
@@ -56,6 +56,11 @@
 struct dma_mapping_ops* dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
+#ifdef CONFIG_XEN_COMPAT_030002
+unsigned long kernel_page_user = _PAGE_USER;
+EXPORT_SYMBOL(kernel_page_user);
+#endif
+
 extern unsigned long *contiguous_bitmap;
 
 static unsigned long dma_reserve __initdata;
@@ -507,7 +512,49 @@ static void __meminit phys_pud_init(pud_
                spin_unlock(&init_mm.page_table_lock);
        }
        __flush_tlb();
-} 
+}
+
+#ifdef CONFIG_XEN_COMPAT_030002
+/*
+ * should we set _PAGE_USER for kernel pages?
+ *   - must be set when running on xen 3.0.2
+ *   - should not be set on xen 3.0.3 (kills tlb flush optimization).
+ */
+static void __init check_page_user_flag(unsigned long *pmd)
+{
+       unsigned long addr, *pte;
+        mmu_update_t u;
+
+       addr = pmd[pmd_index(__START_KERNEL_map)];
+       addr_to_page(addr, pte);
+
+       /* try to clear _PAGE_USER */
+        u.ptr = virt_to_machine(pte);
+        u.val = pte[0] & ~_PAGE_USER;
+       if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) {
+               printk("%s: clear _PAGE_USER: mmu_update failed\n", 
__FUNCTION__);
+               return;
+       }
+
+       if (pte[0] & _PAGE_USER) {
+               /* xen 3.0.3 automagically sets _PAGE_USER */
+               printk("%s: xen 3.0.3+ detected\n", __FUNCTION__);
+               kernel_page_user = 0;
+               return;
+       }
+       printk("%s: xen 3.0.2 detected\n", __FUNCTION__);
+       kernel_page_user = _PAGE_USER;
+
+       /* restore previous state */
+       u.ptr = virt_to_machine(pte);
+       u.val = pte[0] | _PAGE_USER;
+       if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) {
+               printk("%s: set _PAGE_USER: mmu_update failed\n", __FUNCTION__);
+       }
+}
+#else
+static void __init check_page_user_flag(unsigned long *pmd) {}
+#endif
 
 void __init xen_init_pt(void)
 {
@@ -524,6 +571,8 @@ void __init xen_init_pt(void)
        addr = page[pud_index(__START_KERNEL_map)];
        addr_to_page(addr, page);
 
+       check_page_user_flag(page);
+
        /* Construct mapping of initial pte page in our own directories. */
        init_level4_pgt[pgd_index(__START_KERNEL_map)] = 
                mk_kernel_pgd(__pa_symbol(level3_kernel_pgt));
Index: 
build-64-testing-11774/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h
===================================================================
--- 
build-64-testing-11774.orig/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h
+++ 
build-64-testing-11774/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h
@@ -205,8 +205,14 @@ static inline pte_t ptep_get_and_clear_f
 #define _PAGE_PROTNONE 0x080   /* If not present */
 #define _PAGE_NX        (1UL<<_PAGE_BIT_NX)
 
+#ifdef CONFIG_XEN_COMPAT_030002
+extern unsigned long kernel_page_user;
+#else
+#define kernel_page_user 0
+#endif
+
 #define _PAGE_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED 
| _PAGE_DIRTY)
-#define _KERNPG_TABLE  (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | 
_PAGE_DIRTY)
+#define _KERNPG_TABLE  (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | 
_PAGE_DIRTY | kernel_page_user)
 
 #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
 
@@ -218,14 +224,15 @@ static inline pte_t ptep_get_and_clear_f
 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | 
_PAGE_NX)
 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | 
_PAGE_ACCESSED)
+
 #define __PAGE_KERNEL \
-       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | 
kernel_page_user )
 #define __PAGE_KERNEL_EXEC \
-       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | 
kernel_page_user )
 #define __PAGE_KERNEL_NOCACHE \
-       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | 
_PAGE_NX)
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | 
_PAGE_NX | kernel_page_user )
 #define __PAGE_KERNEL_RO \
-       (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
+       (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | 
kernel_page_user )
 #define __PAGE_KERNEL_VSYSCALL \
        (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define __PAGE_KERNEL_VSYSCALL_NOCACHE \
@@ -235,6 +242,7 @@ static inline pte_t ptep_get_and_clear_f
 #define __PAGE_KERNEL_LARGE_EXEC \
        (__PAGE_KERNEL_EXEC | _PAGE_PSE)
 
+
 /*
  * We don't support GLOBAL page in xenolinux64
  */
@@ -422,7 +430,11 @@ static inline pud_t *pud_offset_k(pgd_t 
    can temporarily clear it. */
 #define pmd_present(x) (pmd_val(x))
 #define pmd_clear(xp)  do { set_pmd(xp, __pmd(0)); } while (0)
+#ifdef CONFIG_XEN_COMPAT_030002
+#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & 
~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_USER & ~_PAGE_PRESENT))
+#else
 #define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & 
~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
+#endif
 #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
 #define pmd_pfn(x)  ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
 
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel