summaryrefslogtreecommitdiff
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/asm-offsets.c1
-rw-r--r--arch/sparc64/kernel/dtlb_backend.S2
-rw-r--r--arch/sparc64/kernel/entry.S661
-rw-r--r--arch/sparc64/kernel/head.S3
-rw-r--r--arch/sparc64/kernel/irq.c20
-rw-r--r--arch/sparc64/kernel/kprobes.c36
-rw-r--r--arch/sparc64/kernel/pci.c131
-rw-r--r--arch/sparc64/kernel/pci_iommu.c2
-rw-r--r--arch/sparc64/kernel/pci_psycho.c34
-rw-r--r--arch/sparc64/kernel/pci_sabre.c36
-rw-r--r--arch/sparc64/kernel/pci_schizo.c48
-rw-r--r--arch/sparc64/kernel/power.c5
-rw-r--r--arch/sparc64/kernel/process.c13
-rw-r--r--arch/sparc64/kernel/ptrace.c46
-rw-r--r--arch/sparc64/kernel/rtrap.S13
-rw-r--r--arch/sparc64/kernel/sbus.c2
-rw-r--r--arch/sparc64/kernel/setup.c13
-rw-r--r--arch/sparc64/kernel/signal.c11
-rw-r--r--arch/sparc64/kernel/signal32.c33
-rw-r--r--arch/sparc64/kernel/smp.c42
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c33
-rw-r--r--arch/sparc64/kernel/sunos_ioctl32.c9
-rw-r--r--arch/sparc64/kernel/sys32.S2
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c24
-rw-r--r--arch/sparc64/kernel/systbls.S16
-rw-r--r--arch/sparc64/kernel/time.c26
-rw-r--r--arch/sparc64/kernel/traps.c274
-rw-r--r--arch/sparc64/kernel/ttable.S27
-rw-r--r--arch/sparc64/kernel/una_asm.S153
-rw-r--r--arch/sparc64/kernel/unaligned.c279
-rw-r--r--arch/sparc64/kernel/us2e_cpufreq.c36
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c29
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S3
-rw-r--r--arch/sparc64/kernel/winfixup.S6
35 files changed, 1045 insertions, 1026 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 093281bdf85f..6f00ab8b9d23 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror
extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o setup.o cpu.o idprom.o \
- traps.o devices.o auxio.o \
+ traps.o devices.o auxio.o una_asm.o \
irq.o ptrace.o time.o sys_sparc.o signal.o \
unaligned.o central.o pci.o starfire.o semaphore.o \
power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o
diff --git a/arch/sparc64/kernel/asm-offsets.c b/arch/sparc64/kernel/asm-offsets.c
new file mode 100644
index 000000000000..9e263112a6e2
--- /dev/null
+++ b/arch/sparc64/kernel/asm-offsets.c
@@ -0,0 +1 @@
+/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S
index b73a3c858770..538522848ad4 100644
--- a/arch/sparc64/kernel/dtlb_backend.S
+++ b/arch/sparc64/kernel/dtlb_backend.S
@@ -16,7 +16,7 @@
#elif PAGE_SHIFT == 19
#define SZ_BITS _PAGE_SZ512K
#elif PAGE_SHIFT == 22
-#define SZ_BITS _PAGE_SZ4M
+#define SZ_BITS _PAGE_SZ4MB
#endif
#define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS)
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index d3973d8a7195..3e0badb820c5 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -21,8 +21,7 @@
#include <asm/visasm.h>
#include <asm/estate.h>
#include <asm/auxio.h>
-
-/* #define SYSCALL_TRACING 1 */
+#include <asm/sfafsr.h>
#define curptr g6
@@ -692,14 +691,159 @@ netbsd_syscall:
retl
nop
- /* These next few routines must be sure to clear the
- * SFSR FaultValid bit so that the fast tlb data protection
- * handler does not flush the wrong context and lock up the
- * box.
+ /* We need to carefully read the error status, ACK
+ * the errors, prevent recursive traps, and pass the
+ * information on to C code for logging.
+ *
+ * We pass the AFAR in as-is, and we encode the status
+ * information as described in asm-sparc64/sfafsr.h
+ */
+ .globl __spitfire_access_error
+__spitfire_access_error:
+ /* Disable ESTATE error reporting so that we do not
+ * take recursive traps and RED state the processor.
+ */
+ stxa %g0, [%g0] ASI_ESTATE_ERROR_EN
+ membar #Sync
+
+ mov UDBE_UE, %g1
+ ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
+
+ /* __spitfire_cee_trap branches here with AFSR in %g4 and
+ * UDBE_CE in %g1. It only clears ESTATE_ERR_CE in the
+ * ESTATE Error Enable register.
+ */
+__spitfire_cee_trap_continue:
+ ldxa [%g0] ASI_AFAR, %g5 ! Get AFAR
+
+ rdpr %tt, %g3
+ and %g3, 0x1ff, %g3 ! Paranoia
+ sllx %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3
+ or %g4, %g3, %g4
+ rdpr %tl, %g3
+ cmp %g3, 1
+ mov 1, %g3
+ bleu %xcc, 1f
+ sllx %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3
+
+ or %g4, %g3, %g4
+
+ /* Read in the UDB error register state, clearing the
+ * sticky error bits as-needed. We only clear them if
+ * the UE bit is set. Likewise, __spitfire_cee_trap
+ * below will only do so if the CE bit is set.
+ *
+ * NOTE: UltraSparc-I/II have high and low UDB error
+ * registers, corresponding to the two UDB units
+ * present on those chips. UltraSparc-IIi only
+ * has a single UDB, called "SDB" in the manual.
+ * For IIi the upper UDB register always reads
+ * as zero so for our purposes things will just
+ * work with the checks below.
*/
- .globl __do_data_access_exception
- .globl __do_data_access_exception_tl1
-__do_data_access_exception_tl1:
+1: ldxa [%g0] ASI_UDBH_ERROR_R, %g3
+ and %g3, 0x3ff, %g7 ! Paranoia
+ sllx %g7, SFSTAT_UDBH_SHIFT, %g7
+ or %g4, %g7, %g4
+ andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
+ be,pn %xcc, 1f
+ nop
+ stxa %g3, [%g0] ASI_UDB_ERROR_W
+ membar #Sync
+
+1: mov 0x18, %g3
+ ldxa [%g3] ASI_UDBL_ERROR_R, %g3
+ and %g3, 0x3ff, %g7 ! Paranoia
+ sllx %g7, SFSTAT_UDBL_SHIFT, %g7
+ or %g4, %g7, %g4
+ andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
+ be,pn %xcc, 1f
+ nop
+ mov 0x18, %g7
+ stxa %g3, [%g7] ASI_UDB_ERROR_W
+ membar #Sync
+
+1: /* Ok, now that we've latched the error state,
+ * clear the sticky bits in the AFSR.
+ */
+ stxa %g4, [%g0] ASI_AFSR
+ membar #Sync
+
+ rdpr %tl, %g2
+ cmp %g2, 1
+ rdpr %pil, %g2
+ bleu,pt %xcc, 1f
+ wrpr %g0, 15, %pil
+
+ ba,pt %xcc, etraptl1
+ rd %pc, %g7
+
+ ba,pt %xcc, 2f
+ nop
+
+1: ba,pt %xcc, etrap_irq
+ rd %pc, %g7
+
+2: mov %l4, %o1
+ mov %l5, %o2
+ call spitfire_access_error
+ add %sp, PTREGS_OFF, %o0
+ ba,pt %xcc, rtrap
+ clr %l6
+
+ /* This is the trap handler entry point for ECC correctable
+ * errors. They are corrected, but we listen for the trap
+ * so that the event can be logged.
+ *
+ * Disrupting errors are either:
+ * 1) single-bit ECC errors during UDB reads to system
+ * memory
+ * 2) data parity errors during write-back events
+ *
+ * As far as I can make out from the manual, the CEE trap
+ * is only for correctable errors during memory read
+ * accesses by the front-end of the processor.
+ *
+ * The code below is only for trap level 1 CEE events,
+ * as it is the only situation where we can safely record
+ * and log. For trap level >1 we just clear the CE bit
+ * in the AFSR and return.
+ *
+ * This is just like __spiftire_access_error above, but it
+ * specifically handles correctable errors. If an
+ * uncorrectable error is indicated in the AFSR we
+ * will branch directly above to __spitfire_access_error
+ * to handle it instead. Uncorrectable therefore takes
+ * priority over correctable, and the error logging
+ * C code will notice this case by inspecting the
+ * trap type.
+ */
+ .globl __spitfire_cee_trap
+__spitfire_cee_trap:
+ ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
+ mov 1, %g3
+ sllx %g3, SFAFSR_UE_SHIFT, %g3
+ andcc %g4, %g3, %g0 ! Check for UE
+ bne,pn %xcc, __spitfire_access_error
+ nop
+
+ /* Ok, in this case we only have a correctable error.
+ * Indicate we only wish to capture that state in register
+ * %g1, and we only disable CE error reporting unlike UE
+ * handling which disables all errors.
+ */
+ ldxa [%g0] ASI_ESTATE_ERROR_EN, %g3
+ andn %g3, ESTATE_ERR_CE, %g3
+ stxa %g3, [%g0] ASI_ESTATE_ERROR_EN
+ membar #Sync
+
+ /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */
+ ba,pt %xcc, __spitfire_cee_trap_continue
+ mov UDBE_CE, %g1
+
+ .globl __spitfire_data_access_exception
+ .globl __spitfire_data_access_exception_tl1
+__spitfire_data_access_exception_tl1:
rdpr %pstate, %g4
wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
mov TLB_SFSR, %g3
@@ -708,9 +852,25 @@ __do_data_access_exception_tl1:
ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
membar #Sync
+ rdpr %tt, %g3
+ cmp %g3, 0x80 ! first win spill/fill trap
+ blu,pn %xcc, 1f
+ cmp %g3, 0xff ! last win spill/fill trap
+ bgu,pn %xcc, 1f
+ nop
ba,pt %xcc, winfix_dax
rdpr %tpc, %g3
-__do_data_access_exception:
+1: sethi %hi(109f), %g7
+ ba,pt %xcc, etraptl1
+109: or %g7, %lo(109b), %g7
+ mov %l4, %o1
+ mov %l5, %o2
+ call spitfire_data_access_exception_tl1
+ add %sp, PTREGS_OFF, %o0
+ ba,pt %xcc, rtrap
+ clr %l6
+
+__spitfire_data_access_exception:
rdpr %pstate, %g4
wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
mov TLB_SFSR, %g3
@@ -724,20 +884,19 @@ __do_data_access_exception:
109: or %g7, %lo(109b), %g7
mov %l4, %o1
mov %l5, %o2
- call data_access_exception
+ call spitfire_data_access_exception
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
clr %l6
- .globl __do_instruction_access_exception
- .globl __do_instruction_access_exception_tl1
-__do_instruction_access_exception_tl1:
+ .globl __spitfire_insn_access_exception
+ .globl __spitfire_insn_access_exception_tl1
+__spitfire_insn_access_exception_tl1:
rdpr %pstate, %g4
wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
mov TLB_SFSR, %g3
- mov DMMU_SFAR, %g5
- ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
- ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
+ ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
+ rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
membar #Sync
sethi %hi(109f), %g7
@@ -745,18 +904,17 @@ __do_instruction_access_exception_tl1:
109: or %g7, %lo(109b), %g7
mov %l4, %o1
mov %l5, %o2
- call instruction_access_exception_tl1
+ call spitfire_insn_access_exception_tl1
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
clr %l6
-__do_instruction_access_exception:
+__spitfire_insn_access_exception:
rdpr %pstate, %g4
wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
mov TLB_SFSR, %g3
- mov DMMU_SFAR, %g5
- ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
- ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
+ ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
+ rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
membar #Sync
sethi %hi(109f), %g7
@@ -764,235 +922,11 @@ __do_instruction_access_exception:
109: or %g7, %lo(109b), %g7
mov %l4, %o1
mov %l5, %o2
- call instruction_access_exception
+ call spitfire_insn_access_exception
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
clr %l6
- /* This is the trap handler entry point for ECC correctable
- * errors. They are corrected, but we listen for the trap
- * so that the event can be logged.
- *
- * Disrupting errors are either:
- * 1) single-bit ECC errors during UDB reads to system
- * memory
- * 2) data parity errors during write-back events
- *
- * As far as I can make out from the manual, the CEE trap
- * is only for correctable errors during memory read
- * accesses by the front-end of the processor.
- *
- * The code below is only for trap level 1 CEE events,
- * as it is the only situation where we can safely record
- * and log. For trap level >1 we just clear the CE bit
- * in the AFSR and return.
- */
-
- /* Our trap handling infrastructure allows us to preserve
- * two 64-bit values during etrap for arguments to
- * subsequent C code. Therefore we encode the information
- * as follows:
- *
- * value 1) Full 64-bits of AFAR
- * value 2) Low 33-bits of AFSR, then bits 33-->42
- * are UDBL error status and bits 43-->52
- * are UDBH error status
- */
- .align 64
- .globl cee_trap
-cee_trap:
- ldxa [%g0] ASI_AFSR, %g1 ! Read AFSR
- ldxa [%g0] ASI_AFAR, %g2 ! Read AFAR
- sllx %g1, 31, %g1 ! Clear reserved bits
- srlx %g1, 31, %g1 ! in AFSR
-
- /* NOTE: UltraSparc-I/II have high and low UDB error
- * registers, corresponding to the two UDB units
- * present on those chips. UltraSparc-IIi only
- * has a single UDB, called "SDB" in the manual.
- * For IIi the upper UDB register always reads
- * as zero so for our purposes things will just
- * work with the checks below.
- */
- ldxa [%g0] ASI_UDBL_ERROR_R, %g3 ! Read UDB-Low error status
- andcc %g3, (1 << 8), %g4 ! Check CE bit
- sllx %g3, (64 - 10), %g3 ! Clear reserved bits
- srlx %g3, (64 - 10), %g3 ! in UDB-Low error status
-
- sllx %g3, (33 + 0), %g3 ! Shift up to encoding area
- or %g1, %g3, %g1 ! Or it in
- be,pn %xcc, 1f ! Branch if CE bit was clear
- nop
- stxa %g4, [%g0] ASI_UDB_ERROR_W ! Clear CE sticky bit in UDBL
- membar #Sync ! Synchronize ASI stores
-1: mov 0x18, %g5 ! Addr of UDB-High error status
- ldxa [%g5] ASI_UDBH_ERROR_R, %g3 ! Read it
-
- andcc %g3, (1 << 8), %g4 ! Check CE bit
- sllx %g3, (64 - 10), %g3 ! Clear reserved bits
- srlx %g3, (64 - 10), %g3 ! in UDB-High error status
- sllx %g3, (33 + 10), %g3 ! Shift up to encoding area
- or %g1, %g3, %g1 ! Or it in
- be,pn %xcc, 1f ! Branch if CE bit was clear
- nop
- nop
-
- stxa %g4, [%g5] ASI_UDB_ERROR_W ! Clear CE sticky bit in UDBH
- membar #Sync ! Synchronize ASI stores
-1: mov 1, %g5 ! AFSR CE bit is
- sllx %g5, 20, %g5 ! bit 20
- stxa %g5, [%g0] ASI_AFSR ! Clear CE sticky bit in AFSR
- membar #Sync ! Synchronize ASI stores
- sllx %g2, (64 - 41), %g2 ! Clear reserved bits
- srlx %g2, (64 - 41), %g2 ! in latched AFAR
-
- andn %g2, 0x0f, %g2 ! Finish resv bit clearing
- mov %g1, %g4 ! Move AFSR+UDB* into save reg
- mov %g2, %g5 ! Move AFAR into save reg
- rdpr %pil, %g2
- wrpr %g0, 15, %pil
- ba,pt %xcc, etrap_irq
- rd %pc, %g7
- mov %l4, %o0
-
- mov %l5, %o1
- call cee_log
- add %sp, PTREGS_OFF, %o2
- ba,a,pt %xcc, rtrap_irq
-
- /* Capture I/D/E-cache state into per-cpu error scoreboard.
- *
- * %g1: (TL>=0) ? 1 : 0
- * %g2: scratch
- * %g3: scratch
- * %g4: AFSR
- * %g5: AFAR
- * %g6: current thread ptr
- * %g7: scratch
- */
-#define CHEETAH_LOG_ERROR \
- /* Put "TL1" software bit into AFSR. */ \
- and %g1, 0x1, %g1; \
- sllx %g1, 63, %g2; \
- or %g4, %g2, %g4; \
- /* Get log entry pointer for this cpu at this trap level. */ \
- BRANCH_IF_JALAPENO(g2,g3,50f) \
- ldxa [%g0] ASI_SAFARI_CONFIG, %g2; \
- srlx %g2, 17, %g2; \
- ba,pt %xcc, 60f; \
- and %g2, 0x3ff, %g2; \
-50: ldxa [%g0] ASI_JBUS_CONFIG, %g2; \
- srlx %g2, 17, %g2; \
- and %g2, 0x1f, %g2; \
-60: sllx %g2, 9, %g2; \
- sethi %hi(cheetah_error_log), %g3; \
- ldx [%g3 + %lo(cheetah_error_log)], %g3; \
- brz,pn %g3, 80f; \
- nop; \
- add %g3, %g2, %g3; \
- sllx %g1, 8, %g1; \
- add %g3, %g1, %g1; \
- /* %g1 holds pointer to the top of the logging scoreboard */ \
- ldx [%g1 + 0x0], %g7; \
- cmp %g7, -1; \
- bne,pn %xcc, 80f; \
- nop; \
- stx %g4, [%g1 + 0x0]; \
- stx %g5, [%g1 + 0x8]; \
- add %g1, 0x10, %g1; \
- /* %g1 now points to D-cache logging area */ \
- set 0x3ff8, %g2; /* DC_addr mask */ \
- and %g5, %g2, %g2; /* DC_addr bits of AFAR */ \
- srlx %g5, 12, %g3; \
- or %g3, 1, %g3; /* PHYS tag + valid */ \
-10: ldxa [%g2] ASI_DCACHE_TAG, %g7; \
- cmp %g3, %g7; /* TAG match? */ \
- bne,pt %xcc, 13f; \
- nop; \
- /* Yep, what we want, capture state. */ \
- stx %g2, [%g1 + 0x20]; \
- stx %g7, [%g1 + 0x28]; \
- /* A membar Sync is required before and after utag access. */ \
- membar #Sync; \
- ldxa [%g2] ASI_DCACHE_UTAG, %g7; \
- membar #Sync; \
- stx %g7, [%g1 + 0x30]; \
- ldxa [%g2] ASI_DCACHE_SNOOP_TAG, %g7; \
- stx %g7, [%g1 + 0x38]; \
- clr %g3; \
-12: ldxa [%g2 + %g3] ASI_DCACHE_DATA, %g7; \
- stx %g7, [%g1]; \
- add %g3, (1 << 5), %g3; \
- cmp %g3, (4 << 5); \
- bl,pt %xcc, 12b; \
- add %g1, 0x8, %g1; \
- ba,pt %xcc, 20f; \
- add %g1, 0x20, %g1; \
-13: sethi %hi(1 << 14), %g7; \
- add %g2, %g7, %g2; \
- srlx %g2, 14, %g7; \
- cmp %g7, 4; \
- bl,pt %xcc, 10b; \
- nop; \
- add %g1, 0x40, %g1; \
-20: /* %g1 now points to I-cache logging area */ \
- set 0x1fe0, %g2; /* IC_addr mask */ \
- and %g5, %g2, %g2; /* IC_addr bits of AFAR */ \
- sllx %g2, 1, %g2; /* IC_addr[13:6]==VA[12:5] */ \
- srlx %g5, (13 - 8), %g3; /* Make PTAG */ \
- andn %g3, 0xff, %g3; /* Mask off undefined bits */ \
-21: ldxa [%g2] ASI_IC_TAG, %g7; \
- andn %g7, 0xff, %g7; \
- cmp %g3, %g7; \
- bne,pt %xcc, 23f; \
- nop; \
- /* Yep, what we want, capture state. */ \
- stx %g2, [%g1 + 0x40]; \
- stx %g7, [%g1 + 0x48]; \
- add %g2, (1 << 3), %g2; \
- ldxa [%g2] ASI_IC_TAG, %g7; \
- add %g2, (1 << 3), %g2; \
- stx %g7, [%g1 + 0x50]; \
- ldxa [%g2] ASI_IC_TAG, %g7; \
- add %g2, (1 << 3), %g2; \
- stx %g7, [%g1 + 0x60]; \
- ldxa [%g2] ASI_IC_TAG, %g7; \
- stx %g7, [%g1 + 0x68]; \
- sub %g2, (3 << 3), %g2; \
- ldxa [%g2] ASI_IC_STAG, %g7; \
- stx %g7, [%g1 + 0x58]; \
- clr %g3; \
- srlx %g2, 2, %g2; \
-22: ldxa [%g2 + %g3] ASI_IC_INSTR, %g7; \
- stx %g7, [%g1]; \
- add %g3, (1 << 3), %g3; \
- cmp %g3, (8 << 3); \
- bl,pt %xcc, 22b; \
- add %g1, 0x8, %g1; \
- ba,pt %xcc, 30f; \
- add %g1, 0x30, %g1; \
-23: sethi %hi(1 << 14), %g7; \
- add %g2, %g7, %g2; \
- srlx %g2, 14, %g7; \
- cmp %g7, 4; \
- bl,pt %xcc, 21b; \
- nop; \
- add %g1, 0x70, %g1; \
-30: /* %g1 now points to E-cache logging area */ \
- andn %g5, (32 - 1), %g2; /* E-cache subblock */ \
- stx %g2, [%g1 + 0x20]; \
- ldxa [%g2] ASI_EC_TAG_DATA, %g7; \
- stx %g7, [%g1 + 0x28]; \
- ldxa [%g2] ASI_EC_R, %g0; \
- clr %g3; \
-31: ldxa [%g3] ASI_EC_DATA, %g7; \
- stx %g7, [%g1 + %g3]; \
- add %g3, 0x8, %g3; \
- cmp %g3, 0x20; \
- bl,pt %xcc, 31b; \
- nop; \
-80: /* DONE */
-
/* These get patched into the trap table at boot time
* once we know we have a cheetah processor.
*/
@@ -1229,6 +1163,170 @@ dcpe_icpe_tl1_common:
membar #Sync
retry
+ /* Capture I/D/E-cache state into per-cpu error scoreboard.
+ *
+ * %g1: (TL>=0) ? 1 : 0
+ * %g2: scratch
+ * %g3: scratch
+ * %g4: AFSR
+ * %g5: AFAR
+ * %g6: current thread ptr
+ * %g7: scratch
+ */
+__cheetah_log_error:
+ /* Put "TL1" software bit into AFSR. */
+ and %g1, 0x1, %g1
+ sllx %g1, 63, %g2
+ or %g4, %g2, %g4
+
+ /* Get log entry pointer for this cpu at this trap level. */
+ BRANCH_IF_JALAPENO(g2,g3,50f)
+ ldxa [%g0] ASI_SAFARI_CONFIG, %g2
+ srlx %g2, 17, %g2
+ ba,pt %xcc, 60f
+ and %g2, 0x3ff, %g2
+
+50: ldxa [%g0] ASI_JBUS_CONFIG, %g2
+ srlx %g2, 17, %g2
+ and %g2, 0x1f, %g2
+
+60: sllx %g2, 9, %g2
+ sethi %hi(cheetah_error_log), %g3
+ ldx [%g3 + %lo(cheetah_error_log)], %g3
+ brz,pn %g3, 80f
+ nop
+
+ add %g3, %g2, %g3
+ sllx %g1, 8, %g1
+ add %g3, %g1, %g1
+
+ /* %g1 holds pointer to the top of the logging scoreboard */
+ ldx [%g1 + 0x0], %g7
+ cmp %g7, -1
+ bne,pn %xcc, 80f
+ nop
+
+ stx %g4, [%g1 + 0x0]
+ stx %g5, [%g1 + 0x8]
+ add %g1, 0x10, %g1
+
+ /* %g1 now points to D-cache logging area */
+ set 0x3ff8, %g2 /* DC_addr mask */
+ and %g5, %g2, %g2 /* DC_addr bits of AFAR */
+ srlx %g5, 12, %g3
+ or %g3, 1, %g3 /* PHYS tag + valid */
+
+10: ldxa [%g2] ASI_DCACHE_TAG, %g7
+ cmp %g3, %g7 /* TAG match? */
+ bne,pt %xcc, 13f
+ nop
+
+ /* Yep, what we want, capture state. */
+ stx %g2, [%g1 + 0x20]
+ stx %g7, [%g1 + 0x28]
+
+ /* A membar Sync is required before and after utag access. */
+ membar #Sync
+ ldxa [%g2] ASI_DCACHE_UTAG, %g7
+ membar #Sync
+ stx %g7, [%g1 + 0x30]
+ ldxa [%g2] ASI_DCACHE_SNOOP_TAG, %g7
+ stx %g7, [%g1 + 0x38]
+ clr %g3
+
+12: ldxa [%g2 + %g3] ASI_DCACHE_DATA, %g7
+ stx %g7, [%g1]
+ add %g3, (1 << 5), %g3
+ cmp %g3, (4 << 5)
+ bl,pt %xcc, 12b
+ add %g1, 0x8, %g1
+
+ ba,pt %xcc, 20f
+ add %g1, 0x20, %g1
+
+13: sethi %hi(1 << 14), %g7
+ add %g2, %g7, %g2
+ srlx %g2, 14, %g7
+ cmp %g7, 4
+ bl,pt %xcc, 10b
+ nop
+
+ add %g1, 0x40, %g1
+
+ /* %g1 now points to I-cache logging area */
+20: set 0x1fe0, %g2 /* IC_addr mask */
+ and %g5, %g2, %g2 /* IC_addr bits of AFAR */
+ sllx %g2, 1, %g2 /* IC_addr[13:6]==VA[12:5] */
+ srlx %g5, (13 - 8), %g3 /* Make PTAG */
+ andn %g3, 0xff, %g3 /* Mask off undefined bits */
+
+21: ldxa [%g2] ASI_IC_TAG, %g7
+ andn %g7, 0xff, %g7
+ cmp %g3, %g7
+ bne,pt %xcc, 23f
+ nop
+
+ /* Yep, what we want, capture state. */
+ stx %g2, [%g1 + 0x40]
+ stx %g7, [%g1 + 0x48]
+ add %g2, (1 << 3), %g2
+ ldxa [%g2] ASI_IC_TAG, %g7
+ add %g2, (1 << 3), %g2
+ stx %g7, [%g1 + 0x50]
+ ldxa [%g2] ASI_IC_TAG, %g7
+ add %g2, (1 << 3), %g2
+ stx %g7, [%g1 + 0x60]
+ ldxa [%g2] ASI_IC_TAG, %g7
+ stx %g7, [%g1 + 0x68]
+ sub %g2, (3 << 3), %g2
+ ldxa [%g2] ASI_IC_STAG, %g7
+ stx %g7, [%g1 + 0x58]
+ clr %g3
+ srlx %g2, 2, %g2
+
+22: ldxa [%g2 + %g3] ASI_IC_INSTR, %g7
+ stx %g7, [%g1]
+ add %g3, (1 << 3), %g3
+ cmp %g3, (8 << 3)
+ bl,pt %xcc, 22b
+ add %g1, 0x8, %g1
+
+ ba,pt %xcc, 30f
+ add %g1, 0x30, %g1
+
+23: sethi %hi(1 << 14), %g7
+ add %g2, %g7, %g2
+ srlx %g2, 14, %g7
+ cmp %g7, 4
+ bl,pt %xcc, 21b
+ nop
+
+ add %g1, 0x70, %g1
+
+ /* %g1 now points to E-cache logging area */
+30: andn %g5, (32 - 1), %g2
+ stx %g2, [%g1 + 0x20]
+ ldxa [%g2] ASI_EC_TAG_DATA, %g7
+ stx %g7, [%g1 + 0x28]
+ ldxa [%g2] ASI_EC_R, %g0
+ clr %g3
+
+31: ldxa [%g3] ASI_EC_DATA, %g7
+ stx %g7, [%g1 + %g3]
+ add %g3, 0x8, %g3
+ cmp %g3, 0x20
+
+ bl,pt %xcc, 31b
+ nop
+80:
+ rdpr %tt, %g2
+ cmp %g2, 0x70
+ be c_fast_ecc
+ cmp %g2, 0x63
+ be c_cee
+ nop
+ ba,pt %xcc, c_deferred
+
/* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
* in the trap table. That code has done a memory barrier
* and has disabled both the I-cache and D-cache in the DCU
@@ -1254,8 +1352,10 @@ cheetah_fast_ecc:
stxa %g4, [%g0] ASI_AFSR
membar #Sync
- CHEETAH_LOG_ERROR
+ ba,pt %xcc, __cheetah_log_error
+ nop
+c_fast_ecc:
rdpr %pil, %g2
wrpr %g0, 15, %pil
ba,pt %xcc, etrap_irq
@@ -1280,8 +1380,10 @@ cheetah_cee:
stxa %g4, [%g0] ASI_AFSR
membar #Sync
- CHEETAH_LOG_ERROR
+ ba,pt %xcc, __cheetah_log_error
+ nop
+c_cee:
rdpr %pil, %g2
wrpr %g0, 15, %pil
ba,pt %xcc, etrap_irq
@@ -1306,8 +1408,10 @@ cheetah_deferred_trap:
stxa %g4, [%g0] ASI_AFSR
membar #Sync
- CHEETAH_LOG_ERROR
+ ba,pt %xcc, __cheetah_log_error
+ nop
+c_deferred:
rdpr %pil, %g2
wrpr %g0, 15, %pil
ba,pt %xcc, etrap_irq
@@ -1554,11 +1658,12 @@ sys_ptrace: add %sp, PTREGS_OFF, %o0
nop
.align 32
1: ldx [%curptr + TI_FLAGS], %l5
- andcc %l5, _TIF_SYSCALL_TRACE, %g0
+ andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
be,pt %icc, rtrap
clr %l6
+ add %sp, PTREGS_OFF, %o0
call syscall_trace
- nop
+ mov 1, %o1
ba,pt %xcc, rtrap
clr %l6
@@ -1601,11 +1706,11 @@ sys_clone: flushw
ba,pt %xcc, sparc_do_fork
add %sp, PTREGS_OFF, %o2
ret_from_syscall:
- /* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in
- * %o7 for us. Check performance counter stuff too.
+ /* Clear current_thread_info()->new_child, and
+ * check performance counter stuff too.
*/
- andn %o7, _TIF_NEWCHILD, %l0
- stx %l0, [%g6 + TI_FLAGS]
+ stb %g0, [%g6 + TI_NEW_CHILD]
+ ldx [%g6 + TI_FLAGS], %l0
call schedule_tail
mov %g7, %o0
andcc %l0, _TIF_PERFCTR, %g0
@@ -1642,18 +1747,20 @@ linux_sparc_ni_syscall:
or %l7, %lo(sys_ni_syscall), %l7
linux_syscall_trace32:
+ add %sp, PTREGS_OFF, %o0
call syscall_trace
- nop
+ clr %o1
srl %i0, 0, %o0
- mov %i4, %o4
+ srl %i4, 0, %o4
srl %i1, 0, %o1
srl %i2, 0, %o2
b,pt %xcc, 2f
srl %i3, 0, %o3
linux_syscall_trace:
+ add %sp, PTREGS_OFF, %o0
call syscall_trace
- nop
+ clr %o1
mov %i0, %o0
mov %i1, %o1
mov %i2, %o2
@@ -1671,11 +1778,6 @@ linux_sparc_syscall32:
bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI
srl %i0, 0, %o0 ! IEU0
sll %g1, 2, %l4 ! IEU0 Group
-#ifdef SYSCALL_TRACING
- call syscall_trace_entry
- add %sp, PTREGS_OFF, %o0
- srl %i0, 0, %o0
-#endif
srl %i4, 0, %o4 ! IEU1
lduw [%l7 + %l4], %l7 ! Load
srl %i1, 0, %o1 ! IEU0 Group
@@ -1683,7 +1785,7 @@ linux_sparc_syscall32:
srl %i5, 0, %o5 ! IEU1
srl %i2, 0, %o2 ! IEU0 Group
- andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU0 Group
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
bne,pn %icc, linux_syscall_trace32 ! CTI
mov %i0, %l5 ! IEU1
call %l7 ! CTI Group brk forced
@@ -1699,11 +1801,6 @@ linux_sparc_syscall:
bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI
mov %i0, %o0 ! IEU0
sll %g1, 2, %l4 ! IEU0 Group
-#ifdef SYSCALL_TRACING
- call syscall_trace_entry
- add %sp, PTREGS_OFF, %o0
- mov %i0, %o0
-#endif
mov %i1, %o1 ! IEU1
lduw [%l7 + %l4], %l7 ! Load
4: mov %i2, %o2 ! IEU0 Group
@@ -1711,7 +1808,7 @@ linux_sparc_syscall:
mov %i3, %o3 ! IEU1
mov %i4, %o4 ! IEU0 Group
- andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU1 Group+1 bubble
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
bne,pn %icc, linux_syscall_trace ! CTI Group
mov %i0, %l5 ! IEU0
2: call %l7 ! CTI Group brk forced
@@ -1720,12 +1817,6 @@ linux_sparc_syscall:
3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
ret_sys_call:
-#ifdef SYSCALL_TRACING
- mov %o0, %o1
- call syscall_trace_exit
- add %sp, PTREGS_OFF, %o0
- mov %o1, %o0
-#endif
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
sra %o0, 0, %o0
@@ -1735,17 +1826,16 @@ ret_sys_call:
/* Check if force_successful_syscall_return()
* was invoked.
*/
- ldx [%curptr + TI_FLAGS], %l0
- andcc %l0, _TIF_SYSCALL_SUCCESS, %g0
- be,pt %icc, 1f
- andn %l0, _TIF_SYSCALL_SUCCESS, %l0
+ ldub [%curptr + TI_SYS_NOERROR], %l0
+ brz,pt %l0, 1f
+ nop
ba,pt %xcc, 80f
- stx %l0, [%curptr + TI_FLAGS]
+ stb %g0, [%curptr + TI_SYS_NOERROR]
1:
cmp %o0, -ERESTART_RESTARTBLOCK
bgeu,pn %xcc, 1f
- andcc %l0, _TIF_SYSCALL_TRACE, %l6
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
80:
/* System call success, clear Carry condition code. */
andn %g3, %g2, %g3
@@ -1760,7 +1850,7 @@ ret_sys_call:
/* System call failure, set Carry condition code.
* Also, get abs(errno) to return to the process.
*/
- andcc %l0, _TIF_SYSCALL_TRACE, %l6
+ andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
sub %g0, %o0, %o0
or %g3, %g2, %g3
stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
@@ -1773,8 +1863,9 @@ ret_sys_call:
b,pt %xcc, rtrap
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
linux_syscall_trace2:
+ add %sp, PTREGS_OFF, %o0
call syscall_trace
- nop
+ mov 1, %o1
stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
ba,pt %xcc, rtrap
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 8104a56ca2d8..1fa06c4e3bdb 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -538,11 +538,12 @@ cheetah_tlb_fixup:
nop
call cheetah_plus_patch_winfixup
nop
-
2: /* Patch copy/page operations to cheetah optimized versions. */
call cheetah_patch_copyops
nop
+ call cheetah_patch_copy_page
+ nop
call cheetah_patch_cachetlbops
nop
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index daa2fb93052c..c9b69167632a 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -782,8 +782,14 @@ static void distribute_irqs(void)
}
#endif
+struct sun5_timer {
+ u64 count0;
+ u64 limit0;
+ u64 count1;
+ u64 limit1;
+};
-struct sun5_timer *prom_timers;
+static struct sun5_timer *prom_timers;
static u64 prom_limit0, prom_limit1;
static void map_prom_timers(void)
@@ -839,18 +845,6 @@ static void kill_prom_timer(void)
: "g1", "g2");
}
-void enable_prom_timer(void)
-{
- if (!prom_timers)
- return;
-
- /* Set it to whatever was there before. */
- prom_timers->limit1 = prom_limit1;
- prom_timers->count1 = 0;
- prom_timers->limit0 = prom_limit0;
- prom_timers->count0 = 0;
-}
-
void init_irqwork_curcpu(void)
{
register struct irq_work_struct *workp asm("o2");
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index bbf11f85dab1..0d66d07c8c6e 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -8,6 +8,7 @@
#include <linux/kprobes.h>
#include <asm/kdebug.h>
#include <asm/signal.h>
+#include <asm/cacheflush.h>
/* We do not have hardware single-stepping on sparc64.
* So we implement software single-stepping with breakpoint
@@ -37,31 +38,31 @@
* - Mark that we are no longer actively in a kprobe.
*/
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
return 0;
}
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
{
p->ainsn.insn[0] = *p->addr;
p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
p->opcode = *p->addr;
}
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
{
*p->addr = BREAKPOINT_INSTRUCTION;
flushi(p->addr);
}
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
*p->addr = p->opcode;
flushi(p->addr);
}
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
{
}
@@ -111,7 +112,7 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
}
}
-static int kprobe_handler(struct pt_regs *regs)
+static int __kprobes kprobe_handler(struct pt_regs *regs)
{
struct kprobe *p;
void *addr = (void *) regs->tpc;
@@ -191,8 +192,9 @@ no_kprobe:
* The original INSN location was REAL_PC, it actually
* executed at PC and produced destination address NPC.
*/
-static unsigned long relbranch_fixup(u32 insn, unsigned long real_pc,
- unsigned long pc, unsigned long npc)
+static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc,
+ unsigned long pc,
+ unsigned long npc)
{
/* Branch not taken, no mods necessary. */
if (npc == pc + 0x4UL)
@@ -217,7 +219,8 @@ static unsigned long relbranch_fixup(u32 insn, unsigned long real_pc,
/* If INSN is an instruction which writes it's PC location
* into a destination register, fix that up.
*/
-static void retpc_fixup(struct pt_regs *regs, u32 insn, unsigned long real_pc)
+static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
+ unsigned long real_pc)
{
unsigned long *slot = NULL;
@@ -257,7 +260,7 @@ static void retpc_fixup(struct pt_regs *regs, u32 insn, unsigned long real_pc)
* This function prepares to return from the post-single-step
* breakpoint trap.
*/
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
{
u32 insn = p->ainsn.insn[0];
@@ -315,8 +318,8 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
/*
* Wrapper routine to for handling exceptions.
*/
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
- void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data)
{
struct die_args *args = (struct die_args *)data;
switch (val) {
@@ -344,7 +347,8 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
return NOTIFY_DONE;
}
-asmlinkage void kprobe_trap(unsigned long trap_level, struct pt_regs *regs)
+asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
+ struct pt_regs *regs)
{
BUG_ON(trap_level != 0x170 && trap_level != 0x171);
@@ -368,7 +372,7 @@ static struct pt_regs jprobe_saved_regs;
static struct pt_regs *jprobe_saved_regs_location;
static struct sparc_stackf jprobe_saved_stack;
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
@@ -390,7 +394,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
return 1;
}
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
{
preempt_enable_no_resched();
__asm__ __volatile__(
@@ -403,7 +407,7 @@ extern void jprobe_return_trap_instruction(void);
extern void __show_regs(struct pt_regs * regs);
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
u32 *addr = (u32 *) regs->tpc;
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index bba140d98b1b..2ff7c32ab0ce 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -359,134 +359,17 @@ void pcibios_fixup_bus(struct pci_bus *pbus)
pbus->resource[1] = &pbm->mem_space;
}
-int pci_claim_resource(struct pci_dev *pdev, int resource)
+struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r)
{
struct pci_pbm_info *pbm = pdev->bus->sysdata;
- struct resource *res = &pdev->resource[resource];
- struct resource *root;
-
- if (!pbm)
- return -EINVAL;
+ struct resource *root = NULL;
- if (res->flags & IORESOURCE_IO)
+ if (r->flags & IORESOURCE_IO)
root = &pbm->io_space;
- else
+ if (r->flags & IORESOURCE_MEM)
root = &pbm->mem_space;
- pbm->parent->resource_adjust(pdev, res, root);
-
- return request_resource(root, res);
-}
-
-/*
- * Given the PCI bus a device resides on, try to
- * find an acceptable resource allocation for a
- * specific device resource..
- */
-static int pci_assign_bus_resource(const struct pci_bus *bus,
- struct pci_dev *dev,
- struct resource *res,
- unsigned long size,
- unsigned long min,
- int resno)
-{
- unsigned int type_mask;
- int i;
-
- type_mask = IORESOURCE_IO | IORESOURCE_MEM;
- for (i = 0 ; i < 4; i++) {
- struct resource *r = bus->resource[i];
- if (!r)
- continue;
-
- /* type_mask must match */
- if ((res->flags ^ r->flags) & type_mask)
- continue;
-
- /* Ok, try it out.. */
- if (allocate_resource(r, res, size, min, -1, size, NULL, NULL) < 0)
- continue;
-
- /* PCI config space updated by caller. */
- return 0;
- }
- return -EBUSY;
-}
-
-int pci_assign_resource(struct pci_dev *pdev, int resource)
-{
- struct pcidev_cookie *pcp = pdev->sysdata;
- struct pci_pbm_info *pbm = pcp->pbm;
- struct resource *res = &pdev->resource[resource];
- unsigned long min, size;
- int err;
-
- if (res->flags & IORESOURCE_IO)
- min = pbm->io_space.start + 0x400UL;
- else
- min = pbm->mem_space.start;
-
- size = res->end - res->start + 1;
-
- err = pci_assign_bus_resource(pdev->bus, pdev, res, size, min, resource);
-
- if (err < 0) {
- printk("PCI: Failed to allocate resource %d for %s\n",
- resource, pci_name(pdev));
- } else {
- /* Update PCI config space. */
- pbm->parent->base_address_update(pdev, resource);
- }
-
- return err;
-}
-
-/* Sort resources by alignment */
-void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
-{
- int i;
-
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- struct resource *r;
- struct resource_list *list, *tmp;
- unsigned long r_align;
-
- r = &dev->resource[i];
- r_align = r->end - r->start;
-
- if (!(r->flags) || r->parent)
- continue;
- if (!r_align) {
- printk(KERN_WARNING "PCI: Ignore bogus resource %d "
- "[%lx:%lx] of %s\n",
- i, r->start, r->end, pci_name(dev));
- continue;
- }
- r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
- for (list = head; ; list = list->next) {
- unsigned long align = 0;
- struct resource_list *ln = list->next;
- int idx;
-
- if (ln) {
- idx = ln->res - &ln->dev->resource[0];
- align = (idx < PCI_BRIDGE_RESOURCES) ?
- ln->res->end - ln->res->start + 1 :
- ln->res->start;
- }
- if (r_align > align) {
- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
- if (!tmp)
- panic("pdev_sort_resources(): "
- "kmalloc() failed!\n");
- tmp->next = ln;
- tmp->res = r;
- tmp->dev = dev;
- list->next = tmp;
- break;
- }
- }
- }
+ return root;
}
void pcibios_update_irq(struct pci_dev *pdev, int irq)
@@ -540,6 +423,7 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
pbm->parent->resource_adjust(pdev, res, root);
}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
char * __init pcibios_setup(char *str)
{
@@ -735,8 +619,7 @@ static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma
static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state)
{
- /* Our io_remap_page_range/io_remap_pfn_range takes care of this,
- do nothing. */
+ /* Our io_remap_pfn_range takes care of this, do nothing. */
}
/* Perform the actual remap of the pages for a PCI device mapping, as appropriate
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 2803bc7c2c79..425c60cfea19 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -466,7 +466,7 @@ do_flush_sync:
if (!limit)
break;
udelay(1);
- membar("#LoadLoad");
+ rmb();
}
if (!limit)
printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 91ab466d6c66..6ed1ef25e0ac 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -307,7 +307,7 @@ static unsigned char psycho_pil_table[] = {
/*0x32*/15, /* Power Management */
};
-static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
@@ -344,9 +344,9 @@ static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
return ret;
}
-static unsigned int __init psycho_irq_build(struct pci_pbm_info *pbm,
- struct pci_dev *pdev,
- unsigned int ino)
+static unsigned int psycho_irq_build(struct pci_pbm_info *pbm,
+ struct pci_dev *pdev,
+ unsigned int ino)
{
struct ino_bucket *bucket;
unsigned long imap, iclr;
@@ -1024,7 +1024,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
#define PSYCHO_CE_INO 0x2f
#define PSYCHO_PCIERR_A_INO 0x30
#define PSYCHO_PCIERR_B_INO 0x31
-static void __init psycho_register_error_handlers(struct pci_controller_info *p)
+static void psycho_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
unsigned long base = p->pbm_A.controller_regs;
@@ -1091,15 +1091,15 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
}
/* PSYCHO boot time probing and initialization. */
-static void __init psycho_resource_adjust(struct pci_dev *pdev,
- struct resource *res,
- struct resource *root)
+static void psycho_resource_adjust(struct pci_dev *pdev,
+ struct resource *res,
+ struct resource *root)
{
res->start += root->start;
res->end += root->start;
}
-static void __init psycho_base_address_update(struct pci_dev *pdev, int resource)
+static void psycho_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
@@ -1144,7 +1144,7 @@ static void __init psycho_base_address_update(struct pci_dev *pdev, int resource
pci_write_config_dword(pdev, where + 4, 0);
}
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
{
u8 *addr;
@@ -1161,8 +1161,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
pci_config_write8(addr, 64);
}
-static void __init pbm_scan_bus(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_scan_bus(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
@@ -1189,7 +1189,7 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
pci_setup_busmastering(pbm, pbm->pci_bus);
}
-static void __init psycho_scan_bus(struct pci_controller_info *p)
+static void psycho_scan_bus(struct pci_controller_info *p)
{
pbm_config_busmastering(&p->pbm_B);
p->pbm_B.is_66mhz_capable = 0;
@@ -1204,7 +1204,7 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
psycho_register_error_handlers(p);
}
-static void __init psycho_iommu_init(struct pci_controller_info *p)
+static void psycho_iommu_init(struct pci_controller_info *p)
{
struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i;
@@ -1327,8 +1327,8 @@ static void psycho_controller_hwinit(struct pci_controller_info *p)
psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp);
}
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
char *name = pbm->name;
@@ -1481,7 +1481,7 @@ static void psycho_pbm_init(struct pci_controller_info *p,
#define PSYCHO_CONFIGSPACE 0x001000000UL
-void __init psycho_init(int node, char *model_name)
+void psycho_init(int node, char *model_name)
{
struct linux_prom64_registers pr_regs[3];
struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 52bf3431a422..0ee6bd5b9ac6 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -554,7 +554,7 @@ static unsigned char sabre_pil_table[] = {
/*0x32*/15, /* Power Management */
};
-static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
@@ -612,9 +612,9 @@ static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_a
sabre_read(sync_reg);
}
-static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
- struct pci_dev *pdev,
- unsigned int ino)
+static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
+ struct pci_dev *pdev,
+ unsigned int ino)
{
struct ino_bucket *bucket;
unsigned long imap, iclr;
@@ -1009,7 +1009,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
#define SABRE_UE_INO 0x2e
#define SABRE_CE_INO 0x2f
#define SABRE_PCIERR_INO 0x30
-static void __init sabre_register_error_handlers(struct pci_controller_info *p)
+static void sabre_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
unsigned long base = pbm->controller_regs;
@@ -1056,9 +1056,9 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
sabre_write(base + SABRE_PCICTRL, tmp);
}
-static void __init sabre_resource_adjust(struct pci_dev *pdev,
- struct resource *res,
- struct resource *root)
+static void sabre_resource_adjust(struct pci_dev *pdev,
+ struct resource *res,
+ struct resource *root)
{
struct pci_pbm_info *pbm = pdev->bus->sysdata;
unsigned long base;
@@ -1072,7 +1072,7 @@ static void __init sabre_resource_adjust(struct pci_dev *pdev,
res->end += base;
}
-static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
+static void sabre_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
@@ -1118,7 +1118,7 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
pci_write_config_dword(pdev, where + 4, 0);
}
-static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
+static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
{
struct pci_dev *pdev;
@@ -1181,7 +1181,7 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
return cookie;
}
-static void __init sabre_scan_bus(struct pci_controller_info *p)
+static void sabre_scan_bus(struct pci_controller_info *p)
{
static int once;
struct pci_bus *sabre_bus, *pbus;
@@ -1262,9 +1262,9 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
sabre_register_error_handlers(p);
}
-static void __init sabre_iommu_init(struct pci_controller_info *p,
- int tsbsize, unsigned long dvma_offset,
- u32 dma_mask)
+static void sabre_iommu_init(struct pci_controller_info *p,
+ int tsbsize, unsigned long dvma_offset,
+ u32 dma_mask)
{
struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i, order;
@@ -1345,8 +1345,8 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
}
}
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
char *name = pbm->name;
unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE;
@@ -1415,7 +1415,7 @@ static void __init pbm_register_toplevel_resources(struct pci_controller_info *p
&pbm->mem_space);
}
-static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
+static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
{
struct pci_pbm_info *pbm;
char namebuf[128];
@@ -1552,7 +1552,7 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node,
}
}
-void __init sabre_init(int pnode, char *model_name)
+void sabre_init(int pnode, char *model_name)
{
struct linux_prom64_registers pr_regs[2];
struct pci_controller_info *p;
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index 6a182bb66281..331382e1a75d 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -285,7 +285,7 @@ static unsigned char schizo_pil_table[] = {
/*0x3f*/0, /* Reserved for NewLink */
};
-static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
{
int ret;
@@ -1221,7 +1221,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
* PCI bus units of the same Tomatillo. I still have not really
* figured this out...
*/
-static void __init tomatillo_register_error_handlers(struct pci_controller_info *p)
+static void tomatillo_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm;
unsigned int irq;
@@ -1359,7 +1359,7 @@ static void __init tomatillo_register_error_handlers(struct pci_controller_info
(SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
}
-static void __init schizo_register_error_handlers(struct pci_controller_info *p)
+static void schizo_register_error_handlers(struct pci_controller_info *p)
{
struct pci_pbm_info *pbm;
unsigned int irq;
@@ -1505,7 +1505,7 @@ static void __init schizo_register_error_handlers(struct pci_controller_info *p)
(SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)));
}
-static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+static void pbm_config_busmastering(struct pci_pbm_info *pbm)
{
u8 *addr;
@@ -1522,8 +1522,8 @@ static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
pci_config_write8(addr, 64);
}
-static void __init pbm_scan_bus(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_scan_bus(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
@@ -1550,8 +1550,8 @@ static void __init pbm_scan_bus(struct pci_controller_info *p,
pci_setup_busmastering(pbm, pbm->pci_bus);
}
-static void __init __schizo_scan_bus(struct pci_controller_info *p,
- int chip_type)
+static void __schizo_scan_bus(struct pci_controller_info *p,
+ int chip_type)
{
if (!p->pbm_B.prom_node || !p->pbm_A.prom_node) {
printk("PCI: Only one PCI bus module of controller found.\n");
@@ -1577,17 +1577,17 @@ static void __init __schizo_scan_bus(struct pci_controller_info *p,
schizo_register_error_handlers(p);
}
-static void __init schizo_scan_bus(struct pci_controller_info *p)
+static void schizo_scan_bus(struct pci_controller_info *p)
{
__schizo_scan_bus(p, PBM_CHIP_TYPE_SCHIZO);
}
-static void __init tomatillo_scan_bus(struct pci_controller_info *p)
+static void tomatillo_scan_bus(struct pci_controller_info *p)
{
__schizo_scan_bus(p, PBM_CHIP_TYPE_TOMATILLO);
}
-static void __init schizo_base_address_update(struct pci_dev *pdev, int resource)
+static void schizo_base_address_update(struct pci_dev *pdev, int resource)
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
@@ -1632,9 +1632,9 @@ static void __init schizo_base_address_update(struct pci_dev *pdev, int resource
pci_write_config_dword(pdev, where + 4, 0);
}
-static void __init schizo_resource_adjust(struct pci_dev *pdev,
- struct resource *res,
- struct resource *root)
+static void schizo_resource_adjust(struct pci_dev *pdev,
+ struct resource *res,
+ struct resource *root)
{
res->start += root->start;
res->end += root->start;
@@ -1702,8 +1702,8 @@ static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm)
pbm->mem_space.start);
}
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
- struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
{
pbm->io_space.name = pbm->mem_space.name = pbm->name;
@@ -1932,7 +1932,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
#define TOMATILLO_PCI_IOC_TDIAG (0x2250UL)
#define TOMATILLO_PCI_IOC_DDIAG (0x2290UL)
-static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
+static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
{
u64 tmp;
@@ -1986,9 +1986,9 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm)
}
}
-static void __init schizo_pbm_init(struct pci_controller_info *p,
- int prom_node, u32 portid,
- int chip_type)
+static void schizo_pbm_init(struct pci_controller_info *p,
+ int prom_node, u32 portid,
+ int chip_type)
{
struct linux_prom64_registers pr_regs[4];
unsigned int busrange[2];
@@ -2145,7 +2145,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
return (x == y);
}
-static void __init __schizo_init(int node, char *model_name, int chip_type)
+static void __schizo_init(int node, char *model_name, int chip_type)
{
struct pci_controller_info *p;
struct pci_iommu *iommu;
@@ -2213,17 +2213,17 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
schizo_pbm_init(p, node, portid, chip_type);
}
-void __init schizo_init(int node, char *model_name)
+void schizo_init(int node, char *model_name)
{
__schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO);
}
-void __init schizo_plus_init(int node, char *model_name)
+void schizo_plus_init(int node, char *model_name)
{
__schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
}
-void __init tomatillo_init(int node, char *model_name)
+void tomatillo_init(int node, char *model_name)
{
__schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO);
}
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 52f14e399b1c..946cee0257ea 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -4,6 +4,8 @@
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
*/
+#define __KERNEL_SYSCALLS__
+
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -17,7 +19,6 @@
#include <asm/ebus.h>
#include <asm/auxio.h>
-#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
/*
@@ -68,8 +69,6 @@ void machine_power_off(void)
machine_halt();
}
-EXPORT_SYMBOL(machine_power_off);
-
#ifdef CONFIG_PCI
static int powerd(void *__unused)
{
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index a0cd2b2494d6..7d10b0397091 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -103,7 +103,7 @@ void cpu_idle(void)
* other cpus see our increasing idleness for the buddy
* redistribution algorithm. -DaveM
*/
- membar("#StoreStore | #StoreLoad");
+ membar_storeload_storestore();
}
}
@@ -124,8 +124,6 @@ void machine_halt(void)
panic("Halt failed!");
}
-EXPORT_SYMBOL(machine_halt);
-
void machine_alt_power_off(void)
{
if (!serial_console && prom_palette)
@@ -154,8 +152,6 @@ void machine_restart(char * cmd)
panic("Reboot failed!");
}
-EXPORT_SYMBOL(machine_restart);
-
static void show_regwindow32(struct pt_regs *regs)
{
struct reg_window32 __user *rw;
@@ -611,18 +607,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
struct thread_info *t = p->thread_info;
char *child_trap_frame;
-#ifdef CONFIG_DEBUG_SPINLOCK
- p->thread.smp_lock_count = 0;
- p->thread.smp_lock_pc = 0;
-#endif
-
/* Calculate offset to stack_frame & pt_regs */
child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+STACKFRAME_SZ));
memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ));
t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
- _TIF_NEWCHILD |
(((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT);
+ t->new_child = 1;
t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf));
t->fpsaved[0] = 0;
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 80a76e2ad732..23ad839d113f 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -19,6 +19,8 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/security.h>
+#include <linux/seccomp.h>
+#include <linux/audit.h>
#include <linux/signal.h>
#include <asm/asi.h>
@@ -628,15 +630,27 @@ out:
unlock_kernel();
}
-asmlinkage void syscall_trace(void)
+asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p)
{
-#ifdef DEBUG_PTRACE
- printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
-#endif
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
+ /* do the secure computing check first */
+ secure_computing(regs->u_regs[UREG_G1]);
+
+ if (unlikely(current->audit_context) && syscall_exit_p) {
+ unsigned long tstate = regs->tstate;
+ int result = AUDITSC_SUCCESS;
+
+ if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
+ result = AUDITSC_FAILURE;
+
+ audit_syscall_exit(current, result, regs->u_regs[UREG_I0]);
+ }
+
if (!(current->ptrace & PT_PTRACED))
- return;
+ goto out;
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ goto out;
+
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
@@ -645,12 +659,20 @@ asmlinkage void syscall_trace(void)
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
-#ifdef DEBUG_PTRACE
- printk("%s [%d]: syscall_trace exit= %x\n", current->comm,
- current->pid, current->exit_code);
-#endif
if (current->exit_code) {
- send_sig (current->exit_code, current, 1);
+ send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
+
+out:
+ if (unlikely(current->audit_context) && !syscall_exit_p)
+ audit_syscall_entry(current,
+ (test_thread_flag(TIF_32BIT) ?
+ AUDIT_ARCH_SPARC :
+ AUDIT_ARCH_SPARC64),
+ regs->u_regs[UREG_G1],
+ regs->u_regs[UREG_I0],
+ regs->u_regs[UREG_I1],
+ regs->u_regs[UREG_I2],
+ regs->u_regs[UREG_I3]);
}
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 0696ed4b9d64..fafd227735fa 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -153,11 +153,14 @@ __handle_signal:
rtrap_irq:
rtrap_clr_l6: clr %l6
rtrap:
- ldub [%g6 + TI_CPU], %l0
- sethi %hi(irq_stat), %l2 ! &softirq_active
- or %l2, %lo(irq_stat), %l2 ! &softirq_active
-irqsz_patchme: sllx %l0, 0, %l0
- lduw [%l2 + %l0], %l1 ! softirq_pending
+#ifndef CONFIG_SMP
+ sethi %hi(per_cpu____cpu_data), %l0
+ lduw [%l0 + %lo(per_cpu____cpu_data)], %l1
+#else
+ sethi %hi(per_cpu____cpu_data), %l0
+ or %l0, %lo(per_cpu____cpu_data), %l0
+ lduw [%l0 + %g5], %l1
+#endif
cmp %l1, 0
/* mm/ultra.S:xcall_report_regs KNOWS about this load. */
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 89f5e019f24c..e09ddf927655 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -147,7 +147,7 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long
if (!limit)
break;
udelay(1);
- membar("#LoadLoad");
+ rmb();
}
if (!limit)
printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index b7e6a91952b2..ddbed3341a23 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -33,7 +33,6 @@
#include <linux/cpu.h>
#include <linux/initrd.h>
-#include <asm/segment.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/processor.h>
@@ -512,18 +511,6 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &prom_con;
#endif
-#ifdef CONFIG_SMP
- i = (unsigned long)&irq_stat[1] - (unsigned long)&irq_stat[0];
- if ((i == SMP_CACHE_BYTES) || (i == (2 * SMP_CACHE_BYTES))) {
- extern unsigned int irqsz_patchme[1];
- irqsz_patchme[0] |= ((i == SMP_CACHE_BYTES) ? SMP_CACHE_BYTES_SHIFT : \
- SMP_CACHE_BYTES_SHIFT + 1);
- flushi((long)&irqsz_patchme[0]);
- } else {
- prom_printf("Unexpected size of irq_stat[] elements\n");
- prom_halt();
- }
-#endif
/* Work out if we are starfire early on */
check_if_starfire();
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index b27934671c35..60f5dfabb1e1 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -574,13 +574,12 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
{
setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
- if (!(ka->sa.sa_flags & SA_NOMASK)) {
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NOMASK))
sigaddset(&current->blocked,signr);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- }
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
}
static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index f28428f4170e..aecccd0df1d1 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -877,11 +877,12 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
unsigned long page = (unsigned long)
page_address(pte_page(*ptep));
- __asm__ __volatile__(
- " membar #StoreStore\n"
- " flush %0 + %1"
- : : "r" (page), "r" (address & (PAGE_SIZE - 1))
- : "memory");
+ wmb();
+ __asm__ __volatile__("flush %0 + %1"
+ : /* no outputs */
+ : "r" (page),
+ "r" (address & (PAGE_SIZE - 1))
+ : "memory");
}
pte_unmap(ptep);
preempt_enable();
@@ -1292,11 +1293,12 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
unsigned long page = (unsigned long)
page_address(pte_page(*ptep));
- __asm__ __volatile__(
- " membar #StoreStore\n"
- " flush %0 + %1"
- : : "r" (page), "r" (address & (PAGE_SIZE - 1))
- : "memory");
+ wmb();
+ __asm__ __volatile__("flush %0 + %1"
+ : /* no outputs */
+ : "r" (page),
+ "r" (address & (PAGE_SIZE - 1))
+ : "memory");
}
pte_unmap(ptep);
preempt_enable();
@@ -1325,13 +1327,12 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
else
setup_frame32(&ka->sa, regs, signr, oldset, info);
}
- if (!(ka->sa.sa_flags & SA_NOMASK)) {
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NOMASK))
sigaddset(&current->blocked,signr);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- }
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
}
static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index e5b9c7a27789..b4fc6a5462b2 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -45,8 +45,8 @@ extern void calibrate_delay(void);
/* Please don't make this stuff initdata!!! --DaveM */
static unsigned char boot_cpu_id;
-cpumask_t cpu_online_map = CPU_MASK_NONE;
-cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
+cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
+cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE;
static cpumask_t smp_commenced_mask;
static cpumask_t cpu_callout_map;
@@ -137,14 +137,14 @@ void __init smp_callin(void)
/* Clear this or we will die instantly when we
* schedule back to this idler...
*/
- clear_thread_flag(TIF_NEWCHILD);
+ current_thread_info()->new_child = 0;
/* Attach to the address space of init_task. */
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
while (!cpu_isset(cpuid, smp_commenced_mask))
- membar("#LoadLoad");
+ rmb();
cpu_set(cpuid, cpu_online_map);
}
@@ -155,7 +155,7 @@ void cpu_panic(void)
panic("SMP bolixed\n");
}
-static unsigned long current_tick_offset;
+static unsigned long current_tick_offset __read_mostly;
/* This tick register synchronization scheme is taken entirely from
* the ia64 port, see arch/ia64/kernel/smpboot.c for details and credit.
@@ -184,11 +184,11 @@ static inline long get_delta (long *rt, long *master)
for (i = 0; i < NUM_ITERS; i++) {
t0 = tick_ops->get_tick();
go[MASTER] = 1;
- membar("#StoreLoad");
+ membar_storeload();
while (!(tm = go[SLAVE]))
- membar("#LoadLoad");
+ rmb();
go[SLAVE] = 0;
- membar("#StoreStore");
+ wmb();
t1 = tick_ops->get_tick();
if (t1 - t0 < best_t1 - best_t0)
@@ -221,7 +221,7 @@ void smp_synchronize_tick_client(void)
go[MASTER] = 1;
while (go[MASTER])
- membar("#LoadLoad");
+ rmb();
local_irq_save(flags);
{
@@ -273,21 +273,21 @@ static void smp_synchronize_one_tick(int cpu)
/* wait for client to be ready */
while (!go[MASTER])
- membar("#LoadLoad");
+ rmb();
/* now let the client proceed into his loop */
go[MASTER] = 0;
- membar("#StoreLoad");
+ membar_storeload();
spin_lock_irqsave(&itc_sync_lock, flags);
{
for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) {
while (!go[MASTER])
- membar("#LoadLoad");
+ rmb();
go[MASTER] = 0;
- membar("#StoreStore");
+ wmb();
go[SLAVE] = tick_ops->get_tick();
- membar("#StoreLoad");
+ membar_storeload();
}
}
spin_unlock_irqrestore(&itc_sync_lock, flags);
@@ -927,11 +927,11 @@ void smp_capture(void)
smp_processor_id());
#endif
penguins_are_doing_time = 1;
- membar("#StoreStore | #LoadStore");
+ membar_storestore_loadstore();
atomic_inc(&smp_capture_registry);
smp_cross_call(&xcall_capture, 0, 0, 0);
while (atomic_read(&smp_capture_registry) != ncpus)
- membar("#LoadLoad");
+ rmb();
#ifdef CAPTURE_DEBUG
printk("done\n");
#endif
@@ -947,7 +947,7 @@ void smp_release(void)
smp_processor_id());
#endif
penguins_are_doing_time = 0;
- membar("#StoreStore | #StoreLoad");
+ membar_storeload_storestore();
atomic_dec(&smp_capture_registry);
}
}
@@ -970,9 +970,9 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
save_alternate_globals(global_save);
prom_world(1);
atomic_inc(&smp_capture_registry);
- membar("#StoreLoad | #StoreStore");
+ membar_storeload_storestore();
while (penguins_are_doing_time)
- membar("#LoadLoad");
+ rmb();
restore_alternate_globals(global_save);
atomic_dec(&smp_capture_registry);
prom_world(0);
@@ -1193,8 +1193,8 @@ void smp_send_stop(void)
{
}
-unsigned long __per_cpu_base;
-unsigned long __per_cpu_shift;
+unsigned long __per_cpu_base __read_mostly;
+unsigned long __per_cpu_shift __read_mostly;
EXPORT_SYMBOL(__per_cpu_base);
EXPORT_SYMBOL(__per_cpu_shift);
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 56cd96f4a5cd..cbb5e59824e5 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -79,7 +79,7 @@ extern void linux_sparc_syscall(void);
extern void rtrap(void);
extern void show_regs(struct pt_regs *);
extern void solaris_syscall(void);
-extern void syscall_trace(void);
+extern void syscall_trace(struct pt_regs *, int);
extern u32 sunos_sys_table[], sys_call_table32[];
extern void tl0_solaris(void);
extern void sys_sigsuspend(void);
@@ -88,8 +88,6 @@ extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
extern long sparc32_open(const char __user * filename, int flags, int mode);
-extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from,
- unsigned long offset, unsigned long size, pgprot_t prot, int space);
extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long pfn, unsigned long size, pgprot_t prot);
extern void (*prom_palette)(int);
@@ -99,17 +97,6 @@ extern int __ashrdi3(int, int);
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs);
-#if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK)
-extern void _do_spin_lock (spinlock_t *lock, char *str);
-extern void _do_spin_unlock (spinlock_t *lock);
-extern int _spin_trylock (spinlock_t *lock);
-extern void _do_read_lock(rwlock_t *rw, char *str);
-extern void _do_read_unlock(rwlock_t *rw, char *str);
-extern void _do_write_lock(rwlock_t *rw, char *str);
-extern void _do_write_unlock(rwlock_t *rw);
-extern int _do_write_trylock(rwlock_t *rw, char *str);
-#endif
-
extern unsigned long phys_base;
extern unsigned long pfn_base;
@@ -128,17 +115,12 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data);
/* used by various drivers */
#ifdef CONFIG_SMP
-#ifndef CONFIG_DEBUG_SPINLOCK
/* Out of line rw-locking implementation. */
EXPORT_SYMBOL(__read_lock);
EXPORT_SYMBOL(__read_unlock);
EXPORT_SYMBOL(__write_lock);
EXPORT_SYMBOL(__write_unlock);
EXPORT_SYMBOL(__write_trylock);
-/* Out of line spin-locking implementation. */
-EXPORT_SYMBOL(_raw_spin_lock);
-EXPORT_SYMBOL(_raw_spin_lock_flags);
-#endif
/* Hard IRQ locking */
EXPORT_SYMBOL(synchronize_irq);
@@ -152,18 +134,6 @@ EXPORT_SYMBOL(_mcount);
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(phys_cpu_present_map);
-/* Spinlock debugging library, optional. */
-#ifdef CONFIG_DEBUG_SPINLOCK
-EXPORT_SYMBOL(_do_spin_lock);
-EXPORT_SYMBOL(_do_spin_unlock);
-EXPORT_SYMBOL(_spin_trylock);
-EXPORT_SYMBOL(_do_read_lock);
-EXPORT_SYMBOL(_do_read_unlock);
-EXPORT_SYMBOL(_do_write_lock);
-EXPORT_SYMBOL(_do_write_unlock);
-EXPORT_SYMBOL(_do_write_trylock);
-#endif
-
EXPORT_SYMBOL(smp_call_function);
#endif /* CONFIG_SMP */
@@ -268,7 +238,6 @@ EXPORT_SYMBOL(pci_dma_supported);
#endif
/* I/O device mmaping on Sparc64. */
-EXPORT_SYMBOL(io_remap_page_range);
EXPORT_SYMBOL(io_remap_pfn_range);
/* Solaris/SunOS binary compatibility */
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
index 87c1aeb02220..7654b8a7f03a 100644
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ b/arch/sparc64/kernel/sunos_ioctl32.c
@@ -152,11 +152,12 @@ asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg);
goto out;
- case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */
- ret = sys_ioctl(fd, SIOCSIFMTU, arg);
+ case _IOW('i', 21, struct ifreq32):
+ ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg);
goto out;
- case _IOWR('i', 22, struct ifreq): /* SIOCGIFMTU */
- ret = sys_ioctl(fd, SIOCGIFMTU, arg);
+
+ case _IOWR('i', 22, struct ifreq32):
+ ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg);
goto out;
case _IOWR('i', 23, struct ifreq32):
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index 5a95e98c5317..5f9e4fae612e 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -135,6 +135,8 @@ SIGN2(sys32_shutdown, sys_shutdown, %o0, %o1)
SIGN3(sys32_socketpair, sys_socketpair, %o0, %o1, %o2)
SIGN1(sys32_getpeername, sys_getpeername, %o0)
SIGN1(sys32_getsockname, sys_getsockname, %o0)
+SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
+SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
.globl sys32_mmap2
sys32_mmap2:
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 1d3aa588df8a..7f6239ed2521 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1002,29 +1002,7 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
asmlinkage long sparc32_open(const char __user *filename,
int flags, int mode)
{
- char * tmp;
- int fd, error;
-
- tmp = getname(filename);
- fd = PTR_ERR(tmp);
- if (!IS_ERR(tmp)) {
- fd = get_unused_fd();
- if (fd >= 0) {
- struct file * f = filp_open(tmp, flags, mode);
- error = PTR_ERR(f);
- if (IS_ERR(f))
- goto out_error;
- fd_install(fd, f);
- }
-out:
- putname(tmp);
- }
- return fd;
-
-out_error:
- put_unused_fd(fd);
- fd = error;
- goto out;
+ return do_sys_open(filename, flags, mode);
}
extern unsigned long do_mremap(unsigned long addr,
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index a5e36a4c8924..53eaf2345fe9 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -50,8 +50,8 @@ sys_call_table32:
.word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64
/*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
.word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- .word compat_sys_fcntl64, sys_ni_syscall, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
+/*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+ .word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
/*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall
.word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr
/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents
@@ -59,11 +59,11 @@ sys_call_table32:
/*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
.word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname
/*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl
- .word sys32_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
+ .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask
/*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir
.word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64
/*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, sys32_sysinfo
- .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
+ .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, sys32_adjtimex
/*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid
.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
/*230*/ .word sys32_select, compat_sys_time, sys_nis_syscall, compat_sys_stime, compat_sys_statfs64
@@ -116,8 +116,8 @@ sys_call_table:
.word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
/*140*/ .word sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, sys_getrlimit
.word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/ .word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
- .word sys_nis_syscall, sys_ni_syscall, sys_statfs, sys_fstatfs, sys_oldumount
+/*150*/ .word sys_getsockname, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+ .word sys_nis_syscall, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount
/*160*/ .word sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_utrap_install
.word sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
@@ -125,11 +125,11 @@ sys_call_table:
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
/*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
- .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
+ .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
/*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
- .word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex
+ .word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
/*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index b40db389f90b..3f08a32f51a1 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -73,7 +73,7 @@ static __initdata struct sparc64_tick_ops dummy_tick_ops = {
.get_tick = dummy_get_tick,
};
-struct sparc64_tick_ops *tick_ops = &dummy_tick_ops;
+struct sparc64_tick_ops *tick_ops __read_mostly = &dummy_tick_ops;
#define TICK_PRIV_BIT (1UL << 63)
@@ -195,7 +195,7 @@ static unsigned long tick_add_tick(unsigned long adj, unsigned long offset)
return new_tick;
}
-static struct sparc64_tick_ops tick_operations = {
+static struct sparc64_tick_ops tick_operations __read_mostly = {
.init_tick = tick_init_tick,
.get_tick = tick_get_tick,
.get_compare = tick_get_compare,
@@ -276,7 +276,7 @@ static unsigned long stick_add_compare(unsigned long adj)
return new_compare;
}
-static struct sparc64_tick_ops stick_operations = {
+static struct sparc64_tick_ops stick_operations __read_mostly = {
.init_tick = stick_init_tick,
.get_tick = stick_get_tick,
.get_compare = stick_get_compare,
@@ -422,7 +422,7 @@ static unsigned long hbtick_add_compare(unsigned long adj)
return val;
}
-static struct sparc64_tick_ops hbtick_operations = {
+static struct sparc64_tick_ops hbtick_operations __read_mostly = {
.init_tick = hbtick_init_tick,
.get_tick = hbtick_get_tick,
.get_compare = hbtick_get_compare,
@@ -437,10 +437,9 @@ static struct sparc64_tick_ops hbtick_operations = {
* NOTE: On SUN5 systems the ticker interrupt comes in using 2
* interrupts, one at level14 and one with softint bit 0.
*/
-unsigned long timer_tick_offset;
-unsigned long timer_tick_compare;
+unsigned long timer_tick_offset __read_mostly;
-static unsigned long timer_ticks_per_nsec_quotient;
+static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
#define TICK_SIZE (tick_nsec / 1000)
@@ -450,7 +449,7 @@ static inline void timer_check_rtc(void)
static long last_rtc_update;
/* Determine when to update the Mostek clock. */
- if ((time_status & STA_UNSYNC) == 0 &&
+ if (ntp_synced() &&
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
@@ -464,7 +463,7 @@ static inline void timer_check_rtc(void)
static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
- unsigned long ticks, pstate;
+ unsigned long ticks, compare, pstate;
write_seqlock(&xtime_lock);
@@ -483,14 +482,14 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
: "=r" (pstate)
: "i" (PSTATE_IE));
- timer_tick_compare = tick_ops->add_compare(timer_tick_offset);
+ compare = tick_ops->add_compare(timer_tick_offset);
ticks = tick_ops->get_tick();
/* Restore PSTATE_IE. */
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
: /* no outputs */
: "r" (pstate));
- } while (time_after_eq(ticks, timer_tick_compare));
+ } while (time_after_eq(ticks, compare));
timer_check_rtc();
@@ -506,11 +505,6 @@ void timer_tick_interrupt(struct pt_regs *regs)
do_timer(regs);
- /*
- * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR.
- */
- timer_tick_compare = tick_ops->get_compare() + timer_tick_offset;
-
timer_check_rtc();
write_sequnlock(&xtime_lock);
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index a9f4596d7c2b..b280b2ef674f 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -33,6 +33,7 @@
#include <asm/dcu.h>
#include <asm/estate.h>
#include <asm/chafsr.h>
+#include <asm/sfafsr.h>
#include <asm/psrcompat.h>
#include <asm/processor.h>
#include <asm/timer.h>
@@ -143,8 +144,7 @@ void do_BUG(const char *file, int line)
}
#endif
-void instruction_access_exception(struct pt_regs *regs,
- unsigned long sfsr, unsigned long sfar)
+void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar)
{
siginfo_t info;
@@ -153,8 +153,8 @@ void instruction_access_exception(struct pt_regs *regs,
return;
if (regs->tstate & TSTATE_PRIV) {
- printk("instruction_access_exception: SFSR[%016lx] SFAR[%016lx], going.\n",
- sfsr, sfar);
+ printk("spitfire_insn_access_exception: SFSR[%016lx] "
+ "SFAR[%016lx], going.\n", sfsr, sfar);
die_if_kernel("Iax", regs);
}
if (test_thread_flag(TIF_32BIT)) {
@@ -169,19 +169,17 @@ void instruction_access_exception(struct pt_regs *regs,
force_sig_info(SIGSEGV, &info, current);
}
-void instruction_access_exception_tl1(struct pt_regs *regs,
- unsigned long sfsr, unsigned long sfar)
+void spitfire_insn_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar)
{
if (notify_die(DIE_TRAP_TL1, "instruction access exception tl1", regs,
0, 0x8, SIGTRAP) == NOTIFY_STOP)
return;
dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
- instruction_access_exception(regs, sfsr, sfar);
+ spitfire_insn_access_exception(regs, sfsr, sfar);
}
-void data_access_exception(struct pt_regs *regs,
- unsigned long sfsr, unsigned long sfar)
+void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar)
{
siginfo_t info;
@@ -207,8 +205,8 @@ void data_access_exception(struct pt_regs *regs,
return;
}
/* Shit... */
- printk("data_access_exception: SFSR[%016lx] SFAR[%016lx], going.\n",
- sfsr, sfar);
+ printk("spitfire_data_access_exception: SFSR[%016lx] "
+ "SFAR[%016lx], going.\n", sfsr, sfar);
die_if_kernel("Dax", regs);
}
@@ -220,6 +218,16 @@ void data_access_exception(struct pt_regs *regs,
force_sig_info(SIGSEGV, &info, current);
}
+void spitfire_data_access_exception_tl1(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar)
+{
+ if (notify_die(DIE_TRAP_TL1, "data access exception tl1", regs,
+ 0, 0x30, SIGTRAP) == NOTIFY_STOP)
+ return;
+
+ dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
+ spitfire_data_access_exception(regs, sfsr, sfar);
+}
+
#ifdef CONFIG_PCI
/* This is really pathetic... */
extern volatile int pci_poke_in_progress;
@@ -253,54 +261,13 @@ static void spitfire_clean_and_reenable_l1_caches(void)
: "memory");
}
-void do_iae(struct pt_regs *regs)
+static void spitfire_enable_estate_errors(void)
{
- siginfo_t info;
-
- spitfire_clean_and_reenable_l1_caches();
-
- if (notify_die(DIE_TRAP, "instruction access exception", regs,
- 0, 0x8, SIGTRAP) == NOTIFY_STOP)
- return;
-
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = BUS_OBJERR;
- info.si_addr = (void *)0;
- info.si_trapno = 0;
- force_sig_info(SIGBUS, &info, current);
-}
-
-void do_dae(struct pt_regs *regs)
-{
- siginfo_t info;
-
-#ifdef CONFIG_PCI
- if (pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) {
- spitfire_clean_and_reenable_l1_caches();
-
- pci_poke_faulted = 1;
-
- /* Why the fuck did they have to change this? */
- if (tlb_type == cheetah || tlb_type == cheetah_plus)
- regs->tpc += 4;
-
- regs->tnpc = regs->tpc + 4;
- return;
- }
-#endif
- spitfire_clean_and_reenable_l1_caches();
-
- if (notify_die(DIE_TRAP, "data access exception", regs,
- 0, 0x30, SIGTRAP) == NOTIFY_STOP)
- return;
-
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = BUS_OBJERR;
- info.si_addr = (void *)0;
- info.si_trapno = 0;
- force_sig_info(SIGBUS, &info, current);
+ __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (ESTATE_ERR_ALL),
+ "i" (ASI_ESTATE_ERROR_EN));
}
static char ecc_syndrome_table[] = {
@@ -338,65 +305,15 @@ static char ecc_syndrome_table[] = {
0x0b, 0x48, 0x48, 0x4b, 0x48, 0x4b, 0x4b, 0x4a
};
-/* cee_trap in entry.S encodes AFSR/UDBH/UDBL error status
- * in the following format. The AFAR is left as is, with
- * reserved bits cleared, and is a raw 40-bit physical
- * address.
- */
-#define CE_STATUS_UDBH_UE (1UL << (43 + 9))
-#define CE_STATUS_UDBH_CE (1UL << (43 + 8))
-#define CE_STATUS_UDBH_ESYNDR (0xffUL << 43)
-#define CE_STATUS_UDBH_SHIFT 43
-#define CE_STATUS_UDBL_UE (1UL << (33 + 9))
-#define CE_STATUS_UDBL_CE (1UL << (33 + 8))
-#define CE_STATUS_UDBL_ESYNDR (0xffUL << 33)
-#define CE_STATUS_UDBL_SHIFT 33
-#define CE_STATUS_AFSR_MASK (0x1ffffffffUL)
-#define CE_STATUS_AFSR_ME (1UL << 32)
-#define CE_STATUS_AFSR_PRIV (1UL << 31)
-#define CE_STATUS_AFSR_ISAP (1UL << 30)
-#define CE_STATUS_AFSR_ETP (1UL << 29)
-#define CE_STATUS_AFSR_IVUE (1UL << 28)
-#define CE_STATUS_AFSR_TO (1UL << 27)
-#define CE_STATUS_AFSR_BERR (1UL << 26)
-#define CE_STATUS_AFSR_LDP (1UL << 25)
-#define CE_STATUS_AFSR_CP (1UL << 24)
-#define CE_STATUS_AFSR_WP (1UL << 23)
-#define CE_STATUS_AFSR_EDP (1UL << 22)
-#define CE_STATUS_AFSR_UE (1UL << 21)
-#define CE_STATUS_AFSR_CE (1UL << 20)
-#define CE_STATUS_AFSR_ETS (0xfUL << 16)
-#define CE_STATUS_AFSR_ETS_SHIFT 16
-#define CE_STATUS_AFSR_PSYND (0xffffUL << 0)
-#define CE_STATUS_AFSR_PSYND_SHIFT 0
-
-/* Layout of Ecache TAG Parity Syndrome of AFSR */
-#define AFSR_ETSYNDROME_7_0 0x1UL /* E$-tag bus bits <7:0> */
-#define AFSR_ETSYNDROME_15_8 0x2UL /* E$-tag bus bits <15:8> */
-#define AFSR_ETSYNDROME_21_16 0x4UL /* E$-tag bus bits <21:16> */
-#define AFSR_ETSYNDROME_24_22 0x8UL /* E$-tag bus bits <24:22> */
-
static char *syndrome_unknown = "<Unknown>";
-asmlinkage void cee_log(unsigned long ce_status,
- unsigned long afar,
- struct pt_regs *regs)
+static void spitfire_log_udb_syndrome(unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long bit)
{
- char memmod_str[64];
- char *p;
- unsigned short scode, udb_reg;
+ unsigned short scode;
+ char memmod_str[64], *p;
- printk(KERN_WARNING "CPU[%d]: Correctable ECC Error "
- "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx]\n",
- smp_processor_id(),
- (ce_status & CE_STATUS_AFSR_MASK),
- afar,
- ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL),
- ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL));
-
- udb_reg = ((ce_status >> CE_STATUS_UDBL_SHIFT) & 0x3ffUL);
- if (udb_reg & (1 << 8)) {
- scode = ecc_syndrome_table[udb_reg & 0xff];
+ if (udbl & bit) {
+ scode = ecc_syndrome_table[udbl & 0xff];
if (prom_getunumber(scode, afar,
memmod_str, sizeof(memmod_str)) == -1)
p = syndrome_unknown;
@@ -407,9 +324,8 @@ asmlinkage void cee_log(unsigned long ce_status,
smp_processor_id(), scode, p);
}
- udb_reg = ((ce_status >> CE_STATUS_UDBH_SHIFT) & 0x3ffUL);
- if (udb_reg & (1 << 8)) {
- scode = ecc_syndrome_table[udb_reg & 0xff];
+ if (udbh & bit) {
+ scode = ecc_syndrome_table[udbh & 0xff];
if (prom_getunumber(scode, afar,
memmod_str, sizeof(memmod_str)) == -1)
p = syndrome_unknown;
@@ -419,6 +335,127 @@ asmlinkage void cee_log(unsigned long ce_status,
"Memory Module \"%s\"\n",
smp_processor_id(), scode, p);
}
+
+}
+
+static void spitfire_cee_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, int tl1, struct pt_regs *regs)
+{
+
+ printk(KERN_WARNING "CPU[%d]: Correctable ECC Error "
+ "AFSR[%lx] AFAR[%016lx] UDBL[%lx] UDBH[%lx] TL>1[%d]\n",
+ smp_processor_id(), afsr, afar, udbl, udbh, tl1);
+
+ spitfire_log_udb_syndrome(afar, udbh, udbl, UDBE_CE);
+
+ /* We always log it, even if someone is listening for this
+ * trap.
+ */
+ notify_die(DIE_TRAP, "Correctable ECC Error", regs,
+ 0, TRAP_TYPE_CEE, SIGTRAP);
+
+ /* The Correctable ECC Error trap does not disable I/D caches. So
+ * we only have to restore the ESTATE Error Enable register.
+ */
+ spitfire_enable_estate_errors();
+}
+
+static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long tt, int tl1, struct pt_regs *regs)
+{
+ siginfo_t info;
+
+ printk(KERN_WARNING "CPU[%d]: Uncorrectable Error AFSR[%lx] "
+ "AFAR[%lx] UDBL[%lx] UDBH[%ld] TT[%lx] TL>1[%d]\n",
+ smp_processor_id(), afsr, afar, udbl, udbh, tt, tl1);
+
+ /* XXX add more human friendly logging of the error status
+ * XXX as is implemented for cheetah
+ */
+
+ spitfire_log_udb_syndrome(afar, udbh, udbl, UDBE_UE);
+
+ /* We always log it, even if someone is listening for this
+ * trap.
+ */
+ notify_die(DIE_TRAP, "Uncorrectable Error", regs,
+ 0, tt, SIGTRAP);
+
+ if (regs->tstate & TSTATE_PRIV) {
+ if (tl1)
+ dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
+ die_if_kernel("UE", regs);
+ }
+
+ /* XXX need more intelligent processing here, such as is implemented
+ * XXX for cheetah errors, in fact if the E-cache still holds the
+ * XXX line with bad parity this will loop
+ */
+
+ spitfire_clean_and_reenable_l1_caches();
+ spitfire_enable_estate_errors();
+
+ if (test_thread_flag(TIF_32BIT)) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_OBJERR;
+ info.si_addr = (void *)0;
+ info.si_trapno = 0;
+ force_sig_info(SIGBUS, &info, current);
+}
+
+void spitfire_access_error(struct pt_regs *regs, unsigned long status_encoded, unsigned long afar)
+{
+ unsigned long afsr, tt, udbh, udbl;
+ int tl1;
+
+ afsr = (status_encoded & SFSTAT_AFSR_MASK) >> SFSTAT_AFSR_SHIFT;
+ tt = (status_encoded & SFSTAT_TRAP_TYPE) >> SFSTAT_TRAP_TYPE_SHIFT;
+ tl1 = (status_encoded & SFSTAT_TL_GT_ONE) ? 1 : 0;
+ udbl = (status_encoded & SFSTAT_UDBL_MASK) >> SFSTAT_UDBL_SHIFT;
+ udbh = (status_encoded & SFSTAT_UDBH_MASK) >> SFSTAT_UDBH_SHIFT;
+
+#ifdef CONFIG_PCI
+ if (tt == TRAP_TYPE_DAE &&
+ pci_poke_in_progress && pci_poke_cpu == smp_processor_id()) {
+ spitfire_clean_and_reenable_l1_caches();
+ spitfire_enable_estate_errors();
+
+ pci_poke_faulted = 1;
+ regs->tnpc = regs->tpc + 4;
+ return;
+ }
+#endif
+
+ if (afsr & SFAFSR_UE)
+ spitfire_ue_log(afsr, afar, udbh, udbl, tt, tl1, regs);
+
+ if (tt == TRAP_TYPE_CEE) {
+ /* Handle the case where we took a CEE trap, but ACK'd
+ * only the UE state in the UDB error registers.
+ */
+ if (afsr & SFAFSR_UE) {
+ if (udbh & UDBE_CE) {
+ __asm__ __volatile__(
+ "stxa %0, [%1] %2\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (udbh & UDBE_CE),
+ "r" (0x0), "i" (ASI_UDB_ERROR_W));
+ }
+ if (udbl & UDBE_CE) {
+ __asm__ __volatile__(
+ "stxa %0, [%1] %2\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (udbl & UDBE_CE),
+ "r" (0x18), "i" (ASI_UDB_ERROR_W));
+ }
+ }
+
+ spitfire_cee_log(afsr, afar, udbh, udbl, tl1, regs);
+ }
}
int cheetah_pcache_forced_on;
@@ -2125,6 +2162,11 @@ void __init trap_init(void)
TI_PCR != offsetof(struct thread_info, pcr_reg) ||
TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) ||
TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
+ TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
+ TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) ||
+ TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) ||
+ TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) ||
+ TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) ||
TI_FPREGS != offsetof(struct thread_info, fpregs) ||
(TI_FPREGS & (64 - 1)))
thread_info_offsets_are_bolixed_dave();
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S
index 491bb3681f9d..8365bc1f81f3 100644
--- a/arch/sparc64/kernel/ttable.S
+++ b/arch/sparc64/kernel/ttable.S
@@ -18,9 +18,10 @@ sparc64_ttable_tl0:
tl0_resv000: BOOT_KERNEL BTRAP(0x1) BTRAP(0x2) BTRAP(0x3)
tl0_resv004: BTRAP(0x4) BTRAP(0x5) BTRAP(0x6) BTRAP(0x7)
tl0_iax: membar #Sync
- TRAP_NOSAVE_7INSNS(__do_instruction_access_exception)
+ TRAP_NOSAVE_7INSNS(__spitfire_insn_access_exception)
tl0_resv009: BTRAP(0x9)
-tl0_iae: TRAP(do_iae)
+tl0_iae: membar #Sync
+ TRAP_NOSAVE_7INSNS(__spitfire_access_error)
tl0_resv00b: BTRAP(0xb) BTRAP(0xc) BTRAP(0xd) BTRAP(0xe) BTRAP(0xf)
tl0_ill: membar #Sync
TRAP_7INSNS(do_illegal_instruction)
@@ -36,9 +37,10 @@ tl0_cwin: CLEAN_WINDOW
tl0_div0: TRAP(do_div0)
tl0_resv029: BTRAP(0x29) BTRAP(0x2a) BTRAP(0x2b) BTRAP(0x2c) BTRAP(0x2d) BTRAP(0x2e)
tl0_resv02f: BTRAP(0x2f)
-tl0_dax: TRAP_NOSAVE(__do_data_access_exception)
+tl0_dax: TRAP_NOSAVE(__spitfire_data_access_exception)
tl0_resv031: BTRAP(0x31)
-tl0_dae: TRAP(do_dae)
+tl0_dae: membar #Sync
+ TRAP_NOSAVE_7INSNS(__spitfire_access_error)
tl0_resv033: BTRAP(0x33)
tl0_mna: TRAP_NOSAVE(do_mna)
tl0_lddfmna: TRAP_NOSAVE(do_lddfmna)
@@ -73,7 +75,8 @@ tl0_resv05c: BTRAP(0x5c) BTRAP(0x5d) BTRAP(0x5e) BTRAP(0x5f)
tl0_ivec: TRAP_IVEC
tl0_paw: TRAP(do_paw)
tl0_vaw: TRAP(do_vaw)
-tl0_cee: TRAP_NOSAVE(cee_trap)
+tl0_cee: membar #Sync
+ TRAP_NOSAVE_7INSNS(__spitfire_cee_trap)
tl0_iamiss:
#include "itlb_base.S"
tl0_damiss:
@@ -175,9 +178,10 @@ tl0_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8)
sparc64_ttable_tl1:
tl1_resv000: BOOT_KERNEL BTRAPTL1(0x1) BTRAPTL1(0x2) BTRAPTL1(0x3)
tl1_resv004: BTRAPTL1(0x4) BTRAPTL1(0x5) BTRAPTL1(0x6) BTRAPTL1(0x7)
-tl1_iax: TRAP_NOSAVE(__do_instruction_access_exception_tl1)
+tl1_iax: TRAP_NOSAVE(__spitfire_insn_access_exception_tl1)
tl1_resv009: BTRAPTL1(0x9)
-tl1_iae: TRAPTL1(do_iae_tl1)
+tl1_iae: membar #Sync
+ TRAP_NOSAVE_7INSNS(__spitfire_access_error)
tl1_resv00b: BTRAPTL1(0xb) BTRAPTL1(0xc) BTRAPTL1(0xd) BTRAPTL1(0xe) BTRAPTL1(0xf)
tl1_ill: TRAPTL1(do_ill_tl1)
tl1_privop: BTRAPTL1(0x11)
@@ -193,9 +197,10 @@ tl1_cwin: CLEAN_WINDOW
tl1_div0: TRAPTL1(do_div0_tl1)
tl1_resv029: BTRAPTL1(0x29) BTRAPTL1(0x2a) BTRAPTL1(0x2b) BTRAPTL1(0x2c)
tl1_resv02d: BTRAPTL1(0x2d) BTRAPTL1(0x2e) BTRAPTL1(0x2f)
-tl1_dax: TRAP_NOSAVE(__do_data_access_exception_tl1)
+tl1_dax: TRAP_NOSAVE(__spitfire_data_access_exception_tl1)
tl1_resv031: BTRAPTL1(0x31)
-tl1_dae: TRAPTL1(do_dae_tl1)
+tl1_dae: membar #Sync
+ TRAP_NOSAVE_7INSNS(__spitfire_access_error)
tl1_resv033: BTRAPTL1(0x33)
tl1_mna: TRAP_NOSAVE(do_mna)
tl1_lddfmna: TRAPTL1(do_lddfmna_tl1)
@@ -219,8 +224,8 @@ tl1_paw: TRAPTL1(do_paw_tl1)
tl1_vaw: TRAPTL1(do_vaw_tl1)
/* The grotty trick to save %g1 into current->thread.cee_stuff
- * is because when we take this trap we could be interrupting trap
- * code already using the trap alternate global registers.
+ * is because when we take this trap we could be interrupting
+ * trap code already using the trap alternate global registers.
*
* We cross our fingers and pray that this store/load does
* not cause yet another CEE trap.
diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S
new file mode 100644
index 000000000000..cbb40585253c
--- /dev/null
+++ b/arch/sparc64/kernel/una_asm.S
@@ -0,0 +1,153 @@
+/* una_asm.S: Kernel unaligned trap assembler helpers.
+ *
+ * Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+ .text
+
+kernel_unaligned_trap_fault:
+ call kernel_mna_trap_fault
+ nop
+ retl
+ nop
+ .size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault
+
+ .globl __do_int_store
+__do_int_store:
+ rd %asi, %o4
+ wr %o3, 0, %asi
+ ldx [%o2], %g3
+ cmp %o1, 2
+ be,pn %icc, 2f
+ cmp %o1, 4
+ be,pt %icc, 1f
+ srlx %g3, 24, %g2
+ srlx %g3, 56, %g1
+ srlx %g3, 48, %g7
+4: stba %g1, [%o0] %asi
+ srlx %g3, 40, %g1
+5: stba %g7, [%o0 + 1] %asi
+ srlx %g3, 32, %g7
+6: stba %g1, [%o0 + 2] %asi
+7: stba %g7, [%o0 + 3] %asi
+ srlx %g3, 16, %g1
+8: stba %g2, [%o0 + 4] %asi
+ srlx %g3, 8, %g7
+9: stba %g1, [%o0 + 5] %asi
+10: stba %g7, [%o0 + 6] %asi
+ ba,pt %xcc, 0f
+11: stba %g3, [%o0 + 7] %asi
+1: srl %g3, 16, %g7
+12: stba %g2, [%o0] %asi
+ srl %g3, 8, %g2
+13: stba %g7, [%o0 + 1] %asi
+14: stba %g2, [%o0 + 2] %asi
+ ba,pt %xcc, 0f
+15: stba %g3, [%o0 + 3] %asi
+2: srl %g3, 8, %g2
+16: stba %g2, [%o0] %asi
+17: stba %g3, [%o0 + 1] %asi
+0:
+ wr %o4, 0x0, %asi
+ retl
+ nop
+ .size __do_int_store, .-__do_int_store
+
+ .section __ex_table
+ .word 4b, kernel_unaligned_trap_fault
+ .word 5b, kernel_unaligned_trap_fault
+ .word 6b, kernel_unaligned_trap_fault
+ .word 7b, kernel_unaligned_trap_fault
+ .word 8b, kernel_unaligned_trap_fault
+ .word 9b, kernel_unaligned_trap_fault
+ .word 10b, kernel_unaligned_trap_fault
+ .word 11b, kernel_unaligned_trap_fault
+ .word 12b, kernel_unaligned_trap_fault
+ .word 13b, kernel_unaligned_trap_fault
+ .word 14b, kernel_unaligned_trap_fault
+ .word 15b, kernel_unaligned_trap_fault
+ .word 16b, kernel_unaligned_trap_fault
+ .word 17b, kernel_unaligned_trap_fault
+ .previous
+
+ .globl do_int_load
+do_int_load:
+ rd %asi, %o5
+ wr %o4, 0, %asi
+ cmp %o1, 8
+ bge,pn %icc, 9f
+ cmp %o1, 4
+ be,pt %icc, 6f
+4: lduba [%o2] %asi, %g2
+5: lduba [%o2 + 1] %asi, %g3
+ sll %g2, 8, %g2
+ brz,pt %o3, 3f
+ add %g2, %g3, %g2
+ sllx %g2, 48, %g2
+ srax %g2, 48, %g2
+3: ba,pt %xcc, 0f
+ stx %g2, [%o0]
+6: lduba [%o2 + 1] %asi, %g3
+ sll %g2, 24, %g2
+7: lduba [%o2 + 2] %asi, %g7
+ sll %g3, 16, %g3
+8: lduba [%o2 + 3] %asi, %g1
+ sll %g7, 8, %g7
+ or %g2, %g3, %g2
+ or %g7, %g1, %g7
+ or %g2, %g7, %g2
+ brnz,a,pt %o3, 3f
+ sra %g2, 0, %g2
+3: ba,pt %xcc, 0f
+ stx %g2, [%o0]
+9: lduba [%o2] %asi, %g2
+10: lduba [%o2 + 1] %asi, %g3
+ sllx %g2, 56, %g2
+11: lduba [%o2 + 2] %asi, %g7
+ sllx %g3, 48, %g3
+12: lduba [%o2 + 3] %asi, %g1
+ sllx %g7, 40, %g7
+ sllx %g1, 32, %g1
+ or %g2, %g3, %g2
+ or %g7, %g1, %g7
+13: lduba [%o2 + 4] %asi, %g3
+ or %g2, %g7, %g7
+14: lduba [%o2 + 5] %asi, %g1
+ sllx %g3, 24, %g3
+15: lduba [%o2 + 6] %asi, %g2
+ sllx %g1, 16, %g1
+ or %g7, %g3, %g7
+16: lduba [%o2 + 7] %asi, %g3
+ sllx %g2, 8, %g2
+ or %g7, %g1, %g7
+ or %g2, %g3, %g2
+ or %g7, %g2, %g7
+ cmp %o1, 8
+ be,a,pt %icc, 0f
+ stx %g7, [%o0]
+ srlx %g7, 32, %g2
+ sra %g7, 0, %g7
+ stx %g2, [%o0]
+ stx %g7, [%o0 + 8]
+0:
+ wr %o5, 0x0, %asi
+ retl
+ nop
+ .size __do_int_load, .-__do_int_load
+
+ .section __ex_table
+ .word 4b, kernel_unaligned_trap_fault
+ .word 5b, kernel_unaligned_trap_fault
+ .word 6b, kernel_unaligned_trap_fault
+ .word 7b, kernel_unaligned_trap_fault
+ .word 8b, kernel_unaligned_trap_fault
+ .word 9b, kernel_unaligned_trap_fault
+ .word 10b, kernel_unaligned_trap_fault
+ .word 11b, kernel_unaligned_trap_fault
+ .word 12b, kernel_unaligned_trap_fault
+ .word 13b, kernel_unaligned_trap_fault
+ .word 14b, kernel_unaligned_trap_fault
+ .word 15b, kernel_unaligned_trap_fault
+ .word 16b, kernel_unaligned_trap_fault
+ .previous
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 4372bf32ecf6..da9739f0d437 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -180,169 +180,28 @@ static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs)
die_if_kernel(str, regs);
}
-#define do_integer_load(dest_reg, size, saddr, is_signed, asi, errh) ({ \
-__asm__ __volatile__ ( \
- "wr %4, 0, %%asi\n\t" \
- "cmp %1, 8\n\t" \
- "bge,pn %%icc, 9f\n\t" \
- " cmp %1, 4\n\t" \
- "be,pt %%icc, 6f\n" \
-"4:\t" " lduba [%2] %%asi, %%l1\n" \
-"5:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
- "sll %%l1, 8, %%l1\n\t" \
- "brz,pt %3, 3f\n\t" \
- " add %%l1, %%l2, %%l1\n\t" \
- "sllx %%l1, 48, %%l1\n\t" \
- "srax %%l1, 48, %%l1\n" \
-"3:\t" "ba,pt %%xcc, 0f\n\t" \
- " stx %%l1, [%0]\n" \
-"6:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
- "sll %%l1, 24, %%l1\n" \
-"7:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \
- "sll %%l2, 16, %%l2\n" \
-"8:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \
- "sll %%g7, 8, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%g7, %%l1\n\t" \
- "brnz,a,pt %3, 3f\n\t" \
- " sra %%l1, 0, %%l1\n" \
-"3:\t" "ba,pt %%xcc, 0f\n\t" \
- " stx %%l1, [%0]\n" \
-"9:\t" "lduba [%2] %%asi, %%l1\n" \
-"10:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
- "sllx %%l1, 56, %%l1\n" \
-"11:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \
- "sllx %%l2, 48, %%l2\n" \
-"12:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \
- "sllx %%g7, 40, %%g7\n\t" \
- "sllx %%g1, 32, %%g1\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n" \
-"13:\t" "lduba [%2 + 4] %%asi, %%l2\n\t" \
- "or %%l1, %%g7, %%g7\n" \
-"14:\t" "lduba [%2 + 5] %%asi, %%g1\n\t" \
- "sllx %%l2, 24, %%l2\n" \
-"15:\t" "lduba [%2 + 6] %%asi, %%l1\n\t" \
- "sllx %%g1, 16, %%g1\n\t" \
- "or %%g7, %%l2, %%g7\n" \
-"16:\t" "lduba [%2 + 7] %%asi, %%l2\n\t" \
- "sllx %%l1, 8, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%l1, %%g7\n\t" \
- "cmp %1, 8\n\t" \
- "be,a,pt %%icc, 0f\n\t" \
- " stx %%g7, [%0]\n\t" \
- "srlx %%g7, 32, %%l1\n\t" \
- "sra %%g7, 0, %%g7\n\t" \
- "stx %%l1, [%0]\n\t" \
- "stx %%g7, [%0 + 8]\n" \
-"0:\n\t" \
- "wr %%g0, %5, %%asi\n\n\t" \
- ".section __ex_table\n\t" \
- ".word 4b, " #errh "\n\t" \
- ".word 5b, " #errh "\n\t" \
- ".word 6b, " #errh "\n\t" \
- ".word 7b, " #errh "\n\t" \
- ".word 8b, " #errh "\n\t" \
- ".word 9b, " #errh "\n\t" \
- ".word 10b, " #errh "\n\t" \
- ".word 11b, " #errh "\n\t" \
- ".word 12b, " #errh "\n\t" \
- ".word 13b, " #errh "\n\t" \
- ".word 14b, " #errh "\n\t" \
- ".word 15b, " #errh "\n\t" \
- ".word 16b, " #errh "\n\n\t" \
- ".previous\n\t" \
- : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed), \
- "r" (asi), "i" (ASI_AIUS) \
- : "l1", "l2", "g7", "g1", "cc"); \
-})
+extern void do_int_load(unsigned long *dest_reg, int size,
+ unsigned long *saddr, int is_signed, int asi);
-#define store_common(dst_addr, size, src_val, asi, errh) ({ \
-__asm__ __volatile__ ( \
- "wr %3, 0, %%asi\n\t" \
- "ldx [%2], %%l1\n" \
- "cmp %1, 2\n\t" \
- "be,pn %%icc, 2f\n\t" \
- " cmp %1, 4\n\t" \
- "be,pt %%icc, 1f\n\t" \
- " srlx %%l1, 24, %%l2\n\t" \
- "srlx %%l1, 56, %%g1\n\t" \
- "srlx %%l1, 48, %%g7\n" \
-"4:\t" "stba %%g1, [%0] %%asi\n\t" \
- "srlx %%l1, 40, %%g1\n" \
-"5:\t" "stba %%g7, [%0 + 1] %%asi\n\t" \
- "srlx %%l1, 32, %%g7\n" \
-"6:\t" "stba %%g1, [%0 + 2] %%asi\n" \
-"7:\t" "stba %%g7, [%0 + 3] %%asi\n\t" \
- "srlx %%l1, 16, %%g1\n" \
-"8:\t" "stba %%l2, [%0 + 4] %%asi\n\t" \
- "srlx %%l1, 8, %%g7\n" \
-"9:\t" "stba %%g1, [%0 + 5] %%asi\n" \
-"10:\t" "stba %%g7, [%0 + 6] %%asi\n\t" \
- "ba,pt %%xcc, 0f\n" \
-"11:\t" " stba %%l1, [%0 + 7] %%asi\n" \
-"1:\t" "srl %%l1, 16, %%g7\n" \
-"12:\t" "stba %%l2, [%0] %%asi\n\t" \
- "srl %%l1, 8, %%l2\n" \
-"13:\t" "stba %%g7, [%0 + 1] %%asi\n" \
-"14:\t" "stba %%l2, [%0 + 2] %%asi\n\t" \
- "ba,pt %%xcc, 0f\n" \
-"15:\t" " stba %%l1, [%0 + 3] %%asi\n" \
-"2:\t" "srl %%l1, 8, %%l2\n" \
-"16:\t" "stba %%l2, [%0] %%asi\n" \
-"17:\t" "stba %%l1, [%0 + 1] %%asi\n" \
-"0:\n\t" \
- "wr %%g0, %4, %%asi\n\n\t" \
- ".section __ex_table\n\t" \
- ".word 4b, " #errh "\n\t" \
- ".word 5b, " #errh "\n\t" \
- ".word 6b, " #errh "\n\t" \
- ".word 7b, " #errh "\n\t" \
- ".word 8b, " #errh "\n\t" \
- ".word 9b, " #errh "\n\t" \
- ".word 10b, " #errh "\n\t" \
- ".word 11b, " #errh "\n\t" \
- ".word 12b, " #errh "\n\t" \
- ".word 13b, " #errh "\n\t" \
- ".word 14b, " #errh "\n\t" \
- ".word 15b, " #errh "\n\t" \
- ".word 16b, " #errh "\n\t" \
- ".word 17b, " #errh "\n\n\t" \
- ".previous\n\t" \
- : : "r" (dst_addr), "r" (size), "r" (src_val), "r" (asi), "i" (ASI_AIUS)\
- : "l1", "l2", "g7", "g1", "cc"); \
-})
-
-#define do_integer_store(reg_num, size, dst_addr, regs, asi, errh) ({ \
- unsigned long zero = 0; \
- unsigned long *src_val = &zero; \
- \
- if (size == 16) { \
- size = 8; \
- zero = (((long)(reg_num ? \
- (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | \
- (unsigned)fetch_reg(reg_num + 1, regs); \
- } else if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \
- store_common(dst_addr, size, src_val, asi, errh); \
-})
-
-extern void smp_capture(void);
-extern void smp_release(void);
-
-#define do_atomic(srcdest_reg, mem, errh) ({ \
- unsigned long flags, tmp; \
- \
- smp_capture(); \
- local_irq_save(flags); \
- tmp = *srcdest_reg; \
- do_integer_load(srcdest_reg, 4, mem, 0, errh); \
- store_common(mem, 4, &tmp, errh); \
- local_irq_restore(flags); \
- smp_release(); \
-})
+extern void __do_int_store(unsigned long *dst_addr, int size,
+ unsigned long *src_val, int asi);
+
+static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
+ struct pt_regs *regs, int asi)
+{
+ unsigned long zero = 0;
+ unsigned long *src_val = &zero;
+
+ if (size == 16) {
+ size = 8;
+ zero = (((long)(reg_num ?
+ (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
+ (unsigned)fetch_reg(reg_num + 1, regs);
+ } else if (reg_num) {
+ src_val = fetch_reg_addr(reg_num, regs);
+ }
+ __do_int_store(dst_addr, size, src_val, asi);
+}
static inline void advance(struct pt_regs *regs)
{
@@ -364,24 +223,29 @@ static inline int ok_for_kernel(unsigned int insn)
return !floating_point_load_or_store_p(insn);
}
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
-
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+void kernel_mna_trap_fault(void)
{
- unsigned long g2 = regs->u_regs [UREG_G2];
+ struct pt_regs *regs = current_thread_info()->kern_una_regs;
+ unsigned int insn = current_thread_info()->kern_una_insn;
+ unsigned long g2 = regs->u_regs[UREG_G2];
unsigned long fixup = search_extables_range(regs->tpc, &g2);
if (!fixup) {
- unsigned long address = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f));
+ unsigned long address;
+
+ address = compute_effective_address(regs, insn,
+ ((insn >> 25) & 0x1f));
if (address < PAGE_SIZE) {
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler");
+ printk(KERN_ALERT "Unable to handle kernel NULL "
+ "pointer dereference in mna handler");
} else
- printk(KERN_ALERT "Unable to handle kernel paging request in mna handler");
+ printk(KERN_ALERT "Unable to handle kernel paging "
+ "request in mna handler");
printk(KERN_ALERT " at virtual address %016lx\n",address);
- printk(KERN_ALERT "current->{mm,active_mm}->context = %016lx\n",
+ printk(KERN_ALERT "current->{active_,}mm->context = %016lx\n",
(current->mm ? CTX_HWBITS(current->mm->context) :
CTX_HWBITS(current->active_mm->context)));
- printk(KERN_ALERT "current->{mm,active_mm}->pgd = %016lx\n",
+ printk(KERN_ALERT "current->{active_,}mm->pgd = %016lx\n",
(current->mm ? (unsigned long) current->mm->pgd :
(unsigned long) current->active_mm->pgd));
die_if_kernel("Oops", regs);
@@ -400,48 +264,41 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
enum direction dir = decode_direction(insn);
int size = decode_access_size(insn);
+ current_thread_info()->kern_una_regs = regs;
+ current_thread_info()->kern_una_insn = insn;
+
if (!ok_for_kernel(insn) || dir == both) {
- printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n",
- regs->tpc);
- unaligned_panic("Kernel does fpu/atomic unaligned load/store.", regs);
-
- __asm__ __volatile__ ("\n"
-"kernel_unaligned_trap_fault:\n\t"
- "mov %0, %%o0\n\t"
- "call kernel_mna_trap_fault\n\t"
- " mov %1, %%o1\n\t"
- :
- : "r" (regs), "r" (insn)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
- "g1", "g2", "g3", "g4", "g7", "cc");
+ printk("Unsupported unaligned load/store trap for kernel "
+ "at <%016lx>.\n", regs->tpc);
+ unaligned_panic("Kernel does fpu/atomic "
+ "unaligned load/store.", regs);
+
+ kernel_mna_trap_fault();
} else {
- unsigned long addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f));
+ unsigned long addr;
+ addr = compute_effective_address(regs, insn,
+ ((insn >> 25) & 0x1f));
#ifdef DEBUG_MNA
- printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n",
- regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
+ printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] "
+ "retpc[%016lx]\n",
+ regs->tpc, dirstrings[dir], addr, size,
+ regs->u_regs[UREG_RETPC]);
#endif
switch (dir) {
case load:
- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
- size, (unsigned long *) addr,
- decode_signedness(insn), decode_asi(insn, regs),
- kernel_unaligned_trap_fault);
+ do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn),
+ decode_asi(insn, regs));
break;
case store:
- do_integer_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs,
- decode_asi(insn, regs),
- kernel_unaligned_trap_fault);
- break;
-#if 0 /* unsupported */
- case both:
- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
- (unsigned long *) addr,
- kernel_unaligned_trap_fault);
+ do_int_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs,
+ decode_asi(insn, regs));
break;
-#endif
+
default:
panic("Impossible kernel unaligned trap.");
/* Not reached... */
@@ -492,9 +349,9 @@ int handle_popc(u32 insn, struct pt_regs *regs)
extern void do_fpother(struct pt_regs *regs);
extern void do_privact(struct pt_regs *regs);
-extern void data_access_exception(struct pt_regs *regs,
- unsigned long sfsr,
- unsigned long sfar);
+extern void spitfire_data_access_exception(struct pt_regs *regs,
+ unsigned long sfsr,
+ unsigned long sfar);
int handle_ldf_stq(u32 insn, struct pt_regs *regs)
{
@@ -537,14 +394,14 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs)
break;
}
default:
- data_access_exception(regs, 0, addr);
+ spitfire_data_access_exception(regs, 0, addr);
return 1;
}
if (put_user (first >> 32, (u32 __user *)addr) ||
__put_user ((u32)first, (u32 __user *)(addr + 4)) ||
__put_user (second >> 32, (u32 __user *)(addr + 8)) ||
__put_user ((u32)second, (u32 __user *)(addr + 12))) {
- data_access_exception(regs, 0, addr);
+ spitfire_data_access_exception(regs, 0, addr);
return 1;
}
} else {
@@ -557,7 +414,7 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs)
do_privact(regs);
return 1;
} else if (asi > ASI_SNFL) {
- data_access_exception(regs, 0, addr);
+ spitfire_data_access_exception(regs, 0, addr);
return 1;
}
switch (insn & 0x180000) {
@@ -574,7 +431,7 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs)
err |= __get_user (data[i], (u32 __user *)(addr + 4*i));
}
if (err && !(asi & 0x2 /* NF */)) {
- data_access_exception(regs, 0, addr);
+ spitfire_data_access_exception(regs, 0, addr);
return 1;
}
if (asi & 0x8) /* Little */ {
@@ -677,7 +534,7 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr
*(u64 *)(f->regs + freg) = value;
current_thread_info()->fpsaved[0] |= flag;
} else {
-daex: data_access_exception(regs, sfsr, sfar);
+daex: spitfire_data_access_exception(regs, sfsr, sfar);
return;
}
advance(regs);
@@ -721,7 +578,7 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr
__put_user ((u32)value, (u32 __user *)(sfar + 4)))
goto daex;
} else {
-daex: data_access_exception(regs, sfsr, sfar);
+daex: spitfire_data_access_exception(regs, sfsr, sfar);
return;
}
advance(regs);
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
index 7aae0a18aabe..686e526bec04 100644
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -88,7 +88,6 @@ static void frob_mem_refresh(int cpu_slowing_down,
{
unsigned long old_refr_count, refr_count, mctrl;
-
refr_count = (clock_tick * MCTRL0_REFR_INTERVAL);
refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL);
@@ -230,6 +229,25 @@ static unsigned long estar_to_divisor(unsigned long estar)
return ret;
}
+static unsigned int us2e_freq_get(unsigned int cpu)
+{
+ cpumask_t cpus_allowed;
+ unsigned long clock_tick, estar;
+
+ if (!cpu_online(cpu))
+ return 0;
+
+ cpus_allowed = current->cpus_allowed;
+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+ clock_tick = sparc64_get_clock_tick(cpu) / 1000;
+ estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
+
+ set_cpus_allowed(current, cpus_allowed);
+
+ return clock_tick / estar_to_divisor(estar);
+}
+
static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
{
unsigned long new_bits, new_freq;
@@ -243,7 +261,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
cpus_allowed = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
- new_freq = clock_tick = sparc64_get_clock_tick(cpu);
+ new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
new_bits = index_to_estar_mode(index);
divisor = index_to_divisor(index);
new_freq /= divisor;
@@ -258,7 +276,8 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (old_divisor != divisor)
- us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor);
+ us2e_transition(estar, new_bits, clock_tick * 1000,
+ old_divisor, divisor);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
@@ -272,10 +291,8 @@ static int us2e_freq_target(struct cpufreq_policy *policy,
unsigned int new_index = 0;
if (cpufreq_frequency_table_target(policy,
- &us2e_freq_table[policy->cpu].table[0],
- target_freq,
- relation,
- &new_index))
+ &us2e_freq_table[policy->cpu].table[0],
+ target_freq, relation, &new_index))
return -EINVAL;
us2e_set_cpu_divider_index(policy->cpu, new_index);
@@ -292,7 +309,7 @@ static int us2e_freq_verify(struct cpufreq_policy *policy)
static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
{
unsigned int cpu = policy->cpu;
- unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+ unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
struct cpufreq_frequency_table *table =
&us2e_freq_table[cpu].table[0];
@@ -351,9 +368,10 @@ static int __init us2e_freq_init(void)
memset(us2e_freq_table, 0,
(NR_CPUS * sizeof(struct us2e_freq_percpu_info)));
+ driver->init = us2e_freq_cpu_init;
driver->verify = us2e_freq_verify;
driver->target = us2e_freq_target;
- driver->init = us2e_freq_cpu_init;
+ driver->get = us2e_freq_get;
driver->exit = us2e_freq_cpu_exit;
driver->owner = THIS_MODULE,
strcpy(driver->name, "UltraSPARC-IIe");
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 18fe54b8aa55..9080e7cd4bb0 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -56,7 +56,7 @@ static void write_safari_cfg(unsigned long val)
static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg)
{
- unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+ unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
unsigned long ret;
switch (safari_cfg & SAFARI_CFG_DIV_MASK) {
@@ -76,6 +76,26 @@ static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg
return ret;
}
+static unsigned int us3_freq_get(unsigned int cpu)
+{
+ cpumask_t cpus_allowed;
+ unsigned long reg;
+ unsigned int ret;
+
+ if (!cpu_online(cpu))
+ return 0;
+
+ cpus_allowed = current->cpus_allowed;
+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+ reg = read_safari_cfg();
+ ret = get_current_freq(cpu, reg);
+
+ set_cpus_allowed(current, cpus_allowed);
+
+ return ret;
+}
+
static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
{
unsigned long new_bits, new_freq, reg;
@@ -88,7 +108,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
cpus_allowed = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
- new_freq = sparc64_get_clock_tick(cpu);
+ new_freq = sparc64_get_clock_tick(cpu) / 1000;
switch (index) {
case 0:
new_bits = SAFARI_CFG_DIV_1;
@@ -150,7 +170,7 @@ static int us3_freq_verify(struct cpufreq_policy *policy)
static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
{
unsigned int cpu = policy->cpu;
- unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+ unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
struct cpufreq_frequency_table *table =
&us3_freq_table[cpu].table[0];
@@ -206,9 +226,10 @@ static int __init us3_freq_init(void)
memset(us3_freq_table, 0,
(NR_CPUS * sizeof(struct us3_freq_percpu_info)));
+ driver->init = us3_freq_cpu_init;
driver->verify = us3_freq_verify;
driver->target = us3_freq_target;
- driver->init = us3_freq_cpu_init;
+ driver->get = us3_freq_get;
driver->exit = us3_freq_cpu_exit;
driver->owner = THIS_MODULE,
strcpy(driver->name, "UltraSPARC-III");
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 382fd6798bb9..f47d0be39378 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -17,6 +17,7 @@ SECTIONS
*(.text)
SCHED_TEXT
LOCK_TEXT
+ KPROBES_TEXT
*(.gnu.warning)
} =0
_etext = .;
@@ -32,6 +33,8 @@ SECTIONS
.data1 : { *(.data1) }
. = ALIGN(64);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
+ . = ALIGN(64);
+ .data.read_mostly : { *(.data.read_mostly) }
_edata = .;
PROVIDE (edata = .);
.fixup : { *(.fixup) }
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
index dfbc7e0dcf70..99c809a1e5ac 100644
--- a/arch/sparc64/kernel/winfixup.S
+++ b/arch/sparc64/kernel/winfixup.S
@@ -318,7 +318,7 @@ fill_fixup_dax:
nop
rdpr %pstate, %l1 ! Prepare to change globals.
mov %g4, %o1 ! Setup args for
- mov %g5, %o2 ! final call to data_access_exception.
+ mov %g5, %o2 ! final call to spitfire_data_access_exception.
andn %l1, PSTATE_MM, %l1 ! We want to be in RMO
mov %g6, %o7 ! Stash away current.
@@ -330,7 +330,7 @@ fill_fixup_dax:
mov TSB_REG, %g1
ldxa [%g1] ASI_IMMU, %g5
#endif
- call data_access_exception
+ call spitfire_data_access_exception
add %sp, PTREGS_OFF, %o0
b,pt %xcc, rtrap
@@ -391,7 +391,7 @@ window_dax_from_user_common:
109: or %g7, %lo(109b), %g7
mov %l4, %o1
mov %l5, %o2
- call data_access_exception
+ call spitfire_data_access_exception
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
clr %l6