diff options
-rw-r--r-- | arch/ia64/include/asm/native/patchlist.h | 38 | ||||
-rw-r--r-- | arch/ia64/include/asm/paravirt.h | 35 | ||||
-rw-r--r-- | arch/ia64/kernel/Makefile | 32 | ||||
-rw-r--r-- | arch/ia64/kernel/Makefile.gate | 27 | ||||
-rw-r--r-- | arch/ia64/kernel/gate.lds.S | 17 | ||||
-rw-r--r-- | arch/ia64/kernel/paravirt_patchlist.c | 79 | ||||
-rw-r--r-- | arch/ia64/kernel/paravirt_patchlist.h | 28 | ||||
-rw-r--r-- | arch/ia64/kernel/patch.c | 12 | ||||
-rw-r--r-- | arch/ia64/mm/init.c | 6 |
9 files changed, 231 insertions, 43 deletions
diff --git a/arch/ia64/include/asm/native/patchlist.h b/arch/ia64/include/asm/native/patchlist.h new file mode 100644 index 000000000000..be16ca9311bf --- /dev/null +++ b/arch/ia64/include/asm/native/patchlist.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /****************************************************************************** | ||
2 | * arch/ia64/include/asm/native/inst.h | ||
3 | * | ||
4 | * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> | ||
5 | * VA Linux Systems Japan K.K. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #define __paravirt_start_gate_fsyscall_patchlist \ | ||
24 | __ia64_native_start_gate_fsyscall_patchlist | ||
25 | #define __paravirt_end_gate_fsyscall_patchlist \ | ||
26 | __ia64_native_end_gate_fsyscall_patchlist | ||
27 | #define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \ | ||
28 | __ia64_native_start_gate_brl_fsys_bubble_down_patchlist | ||
29 | #define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \ | ||
30 | __ia64_native_end_gate_brl_fsys_bubble_down_patchlist | ||
31 | #define __paravirt_start_gate_vtop_patchlist \ | ||
32 | __ia64_native_start_gate_vtop_patchlist | ||
33 | #define __paravirt_end_gate_vtop_patchlist \ | ||
34 | __ia64_native_end_gate_vtop_patchlist | ||
35 | #define __paravirt_start_gate_mckinley_e9_patchlist \ | ||
36 | __ia64_native_start_gate_mckinley_e9_patchlist | ||
37 | #define __paravirt_end_gate_mckinley_e9_patchlist \ | ||
38 | __ia64_native_end_gate_mckinley_e9_patchlist | ||
diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h index a73e77add7e2..fc433f6c3275 100644 --- a/arch/ia64/include/asm/paravirt.h +++ b/arch/ia64/include/asm/paravirt.h | |||
@@ -35,6 +35,41 @@ extern struct pv_fsys_data pv_fsys_data; | |||
35 | 35 | ||
36 | unsigned long *paravirt_get_fsyscall_table(void); | 36 | unsigned long *paravirt_get_fsyscall_table(void); |
37 | char *paravirt_get_fsys_bubble_down(void); | 37 | char *paravirt_get_fsys_bubble_down(void); |
38 | |||
39 | /****************************************************************************** | ||
40 | * patchlist addresses for gate page | ||
41 | */ | ||
42 | enum pv_gate_patchlist { | ||
43 | PV_GATE_START_FSYSCALL, | ||
44 | PV_GATE_END_FSYSCALL, | ||
45 | |||
46 | PV_GATE_START_BRL_FSYS_BUBBLE_DOWN, | ||
47 | PV_GATE_END_BRL_FSYS_BUBBLE_DOWN, | ||
48 | |||
49 | PV_GATE_START_VTOP, | ||
50 | PV_GATE_END_VTOP, | ||
51 | |||
52 | PV_GATE_START_MCKINLEY_E9, | ||
53 | PV_GATE_END_MCKINLEY_E9, | ||
54 | }; | ||
55 | |||
56 | struct pv_patchdata { | ||
57 | unsigned long start_fsyscall_patchlist; | ||
58 | unsigned long end_fsyscall_patchlist; | ||
59 | unsigned long start_brl_fsys_bubble_down_patchlist; | ||
60 | unsigned long end_brl_fsys_bubble_down_patchlist; | ||
61 | unsigned long start_vtop_patchlist; | ||
62 | unsigned long end_vtop_patchlist; | ||
63 | unsigned long start_mckinley_e9_patchlist; | ||
64 | unsigned long end_mckinley_e9_patchlist; | ||
65 | |||
66 | void *gate_section; | ||
67 | }; | ||
68 | |||
69 | extern struct pv_patchdata pv_patchdata; | ||
70 | |||
71 | unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type); | ||
72 | void *paravirt_get_gate_section(void); | ||
38 | #endif | 73 | #endif |
39 | 74 | ||
40 | #ifdef CONFIG_PARAVIRT_GUEST | 75 | #ifdef CONFIG_PARAVIRT_GUEST |
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 1ab150ec8cea..8dc9df8a87a5 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := head.o init_task.o vmlinux.lds | 5 | extra-y := head.o init_task.o vmlinux.lds |
6 | 6 | ||
7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ | 7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ |
8 | irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ | 8 | irq_lsapic.o ivt.o machvec.o pal.o paravirt_patchlist.o patch.o process.o perfmon.o ptrace.o sal.o \ |
9 | salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ | 9 | salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ |
10 | unwind.o mca.o mca_asm.o topology.o | 10 | unwind.o mca.o mca_asm.o topology.o |
11 | 11 | ||
@@ -47,35 +47,13 @@ ifeq ($(CONFIG_DMAR), y) | |||
47 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o | 47 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o |
48 | endif | 48 | endif |
49 | 49 | ||
50 | # The gate DSO image is built using a special linker script. | ||
51 | targets += gate.so gate-syms.o | ||
52 | |||
53 | extra-y += gate.so gate-syms.o gate.lds gate.o | ||
54 | |||
55 | # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. | 50 | # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. |
56 | CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 | 51 | CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 |
57 | 52 | ||
58 | CPPFLAGS_gate.lds := -P -C -U$(ARCH) | 53 | # The gate DSO image is built using a special linker script. |
59 | 54 | include $(srctree)/arch/ia64/kernel/Makefile.gate | |
60 | quiet_cmd_gate = GATE $@ | 55 | # tell compiled for native |
61 | cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ | 56 | CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE |
62 | |||
63 | GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ | ||
64 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | ||
65 | $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE | ||
66 | $(call if_changed,gate) | ||
67 | |||
68 | $(obj)/built-in.o: $(obj)/gate-syms.o | ||
69 | $(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o | ||
70 | |||
71 | GATECFLAGS_gate-syms.o = -r | ||
72 | $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE | ||
73 | $(call if_changed,gate) | ||
74 | |||
75 | # gate-data.o contains the gate DSO image as data in section .data.gate. | ||
76 | # We must build gate.so before we can assemble it. | ||
77 | # Note: kbuild does not track this dependency due to usage of .incbin | ||
78 | $(obj)/gate-data.o: $(obj)/gate.so | ||
79 | 57 | ||
80 | # Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config | 58 | # Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config |
81 | define sed-y | 59 | define sed-y |
diff --git a/arch/ia64/kernel/Makefile.gate b/arch/ia64/kernel/Makefile.gate new file mode 100644 index 000000000000..1d87f84069b3 --- /dev/null +++ b/arch/ia64/kernel/Makefile.gate | |||
@@ -0,0 +1,27 @@ | |||
1 | # The gate DSO image is built using a special linker script. | ||
2 | |||
3 | targets += gate.so gate-syms.o | ||
4 | |||
5 | extra-y += gate.so gate-syms.o gate.lds gate.o | ||
6 | |||
7 | CPPFLAGS_gate.lds := -P -C -U$(ARCH) | ||
8 | |||
9 | quiet_cmd_gate = GATE $@ | ||
10 | cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ | ||
11 | |||
12 | GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \ | ||
13 | $(call ld-option, -Wl$(comma)--hash-style=sysv) | ||
14 | $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE | ||
15 | $(call if_changed,gate) | ||
16 | |||
17 | $(obj)/built-in.o: $(obj)/gate-syms.o | ||
18 | $(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o | ||
19 | |||
20 | GATECFLAGS_gate-syms.o = -r | ||
21 | $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE | ||
22 | $(call if_changed,gate) | ||
23 | |||
24 | # gate-data.o contains the gate DSO image as data in section .data.gate. | ||
25 | # We must build gate.so before we can assemble it. | ||
26 | # Note: kbuild does not track this dependency due to usage of .incbin | ||
27 | $(obj)/gate-data.o: $(obj)/gate.so | ||
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S index 3cb1abc00e24..88c64ed47c36 100644 --- a/arch/ia64/kernel/gate.lds.S +++ b/arch/ia64/kernel/gate.lds.S | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | 8 | ||
9 | #include <asm/system.h> | 9 | #include <asm/system.h> |
10 | #include "paravirt_patchlist.h" | ||
10 | 11 | ||
11 | SECTIONS | 12 | SECTIONS |
12 | { | 13 | { |
@@ -33,21 +34,21 @@ SECTIONS | |||
33 | . = GATE_ADDR + 0x600; | 34 | . = GATE_ADDR + 0x600; |
34 | 35 | ||
35 | .data.patch : { | 36 | .data.patch : { |
36 | __start_gate_mckinley_e9_patchlist = .; | 37 | __paravirt_start_gate_mckinley_e9_patchlist = .; |
37 | *(.data.patch.mckinley_e9) | 38 | *(.data.patch.mckinley_e9) |
38 | __end_gate_mckinley_e9_patchlist = .; | 39 | __paravirt_end_gate_mckinley_e9_patchlist = .; |
39 | 40 | ||
40 | __start_gate_vtop_patchlist = .; | 41 | __paravirt_start_gate_vtop_patchlist = .; |
41 | *(.data.patch.vtop) | 42 | *(.data.patch.vtop) |
42 | __end_gate_vtop_patchlist = .; | 43 | __paravirt_end_gate_vtop_patchlist = .; |
43 | 44 | ||
44 | __start_gate_fsyscall_patchlist = .; | 45 | __paravirt_start_gate_fsyscall_patchlist = .; |
45 | *(.data.patch.fsyscall_table) | 46 | *(.data.patch.fsyscall_table) |
46 | __end_gate_fsyscall_patchlist = .; | 47 | __paravirt_end_gate_fsyscall_patchlist = .; |
47 | 48 | ||
48 | __start_gate_brl_fsys_bubble_down_patchlist = .; | 49 | __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .; |
49 | *(.data.patch.brl_fsys_bubble_down) | 50 | *(.data.patch.brl_fsys_bubble_down) |
50 | __end_gate_brl_fsys_bubble_down_patchlist = .; | 51 | __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .; |
51 | } :readable | 52 | } :readable |
52 | 53 | ||
53 | .IA_64.unwind_info : { *(.IA_64.unwind_info*) } | 54 | .IA_64.unwind_info : { *(.IA_64.unwind_info*) } |
diff --git a/arch/ia64/kernel/paravirt_patchlist.c b/arch/ia64/kernel/paravirt_patchlist.c new file mode 100644 index 000000000000..b28082a95d45 --- /dev/null +++ b/arch/ia64/kernel/paravirt_patchlist.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /****************************************************************************** | ||
2 | * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> | ||
3 | * VA Linux Systems Japan K.K. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/bug.h> | ||
22 | #include <asm/paravirt.h> | ||
23 | |||
24 | #define DECLARE(name) \ | ||
25 | extern unsigned long \ | ||
26 | __ia64_native_start_gate_##name##_patchlist[]; \ | ||
27 | extern unsigned long \ | ||
28 | __ia64_native_end_gate_##name##_patchlist[] | ||
29 | |||
30 | DECLARE(fsyscall); | ||
31 | DECLARE(brl_fsys_bubble_down); | ||
32 | DECLARE(vtop); | ||
33 | DECLARE(mckinley_e9); | ||
34 | |||
35 | extern unsigned long __start_gate_section[]; | ||
36 | |||
37 | #define ASSIGN(name) \ | ||
38 | .start_##name##_patchlist = \ | ||
39 | (unsigned long)__ia64_native_start_gate_##name##_patchlist, \ | ||
40 | .end_##name##_patchlist = \ | ||
41 | (unsigned long)__ia64_native_end_gate_##name##_patchlist | ||
42 | |||
43 | struct pv_patchdata pv_patchdata __initdata = { | ||
44 | ASSIGN(fsyscall), | ||
45 | ASSIGN(brl_fsys_bubble_down), | ||
46 | ASSIGN(vtop), | ||
47 | ASSIGN(mckinley_e9), | ||
48 | |||
49 | .gate_section = (void*)__start_gate_section, | ||
50 | }; | ||
51 | |||
52 | |||
53 | unsigned long __init | ||
54 | paravirt_get_gate_patchlist(enum pv_gate_patchlist type) | ||
55 | { | ||
56 | |||
57 | #define CASE(NAME, name) \ | ||
58 | case PV_GATE_START_##NAME: \ | ||
59 | return pv_patchdata.start_##name##_patchlist; \ | ||
60 | case PV_GATE_END_##NAME: \ | ||
61 | return pv_patchdata.end_##name##_patchlist; \ | ||
62 | |||
63 | switch (type) { | ||
64 | CASE(FSYSCALL, fsyscall); | ||
65 | CASE(BRL_FSYS_BUBBLE_DOWN, brl_fsys_bubble_down); | ||
66 | CASE(VTOP, vtop); | ||
67 | CASE(MCKINLEY_E9, mckinley_e9); | ||
68 | default: | ||
69 | BUG(); | ||
70 | break; | ||
71 | } | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | void * __init | ||
76 | paravirt_get_gate_section(void) | ||
77 | { | ||
78 | return pv_patchdata.gate_section; | ||
79 | } | ||
diff --git a/arch/ia64/kernel/paravirt_patchlist.h b/arch/ia64/kernel/paravirt_patchlist.h new file mode 100644 index 000000000000..0684aa6c6507 --- /dev/null +++ b/arch/ia64/kernel/paravirt_patchlist.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /****************************************************************************** | ||
2 | * linux/arch/ia64/xen/paravirt_patchlist.h | ||
3 | * | ||
4 | * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> | ||
5 | * VA Linux Systems Japan K.K. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #if defined(__IA64_GATE_PARAVIRTUALIZED_XEN) | ||
24 | #include <asm/xen/patchlist.h> | ||
25 | #else | ||
26 | #include <asm/native/patchlist.h> | ||
27 | #endif | ||
28 | |||
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c index 02dd977436fc..64c6f95daa34 100644 --- a/arch/ia64/kernel/patch.c +++ b/arch/ia64/kernel/patch.c | |||
@@ -227,13 +227,13 @@ patch_brl_fsys_bubble_down (unsigned long start, unsigned long end) | |||
227 | void __init | 227 | void __init |
228 | ia64_patch_gate (void) | 228 | ia64_patch_gate (void) |
229 | { | 229 | { |
230 | # define START(name) ((unsigned long) __start_gate_##name##_patchlist) | 230 | # define START(name) paravirt_get_gate_patchlist(PV_GATE_START_##name) |
231 | # define END(name) ((unsigned long)__end_gate_##name##_patchlist) | 231 | # define END(name) paravirt_get_gate_patchlist(PV_GATE_END_##name) |
232 | 232 | ||
233 | patch_fsyscall_table(START(fsyscall), END(fsyscall)); | 233 | patch_fsyscall_table(START(FSYSCALL), END(FSYSCALL)); |
234 | patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down)); | 234 | patch_brl_fsys_bubble_down(START(BRL_FSYS_BUBBLE_DOWN), END(BRL_FSYS_BUBBLE_DOWN)); |
235 | ia64_patch_vtop(START(vtop), END(vtop)); | 235 | ia64_patch_vtop(START(VTOP), END(VTOP)); |
236 | ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); | 236 | ia64_patch_mckinley_e9(START(MCKINLEY_E9), END(MCKINLEY_E9)); |
237 | } | 237 | } |
238 | 238 | ||
239 | void ia64_patch_phys_stack_reg(unsigned long val) | 239 | void ia64_patch_phys_stack_reg(unsigned long val) |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index c9bc5b305ffa..8503d534794f 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -260,6 +260,7 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot) | |||
260 | static void __init | 260 | static void __init |
261 | setup_gate (void) | 261 | setup_gate (void) |
262 | { | 262 | { |
263 | void *gate_section; | ||
263 | struct page *page; | 264 | struct page *page; |
264 | 265 | ||
265 | /* | 266 | /* |
@@ -267,10 +268,11 @@ setup_gate (void) | |||
267 | * headers etc. and once execute-only page to enable | 268 | * headers etc. and once execute-only page to enable |
268 | * privilege-promotion via "epc": | 269 | * privilege-promotion via "epc": |
269 | */ | 270 | */ |
270 | page = virt_to_page(ia64_imva(__start_gate_section)); | 271 | gate_section = paravirt_get_gate_section(); |
272 | page = virt_to_page(ia64_imva(gate_section)); | ||
271 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); | 273 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); |
272 | #ifdef HAVE_BUGGY_SEGREL | 274 | #ifdef HAVE_BUGGY_SEGREL |
273 | page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE)); | 275 | page = virt_to_page(ia64_imva(gate_section + PAGE_SIZE)); |
274 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); | 276 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); |
275 | #else | 277 | #else |
276 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); | 278 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); |