aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2009-03-04 07:05:42 -0500
committerTony Luck <tony.luck@intel.com>2009-03-26 13:51:02 -0400
commite4ff5b8f545811008123dd9556a51d814f562fcf (patch)
tree2c308a3b1cc002f0d345ed64dd94a395678543bb /arch
parent1aec1c558a797512e922581b21a178a05438bfc9 (diff)
ia64/pv_ops: gate page paravirtualization.
paravirtualize gate page by allowing each pv_ops instances to define its own gate page. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/include/asm/native/patchlist.h38
-rw-r--r--arch/ia64/include/asm/paravirt.h35
-rw-r--r--arch/ia64/kernel/Makefile32
-rw-r--r--arch/ia64/kernel/Makefile.gate27
-rw-r--r--arch/ia64/kernel/gate.lds.S17
-rw-r--r--arch/ia64/kernel/paravirt_patchlist.c79
-rw-r--r--arch/ia64/kernel/paravirt_patchlist.h28
-rw-r--r--arch/ia64/kernel/patch.c12
-rw-r--r--arch/ia64/mm/init.c6
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
36unsigned long *paravirt_get_fsyscall_table(void); 36unsigned long *paravirt_get_fsyscall_table(void);
37char *paravirt_get_fsys_bubble_down(void); 37char *paravirt_get_fsys_bubble_down(void);
38
39/******************************************************************************
40 * patchlist addresses for gate page
41 */
42enum 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
56struct 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
69extern struct pv_patchdata pv_patchdata;
70
71unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type);
72void *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 @@
5extra-y := head.o init_task.o vmlinux.lds 5extra-y := head.o init_task.o vmlinux.lds
6 6
7obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ 7obj-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)
47obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 47obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
48endif 48endif
49 49
50# The gate DSO image is built using a special linker script.
51targets += gate.so gate-syms.o
52
53extra-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.
56CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 51CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
57 52
58CPPFLAGS_gate.lds := -P -C -U$(ARCH) 53# The gate DSO image is built using a special linker script.
59 54include $(srctree)/arch/ia64/kernel/Makefile.gate
60quiet_cmd_gate = GATE $@ 55# tell compiled for native
61 cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@ 56CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE
62
63GATECFLAGS_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
71GATECFLAGS_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
81define sed-y 59define 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
3targets += gate.so gate-syms.o
4
5extra-y += gate.so gate-syms.o gate.lds gate.o
6
7CPPFLAGS_gate.lds := -P -C -U$(ARCH)
8
9quiet_cmd_gate = GATE $@
10 cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
11
12GATECFLAGS_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
20GATECFLAGS_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
11SECTIONS 12SECTIONS
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
30DECLARE(fsyscall);
31DECLARE(brl_fsys_bubble_down);
32DECLARE(vtop);
33DECLARE(mckinley_e9);
34
35extern 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
43struct 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
53unsigned long __init
54paravirt_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
75void * __init
76paravirt_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)
227void __init 227void __init
228ia64_patch_gate (void) 228ia64_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
239void ia64_patch_phys_stack_reg(unsigned long val) 239void 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)
260static void __init 260static void __init
261setup_gate (void) 261setup_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);