Commit 880700ed authored by David Mosberger's avatar David Mosberger

ia64: Add light-weight version of getppid(). Detect at boottime whether the

	McKinley Erratum 9 workaround is needed and, if not, patch the workaround
	bundles with NOPs.
parent a58d36df
...@@ -46,7 +46,7 @@ ENTRY(fsys_getpid) ...@@ -46,7 +46,7 @@ ENTRY(fsys_getpid)
add r8=IA64_TASK_TGID_OFFSET,r16 add r8=IA64_TASK_TGID_OFFSET,r16
;; ;;
and r9=TIF_ALLWORK_MASK,r9 and r9=TIF_ALLWORK_MASK,r9
ld4 r8=[r8] ld4 r8=[r8] // r8 = current->tgid
;; ;;
cmp.ne p8,p0=0,r9 cmp.ne p8,p0=0,r9
(p8) br.spnt.many fsys_fallback_syscall (p8) br.spnt.many fsys_fallback_syscall
...@@ -54,6 +54,51 @@ ENTRY(fsys_getpid) ...@@ -54,6 +54,51 @@ ENTRY(fsys_getpid)
br.ret.sptk.many b6 br.ret.sptk.many b6
END(fsys_getpid) END(fsys_getpid)
ENTRY(fsys_getppid)
add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16
;;
ld8 r17=[r17] // r17 = current->group_leader
add r9=TI_FLAGS+IA64_TASK_SIZE,r16
;;
ld4 r9=[r9]
add r17=IA64_TASK_REAL_PARENT_OFFSET,r17 // r17 = &current->group_leader->real_parent
;;
and r9=TIF_ALLWORK_MASK,r9
1: ld8 r18=[r17] // r18 = current->group_leader->real_parent
;;
cmp.ne p8,p0=0,r9
add r8=IA64_TASK_TGID_OFFSET,r18 // r8 = &current->group_leader->real_parent->tgid
;;
/*
* The .acq is needed to ensure that the read of tgid has returned its data before
* we re-check "real_parent".
*/
ld4.acq r8=[r8] // r8 = current->group_leader->real_parent->tgid
#ifdef CONFIG_SMP
/*
* Re-read current->group_leader->real_parent.
*/
ld8 r19=[r17] // r19 = current->group_leader->real_parent
(p8) br.spnt.many fsys_fallback_syscall
;;
cmp.ne p6,p0=r18,r19 // did real_parent change?
mov r19=0 // i must not leak kernel bits...
(p6) br.cond.spnt.few 1b // yes -> redo the read of tgid and the check
;;
mov r17=0 // i must not leak kernel bits...
mov r18=0 // i must not leak kernel bits...
#else
mov r17=0 // i must not leak kernel bits...
mov r18=0 // i must not leak kernel bits...
mov r19=0 // i must not leak kernel bits...
#endif
MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6
END(fsys_getppid)
ENTRY(fsys_set_tid_address) ENTRY(fsys_set_tid_address)
add r9=TI_FLAGS+IA64_TASK_SIZE,r16 add r9=TI_FLAGS+IA64_TASK_SIZE,r16
;; ;;
...@@ -72,8 +117,8 @@ ENTRY(fsys_set_tid_address) ...@@ -72,8 +117,8 @@ ENTRY(fsys_set_tid_address)
(p7) st8 [r18]=r17 (p7) st8 [r18]=r17
(p8) br.spnt.many fsys_fallback_syscall (p8) br.spnt.many fsys_fallback_syscall
;; ;;
mov r17=0 // don't leak kernel bits... mov r17=0 // i must not leak kernel bits...
mov r18=0 // don't leak kernel bits... mov r18=0 // i must not leak kernel bits...
MCKINLEY_E9_WORKAROUND MCKINLEY_E9_WORKAROUND
br.ret.sptk.many b6 br.ret.sptk.many b6
END(fsys_set_tid_address) END(fsys_set_tid_address)
...@@ -100,7 +145,7 @@ fsyscall_table: ...@@ -100,7 +145,7 @@ fsyscall_table:
data8 fsys_fallback_syscall // chown data8 fsys_fallback_syscall // chown
data8 fsys_fallback_syscall // lseek // 1040 data8 fsys_fallback_syscall // lseek // 1040
data8 fsys_getpid data8 fsys_getpid
data8 fsys_fallback_syscall // getppid data8 fsys_getppid // getppid
data8 fsys_fallback_syscall // mount data8 fsys_fallback_syscall // mount
data8 fsys_fallback_syscall // umount data8 fsys_fallback_syscall // umount
data8 fsys_fallback_syscall // setuid // 1045 data8 fsys_fallback_syscall // setuid // 1045
......
/* /*
* Architecture-specific setup. * Architecture-specific setup.
* *
* Copyright (C) 1998-2001 Hewlett-Packard Co * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* Stephane Eranian <eranian@hpl.hp.com> * Stephane Eranian <eranian@hpl.hp.com>
* Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com> * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
...@@ -748,10 +748,39 @@ cpu_init (void) ...@@ -748,10 +748,39 @@ cpu_init (void)
} }
if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) { if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) {
printk ("cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n"); printk(KERN_WARNING"cpu_init: PAL RSE info failed; assuming 96 physical "
"stacked regs\n");
num_phys_stacked = 96; num_phys_stacked = 96;
} }
/* size of physical stacked register partition plus 8 bytes: */ /* size of physical stacked register partition plus 8 bytes: */
__get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
platform_cpu_init(); platform_cpu_init();
} }
void
check_bugs (void)
{
extern int __start___mckinley_e9_bundles[];
extern int __end___mckinley_e9_bundles[];
u64 *bundle;
int *wp;
if (local_cpu_data->family == 0x1f && local_cpu_data->model == 0)
printk(KERN_INFO"check_bugs: leaving McKinley Errata 9 workaround enabled\n");
else {
printk(KERN_INFO"check_bugs: McKinley Errata 9 workaround not needed; "
"disabling it\n");
for (wp = __start___mckinley_e9_bundles; wp < __end___mckinley_e9_bundles; ++wp) {
bundle = (u64 *) ((char *) wp + *wp);
/* install a bundle of NOPs: */
bundle[0] = 0x0000000100000000;
bundle[1] = 0x0004000000000200;
ia64_fc(bundle);
}
ia64_insn_group_barrier();
ia64_sync_i();
ia64_insn_group_barrier();
ia64_srlz_i();
ia64_insn_group_barrier();
}
}
...@@ -52,11 +52,13 @@ tab[] = ...@@ -52,11 +52,13 @@ tab[] =
{ "SIGFRAME_SIZE", sizeof (struct sigframe) }, { "SIGFRAME_SIZE", sizeof (struct sigframe) },
{ "UNW_FRAME_INFO_SIZE", sizeof (struct unw_frame_info) }, { "UNW_FRAME_INFO_SIZE", sizeof (struct unw_frame_info) },
{ "", 0 }, /* spacer */ { "", 0 }, /* spacer */
{ "IA64_TASK_THREAD_KSP_OFFSET", offsetof (struct task_struct, thread.ksp) }, { "IA64_TASK_CLEAR_CHILD_TID_OFFSET",offsetof (struct task_struct, clear_child_tid) },
{ "IA64_TASK_THREAD_ON_USTACK_OFFSET", offsetof (struct task_struct, thread.on_ustack) }, { "IA64_TASK_GROUP_LEADER_OFFSET", offsetof (struct task_struct, group_leader) },
{ "IA64_TASK_PID_OFFSET", offsetof (struct task_struct, pid) }, { "IA64_TASK_PID_OFFSET", offsetof (struct task_struct, pid) },
{ "IA64_TASK_REAL_PARENT_OFFSET", offsetof (struct task_struct, real_parent) },
{ "IA64_TASK_TGID_OFFSET", offsetof (struct task_struct, tgid) }, { "IA64_TASK_TGID_OFFSET", offsetof (struct task_struct, tgid) },
{ "IA64_TASK_CLEAR_CHILD_TID_OFFSET",offsetof (struct task_struct, clear_child_tid) }, { "IA64_TASK_THREAD_KSP_OFFSET", offsetof (struct task_struct, thread.ksp) },
{ "IA64_TASK_THREAD_ON_USTACK_OFFSET", offsetof (struct task_struct, thread.on_ustack) },
{ "IA64_PT_REGS_CR_IPSR_OFFSET", offsetof (struct pt_regs, cr_ipsr) }, { "IA64_PT_REGS_CR_IPSR_OFFSET", offsetof (struct pt_regs, cr_ipsr) },
{ "IA64_PT_REGS_CR_IIP_OFFSET", offsetof (struct pt_regs, cr_iip) }, { "IA64_PT_REGS_CR_IIP_OFFSET", offsetof (struct pt_regs, cr_iip) },
{ "IA64_PT_REGS_CR_IFS_OFFSET", offsetof (struct pt_regs, cr_ifs) }, { "IA64_PT_REGS_CR_IFS_OFFSET", offsetof (struct pt_regs, cr_ifs) },
......
...@@ -54,6 +54,13 @@ SECTIONS ...@@ -54,6 +54,13 @@ SECTIONS
__stop___ex_table = .; __stop___ex_table = .;
} }
__mckinley_e9_bundles : AT(ADDR(__mckinley_e9_bundles) - PAGE_OFFSET)
{
__start___mckinley_e9_bundles = .;
*(__mckinley_e9_bundles)
__end___mckinley_e9_bundles = .;
}
/* Global data */ /* Global data */
_data = .; _data = .;
......
...@@ -59,10 +59,22 @@ ...@@ -59,10 +59,22 @@
99: x 99: x
#endif #endif
#ifdef CONFIG_MCKINLEY /*
* For now, we always put in the McKinley E9 workaround. On CPUs that don't need it,
* we'll patch out the work-around bundles with NOPs, so their impact is minimal.
*/
#define DO_MCKINLEY_E9_WORKAROUND
#ifdef DO_MCKINLEY_E9_WORKAROUND
.section "__mckinley_e9_bundles", "a"
.previous
/* workaround for Itanium 2 Errata 9: */ /* workaround for Itanium 2 Errata 9: */
# define MCKINLEY_E9_WORKAROUND \ # define MCKINLEY_E9_WORKAROUND \
.xdata4 "__mckinley_e9_bundles", 1f-.; \
1:{ .mib; \
nop.m 0; \
nop.i 0; \
br.call.sptk.many b7=1f;; \ br.call.sptk.many b7=1f;; \
}; \
1: 1:
#else #else
# define MCKINLEY_E9_WORKAROUND # define MCKINLEY_E9_WORKAROUND
......
...@@ -4,16 +4,14 @@ ...@@ -4,16 +4,14 @@
* Needs: * Needs:
* void check_bugs(void); * void check_bugs(void);
* *
* Copyright (C) 1998, 1999 Hewlett-Packard Co * Copyright (C) 1998, 1999, 2003 Hewlett-Packard Co
* Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
*/ */
#ifndef _ASM_IA64_BUGS_H
#define _ASM_IA64_BUGS_H
#include <asm/processor.h> #include <asm/processor.h>
/* extern void check_bugs (void);
* I don't know of any ia-64 bugs yet..
*/ #endif /* _ASM_IA64_BUGS_H */
static void
check_bugs (void)
{
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment