From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Andrew Morton <akpm@osdl.org>
Cc: Linus Torvalds <torvalds@osdl.org>,
Linux Kernel list <linux-kernel@vger.kernel.org>
Subject: [PATCH] ppc32: More preempt fixes
Date: Mon, 29 Mar 2004 16:27:14 +1000 [thread overview]
Message-ID: <1080541634.1212.2.camel@gaston> (raw)
Hi !
This patch fixes more cases of possible preempt issue when testing
MSR for FP or VEC bits and then doing giveup_fpu or giveup_altivec
that I missed in my previous round of fixes (bk get helps before
grepping ;)
I also change the single step and program check exceptions to not
re-enable interrupts right away on C code entry, it was useless and
would cause interesting issues with preempt & xmon
diff -urN linux-2.5/arch/ppc/kernel/align.c linuxppc-2.5-benh/arch/ppc/kernel/align.c
--- linux-2.5/arch/ppc/kernel/align.c 2004-03-01 18:11:10.000000000 +1100
+++ linuxppc-2.5-benh/arch/ppc/kernel/align.c 2004-03-29 14:45:57.000000000 +1000
@@ -262,8 +262,12 @@
return -EFAULT; /* bad address */
}
- if ((flags & F) && (regs->msr & MSR_FP))
- giveup_fpu(current);
+ if (flags & F) {
+ preempt_disable();
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
+ preempt_enable();
+ }
if (flags & M)
return 0; /* too hard for now */
diff -urN linux-2.5/arch/ppc/kernel/head.S linuxppc-2.5-benh/arch/ppc/kernel/head.S
--- linux-2.5/arch/ppc/kernel/head.S 2004-03-12 15:53:22.000000000 +1100
+++ linuxppc-2.5-benh/arch/ppc/kernel/head.S 2004-03-29 14:52:30.000000000 +1000
@@ -462,7 +462,7 @@
EXC_XFER_EE(0x600, AlignmentException)
/* Program check exception */
- EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_EE)
+ EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
/* Floating-point unavailable */
. = 0x800
@@ -485,7 +485,7 @@
EXC_XFER_EE_LITE(0xc00, DoSyscall)
/* Single step - not used on 601 */
- EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_EE)
+ EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
/*
diff -urN linux-2.5/arch/ppc/kernel/ptrace.c linuxppc-2.5-benh/arch/ppc/kernel/ptrace.c
--- linux-2.5/arch/ppc/kernel/ptrace.c 2004-03-01 18:11:11.000000000 +1100
+++ linuxppc-2.5-benh/arch/ppc/kernel/ptrace.c 2004-03-29 14:48:22.000000000 +1000
@@ -242,8 +242,10 @@
if (index < PT_FPR0) {
tmp = get_reg(child, (int) index);
} else {
+ preempt_disable();
if (child->thread.regs->msr & MSR_FP)
giveup_fpu(child);
+ preempt_enable();
tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
}
ret = put_user(tmp,(unsigned long *) data);
@@ -276,8 +278,10 @@
if (index < PT_FPR0) {
ret = put_reg(child, index, data);
} else {
+ preempt_disable();
if (child->thread.regs->msr & MSR_FP)
giveup_fpu(child);
+ preempt_enable();
((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
ret = 0;
}
@@ -338,8 +342,10 @@
#ifdef CONFIG_ALTIVEC
case PTRACE_GETVRREGS:
/* Get the child altivec register state. */
+ preempt_disable();
if (child->thread.regs->msr & MSR_VEC)
giveup_altivec(child);
+ preempt_enable();
ret = get_vrregs((unsigned long *)data, child);
break;
@@ -347,8 +353,10 @@
/* Set the child altivec register state. */
/* this is to clear the MSR_VEC bit to force a reload
* of register state from memory */
+ preempt_disable();
if (child->thread.regs->msr & MSR_VEC)
giveup_altivec(child);
+ preempt_enable();
ret = set_vrregs(child, (unsigned long *)data);
break;
#endif
diff -urN linux-2.5/arch/ppc/kernel/signal.c linuxppc-2.5-benh/arch/ppc/kernel/signal.c
--- linux-2.5/arch/ppc/kernel/signal.c 2004-03-01 18:11:11.000000000 +1100
+++ linuxppc-2.5-benh/arch/ppc/kernel/signal.c 2004-03-29 14:51:39.000000000 +1000
@@ -191,8 +191,15 @@
{
/* save general and floating-point registers */
CHECK_FULL_REGS(regs);
+ preempt_disable();
if (regs->msr & MSR_FP)
giveup_fpu(current);
+#ifdef CONFIG_ALTIVEC
+ if (current->thread.used_vr && (regs->msr & MSR_VEC))
+ giveup_altivec(current);
+#endif /* CONFIG_ALTIVEC */
+ preempt_enable();
+
if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE)
|| __copy_to_user(&frame->mc_fregs, current->thread.fpr,
ELF_NFPREG * sizeof(double)))
@@ -203,8 +210,6 @@
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
ELF_NVRREG * sizeof(vector128)))
return 1;
reply other threads:[~2004-03-29 6:27 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1080541634.1212.2.camel@gaston \
--to=benh@kernel.crashing.org \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox