diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2009-03-04 07:05:34 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2009-03-26 13:48:33 -0400 |
commit | dd97d5cb540939602cba9af6f88e883a6fe451f0 (patch) | |
tree | 8425ba5692e3fe9175ed10ce85d02ef4a77dedd8 | |
parent | ac93925acbf841d70a95ab576b76b15a34d194eb (diff) |
ia64/pv_ops: add hooks to paravirtualize fsyscall implementation.
Add two hooks, paravirt_get_fsyscall_table() and
paravirt_get_fsys_bubble_doen() to paravirtualize fsyscall implementation.
This patch just add the hooks fsyscall and don't paravirtualize it.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | arch/ia64/include/asm/native/inst.h | 3 | ||||
-rw-r--r-- | arch/ia64/include/asm/paravirt.h | 15 | ||||
-rw-r--r-- | arch/ia64/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/fsys.S | 17 | ||||
-rw-r--r-- | arch/ia64/kernel/patch.c | 26 | ||||
-rw-r--r-- | arch/ia64/mm/init.c | 3 |
6 files changed, 54 insertions, 14 deletions
diff --git a/arch/ia64/include/asm/native/inst.h b/arch/ia64/include/asm/native/inst.h index 0a1026cca4fa..5e4e15133f41 100644 --- a/arch/ia64/include/asm/native/inst.h +++ b/arch/ia64/include/asm/native/inst.h | |||
@@ -30,6 +30,9 @@ | |||
30 | #define __paravirt_work_processed_syscall_target \ | 30 | #define __paravirt_work_processed_syscall_target \ |
31 | ia64_work_processed_syscall | 31 | ia64_work_processed_syscall |
32 | 32 | ||
33 | #define paravirt_fsyscall_table ia64_native_fsyscall_table | ||
34 | #define paravirt_fsys_bubble_down ia64_native_fsys_bubble_down | ||
35 | |||
33 | #ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK | 36 | #ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK |
34 | # define PARAVIRT_POISON 0xdeadbeefbaadf00d | 37 | # define PARAVIRT_POISON 0xdeadbeefbaadf00d |
35 | # define CLOBBER(clob) \ | 38 | # define CLOBBER(clob) \ |
diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h index 2bf3636473fe..56f69f938cca 100644 --- a/arch/ia64/include/asm/paravirt.h +++ b/arch/ia64/include/asm/paravirt.h | |||
@@ -22,6 +22,21 @@ | |||
22 | #ifndef __ASM_PARAVIRT_H | 22 | #ifndef __ASM_PARAVIRT_H |
23 | #define __ASM_PARAVIRT_H | 23 | #define __ASM_PARAVIRT_H |
24 | 24 | ||
25 | #ifndef __ASSEMBLY__ | ||
26 | /****************************************************************************** | ||
27 | * fsys related addresses | ||
28 | */ | ||
29 | struct pv_fsys_data { | ||
30 | unsigned long *fsyscall_table; | ||
31 | void *fsys_bubble_down; | ||
32 | }; | ||
33 | |||
34 | extern struct pv_fsys_data pv_fsys_data; | ||
35 | |||
36 | unsigned long *paravirt_get_fsyscall_table(void); | ||
37 | char *paravirt_get_fsys_bubble_down(void); | ||
38 | #endif | ||
39 | |||
25 | #ifdef CONFIG_PARAVIRT_GUEST | 40 | #ifdef CONFIG_PARAVIRT_GUEST |
26 | 41 | ||
27 | #define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0 | 42 | #define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0 |
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index c381ea954892..1ab150ec8cea 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
@@ -111,9 +111,9 @@ include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s | |||
111 | clean-files += $(objtree)/include/asm-ia64/nr-irqs.h | 111 | clean-files += $(objtree)/include/asm-ia64/nr-irqs.h |
112 | 112 | ||
113 | # | 113 | # |
114 | # native ivt.S and entry.S | 114 | # native ivt.S, entry.S and fsys.S |
115 | # | 115 | # |
116 | ASM_PARAVIRT_OBJS = ivt.o entry.o | 116 | ASM_PARAVIRT_OBJS = ivt.o entry.o fsys.o |
117 | define paravirtualized_native | 117 | define paravirtualized_native |
118 | AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE | 118 | AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE |
119 | AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK | 119 | AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index c1625c7e1779..788319f121ab 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/unistd.h> | 25 | #include <asm/unistd.h> |
26 | 26 | ||
27 | #include "entry.h" | 27 | #include "entry.h" |
28 | #include "paravirt_inst.h" | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * See Documentation/ia64/fsys.txt for details on fsyscalls. | 31 | * See Documentation/ia64/fsys.txt for details on fsyscalls. |
@@ -602,7 +603,7 @@ ENTRY(fsys_fallback_syscall) | |||
602 | mov r26=ar.pfs | 603 | mov r26=ar.pfs |
603 | END(fsys_fallback_syscall) | 604 | END(fsys_fallback_syscall) |
604 | /* FALL THROUGH */ | 605 | /* FALL THROUGH */ |
605 | GLOBAL_ENTRY(fsys_bubble_down) | 606 | GLOBAL_ENTRY(paravirt_fsys_bubble_down) |
606 | .prologue | 607 | .prologue |
607 | .altrp b6 | 608 | .altrp b6 |
608 | .body | 609 | .body |
@@ -640,7 +641,7 @@ GLOBAL_ENTRY(fsys_bubble_down) | |||
640 | * | 641 | * |
641 | * PSR.BE : already is turned off in __kernel_syscall_via_epc() | 642 | * PSR.BE : already is turned off in __kernel_syscall_via_epc() |
642 | * PSR.AC : don't care (kernel normally turns PSR.AC on) | 643 | * PSR.AC : don't care (kernel normally turns PSR.AC on) |
643 | * PSR.I : already turned off by the time fsys_bubble_down gets | 644 | * PSR.I : already turned off by the time paravirt_fsys_bubble_down gets |
644 | * invoked | 645 | * invoked |
645 | * PSR.DFL: always 0 (kernel never turns it on) | 646 | * PSR.DFL: always 0 (kernel never turns it on) |
646 | * PSR.DFH: don't care --- kernel never touches f32-f127 on its own | 647 | * PSR.DFH: don't care --- kernel never touches f32-f127 on its own |
@@ -650,7 +651,7 @@ GLOBAL_ENTRY(fsys_bubble_down) | |||
650 | * PSR.DB : don't care --- kernel never enables kernel-level | 651 | * PSR.DB : don't care --- kernel never enables kernel-level |
651 | * breakpoints | 652 | * breakpoints |
652 | * PSR.TB : must be 0 already; if it wasn't zero on entry to | 653 | * PSR.TB : must be 0 already; if it wasn't zero on entry to |
653 | * __kernel_syscall_via_epc, the branch to fsys_bubble_down | 654 | * __kernel_syscall_via_epc, the branch to paravirt_fsys_bubble_down |
654 | * will trigger a taken branch; the taken-trap-handler then | 655 | * will trigger a taken branch; the taken-trap-handler then |
655 | * converts the syscall into a break-based system-call. | 656 | * converts the syscall into a break-based system-call. |
656 | */ | 657 | */ |
@@ -741,14 +742,14 @@ GLOBAL_ENTRY(fsys_bubble_down) | |||
741 | nop.m 0 | 742 | nop.m 0 |
742 | (p8) br.call.sptk.many b6=b6 // B (ignore return address) | 743 | (p8) br.call.sptk.many b6=b6 // B (ignore return address) |
743 | br.cond.spnt ia64_trace_syscall // B | 744 | br.cond.spnt ia64_trace_syscall // B |
744 | END(fsys_bubble_down) | 745 | END(paravirt_fsys_bubble_down) |
745 | 746 | ||
746 | .rodata | 747 | .rodata |
747 | .align 8 | 748 | .align 8 |
748 | .globl fsyscall_table | 749 | .globl paravirt_fsyscall_table |
749 | 750 | ||
750 | data8 fsys_bubble_down | 751 | data8 paravirt_fsys_bubble_down |
751 | fsyscall_table: | 752 | paravirt_fsyscall_table: |
752 | data8 fsys_ni_syscall | 753 | data8 fsys_ni_syscall |
753 | data8 0 // exit // 1025 | 754 | data8 0 // exit // 1025 |
754 | data8 0 // read | 755 | data8 0 // read |
@@ -1033,4 +1034,4 @@ fsyscall_table: | |||
1033 | 1034 | ||
1034 | // fill in zeros for the remaining entries | 1035 | // fill in zeros for the remaining entries |
1035 | .zero: | 1036 | .zero: |
1036 | .space fsyscall_table + 8*NR_syscalls - .zero, 0 | 1037 | .space paravirt_fsyscall_table + 8*NR_syscalls - .zero, 0 |
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c index b83b2c516008..02dd977436fc 100644 --- a/arch/ia64/kernel/patch.c +++ b/arch/ia64/kernel/patch.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/string.h> | 8 | #include <linux/string.h> |
9 | 9 | ||
10 | #include <asm/paravirt.h> | ||
10 | #include <asm/patch.h> | 11 | #include <asm/patch.h> |
11 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
12 | #include <asm/sections.h> | 13 | #include <asm/sections.h> |
@@ -169,16 +170,35 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end) | |||
169 | ia64_srlz_i(); | 170 | ia64_srlz_i(); |
170 | } | 171 | } |
171 | 172 | ||
173 | extern unsigned long ia64_native_fsyscall_table[NR_syscalls]; | ||
174 | extern char ia64_native_fsys_bubble_down[]; | ||
175 | struct pv_fsys_data pv_fsys_data __initdata = { | ||
176 | .fsyscall_table = (unsigned long *)ia64_native_fsyscall_table, | ||
177 | .fsys_bubble_down = (void *)ia64_native_fsys_bubble_down, | ||
178 | }; | ||
179 | |||
180 | unsigned long * __init | ||
181 | paravirt_get_fsyscall_table(void) | ||
182 | { | ||
183 | return pv_fsys_data.fsyscall_table; | ||
184 | } | ||
185 | |||
186 | char * __init | ||
187 | paravirt_get_fsys_bubble_down(void) | ||
188 | { | ||
189 | return pv_fsys_data.fsys_bubble_down; | ||
190 | } | ||
191 | |||
172 | static void __init | 192 | static void __init |
173 | patch_fsyscall_table (unsigned long start, unsigned long end) | 193 | patch_fsyscall_table (unsigned long start, unsigned long end) |
174 | { | 194 | { |
175 | extern unsigned long fsyscall_table[NR_syscalls]; | 195 | u64 fsyscall_table = (u64)paravirt_get_fsyscall_table(); |
176 | s32 *offp = (s32 *) start; | 196 | s32 *offp = (s32 *) start; |
177 | u64 ip; | 197 | u64 ip; |
178 | 198 | ||
179 | while (offp < (s32 *) end) { | 199 | while (offp < (s32 *) end) { |
180 | ip = (u64) ia64_imva((char *) offp + *offp); | 200 | ip = (u64) ia64_imva((char *) offp + *offp); |
181 | ia64_patch_imm64(ip, (u64) fsyscall_table); | 201 | ia64_patch_imm64(ip, fsyscall_table); |
182 | ia64_fc((void *) ip); | 202 | ia64_fc((void *) ip); |
183 | ++offp; | 203 | ++offp; |
184 | } | 204 | } |
@@ -189,7 +209,7 @@ patch_fsyscall_table (unsigned long start, unsigned long end) | |||
189 | static void __init | 209 | static void __init |
190 | patch_brl_fsys_bubble_down (unsigned long start, unsigned long end) | 210 | patch_brl_fsys_bubble_down (unsigned long start, unsigned long end) |
191 | { | 211 | { |
192 | extern char fsys_bubble_down[]; | 212 | u64 fsys_bubble_down = (u64)paravirt_get_fsys_bubble_down(); |
193 | s32 *offp = (s32 *) start; | 213 | s32 *offp = (s32 *) start; |
194 | u64 ip; | 214 | u64 ip; |
195 | 215 | ||
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 56e12903973c..c9bc5b305ffa 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
36 | #include <asm/unistd.h> | 36 | #include <asm/unistd.h> |
37 | #include <asm/mca.h> | 37 | #include <asm/mca.h> |
38 | #include <asm/paravirt.h> | ||
38 | 39 | ||
39 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 40 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
40 | 41 | ||
@@ -667,8 +668,8 @@ mem_init (void) | |||
667 | * code can tell them apart. | 668 | * code can tell them apart. |
668 | */ | 669 | */ |
669 | for (i = 0; i < NR_syscalls; ++i) { | 670 | for (i = 0; i < NR_syscalls; ++i) { |
670 | extern unsigned long fsyscall_table[NR_syscalls]; | ||
671 | extern unsigned long sys_call_table[NR_syscalls]; | 671 | extern unsigned long sys_call_table[NR_syscalls]; |
672 | unsigned long *fsyscall_table = paravirt_get_fsyscall_table(); | ||
672 | 673 | ||
673 | if (!fsyscall_table[i] || nolwsys) | 674 | if (!fsyscall_table[i] || nolwsys) |
674 | fsyscall_table[i] = sys_call_table[i] | 1; | 675 | fsyscall_table[i] = sys_call_table[i] | 1; |