提交 dd97d5cb 编写于 作者: I Isaku Yamahata 提交者: Tony Luck

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: NIsaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: NTony Luck <tony.luck@intel.com>
上级 ac93925a
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
#define __paravirt_work_processed_syscall_target \ #define __paravirt_work_processed_syscall_target \
ia64_work_processed_syscall ia64_work_processed_syscall
#define paravirt_fsyscall_table ia64_native_fsyscall_table
#define paravirt_fsys_bubble_down ia64_native_fsys_bubble_down
#ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK #ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
# define PARAVIRT_POISON 0xdeadbeefbaadf00d # define PARAVIRT_POISON 0xdeadbeefbaadf00d
# define CLOBBER(clob) \ # define CLOBBER(clob) \
......
...@@ -22,6 +22,21 @@ ...@@ -22,6 +22,21 @@
#ifndef __ASM_PARAVIRT_H #ifndef __ASM_PARAVIRT_H
#define __ASM_PARAVIRT_H #define __ASM_PARAVIRT_H
#ifndef __ASSEMBLY__
/******************************************************************************
* fsys related addresses
*/
struct pv_fsys_data {
unsigned long *fsyscall_table;
void *fsys_bubble_down;
};
extern struct pv_fsys_data pv_fsys_data;
unsigned long *paravirt_get_fsyscall_table(void);
char *paravirt_get_fsys_bubble_down(void);
#endif
#ifdef CONFIG_PARAVIRT_GUEST #ifdef CONFIG_PARAVIRT_GUEST
#define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0 #define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0
......
...@@ -111,9 +111,9 @@ include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s ...@@ -111,9 +111,9 @@ include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
clean-files += $(objtree)/include/asm-ia64/nr-irqs.h clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
# #
# native ivt.S and entry.S # native ivt.S, entry.S and fsys.S
# #
ASM_PARAVIRT_OBJS = ivt.o entry.o ASM_PARAVIRT_OBJS = ivt.o entry.o fsys.o
define paravirtualized_native define paravirtualized_native
AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/unistd.h> #include <asm/unistd.h>
#include "entry.h" #include "entry.h"
#include "paravirt_inst.h"
/* /*
* See Documentation/ia64/fsys.txt for details on fsyscalls. * See Documentation/ia64/fsys.txt for details on fsyscalls.
...@@ -602,7 +603,7 @@ ENTRY(fsys_fallback_syscall) ...@@ -602,7 +603,7 @@ ENTRY(fsys_fallback_syscall)
mov r26=ar.pfs mov r26=ar.pfs
END(fsys_fallback_syscall) END(fsys_fallback_syscall)
/* FALL THROUGH */ /* FALL THROUGH */
GLOBAL_ENTRY(fsys_bubble_down) GLOBAL_ENTRY(paravirt_fsys_bubble_down)
.prologue .prologue
.altrp b6 .altrp b6
.body .body
...@@ -640,7 +641,7 @@ GLOBAL_ENTRY(fsys_bubble_down) ...@@ -640,7 +641,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
* *
* PSR.BE : already is turned off in __kernel_syscall_via_epc() * PSR.BE : already is turned off in __kernel_syscall_via_epc()
* PSR.AC : don't care (kernel normally turns PSR.AC on) * PSR.AC : don't care (kernel normally turns PSR.AC on)
* PSR.I : already turned off by the time fsys_bubble_down gets * PSR.I : already turned off by the time paravirt_fsys_bubble_down gets
* invoked * invoked
* PSR.DFL: always 0 (kernel never turns it on) * PSR.DFL: always 0 (kernel never turns it on)
* PSR.DFH: don't care --- kernel never touches f32-f127 on its own * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
...@@ -650,7 +651,7 @@ GLOBAL_ENTRY(fsys_bubble_down) ...@@ -650,7 +651,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
* PSR.DB : don't care --- kernel never enables kernel-level * PSR.DB : don't care --- kernel never enables kernel-level
* breakpoints * breakpoints
* PSR.TB : must be 0 already; if it wasn't zero on entry to * PSR.TB : must be 0 already; if it wasn't zero on entry to
* __kernel_syscall_via_epc, the branch to fsys_bubble_down * __kernel_syscall_via_epc, the branch to paravirt_fsys_bubble_down
* will trigger a taken branch; the taken-trap-handler then * will trigger a taken branch; the taken-trap-handler then
* converts the syscall into a break-based system-call. * converts the syscall into a break-based system-call.
*/ */
...@@ -741,14 +742,14 @@ GLOBAL_ENTRY(fsys_bubble_down) ...@@ -741,14 +742,14 @@ GLOBAL_ENTRY(fsys_bubble_down)
nop.m 0 nop.m 0
(p8) br.call.sptk.many b6=b6 // B (ignore return address) (p8) br.call.sptk.many b6=b6 // B (ignore return address)
br.cond.spnt ia64_trace_syscall // B br.cond.spnt ia64_trace_syscall // B
END(fsys_bubble_down) END(paravirt_fsys_bubble_down)
.rodata .rodata
.align 8 .align 8
.globl fsyscall_table .globl paravirt_fsyscall_table
data8 fsys_bubble_down data8 paravirt_fsys_bubble_down
fsyscall_table: paravirt_fsyscall_table:
data8 fsys_ni_syscall data8 fsys_ni_syscall
data8 0 // exit // 1025 data8 0 // exit // 1025
data8 0 // read data8 0 // read
...@@ -1033,4 +1034,4 @@ fsyscall_table: ...@@ -1033,4 +1034,4 @@ fsyscall_table:
// fill in zeros for the remaining entries // fill in zeros for the remaining entries
.zero: .zero:
.space fsyscall_table + 8*NR_syscalls - .zero, 0 .space paravirt_fsyscall_table + 8*NR_syscalls - .zero, 0
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h> #include <linux/string.h>
#include <asm/paravirt.h>
#include <asm/patch.h> #include <asm/patch.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/sections.h> #include <asm/sections.h>
...@@ -169,16 +170,35 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end) ...@@ -169,16 +170,35 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
ia64_srlz_i(); ia64_srlz_i();
} }
extern unsigned long ia64_native_fsyscall_table[NR_syscalls];
extern char ia64_native_fsys_bubble_down[];
struct pv_fsys_data pv_fsys_data __initdata = {
.fsyscall_table = (unsigned long *)ia64_native_fsyscall_table,
.fsys_bubble_down = (void *)ia64_native_fsys_bubble_down,
};
unsigned long * __init
paravirt_get_fsyscall_table(void)
{
return pv_fsys_data.fsyscall_table;
}
char * __init
paravirt_get_fsys_bubble_down(void)
{
return pv_fsys_data.fsys_bubble_down;
}
static void __init static void __init
patch_fsyscall_table (unsigned long start, unsigned long end) patch_fsyscall_table (unsigned long start, unsigned long end)
{ {
extern unsigned long fsyscall_table[NR_syscalls]; u64 fsyscall_table = (u64)paravirt_get_fsyscall_table();
s32 *offp = (s32 *) start; s32 *offp = (s32 *) start;
u64 ip; u64 ip;
while (offp < (s32 *) end) { while (offp < (s32 *) end) {
ip = (u64) ia64_imva((char *) offp + *offp); ip = (u64) ia64_imva((char *) offp + *offp);
ia64_patch_imm64(ip, (u64) fsyscall_table); ia64_patch_imm64(ip, fsyscall_table);
ia64_fc((void *) ip); ia64_fc((void *) ip);
++offp; ++offp;
} }
...@@ -189,7 +209,7 @@ patch_fsyscall_table (unsigned long start, unsigned long end) ...@@ -189,7 +209,7 @@ patch_fsyscall_table (unsigned long start, unsigned long end)
static void __init static void __init
patch_brl_fsys_bubble_down (unsigned long start, unsigned long end) patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
{ {
extern char fsys_bubble_down[]; u64 fsys_bubble_down = (u64)paravirt_get_fsys_bubble_down();
s32 *offp = (s32 *) start; s32 *offp = (s32 *) start;
u64 ip; u64 ip;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/mca.h> #include <asm/mca.h>
#include <asm/paravirt.h>
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
...@@ -667,8 +668,8 @@ mem_init (void) ...@@ -667,8 +668,8 @@ mem_init (void)
* code can tell them apart. * code can tell them apart.
*/ */
for (i = 0; i < NR_syscalls; ++i) { for (i = 0; i < NR_syscalls; ++i) {
extern unsigned long fsyscall_table[NR_syscalls];
extern unsigned long sys_call_table[NR_syscalls]; extern unsigned long sys_call_table[NR_syscalls];
unsigned long *fsyscall_table = paravirt_get_fsyscall_table();
if (!fsyscall_table[i] || nolwsys) if (!fsyscall_table[i] || nolwsys)
fsyscall_table[i] = sys_call_table[i] | 1; fsyscall_table[i] = sys_call_table[i] | 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册