mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
[IA64] paravirtualize vdso
paravirtualize vdso area. introduce hyperprivop HYPERPRIVOP_RSM_BE and HYPERPRIVOP_GET_PSR. and paravirtualize vdso area using them. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
This commit is contained in:
1 parent
09879197ca
commit
ed2f30d1f5
6 files changed
+129
-1
No files matched your search
@@ -14,6 +14,9 @@
|
||||
#include <asm/sigcontext.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/unistd.h>
|
||||
#ifdef CONFIG_XEN
|
||||
# include <asm/privop.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We can't easily refer to symbols inside the kernel. To avoid full runtime relocation,
|
||||
@@ -33,6 +36,15 @@
|
||||
[1:](pr)brl.cond.sptk 0; \
|
||||
.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
|
||||
|
||||
// Currently is_running_on_xen() is defined as running_on_xen.
|
||||
// If is_running_on_xen() is a real function, we must update
|
||||
// according to it.
|
||||
.section ".data.patch.running_on_xen", "a"
|
||||
.previous
|
||||
#define LOAD_RUNNING_ON_XEN(reg) \
|
||||
[1:] movl reg=0; \
|
||||
.xdata4 ".data.patch.running_on_xen", 1b-.
|
||||
|
||||
GLOBAL_ENTRY(__kernel_syscall_via_break)
|
||||
.prologue
|
||||
.altrp b6
|
||||
@@ -77,7 +89,42 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
|
||||
epc // B causes split-issue
|
||||
}
|
||||
;;
|
||||
#ifdef CONFIG_XEN
|
||||
// r20 = 1
|
||||
// r22 = &vcpu->evtchn_mask
|
||||
// r23 = &vpsr.ic
|
||||
// r24 = vcpu->pending_interruption
|
||||
// r25 = tmp
|
||||
// r28 = &running_on_xen
|
||||
// r30 = running_on_xen
|
||||
// r31 = tmp
|
||||
// p11 = tmp
|
||||
// p12 = running_on_xen
|
||||
// p13 = !running_on_xen
|
||||
// p14 = tmp
|
||||
// p15 = tmp
|
||||
#define isXen p12
|
||||
#define isRaw p13
|
||||
LOAD_RUNNING_ON_XEN(r28)
|
||||
movl r22=XSI_PSR_I_ADDR
|
||||
movl r23=XSI_PSR_IC
|
||||
movl r24=XSI_PEND
|
||||
mov r20=1
|
||||
;;
|
||||
ld4 r30=[r28]
|
||||
;;
|
||||
cmp.ne p12,p13=r0,r30
|
||||
;;
|
||||
(isXen) ld8 r22=[r22]
|
||||
(isRaw) rsm psr.be | psr.i
|
||||
;;
|
||||
(isXen) st1 [r22]=r20
|
||||
(isXen) st4 [r23]=r0
|
||||
(isXen) XEN_HYPER_RSM_BE
|
||||
(isXen) st4 [r23]=r20
|
||||
#else
|
||||
rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
|
||||
#endif
|
||||
LOAD_FSYSCALL_TABLE(r14) // X
|
||||
;;
|
||||
mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
|
||||
@@ -85,7 +132,19 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
|
||||
mov r19=NR_syscalls-1 // A
|
||||
;;
|
||||
lfetch [r18] // M0|1
|
||||
#ifdef CONFIG_XEN
|
||||
(isXen) mov r31=r8
|
||||
(isXen) mov r25=IA64_PSR_IC
|
||||
(isXen) st4 [r23]=r0
|
||||
(isXen) XEN_HYPER_GET_PSR
|
||||
(isRaw) mov r29=psr
|
||||
;;
|
||||
(isXen) st4 [r23]=r20
|
||||
(isXen) or r29=r8,r25 // vpsr.ic was cleared for hyperprivop
|
||||
(isXen) mov r8=r31
|
||||
#else
|
||||
mov r29=psr // M2 (12 cyc)
|
||||
#endif
|
||||
// If r17 is a NaT, p6 will be zero
|
||||
cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
|
||||
;;
|
||||
@@ -99,9 +158,26 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
|
||||
;;
|
||||
nop.m 0
|
||||
(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
|
||||
#ifdef CONFIG_XEN
|
||||
;;
|
||||
// p14 = running_on_xen && p8
|
||||
// p15 = !running_on_xen && p8
|
||||
(p8) cmp.ne.unc p14,p15=r0,r30
|
||||
;;
|
||||
(p14) st4 [r22]=r20
|
||||
(p14) ld4 r25=[r24]
|
||||
(p15) ssm psr.i
|
||||
;;
|
||||
(p14) cmp.ne.unc p11,p0=r0, r25
|
||||
;;
|
||||
(p11) st4 [r22]=r0
|
||||
(p11) st4 [r23]=r0
|
||||
(p11) XEN_HYPER_SSM_I
|
||||
#else
|
||||
nop.i 0
|
||||
;;
|
||||
(p8) ssm psr.i
|
||||
#endif
|
||||
(p6) mov b7=r18 // I0
|
||||
(p8) br.dptk.many b7 // B
|
||||
|
||||
@@ -122,7 +198,20 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
|
||||
#else
|
||||
BRL_COND_FSYS_BUBBLE_DOWN(p6)
|
||||
#endif
|
||||
#ifdef CONFIG_XEN
|
||||
(isXen) st4 [r22]=r20
|
||||
(isXen) ld4 r25=[r24]
|
||||
(isRaw) ssm psr.i
|
||||
;;
|
||||
(isXen) cmp.ne.unc p11,p0=r0, r25
|
||||
;;
|
||||
(p11) st4 [r22]=r0
|
||||
(p11) st4 [r23]=r0
|
||||
(p11) XEN_HYPER_SSM_I
|
||||
;;
|
||||
#else
|
||||
ssm psr.i
|
||||
#endif
|
||||
mov r10=-1
|
||||
(p10) mov r8=EINVAL
|
||||
(p9) mov r8=ENOSYS
|
||||
|
||||
@@ -43,6 +43,10 @@ SECTIONS
|
||||
__start_gate_brl_fsys_bubble_down_patchlist = .;
|
||||
*(.data.patch.brl_fsys_bubble_down)
|
||||
__end_gate_brl_fsys_bubble_down_patchlist = .;
|
||||
|
||||
__start_gate_running_on_xen_patchlist = .;
|
||||
*(.data.patch.running_on_xen)
|
||||
__end_gate_running_on_xen_patchlist = .;
|
||||
} :readable
|
||||
.IA_64.unwind_info : { *(.IA_64.unwind_info*) }
|
||||
.IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind
|
||||
|
||||
@@ -184,6 +184,29 @@ patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
|
||||
ia64_srlz_i();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
extern char __start_gate_running_on_xen_patchlist[];
|
||||
extern char __end_gate_running_on_xen_patchlist[];
|
||||
void
|
||||
patch_running_on_xen(unsigned long start, unsigned long end)
|
||||
{
|
||||
extern int running_on_xen;
|
||||
s32 *offp = (s32 *) start;
|
||||
u64 ip;
|
||||
|
||||
while (offp < (s32 *) end) {
|
||||
ip = (u64) ia64_imva((char *) offp + *offp);
|
||||
ia64_patch_imm64(ip, (u64) &running_on_xen);
|
||||
ia64_fc((void *) ip);
|
||||
++offp;
|
||||
}
|
||||
ia64_sync_i();
|
||||
ia64_srlz_i();
|
||||
}
|
||||
#else
|
||||
#define patch_running_on_xen(start, end) do { } while (0)
|
||||
#endif
|
||||
|
||||
void
|
||||
ia64_patch_gate (void)
|
||||
{
|
||||
@@ -192,6 +215,7 @@ ia64_patch_gate (void)
|
||||
|
||||
patch_fsyscall_table(START(fsyscall), END(fsyscall));
|
||||
patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
|
||||
patch_running_on_xen(START(running_on_xen), END(running_on_xen));
|
||||
ia64_patch_vtop(START(vtop), END(vtop));
|
||||
ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
|
||||
}
|
||||
@@ -39,6 +39,8 @@
|
||||
#define XEN_HYPER_GET_PMD break HYPERPRIVOP_GET_PMD
|
||||
#define XEN_HYPER_GET_EFLAG break HYPERPRIVOP_GET_EFLAG
|
||||
#define XEN_HYPER_SET_EFLAG break HYPERPRIVOP_SET_EFLAG
|
||||
#define XEN_HYPER_RSM_BE break HYPERPRIVOP_RSM_BE
|
||||
#define XEN_HYPER_GET_PSR break HYPERPRIVOP_GET_PSR
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@@ -897,6 +897,13 @@ ia64_hyperprivop(unsigned long iim, REGS *regs)
|
||||
case HYPERPRIVOP_SET_EFLAG:
|
||||
(void)vcpu_set_ar(v,24,regs->r8);
|
||||
return 1;
|
||||
case HYPERPRIVOP_RSM_BE:
|
||||
(void)vcpu_reset_psr_sm(v, IA64_PSR_BE);
|
||||
return 1;
|
||||
case HYPERPRIVOP_GET_PSR:
|
||||
(void)vcpu_get_psr(v, &val);
|
||||
regs->r8 = val;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -400,7 +400,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
|
||||
#define HYPERPRIVOP_GET_PMD 0x15
|
||||
#define HYPERPRIVOP_GET_EFLAG 0x16
|
||||
#define HYPERPRIVOP_SET_EFLAG 0x17
|
||||
#define HYPERPRIVOP_MAX 0x17
|
||||
#define HYPERPRIVOP_RSM_BE 0x18
|
||||
#define HYPERPRIVOP_GET_PSR 0x19
|
||||
#define HYPERPRIVOP_MAX 0x19
|
||||
|
||||
#endif /* __HYPERVISOR_IF_IA64_H__ */
|
||||
|
||||
|
||||