summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-07 15:45:24 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-07 15:45:24 +0000
commit9f9f3e6e8548a596697778337110a423c384b6f3 (patch)
tree5dd4b290ef532cf5ecb058e1a92cd3435afeac8c /arch/sparc64/kernel
parentd5c9a365ee7d2fded249aa5abfc5e89587583029 (diff)
Merge with Linux 2.3.49.
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/irq.c46
-rw-r--r--arch/sparc64/kernel/pci.c7
-rw-r--r--arch/sparc64/kernel/process.c10
-rw-r--r--arch/sparc64/kernel/smp.c106
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c16
-rw-r--r--arch/sparc64/kernel/time.c43
6 files changed, 184 insertions, 44 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index ed9e49685..d2bc6baf5 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.84 2000/02/25 05:44:41 davem Exp $
+/* $Id: irq.c,v 1.85 2000/03/02 02:00:24 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -955,7 +955,7 @@ int probe_irq_off(unsigned long mask)
void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
unsigned long *clock)
{
- unsigned long flags;
+ unsigned long pstate;
extern unsigned long timer_tick_offset;
int node, err;
#ifdef __SMP__
@@ -978,31 +978,57 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
prom_halt();
}
- save_and_cli(flags);
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
/* Set things up so user can access tick register for profiling
- * purposes.
+ * purposes. Also workaround BB_ERRATA_1 by doing a dummy
+ * read back of %tick after writing it.
*/
__asm__ __volatile__("
sethi %%hi(0x80000000), %%g1
- sllx %%g1, 32, %%g1
- rd %%tick, %%g2
+ ba,pt %%xcc, 1f
+ sllx %%g1, 32, %%g1
+ .align 64
+ 1: rd %%tick, %%g2
add %%g2, 6, %%g2
andn %%g2, %%g1, %%g2
wrpr %%g2, 0, %%tick
-" : /* no outputs */
+ rdpr %%tick, %%g0"
+ : /* no outputs */
: /* no inputs */
: "g1", "g2");
+ /* Workaround for Spitfire Errata (#54 I think??), I discovered
+ * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+ * number 103640.
+ *
+ * On Blackbird writes to %tick_cmpr can fail, the
+ * workaround seems to be to execute the wr instruction
+ * at the start of an I-cache line, and perform a dummy
+ * read back from %tick_cmpr right after writing to it. -DaveM
+ */
__asm__ __volatile__("
rd %%tick, %%g1
- add %%g1, %0, %%g1
- wr %%g1, 0x0, %%tick_cmpr"
+ ba,pt %%xcc, 1f
+ add %%g1, %0, %%g1
+ .align 64
+ 1: wr %%g1, 0x0, %%tick_cmpr
+ rd %%tick_cmpr, %%g0"
: /* no outputs */
: "r" (timer_tick_offset)
: "g1");
- restore_flags(flags);
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : /* no outputs */
+ : "r" (pstate));
+
sti();
}
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 3cf95bb86..cd28d9392 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.15 2000/02/08 05:11:29 jj Exp $
+/* $Id: pci.c,v 1.16 2000/03/01 02:53:33 davem Exp $
* pci.c: UltraSparc PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -218,11 +218,6 @@ void pcibios_align_resource(void *data, struct resource *res, unsigned long size
{
}
-int pci_assign_resource(struct pci_dev *dev, int i)
-{
- return -ENOSYS; /* :-)... actually implement this soon */
-}
-
int pcibios_enable_device(struct pci_dev *pdev)
{
return 0;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 503f5b875..dd71b1e92 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.103 2000/01/21 11:38:53 jj Exp $
+/* $Id: process.c,v 1.104 2000/03/01 02:53:32 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -779,24 +779,22 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
/* User register window flush is done by entry.S */
/* Check for indirect call. */
- if(regs->u_regs[UREG_G1] == 0)
+ if (regs->u_regs[UREG_G1] == 0)
base = 1;
- lock_kernel();
filename = getname((char *)regs->u_regs[base + UREG_I0]);
error = PTR_ERR(filename);
- if(IS_ERR(filename))
+ if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char **) regs->u_regs[base + UREG_I1],
(char **) regs->u_regs[base + UREG_I2], regs);
putname(filename);
- if(!error) {
+ if (!error) {
fprs_write(0);
current->thread.xfsr[0] = 0;
current->thread.fpsaved[0] = 0;
regs->tstate &= ~TSTATE_PEF;
}
out:
- unlock_kernel();
return error;
}
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 273c12de1..175372877 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -119,6 +119,7 @@ extern void cpu_probe(void);
void __init smp_callin(void)
{
int cpuid = hard_smp_processor_id();
+ unsigned long pstate;
inherit_locked_prom_mappings(0);
@@ -127,18 +128,37 @@ void __init smp_callin(void)
cpu_probe();
- /* Master did this already, now is the time for us to do it. */
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
+
+ /* Set things up so user can access tick register for profiling
+ * purposes. Also workaround BB_ERRATA_1 by doing a dummy
+ * read back of %tick after writing it.
+ */
__asm__ __volatile__("
sethi %%hi(0x80000000), %%g1
- sllx %%g1, 32, %%g1
- rd %%tick, %%g2
+ ba,pt %%xcc, 1f
+ sllx %%g1, 32, %%g1
+ .align 64
+1: rd %%tick, %%g2
add %%g2, 6, %%g2
andn %%g2, %%g1, %%g2
wrpr %%g2, 0, %%tick
-" : /* no outputs */
+ rdpr %%tick, %%g0"
+ : /* no outputs */
: /* no inputs */
: "g1", "g2");
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : /* no outputs */
+ : "r" (pstate));
+
smp_setup_percpu_timer();
__sti();
@@ -598,7 +618,7 @@ extern void update_one_process(struct task_struct *p, unsigned long ticks,
void smp_percpu_timer_interrupt(struct pt_regs *regs)
{
- unsigned long compare, tick;
+ unsigned long compare, tick, pstate;
int cpu = smp_processor_id();
int user = user_mode(regs);
@@ -664,27 +684,87 @@ do { hardirq_enter(cpu); \
prof_counter(cpu) = prof_multiplier(cpu);
}
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
+
+ /* Workaround for Spitfire Errata (#54 I think??), I discovered
+ * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+ * number 103640.
+ *
+ * On Blackbird writes to %tick_cmpr can fail, the
+ * workaround seems to be to execute the wr instruction
+ * at the start of an I-cache line, and perform a dummy
+ * read back from %tick_cmpr right after writing to it. -DaveM
+ *
+ * Just to be anal we add a workaround for Spitfire
+ * Errata 50 by preventing pipeline bypasses on the
+ * final read of the %tick register into a compare
+ * instruction. The Errata 50 description states
+ * that %tick is not prone to this bug, but I am not
+ * taking any chances.
+ */
__asm__ __volatile__("rd %%tick_cmpr, %0\n\t"
- "add %0, %2, %0\n\t"
- "wr %0, 0x0, %%tick_cmpr\n\t"
- "rd %%tick, %1"
+ "ba,pt %%xcc, 1f\n\t"
+ " add %0, %2, %0\n\t"
+ ".align 64\n"
+ "1: wr %0, 0x0, %%tick_cmpr\n\t"
+ "rd %%tick_cmpr, %%g0\n\t"
+ "rd %%tick, %1\n\t"
+ "mov %1, %1"
: "=&r" (compare), "=r" (tick)
: "r" (current_tick_offset));
+
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : /* no outputs */
+ : "r" (pstate));
} while (tick >= compare);
}
static void __init smp_setup_percpu_timer(void)
{
int cpu = smp_processor_id();
+ unsigned long pstate;
prof_counter(cpu) = prof_multiplier(cpu) = 1;
- __asm__ __volatile__("rd %%tick, %%g1\n\t"
- "add %%g1, %0, %%g1\n\t"
- "wr %%g1, 0x0, %%tick_cmpr"
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
+
+ /* Workaround for Spitfire Errata (#54 I think??), I discovered
+ * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+ * number 103640.
+ *
+ * On Blackbird writes to %tick_cmpr can fail, the
+ * workaround seems to be to execute the wr instruction
+ * at the start of an I-cache line, and perform a dummy
+ * read back from %tick_cmpr right after writing to it. -DaveM
+ */
+ __asm__ __volatile__("
+ rd %%tick, %%g1
+ ba,pt %%xcc, 1f
+ add %%g1, %0, %%g1
+ .align 64
+ 1: wr %%g1, 0x0, %%tick_cmpr
+ rd %%tick_cmpr, %%g0"
+ : /* no outputs */
+ : "r" (current_tick_offset)
+ : "g1");
+
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
: /* no outputs */
- : "r" (current_tick_offset)
- : "g1");
+ : "r" (pstate));
}
void __init smp_tick_init(void)
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 1ebb7772c..6e2d566b2 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.132 2000/02/16 07:31:35 davem Exp $
+/* $Id: sys_sparc32.c,v 1.133 2000/03/01 02:53:33 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -3086,7 +3086,10 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
+ lock_kernel();
dentry = open_namei(filename, 0, 0);
+ unlock_kernel();
+
retval = PTR_ERR(dentry);
if (IS_ERR(dentry))
return retval;
@@ -3097,11 +3100,15 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
bprm.loader = 0;
bprm.exec = 0;
if ((bprm.argc = count32(argv)) < 0) {
+ lock_kernel();
dput(dentry);
+ unlock_kernel();
return bprm.argc;
}
if ((bprm.envc = count32(envp)) < 0) {
+ lock_kernel();
dput(dentry);
+ unlock_kernel();
return bprm.envc;
}
@@ -3129,8 +3136,11 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
out:
/* Something went wrong, return the inode and free the argument pages*/
- if (bprm.dentry)
+ if (bprm.dentry) {
+ lock_kernel();
dput(bprm.dentry);
+ unlock_kernel();
+ }
for (i=0 ; i<MAX_ARG_PAGES ; i++)
if (bprm.page[i])
@@ -3154,7 +3164,6 @@ asmlinkage int sparc32_execve(struct pt_regs *regs)
if((u32)regs->u_regs[UREG_G1] == 0)
base = 1;
- lock_kernel();
filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
error = PTR_ERR(filename);
if(IS_ERR(filename))
@@ -3171,7 +3180,6 @@ asmlinkage int sparc32_execve(struct pt_regs *regs)
regs->tstate &= ~TSTATE_PEF;
}
out:
- unlock_kernel();
return error;
}
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 57f5b1622..e599b48cb 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.23 1999/09/21 14:35:27 davem Exp $
+/* $Id: time.c,v 1.24 2000/03/02 02:00:25 davem Exp $
* time.c: UltraSparc timer and TOD clock support.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -69,20 +69,53 @@ static __inline__ void timer_check_rtc(void)
static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
- unsigned long ticks;
+ unsigned long ticks, pstate;
write_lock(&xtime_lock);
do {
do_timer(regs);
+ /* Guarentee that the following sequences execute
+ * uninterrupted.
+ */
+ __asm__ __volatile__("rdpr %%pstate, %0\n\t"
+ "wrpr %0, %1, %%pstate"
+ : "=r" (pstate)
+ : "i" (PSTATE_IE));
+
+ /* Workaround for Spitfire Errata (#54 I think??), I discovered
+ * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+ * number 103640.
+ *
+ * On Blackbird writes to %tick_cmpr can fail, the
+ * workaround seems to be to execute the wr instruction
+ * at the start of an I-cache line, and perform a dummy
+ * read back from %tick_cmpr right after writing to it. -DaveM
+ *
+ * Just to be anal we add a workaround for Spitfire
+ * Errata 50 by preventing pipeline bypasses on the
+ * final read of the %tick register into a compare
+ * instruction. The Errata 50 description states
+ * that %tick is not prone to this bug, but I am not
+ * taking any chances.
+ */
__asm__ __volatile__("
rd %%tick_cmpr, %0
- add %0, %2, %0
- wr %0, 0, %%tick_cmpr
- rd %%tick, %1"
+ ba,pt %%xcc, 1f
+ add %0, %2, %0
+ .align 64
+ 1: wr %0, 0, %%tick_cmpr
+ rd %%tick_cmpr, %%g0
+ rd %%tick, %1
+ mov %1, %1"
: "=&r" (timer_tick_compare), "=r" (ticks)
: "r" (timer_tick_offset));
+
+ /* Restore PSTATE_IE. */
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : /* no outputs */
+ : "r" (pstate));
} while (ticks >= timer_tick_compare);
timer_check_rtc();