source: trunk/packages/xen-common/xen-common/patches/linux-2.6.18/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

  • Property svn:mime-type set to text/x-patch
File size: 10.8 KB
  • arch/i386/kernel/machine_kexec.c

    diff -pruN ../orig-linux-2.6.18/arch/i386/kernel/machine_kexec.c ./arch/i386/kernel/machine_kexec.c
    old new  
    2020#include <asm/system.h>
    2121
    2222#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
    23 
    24 #define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
    25 #define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
    26 #define L2_ATTR (_PAGE_PRESENT)
    27 
    28 #define LEVEL0_SIZE (1UL << 12UL)
    29 
    30 #ifndef CONFIG_X86_PAE
    31 #define LEVEL1_SIZE (1UL << 22UL)
    32 static u32 pgtable_level1[1024] PAGE_ALIGNED;
    33 
    34 static void identity_map_page(unsigned long address)
    35 {
    36         unsigned long level1_index, level2_index;
    37         u32 *pgtable_level2;
    38 
    39         /* Find the current page table */
    40         pgtable_level2 = __va(read_cr3());
    41 
    42         /* Find the indexes of the physical address to identity map */
    43         level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
    44         level2_index = address / LEVEL1_SIZE;
    45 
    46         /* Identity map the page table entry */
    47         pgtable_level1[level1_index] = address | L0_ATTR;
    48         pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
    49 
    50         /* Flush the tlb so the new mapping takes effect.
    51          * Global tlb entries are not flushed but that is not an issue.
    52          */
    53         load_cr3(pgtable_level2);
    54 }
    55 
    56 #else
    57 #define LEVEL1_SIZE (1UL << 21UL)
    58 #define LEVEL2_SIZE (1UL << 30UL)
    59 static u64 pgtable_level1[512] PAGE_ALIGNED;
    60 static u64 pgtable_level2[512] PAGE_ALIGNED;
    61 
    62 static void identity_map_page(unsigned long address)
    63 {
    64         unsigned long level1_index, level2_index, level3_index;
    65         u64 *pgtable_level3;
    66 
    67         /* Find the current page table */
    68         pgtable_level3 = __va(read_cr3());
    69 
    70         /* Find the indexes of the physical address to identity map */
    71         level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
    72         level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
    73         level3_index = address / LEVEL2_SIZE;
    74 
    75         /* Identity map the page table entry */
    76         pgtable_level1[level1_index] = address | L0_ATTR;
    77         pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
    78         set_64bit(&pgtable_level3[level3_index],
    79                                                __pa(pgtable_level2) | L2_ATTR);
    80 
    81         /* Flush the tlb so the new mapping takes effect.
    82          * Global tlb entries are not flushed but that is not an issue.
    83          */
    84         load_cr3(pgtable_level3);
    85 }
     23static u32 kexec_pgd[1024] PAGE_ALIGNED;
     24#ifdef CONFIG_X86_PAE
     25static u32 kexec_pmd0[1024] PAGE_ALIGNED;
     26static u32 kexec_pmd1[1024] PAGE_ALIGNED;
    8627#endif
     28static u32 kexec_pte0[1024] PAGE_ALIGNED;
     29static u32 kexec_pte1[1024] PAGE_ALIGNED;
    8730
    8831static void set_idt(void *newidt, __u16 limit)
    8932{
    static void load_segments(void) 
    12770#undef __STR
    12871}
    12972
    130 typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
    131                                         unsigned long indirection_page,
    132                                         unsigned long reboot_code_buffer,
    133                                         unsigned long start_address,
    134                                         unsigned int has_pae) ATTRIB_NORET;
    135 
    136 extern const unsigned char relocate_new_kernel[];
    137 extern void relocate_new_kernel_end(void);
    138 extern const unsigned int relocate_new_kernel_size;
    139 
    14073/*
    14174 * A architecture hook called to validate the
    14275 * proposed image and prepare the control pages
    void machine_kexec_cleanup(struct kimage 
    169102 */
    170103NORET_TYPE void machine_kexec(struct kimage *image)
    171104{
    172         unsigned long page_list;
    173         unsigned long reboot_code_buffer;
    174 
    175         relocate_new_kernel_t rnk;
     105        unsigned long page_list[PAGES_NR];
     106        void *control_page;
    176107
    177108        /* Interrupts aren't acceptable while we reboot */
    178109        local_irq_disable();
    179110
    180         /* Compute some offsets */
    181         reboot_code_buffer = page_to_pfn(image->control_code_page)
    182                                                                 << PAGE_SHIFT;
    183         page_list = image->head;
    184 
    185         /* Set up an identity mapping for the reboot_code_buffer */
    186         identity_map_page(reboot_code_buffer);
    187 
    188         /* copy it out */
    189         memcpy((void *)reboot_code_buffer, relocate_new_kernel,
    190                                                 relocate_new_kernel_size);
     111        control_page = page_address(image->control_code_page);
     112        memcpy(control_page, relocate_kernel, PAGE_SIZE);
     113
     114        page_list[PA_CONTROL_PAGE] = __pa(control_page);
     115        page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
     116        page_list[PA_PGD] = __pa(kexec_pgd);
     117        page_list[VA_PGD] = (unsigned long)kexec_pgd;
     118#ifdef CONFIG_X86_PAE
     119        page_list[PA_PMD_0] = __pa(kexec_pmd0);
     120        page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
     121        page_list[PA_PMD_1] = __pa(kexec_pmd1);
     122        page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
     123#endif
     124        page_list[PA_PTE_0] = __pa(kexec_pte0);
     125        page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
     126        page_list[PA_PTE_1] = __pa(kexec_pte1);
     127        page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
    191128
    192129        /* The segment registers are funny things, they have both a
    193130         * visible and an invisible part.  Whenever the visible part is
    NORET_TYPE void machine_kexec(struct kim 
    206143        set_idt(phys_to_virt(0),0);
    207144
    208145        /* now call it */
    209         rnk = (relocate_new_kernel_t) reboot_code_buffer;
    210         (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
     146        relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
     147                        image->start, cpu_has_pae);
    211148}
  • arch/i386/kernel/relocate_kernel.S

    diff -pruN ../orig-linux-2.6.18/arch/i386/kernel/relocate_kernel.S ./arch/i386/kernel/relocate_kernel.S
    old new  
    77 */
    88
    99#include <linux/linkage.h>
     10#include <asm/page.h>
     11#include <asm/kexec.h>
     12
     13/*
     14 * Must be relocatable PIC code callable as a C function
     15 */
     16
     17#define PTR(x) (x << 2)
     18#define PAGE_ALIGNED (1 << PAGE_SHIFT)
     19#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
     20#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
     21
     22        .text
     23        .align PAGE_ALIGNED
     24        .globl relocate_kernel
     25relocate_kernel:
     26        movl    8(%esp), %ebp /* list of pages */
     27
     28#ifdef CONFIG_X86_PAE
     29        /* map the control page at its virtual address */
     30
     31        movl    PTR(VA_PGD)(%ebp), %edi
     32        movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
     33        andl    $0xc0000000, %eax
     34        shrl    $27, %eax
     35        addl    %edi, %eax
     36
     37        movl    PTR(PA_PMD_0)(%ebp), %edx
     38        orl     $PAE_PGD_ATTR, %edx
     39        movl    %edx, (%eax)
     40
     41        movl    PTR(VA_PMD_0)(%ebp), %edi
     42        movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
     43        andl    $0x3fe00000, %eax
     44        shrl    $18, %eax
     45        addl    %edi, %eax
     46
     47        movl    PTR(PA_PTE_0)(%ebp), %edx
     48        orl     $PAGE_ATTR, %edx
     49        movl    %edx, (%eax)
     50
     51        movl    PTR(VA_PTE_0)(%ebp), %edi
     52        movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
     53        andl    $0x001ff000, %eax
     54        shrl    $9, %eax
     55        addl    %edi, %eax
     56
     57        movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
     58        orl     $PAGE_ATTR, %edx
     59        movl    %edx, (%eax)
     60
     61        /* identity map the control page at its physical address */
     62
     63        movl    PTR(VA_PGD)(%ebp), %edi
     64        movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
     65        andl    $0xc0000000, %eax
     66        shrl    $27, %eax
     67        addl    %edi, %eax
     68
     69        movl    PTR(PA_PMD_1)(%ebp), %edx
     70        orl     $PAE_PGD_ATTR, %edx
     71        movl    %edx, (%eax)
     72
     73        movl    PTR(VA_PMD_1)(%ebp), %edi
     74        movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
     75        andl    $0x3fe00000, %eax
     76        shrl    $18, %eax
     77        addl    %edi, %eax
     78
     79        movl    PTR(PA_PTE_1)(%ebp), %edx
     80        orl     $PAGE_ATTR, %edx
     81        movl    %edx, (%eax)
     82
     83        movl    PTR(VA_PTE_1)(%ebp), %edi
     84        movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
     85        andl    $0x001ff000, %eax
     86        shrl    $9, %eax
     87        addl    %edi, %eax
     88
     89        movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
     90        orl     $PAGE_ATTR, %edx
     91        movl    %edx, (%eax)
     92#else
     93        /* map the control page at its virtual address */
     94
     95        movl    PTR(VA_PGD)(%ebp), %edi
     96        movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
     97        andl    $0xffc00000, %eax
     98        shrl    $20, %eax
     99        addl    %edi, %eax
     100
     101        movl    PTR(PA_PTE_0)(%ebp), %edx
     102        orl     $PAGE_ATTR, %edx
     103        movl    %edx, (%eax)
     104
     105        movl    PTR(VA_PTE_0)(%ebp), %edi
     106        movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
     107        andl    $0x003ff000, %eax
     108        shrl    $10, %eax
     109        addl    %edi, %eax
     110
     111        movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
     112        orl     $PAGE_ATTR, %edx
     113        movl    %edx, (%eax)
     114
     115        /* identity map the control page at its physical address */
     116
     117        movl    PTR(VA_PGD)(%ebp), %edi
     118        movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
     119        andl    $0xffc00000, %eax
     120        shrl    $20, %eax
     121        addl    %edi, %eax
     122
     123        movl    PTR(PA_PTE_1)(%ebp), %edx
     124        orl     $PAGE_ATTR, %edx
     125        movl    %edx, (%eax)
     126
     127        movl    PTR(VA_PTE_1)(%ebp), %edi
     128        movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
     129        andl    $0x003ff000, %eax
     130        shrl    $10, %eax
     131        addl    %edi, %eax
     132
     133        movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
     134        orl     $PAGE_ATTR, %edx
     135        movl    %edx, (%eax)
     136#endif
    10137
    11         /*
    12          * Must be relocatable PIC code callable as a C function, that once
    13          * it starts can not use the previous processes stack.
    14          */
    15         .globl relocate_new_kernel
    16138relocate_new_kernel:
    17139        /* read the arguments and say goodbye to the stack */
    18140        movl  4(%esp), %ebx /* page_list */
    19         movl  8(%esp), %ebp /* reboot_code_buffer */
     141        movl  8(%esp), %ebp /* list of pages */
    20142        movl  12(%esp), %edx /* start address */
    21143        movl  16(%esp), %ecx /* cpu_has_pae */
    22144
    relocate_new_kernel: 
    24146        pushl $0
    25147        popfl
    26148
    27         /* set a new stack at the bottom of our page... */
    28         lea   4096(%ebp), %esp
     149        /* get physical address of control page now */
     150        /* this is impossible after page table switch */
     151        movl    PTR(PA_CONTROL_PAGE)(%ebp), %edi
     152
     153        /* switch to new set of page tables */
     154        movl    PTR(PA_PGD)(%ebp), %eax
     155        movl    %eax, %cr3
     156
     157        /* setup a new stack at the end of the physical control page */
     158        lea     4096(%edi), %esp
    29159
    30         /* store the parameters back on the stack */
    31         pushl   %edx /* store the start address */
     160        /* jump to identity mapped page */
     161        movl    %edi, %eax
     162        addl    $(identity_mapped - relocate_kernel), %eax
     163        pushl   %eax
     164        ret
     165
     166identity_mapped:
     167        /* store the start address on the stack */
     168        pushl   %edx
    32169
    33170        /* Set cr0 to a known state:
    34171         * 31 0 == Paging disabled
    relocate_new_kernel: 
    113250        xorl    %edi, %edi
    114251        xorl    %ebp, %ebp
    115252        ret
    116 relocate_new_kernel_end:
    117 
    118         .globl relocate_new_kernel_size
    119 relocate_new_kernel_size:
    120         .long relocate_new_kernel_end - relocate_new_kernel
  • include/asm-i386/kexec.h

    diff -pruN ../orig-linux-2.6.18/include/asm-i386/kexec.h ./include/asm-i386/kexec.h
    old new  
    11#ifndef _I386_KEXEC_H
    22#define _I386_KEXEC_H
    33
     4#define PA_CONTROL_PAGE  0
     5#define VA_CONTROL_PAGE  1
     6#define PA_PGD           2
     7#define VA_PGD           3
     8#define PA_PTE_0         4
     9#define VA_PTE_0         5
     10#define PA_PTE_1         6
     11#define VA_PTE_1         7
     12#ifdef CONFIG_X86_PAE
     13#define PA_PMD_0         8
     14#define VA_PMD_0         9
     15#define PA_PMD_1         10
     16#define VA_PMD_1         11
     17#define PAGES_NR         12
     18#else
     19#define PAGES_NR         8
     20#endif
     21
     22#ifndef __ASSEMBLY__
     23
    424#include <asm/fixmap.h>
    525#include <asm/ptrace.h>
    626#include <asm/string.h>
    static inline void crash_setup_regs(stru 
    7292               newregs->eip = (unsigned long)current_text_addr();
    7393       }
    7494}
     95asmlinkage NORET_TYPE void
     96relocate_kernel(unsigned long indirection_page,
     97                unsigned long control_page,
     98                unsigned long start_address,
     99                unsigned int has_pae) ATTRIB_NORET;
     100
     101#endif /* __ASSEMBLY__ */
    75102
    76103#endif /* _I386_KEXEC_H */
Note: See TracBrowser for help on using the repository browser.