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-changelog

[Xen-changelog] [linux-2.6.18-xen] Imported patch git-3566561bfadffcb5db

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] Imported patch git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch from xen-unstable.hg 15200:bd3d6b4c52ec
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 11 Jun 2007 02:22:45 -0700
Delivery-date: Tue, 12 Jun 2007 05:08:26 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Date 1180947923 -3600
# Node ID 07baeb6664de2fe650f32a2c77ed30217a84c701
# Parent  95e4a4dfb6682876991bcfc0a41398d0d49398ea
Imported patch git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch from 
xen-unstable.hg 15200:bd3d6b4c52ec
---
 arch/i386/kernel/machine_kexec.c   |  115 +++++--------------------
 arch/i386/kernel/relocate_kernel.S |  166 +++++++++++++++++++++++++++++++++----
 include/asm-i386/kexec.h           |   27 ++++++
 3 files changed, 202 insertions(+), 106 deletions(-)

diff -r 95e4a4dfb668 -r 07baeb6664de arch/i386/kernel/machine_kexec.c
--- a/arch/i386/kernel/machine_kexec.c  Mon May 21 14:14:36 2007 +0100
+++ b/arch/i386/kernel/machine_kexec.c  Mon Jun 04 10:05:23 2007 +0100
@@ -20,70 +20,13 @@
 #include <asm/system.h>
 
 #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
-
-#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
-#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
-#define L2_ATTR (_PAGE_PRESENT)
-
-#define LEVEL0_SIZE (1UL << 12UL)
-
-#ifndef CONFIG_X86_PAE
-#define LEVEL1_SIZE (1UL << 22UL)
-static u32 pgtable_level1[1024] PAGE_ALIGNED;
-
-static void identity_map_page(unsigned long address)
-{
-       unsigned long level1_index, level2_index;
-       u32 *pgtable_level2;
-
-       /* Find the current page table */
-       pgtable_level2 = __va(read_cr3());
-
-       /* Find the indexes of the physical address to identity map */
-       level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
-       level2_index = address / LEVEL1_SIZE;
-
-       /* Identity map the page table entry */
-       pgtable_level1[level1_index] = address | L0_ATTR;
-       pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
-
-       /* Flush the tlb so the new mapping takes effect.
-        * Global tlb entries are not flushed but that is not an issue.
-        */
-       load_cr3(pgtable_level2);
-}
-
-#else
-#define LEVEL1_SIZE (1UL << 21UL)
-#define LEVEL2_SIZE (1UL << 30UL)
-static u64 pgtable_level1[512] PAGE_ALIGNED;
-static u64 pgtable_level2[512] PAGE_ALIGNED;
-
-static void identity_map_page(unsigned long address)
-{
-       unsigned long level1_index, level2_index, level3_index;
-       u64 *pgtable_level3;
-
-       /* Find the current page table */
-       pgtable_level3 = __va(read_cr3());
-
-       /* Find the indexes of the physical address to identity map */
-       level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
-       level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
-       level3_index = address / LEVEL2_SIZE;
-
-       /* Identity map the page table entry */
-       pgtable_level1[level1_index] = address | L0_ATTR;
-       pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
-       set_64bit(&pgtable_level3[level3_index],
-                                              __pa(pgtable_level2) | L2_ATTR);
-
-       /* Flush the tlb so the new mapping takes effect.
-        * Global tlb entries are not flushed but that is not an issue.
-        */
-       load_cr3(pgtable_level3);
-}
+static u32 kexec_pgd[1024] PAGE_ALIGNED;
+#ifdef CONFIG_X86_PAE
+static u32 kexec_pmd0[1024] PAGE_ALIGNED;
+static u32 kexec_pmd1[1024] PAGE_ALIGNED;
 #endif
+static u32 kexec_pte0[1024] PAGE_ALIGNED;
+static u32 kexec_pte1[1024] PAGE_ALIGNED;
 
 static void set_idt(void *newidt, __u16 limit)
 {
@@ -126,16 +69,6 @@ static void load_segments(void)
 #undef STR
 #undef __STR
 }
