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: Jan Beulich <jbeulich@xxxxxxxxxx>
Subject: Re: [Xen-devel] CONFIG_XEN_COMPAT_030002 broken?
From: Gerd Hoffmann <kraxel@xxxxxxx>
Date: Tue, 14 Nov 2006 16:11:29 +0100
Cc: Xen devel list <xen-devel@xxxxxxxxxxxxxxxxxxx>, Keir Fraser <keir@xxxxxxxxxxxxx>
Delivery-date: Tue, 14 Nov 2006 07:12:00 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <4559C55D.76E4.0078.0@xxxxxxxxxx>
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: <4559B322.76E4.0078.0@xxxxxxxxxx> <C17F5E15.4802%keir@xxxxxxxxxxxxx> <4559C55D.76E4.0078.0@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 1.5.0.7 (X11/20060911)
Jan Beulich wrote:
> not nice for use in (early) feature detection. Maybe it'd be better to try 
> and write
> a page table entry without PAGE_USER, and check whether that bit got turned
> on implicitly...

Patch attached, seems to work ok, survived quick test with ttylinux on
both 3.0.3 and 3.0.2 without crashing and detected both versions correctly.

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                |    4 
 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c                 |   52 
+++++++++-
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h |   26 +++--
 3 files changed, 73 insertions(+), 9 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,10 @@ 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__) && defined(CONFIG_XEN_COMPAT_030002)
+       if (kernel_pages_need_user_flag)
+               flags |= _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,12 @@
 struct dma_mapping_ops* dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
+#ifdef CONFIG_XEN_COMPAT_030002
+int kernel_pages_need_user_flag = 1;
+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 +513,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_pages_need_user_flag = 0;
+               kernel_page_user = 0;
+               return;
+       }
+       printk("%s: xen 3.0.2 detected\n", __FUNCTION__);
+
+       /* 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 +572,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,16 @@ 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 int kernel_pages_need_user_flag;
+extern unsigned long kernel_page_user;
+#else
+#define kernel_pages_need_user_flag 0
+#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,22 +226,24 @@ 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 \
        (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
 #define __PAGE_KERNEL_LARGE \
-       (__PAGE_KERNEL | _PAGE_PSE)
+       (__PAGE_KERNEL | _PAGE_PSE | kernel_page_user )
 #define __PAGE_KERNEL_LARGE_EXEC \
-       (__PAGE_KERNEL_EXEC | _PAGE_PSE)
+       (__PAGE_KERNEL_EXEC | _PAGE_PSE | kernel_page_user )
+
 
 /*
  * We don't support GLOBAL page in xenolinux64
@@ -422,7 +432,7 @@ 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)
-#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & 
~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
+#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & 
~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_USER & ~_PAGE_PRESENT))
 #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