Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101808
b: refs/heads/master
c: beae4c0
h: refs/heads/master
v: v3
  • Loading branch information
Josh Boyer committed Jul 9, 2008
1 parent f9d8685 commit 950f19d
Show file tree
Hide file tree
Showing 26 changed files with 603 additions and 305 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9fde9bdd3023854f7b03cc425ff4a0ed51bd1eb3
refs/heads/master: beae4c03c0fe69cf7d57518aa0572ad21730b8be
6 changes: 6 additions & 0 deletions trunk/arch/powerpc/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ int module_finalize(const Elf_Ehdr *hdr,
(void *)sect->sh_addr + sect->sh_size);
#endif

sect = find_section(hdr, sechdrs, "__lwsync_fixup");
if (sect != NULL)
do_lwsync_fixups(cur_cpu_spec->cpu_features,
(void *)sect->sh_addr,
(void *)sect->sh_addr + sect->sh_size);

return 0;
}

Expand Down
83 changes: 0 additions & 83 deletions trunk/arch/powerpc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,29 +105,6 @@ void enable_kernel_fp(void)
}
EXPORT_SYMBOL(enable_kernel_fp);

int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
{
#ifdef CONFIG_VSX
int i;
elf_fpreg_t *reg;
#endif

if (!tsk->thread.regs)
return 0;
flush_fp_to_thread(current);

#ifdef CONFIG_VSX
reg = (elf_fpreg_t *)fpregs;
for (i = 0; i < ELF_NFPREG - 1; i++, reg++)
*reg = tsk->thread.TS_FPR(i);
memcpy(reg, &tsk->thread.fpscr, sizeof(elf_fpreg_t));
#else
memcpy(fpregs, &tsk->thread.TS_FPR(0), sizeof(*fpregs));
#endif

return 1;
}

#ifdef CONFIG_ALTIVEC
void enable_kernel_altivec(void)
{
Expand Down Expand Up @@ -161,35 +138,6 @@ void flush_altivec_to_thread(struct task_struct *tsk)
preempt_enable();
}
}

int dump_task_altivec(struct task_struct *tsk, elf_vrregset_t *vrregs)
{
/* ELF_NVRREG includes the VSCR and VRSAVE which we need to save
* separately, see below */
const int nregs = ELF_NVRREG - 2;
elf_vrreg_t *reg;
u32 *dest;

if (tsk == current)
flush_altivec_to_thread(tsk);

reg = (elf_vrreg_t *)vrregs;

/* copy the 32 vr registers */
memcpy(reg, &tsk->thread.vr[0], nregs * sizeof(*reg));
reg += nregs;

/* copy the vscr */
memcpy(reg, &tsk->thread.vscr, sizeof(*reg));
reg++;

/* vrsave is stored in the high 32bit slot of the final 128bits */
memset(reg, 0, sizeof(*reg));
dest = (u32 *)reg;
*dest = tsk->thread.vrsave;

return 1;
}
#endif /* CONFIG_ALTIVEC */

#ifdef CONFIG_VSX
Expand Down Expand Up @@ -224,29 +172,6 @@ void flush_vsx_to_thread(struct task_struct *tsk)
preempt_enable();
}
}

/*
* This dumps the lower half 64bits of the first 32 VSX registers.
* This needs to be called with dump_task_fp and dump_task_altivec to
* get all the VSX state.
*/
int dump_task_vsx(struct task_struct *tsk, elf_vrreg_t *vrregs)
{
elf_vrreg_t *reg;
double buf[32];
int i;

if (tsk == current)
flush_vsx_to_thread(tsk);

reg = (elf_vrreg_t *)vrregs;

for (i = 0; i < 32 ; i++)
buf[i] = current->thread.fpr[i][TS_VSRLOWOFFSET];
memcpy(reg, buf, sizeof(buf));

return 1;
}
#endif /* CONFIG_VSX */

#ifdef CONFIG_SPE
Expand Down Expand Up @@ -279,14 +204,6 @@ void flush_spe_to_thread(struct task_struct *tsk)
preempt_enable();
}
}

int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
{
flush_spe_to_thread(current);
/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
memcpy(evrregs, &current->thread.evr[0], sizeof(u32) * 35);
return 1;
}
#endif /* CONFIG_SPE */

#ifndef CONFIG_SMP
Expand Down
4 changes: 4 additions & 0 deletions trunk/arch/powerpc/kernel/setup_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ unsigned long __init early_init(unsigned long dt_ptr)
PTRRELOC(&__start___ftr_fixup),
PTRRELOC(&__stop___ftr_fixup));

do_lwsync_fixups(spec->cpu_features,
PTRRELOC(&__start___lwsync_fixup),
PTRRELOC(&__stop___lwsync_fixup));

return KERNELBASE + offset;
}

Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/powerpc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ void __init setup_system(void)
&__start___ftr_fixup, &__stop___ftr_fixup);
do_feature_fixups(powerpc_firmware_features,
&__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
do_lwsync_fixups(cur_cpu_spec->cpu_features,
&__start___lwsync_fixup, &__stop___lwsync_fixup);

/*
* Unflatten the device-tree passed by prom_init or kexec
Expand Down
10 changes: 10 additions & 0 deletions trunk/arch/powerpc/kernel/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ extern int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset,
struct pt_regs *regs);

extern unsigned long copy_fpr_to_user(void __user *to,
struct task_struct *task);
extern unsigned long copy_fpr_from_user(struct task_struct *task,
void __user *from);
#ifdef CONFIG_VSX
extern unsigned long copy_vsx_to_user(void __user *to,
struct task_struct *task);
extern unsigned long copy_vsx_from_user(struct task_struct *task,
void __user *from);
#endif

#ifdef CONFIG_PPC64

Expand Down
109 changes: 75 additions & 34 deletions trunk/arch/powerpc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,75 @@ struct rt_sigframe {
int abigap[56];
};

#ifdef CONFIG_VSX
unsigned long copy_fpr_to_user(void __user *to,
struct task_struct *task)
{
double buf[ELF_NFPREG];
int i;

/* save FPR copy to local buffer then write to the thread_struct */
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
buf[i] = task->thread.TS_FPR(i);
memcpy(&buf[i], &task->thread.fpscr, sizeof(double));
return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
}

unsigned long copy_fpr_from_user(struct task_struct *task,
void __user *from)
{
double buf[ELF_NFPREG];
int i;

if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
return 1;
for (i = 0; i < (ELF_NFPREG - 1) ; i++)
task->thread.TS_FPR(i) = buf[i];
memcpy(&task->thread.fpscr, &buf[i], sizeof(double));

return 0;
}

unsigned long copy_vsx_to_user(void __user *to,
struct task_struct *task)
{
double buf[ELF_NVSRHALFREG];
int i;

/* save FPR copy to local buffer then write to the thread_struct */
for (i = 0; i < ELF_NVSRHALFREG; i++)
buf[i] = task->thread.fpr[i][TS_VSRLOWOFFSET];
return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
}

unsigned long copy_vsx_from_user(struct task_struct *task,
void __user *from)
{
double buf[ELF_NVSRHALFREG];
int i;

if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
return 1;
for (i = 0; i < ELF_NVSRHALFREG ; i++)
task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i];
return 0;
}
#else
inline unsigned long copy_fpr_to_user(void __user *to,
struct task_struct *task)
{
return __copy_to_user(to, task->thread.fpr,
ELF_NFPREG * sizeof(double));
}

inline unsigned long copy_fpr_from_user(struct task_struct *task,
void __user *from)
{
return __copy_from_user(task->thread.fpr, from,
ELF_NFPREG * sizeof(double));
}
#endif

/*
* Save the current user registers on the user stack.
* We only save the altivec/spe registers if the process has used
Expand All @@ -337,10 +406,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
int sigret)
{
unsigned long msr = regs->msr;
#ifdef CONFIG_VSX
double buf[32];
int i;
#endif

/* Make sure floating point registers are stored in regs */
flush_fp_to_thread(current);
Expand Down Expand Up @@ -370,14 +435,9 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_VSX
/* save FPR copy to local buffer then write to the thread_struct */
flush_fp_to_thread(current);
for (i = 0; i < 32 ; i++)
buf[i] = current->thread.TS_FPR(i);
memcpy(&buf[i], &current->thread.fpscr, sizeof(double));
if (__copy_to_user(&frame->mc_fregs, buf, ELF_NFPREG * sizeof(double)))
if (copy_fpr_to_user(&frame->mc_fregs, current))
return 1;
#ifdef CONFIG_VSX
/*
* Copy VSR 0-31 upper half from thread_struct to local
* buffer, then write that to userspace. Also set MSR_VSX in
Expand All @@ -386,18 +446,10 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
*/
if (current->thread.used_vsr) {
flush_vsx_to_thread(current);
for (i = 0; i < 32 ; i++)
buf[i] = current->thread.fpr[i][TS_VSRLOWOFFSET];
if (__copy_to_user(&frame->mc_vsregs, buf,
ELF_NVSRHALFREG * sizeof(double)))
if (copy_vsx_to_user(&frame->mc_vsregs, current))
return 1;
msr |= MSR_VSX;
}
#else
/* save floating-point registers */
if (__copy_to_user(&frame->mc_fregs, current->thread.fpr,
ELF_NFPREG * sizeof(double)))
return 1;
#endif /* CONFIG_VSX */
#ifdef CONFIG_SPE
/* save spe registers */
Expand Down Expand Up @@ -442,7 +494,6 @@ static long restore_user_regs(struct pt_regs *regs,
unsigned int save_r2 = 0;
unsigned long msr;
#ifdef CONFIG_VSX
double buf[32];
int i;
#endif

Expand Down Expand Up @@ -490,13 +541,10 @@ static long restore_user_regs(struct pt_regs *regs,
if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
if (copy_fpr_from_user(current, &sr->mc_fregs))
return 1;

#ifdef CONFIG_VSX
if (__copy_from_user(buf, &sr->mc_fregs,sizeof(sr->mc_fregs)))
return 1;
for (i = 0; i < 32 ; i++)
current->thread.TS_FPR(i) = buf[i];
memcpy(&current->thread.fpscr, &buf[i], sizeof(double));
/*
* Force the process to reload the VSX registers from
* current->thread when it next does VSX instruction.
Expand All @@ -507,18 +555,11 @@ static long restore_user_regs(struct pt_regs *regs,
* Restore altivec registers from the stack to a local
* buffer, then write this out to the thread_struct
*/
if (__copy_from_user(buf, &sr->mc_vsregs,
sizeof(sr->mc_vsregs)))
if (copy_vsx_from_user(current, &sr->mc_vsregs))
return 1;
for (i = 0; i < 32 ; i++)
current->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i];
} else if (current->thread.used_vsr)
for (i = 0; i < 32 ; i++)
current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
#else
if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
sizeof(sr->mc_fregs)))
return 1;
#endif /* CONFIG_VSX */
/*
* force the process to reload the FP registers from
Expand Down
Loading

0 comments on commit 950f19d

Please sign in to comment.