-
-typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
-                                       unsigned long indirection_page,
-                                       unsigned long reboot_code_buffer,
-                                       unsigned long start_address,
-                                       unsigned int has_pae) ATTRIB_NORET;
-
-extern const unsigned char relocate_new_kernel[];
-extern void relocate_new_kernel_end(void);
-extern const unsigned int relocate_new_kernel_size;
 
 /*
  * A architecture hook called to validate the
@@ -169,25 +102,29 @@ void machine_kexec_cleanup(struct kimage
  */
 NORET_TYPE void machine_kexec(struct kimage *image)
 {
-       unsigned long page_list;
-       unsigned long reboot_code_buffer;
-
-       relocate_new_kernel_t rnk;
+       unsigned long page_list[PAGES_NR];
+       void *control_page;
 
        /* Interrupts aren't acceptable while we reboot */
        local_irq_disable();
 
-       /* Compute some offsets */
-       reboot_code_buffer = page_to_pfn(image->control_code_page)
-                                                               << PAGE_SHIFT;
-       page_list = image->head;
+       control_page = page_address(image->control_code_page);
+       memcpy(control_page, relocate_kernel, PAGE_SIZE);
 
-       /* Set up an identity mapping for the reboot_code_buffer */
-       identity_map_page(reboot_code_buffer);
-
-       /* copy it out */
-       memcpy((void *)reboot_code_buffer, relocate_new_kernel,
-                                               relocate_new_kernel_size);
+       page_list[PA_CONTROL_PAGE] = __pa(control_page);
+       page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
+       page_list[PA_PGD] = __pa(kexec_pgd);
+       page_list[VA_PGD] = (unsigned long)kexec_pgd;
+#ifdef CONFIG_X86_PAE
+       page_list[PA_PMD_0] = __pa(kexec_pmd0);
+       page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
+       page_list[PA_PMD_1] = __pa(kexec_pmd1);
+       page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
+#endif
+       page_list[PA_PTE_0] = __pa(kexec_pte0);
+       page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
+       page_list[PA_PTE_1] = __pa(kexec_pte1);
+       page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
 
        /* The segment registers are funny things, they have both a
         * visible and an invisible part.  Whenever the visible part is
@@ -206,6 +143,6 @@ NORET_TYPE void machine_kexec(struct kim
        set_idt(phys_to_virt(0),0);
 
        /* now call it */
-       rnk = (relocate_new_kernel_t) reboot_code_buffer;
-       (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
+       relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
+                       image->start, cpu_has_pae);
 }
diff -r 95e4a4dfb668 -r 07baeb6664de arch/i386/kernel/relocate_kernel.S
--- a/arch/i386/kernel/relocate_kernel.S        Mon May 21 14:14:36 2007 +0100
+++ b/arch/i386/kernel/relocate_kernel.S        Mon Jun 04 10:05:23 2007 +0100
@@ -7,16 +7,138 @@
  */
 
 #include <linux/linkage.h>
-
-       /*
-        * Must be relocatable PIC code callable as a C function, that once
-        * it starts can not use the previous processes stack.
-        */
-       .globl relocate_new_kernel
+#include <asm/page.h>
+#include <asm/kexec.h>
+
+/*
+ * Must be relocatable PIC code callable as a C function
+ */
+
+#define PTR(x) (x << 2)
+#define PAGE_ALIGNED (1 << PAGE_SHIFT)
+#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
+#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
+
+       .text
+       .align PAGE_ALIGNED
+       .globl relocate_kernel
+relocate_kernel:
+       movl    8(%esp), %ebp /* list of pages */
+
+#ifdef CONFIG_X86_PAE
+       /* map the control page at its virtual address */
+
+       movl    PTR(VA_PGD)(%ebp), %edi
+       movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0xc0000000, %eax
+       shrl    $27, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_PMD_0)(%ebp), %edx
+       orl     $PAE_PGD_ATTR, %edx
+       movl    %edx, (%eax)
+
+       movl    PTR(VA_PMD_0)(%ebp), %edi
+       movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0x3fe00000, %eax
+       shrl    $18, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_PTE_0)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+
+       movl    PTR(VA_PTE_0)(%ebp), %edi
+       movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0x001ff000, %eax
+       shrl    $9, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+
+       /* identity map the control page at its physical address */
+
+       movl    PTR(VA_PGD)(%ebp), %edi
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0xc0000000, %eax
+       shrl    $27, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_PMD_1)(%ebp), %edx
+       orl     $PAE_PGD_ATTR, %edx
+       movl    %edx, (%eax)
+
+       movl    PTR(VA_PMD_1)(%ebp), %edi
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0x3fe00000, %eax
+       shrl    $18, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_PTE_1)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+
+       movl    PTR(VA_PTE_1)(%ebp), %edi
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0x001ff000, %eax
+       shrl    $9, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+#else
+       /* map the control page at its virtual address */
+
+       movl    PTR(VA_PGD)(%ebp), %edi
+       movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0xffc00000, %eax
+       shrl    $20, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_PTE_0)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+
+       movl    PTR(VA_PTE_0)(%ebp), %edi
+       movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0x003ff000, %eax
+       shrl    $10, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+
+       /* identity map the control page at its physical address */
+
+       movl    PTR(VA_PGD)(%ebp), %edi
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0xffc00000, %eax
+       shrl    $20, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_PTE_1)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+
+       movl    PTR(VA_PTE_1)(%ebp), %edi
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
+       andl    $0x003ff000, %eax
+       shrl    $10, %eax
+       addl    %edi, %eax
+
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
+       orl     $PAGE_ATTR, %edx
+       movl    %edx, (%eax)
+#endif
+
 relocate_new_kernel:
        /* read the arguments and say goodbye to the stack */
        movl  4(%esp), %ebx /* page_list */
