source: trunk/packages/xen-3.1/xen-3.1/linux-2.6-xen-sparse/arch/i386/kernel/machine_kexec.c @ 34

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

Add xen and xen-common

File size: 3.5 KB
Line 
1/*
2 * machine_kexec.c - handle transition of Linux booting another kernel
3 * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
4 *
5 * This source code is licensed under the GNU General Public License,
6 * Version 2.  See the file COPYING for more details.
7 */
8
9#include <linux/mm.h>
10#include <linux/kexec.h>
11#include <linux/delay.h>
12#include <asm/pgtable.h>
13#include <asm/pgalloc.h>
14#include <asm/tlbflush.h>
15#include <asm/mmu_context.h>
16#include <asm/io.h>
17#include <asm/apic.h>
18#include <asm/cpufeature.h>
19#include <asm/desc.h>
20#include <asm/system.h>
21
22#ifdef CONFIG_XEN
23#include <xen/interface/kexec.h>
24#endif
25
26#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
27static u32 kexec_pgd[1024] PAGE_ALIGNED;
28#ifdef CONFIG_X86_PAE
29static u32 kexec_pmd0[1024] PAGE_ALIGNED;
30static u32 kexec_pmd1[1024] PAGE_ALIGNED;
31#endif
32static u32 kexec_pte0[1024] PAGE_ALIGNED;
33static u32 kexec_pte1[1024] PAGE_ALIGNED;
34
35#ifdef CONFIG_XEN
36
37#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT)
38
39#if PAGES_NR > KEXEC_XEN_NO_PAGES
40#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break
41#endif
42
43#if PA_CONTROL_PAGE != 0
44#error PA_CONTROL_PAGE is non zero - Xen support will break
45#endif
46
47void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
48{
49        void *control_page;
50
51        memset(xki->page_list, 0, sizeof(xki->page_list));
52
53        control_page = page_address(image->control_code_page);
54        memcpy(control_page, relocate_kernel, PAGE_SIZE);
55
56        xki->page_list[PA_CONTROL_PAGE] = __ma(control_page);
57        xki->page_list[PA_PGD] = __ma(kexec_pgd);
58#ifdef CONFIG_X86_PAE
59        xki->page_list[PA_PMD_0] = __ma(kexec_pmd0);
60        xki->page_list[PA_PMD_1] = __ma(kexec_pmd1);
61#endif
62        xki->page_list[PA_PTE_0] = __ma(kexec_pte0);
63        xki->page_list[PA_PTE_1] = __ma(kexec_pte1);
64
65}
66
67#endif /* CONFIG_XEN */
68
69/*
70 * A architecture hook called to validate the
71 * proposed image and prepare the control pages
72 * as needed.  The pages for KEXEC_CONTROL_CODE_SIZE
73 * have been allocated, but the segments have yet
74 * been copied into the kernel.
75 *
76 * Do what every setup is needed on image and the
77 * reboot code buffer to allow us to avoid allocations
78 * later.
79 *
80 * Currently nothing.
81 */
82int machine_kexec_prepare(struct kimage *image)
83{
84        return 0;
85}
86
87/*
88 * Undo anything leftover by machine_kexec_prepare
89 * when an image is freed.
90 */
91void machine_kexec_cleanup(struct kimage *image)
92{
93}
94
95#ifndef CONFIG_XEN
96/*
97 * Do not allocate memory (or fail in any way) in machine_kexec().
98 * We are past the point of no return, committed to rebooting now.
99 */
100NORET_TYPE void machine_kexec(struct kimage *image)
101{
102        unsigned long page_list[PAGES_NR];
103        void *control_page;
104
105        /* Interrupts aren't acceptable while we reboot */
106        local_irq_disable();
107
108        control_page = page_address(image->control_code_page);
109        memcpy(control_page, relocate_kernel, PAGE_SIZE);
110
111        page_list[PA_CONTROL_PAGE] = __pa(control_page);
112        page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
113        page_list[PA_PGD] = __pa(kexec_pgd);
114        page_list[VA_PGD] = (unsigned long)kexec_pgd;
115#ifdef CONFIG_X86_PAE
116        page_list[PA_PMD_0] = __pa(kexec_pmd0);
117        page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
118        page_list[PA_PMD_1] = __pa(kexec_pmd1);
119        page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
120#endif
121        page_list[PA_PTE_0] = __pa(kexec_pte0);
122        page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
123        page_list[PA_PTE_1] = __pa(kexec_pte1);
124        page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
125
126        relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
127                        image->start, cpu_has_pae);
128}
129#endif
Note: See TracBrowser for help on using the repository browser.