-       movl  8(%esp), %ebp /* reboot_code_buffer */
+       movl  8(%esp), %ebp /* list of pages */
        movl  12(%esp), %edx /* start address */
        movl  16(%esp), %ecx /* cpu_has_pae */
 
@@ -24,11 +146,26 @@ relocate_new_kernel:
        pushl $0
        popfl
 
-       /* set a new stack at the bottom of our page... */
-       lea   4096(%ebp), %esp
-
-       /* store the parameters back on the stack */
-       pushl   %edx /* store the start address */
+       /* get physical address of control page now */
+       /* this is impossible after page table switch */
+       movl    PTR(PA_CONTROL_PAGE)(%ebp), %edi
+
+       /* switch to new set of page tables */
+       movl    PTR(PA_PGD)(%ebp), %eax
+       movl    %eax, %cr3
+
+       /* setup a new stack at the end of the physical control page */
+       lea     4096(%edi), %esp
+
+       /* jump to identity mapped page */
+       movl    %edi, %eax
+       addl    $(identity_mapped - relocate_kernel), %eax
+       pushl   %eax
+       ret
+
+identity_mapped:
+       /* store the start address on the stack */
+       pushl   %edx
 
        /* Set cr0 to a known state:
         * 31 0 == Paging disabled
@@ -113,8 +250,3 @@ 3:
        xorl    %edi, %edi
        xorl    %ebp, %ebp
        ret
-relocate_new_kernel_end:
-
-       .globl relocate_new_kernel_size
-relocate_new_kernel_size:
-       .long relocate_new_kernel_end - relocate_new_kernel
diff -r 95e4a4dfb668 -r 07baeb6664de include/asm-i386/kexec.h
--- a/include/asm-i386/kexec.h  Mon May 21 14:14:36 2007 +0100
+++ b/include/asm-i386/kexec.h  Mon Jun 04 10:05:23 2007 +0100
@@ -1,5 +1,25 @@
 #ifndef _I386_KEXEC_H
 #define _I386_KEXEC_H
+
+#define PA_CONTROL_PAGE  0
+#define VA_CONTROL_PAGE  1
+#define PA_PGD           2
+#define VA_PGD           3
+#define PA_PTE_0         4
+#define VA_PTE_0         5
+#define PA_PTE_1         6
+#define VA_PTE_1         7
+#ifdef CONFIG_X86_PAE
+#define PA_PMD_0         8
+#define VA_PMD_0         9
+#define PA_PMD_1         10
+#define VA_PMD_1         11
+#define PAGES_NR         12
+#else
+#define PAGES_NR         8
+#endif
+
+#ifndef __ASSEMBLY__
 
 #include <asm/fixmap.h>
 #include <asm/ptrace.h>
@@ -72,5 +92,12 @@ static inline void crash_setup_regs(stru
                newregs->eip = (unsigned long)current_text_addr();
        }
 }
+asmlinkage NORET_TYPE void
+relocate_kernel(unsigned long indirection_page,
+               unsigned long control_page,
+               unsigned long start_address,
+               unsigned int has_pae) ATTRIB_NORET;
+
+#endif /* __ASSEMBLY__ */
 
 #endif /* _I386_KEXEC_H */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] Imported patch git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch from xen-unstable.hg 15200:bd3d6b4c52ec, Xen patchbot-linux-2.6.18-xen <=