Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
a0adf3b1
Commit
a0adf3b1
authored
Sep 01, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge davem@nuts.davemloft.net:/disk1/BK/sparc-2.6
into kernel.bkbits.net:/home/davem/sparc-2.6
parents
6ce8ea8a
39e8d677
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
704 additions
and
221 deletions
+704
-221
arch/sparc/kernel/systbls.S
arch/sparc/kernel/systbls.S
+1
-1
arch/sparc64/Kconfig.debug
arch/sparc64/Kconfig.debug
+10
-0
arch/sparc64/defconfig
arch/sparc64/defconfig
+7
-6
arch/sparc64/kernel/Makefile
arch/sparc64/kernel/Makefile
+1
-0
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/irq.c
+14
-5
arch/sparc64/kernel/kprobes.c
arch/sparc64/kernel/kprobes.c
+276
-0
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci.c
+0
-4
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_common.c
+49
-73
arch/sparc64/kernel/pci_impl.h
arch/sparc64/kernel/pci_impl.h
+0
-1
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_psycho.c
+0
-6
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_sabre.c
+4
-11
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/pci_schizo.c
+0
-6
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/signal32.c
+74
-3
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sparc32.c
+24
-4
arch/sparc64/kernel/systbls.S
arch/sparc64/kernel/systbls.S
+2
-2
arch/sparc64/kernel/traps.c
arch/sparc64/kernel/traps.c
+91
-6
arch/sparc64/kernel/ttable.S
arch/sparc64/kernel/ttable.S
+1
-1
arch/sparc64/mm/fault.c
arch/sparc64/mm/fault.c
+10
-1
arch/sparc64/solaris/misc.c
arch/sparc64/solaris/misc.c
+44
-25
include/asm-sparc/unistd.h
include/asm-sparc/unistd.h
+6
-5
include/asm-sparc64/kdebug.h
include/asm-sparc64/kdebug.h
+46
-3
include/asm-sparc64/kprobes.h
include/asm-sparc64/kprobes.h
+24
-0
include/asm-sparc64/siginfo.h
include/asm-sparc64/siginfo.h
+3
-51
include/asm-sparc64/ttable.h
include/asm-sparc64/ttable.h
+6
-0
include/asm-sparc64/unistd.h
include/asm-sparc64/unistd.h
+7
-5
kernel/kprobes.c
kernel/kprobes.c
+4
-2
No files found.
arch/sparc/kernel/systbls.S
View file @
a0adf3b1
...
...
@@ -74,7 +74,7 @@ sys_call_table:
/*
260
*/
.
long
sys_sched_getaffinity
,
sys_sched_setaffinity
,
sys_timer_settime
,
sys_timer_gettime
,
sys_timer_getoverrun
/*
265
*/
.
long
sys_timer_delete
,
sys_timer_create
,
sys_nis_syscall
,
sys_io_setup
,
sys_io_destroy
/*
270
*/
.
long
sys_io_submit
,
sys_io_cancel
,
sys_io_getevents
,
sys_mq_open
,
sys_mq_unlink
/*
275
*/
.
long
sys_mq_timedsend
,
sys_mq_timedreceive
,
sys_mq_notify
,
sys_mq_getsetattr
,
sys_
ni_syscall
/*
275
*/
.
long
sys_mq_timedsend
,
sys_mq_timedreceive
,
sys_mq_notify
,
sys_mq_getsetattr
,
sys_
waitid
/*
280
*/
.
long
sys_ni_syscall
,
sys_ni_syscall
,
sys_ni_syscall
#ifdef CONFIG_SUNOS_EMUL
...
...
arch/sparc64/Kconfig.debug
View file @
a0adf3b1
...
...
@@ -11,6 +11,16 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat.
config KPROBES
bool "Kprobes"
depends on DEBUG_KERNEL
help
Kprobes allows you to trap at almost any kernel address and
execute a callback function. register_kprobe() establishes
a probepoint and specifies the callback. Kprobes is useful
for kernel debugging, non-intrusive instrumentation and testing.
If in doubt, say "N".
config DEBUG_DCFLUSH
bool "D-cache flush debugging"
depends on DEBUG_KERNEL
...
...
arch/sparc64/defconfig
View file @
a0adf3b1
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.9-rc1
#
Fri Aug 27 17:37:00
2004
#
Wed Sep 1 17:54:49
2004
#
CONFIG_64BIT=y
CONFIG_MMU=y
...
...
@@ -35,6 +35,8 @@ CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
# CONFIG_TINY_SHMEM is not set
#
# Loadable module support
...
...
@@ -332,7 +334,8 @@ CONFIG_AIC79XX_RESET_DELAY_MS=15000
# CONFIG_AIC79XX_DEBUG_ENABLE is not set
CONFIG_AIC79XX_DEBUG_MASK=0
# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
CONFIG_SCSI_SATA=y
CONFIG_SCSI_SATA_SVW=m
CONFIG_SCSI_ATA_PIIX=m
...
...
@@ -357,9 +360,7 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
CONFIG_SCSI_IPR=m
# CONFIG_SCSI_IPR_TRACE is not set
# CONFIG_SCSI_IPR_DUMP is not set
# CONFIG_SCSI_IPR is not set
CONFIG_SCSI_QLOGIC_ISP=m
CONFIG_SCSI_QLOGIC_FC=y
CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y
...
...
@@ -417,7 +418,6 @@ CONFIG_DM_ZERO=m
#
CONFIG_FUSION=m
CONFIG_FUSION_MAX_SGE=40
CONFIG_FUSION_ISENSE=m
CONFIG_FUSION_CTL=m
CONFIG_FUSION_LAN=m
...
...
@@ -1757,6 +1757,7 @@ CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_KPROBES=y
# CONFIG_DEBUG_DCFLUSH is not set
# CONFIG_STACK_DEBUG is not set
# CONFIG_DEBUG_BOOTMEM is not set
...
...
arch/sparc64/kernel/Makefile
View file @
a0adf3b1
...
...
@@ -22,6 +22,7 @@ obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
obj-$(CONFIG_MODULES)
+=
module.o
obj-$(CONFIG_US3_FREQ)
+=
us3_cpufreq.o
obj-$(CONFIG_US2E_FREQ)
+=
us2e_cpufreq.o
obj-$(CONFIG_KPROBES)
+=
kprobes.o
ifdef
CONFIG_SUNOS_EMUL
obj-y
+=
sys_sunos32.o sunos_ioctl32.o
...
...
arch/sparc64/kernel/irq.c
View file @
a0adf3b1
...
...
@@ -791,16 +791,24 @@ void handler_irq(int irq, struct pt_regs *regs)
#endif
if
((
flags
&
IBF_MULTI
)
==
0
)
{
struct
irqaction
*
ap
=
bp
->
irq_info
;
ap
->
handler
(
__irq
(
bp
),
ap
->
dev_id
,
regs
);
random
|=
ap
->
flags
&
SA_SAMPLE_RANDOM
;
int
ret
;
ret
=
ap
->
handler
(
__irq
(
bp
),
ap
->
dev_id
,
regs
);
if
(
ret
==
IRQ_HANDLED
)
random
|=
ap
->
flags
;
}
else
{
void
**
vector
=
(
void
**
)
bp
->
irq_info
;
int
ent
;
for
(
ent
=
0
;
ent
<
4
;
ent
++
)
{
struct
irqaction
*
ap
=
vector
[
ent
];
if
(
ap
!=
NULL
)
{
ap
->
handler
(
__irq
(
bp
),
ap
->
dev_id
,
regs
);
random
|=
ap
->
flags
&
SA_SAMPLE_RANDOM
;
int
ret
;
ret
=
ap
->
handler
(
__irq
(
bp
),
ap
->
dev_id
,
regs
);
if
(
ret
==
IRQ_HANDLED
)
random
|=
ap
->
flags
;
}
}
}
...
...
@@ -813,8 +821,9 @@ void handler_irq(int irq, struct pt_regs *regs)
}
#endif
upa_writel
(
ICLR_IDLE
,
bp
->
iclr
);
/* Test and add entropy */
if
(
random
)
if
(
random
&
SA_SAMPLE_RANDOM
)
add_interrupt_randomness
(
irq
);
}
}
else
...
...
arch/sparc64/kernel/kprobes.c
0 → 100644
View file @
a0adf3b1
/* arch/sparc64/kernel/kprobes.c
*
* Copyright (C) 2004 David S. Miller <davem@davemloft.net>
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <asm/kdebug.h>
#include <asm/signal.h>
/* We do not have hardware single-stepping, so in order
* to implement post handlers correctly we use two breakpoint
* instructions.
*
* 1) ta 0x70 --> 0x91d02070
* 2) ta 0x71 --> 0x91d02071
*
* When these are hit, control is transferred to kprobe_trap()
* below. The arg 'level' tells us which of the two traps occurred.
*
* Initially, the instruction at p->addr gets set to "ta 0x70"
* by code in register_kprobe() by setting that memory address
* to BREAKPOINT_INSTRUCTION. When this breakpoint is hit
* the following happens:
*
* 1) We run the pre-handler
* 2) We replace p->addr with the original opcode
* 3) We set the instruction at "regs->npc" to "ta 0x71"
* 4) We mark that we are waiting for the second breakpoint
* to hit and return from the trap.
*
* At this point we wait for the second breakpoint to hit.
* When it does:
*
* 1) We run the post-handler
* 2) We re-install "ta 0x70" at p->addr
* 3) We restore the opcode at the "ta 0x71" breakpoint
* 4) We reset our "waiting for "ta 0x71" state
* 5) We return from the trap
*
* We could use the trick used by the i386 kprobe code but I
* think that scheme has problems with exception tables. On i386
* they single-step over the original instruction stored at
* kprobe->insn. So they set the processor to single step, and
* set the program counter to kprobe->insn.
*
* But that explodes if the original opcode is a user space
* access instruction and that faults. It will go wrong because
* since the location of the instruction being executed is
* different from that recorded in the exception tables, the
* kernel will not find it and this will cause an erroneous
* kernel OOPS.
*/
void
arch_prepare_kprobe
(
struct
kprobe
*
p
)
{
p
->
insn
[
0
]
=
*
p
->
addr
;
p
->
insn
[
1
]
=
0xdeadbeef
;
}
static
void
prepare_singlestep
(
struct
kprobe
*
p
,
struct
pt_regs
*
regs
)
{
u32
*
insn2
=
(
u32
*
)
regs
->
tpc
;
p
->
insn
[
1
]
=
*
insn2
;
*
insn2
=
BREAKPOINT_INSTRUCTION_2
;
flushi
(
insn2
);
}
static
void
undo_singlestep
(
struct
kprobe
*
p
,
struct
pt_regs
*
regs
)
{
u32
*
insn2
=
(
u32
*
)
regs
->
tpc
;
BUG_ON
(
p
->
insn
[
1
]
==
0xdeadbeef
);
*
insn2
=
p
->
insn
[
1
];
flushi
(
insn2
);
p
->
insn
[
1
]
=
0xdeadbeef
;
}
/* kprobe_status settings */
#define KPROBE_HIT_ACTIVE 0x00000001
#define KPROBE_HIT_SS 0x00000002
static
struct
kprobe
*
current_kprobe
;
static
unsigned
int
kprobe_status
;
static
int
kprobe_handler
(
struct
pt_regs
*
regs
)
{
struct
kprobe
*
p
;
void
*
addr
=
(
void
*
)
regs
->
tpc
;
int
ret
=
0
;
preempt_disable
();
if
(
kprobe_running
())
{
p
=
get_kprobe
(
addr
);
if
(
p
)
{
*
p
->
addr
=
p
->
opcode
;
flushi
(
p
->
addr
);
ret
=
1
;
}
else
{
p
=
current_kprobe
;
if
(
p
->
break_handler
&&
p
->
break_handler
(
p
,
regs
))
goto
ss_probe
;
}
goto
no_kprobe
;
}
lock_kprobes
();
p
=
get_kprobe
(
addr
);
if
(
!
p
)
{
unlock_kprobes
();
if
(
*
(
u32
*
)
addr
!=
BREAKPOINT_INSTRUCTION
)
ret
=
1
;
goto
no_kprobe
;
}
kprobe_status
=
KPROBE_HIT_ACTIVE
;
current_kprobe
=
p
;
if
(
p
->
pre_handler
(
p
,
regs
))
return
1
;
ss_probe:
prepare_singlestep
(
p
,
regs
);
kprobe_status
=
KPROBE_HIT_SS
;
return
1
;
no_kprobe:
preempt_enable_no_resched
();
return
ret
;
}
static
int
post_kprobe_handler
(
struct
pt_regs
*
regs
)
{
u32
*
insn_p
=
(
u32
*
)
regs
->
tpc
;
if
(
!
kprobe_running
()
||
(
*
insn_p
!=
BREAKPOINT_INSTRUCTION_2
))
return
0
;
if
(
current_kprobe
->
post_handler
)
current_kprobe
->
post_handler
(
current_kprobe
,
regs
,
0
);
undo_singlestep
(
current_kprobe
,
regs
);
unlock_kprobes
();
preempt_enable_no_resched
();
return
1
;
}
/* Interrupts disabled, kprobe_lock held. */
static
inline
int
kprobe_fault_handler
(
struct
pt_regs
*
regs
,
int
trapnr
)
{
if
(
current_kprobe
->
fault_handler
&&
current_kprobe
->
fault_handler
(
current_kprobe
,
regs
,
trapnr
))
return
1
;
if
(
kprobe_status
&
KPROBE_HIT_SS
)
{
undo_singlestep
(
current_kprobe
,
regs
);
unlock_kprobes
();
preempt_enable_no_resched
();
}
return
0
;
}
/*
* Wrapper routine to for handling exceptions.
*/
int
kprobe_exceptions_notify
(
struct
notifier_block
*
self
,
unsigned
long
val
,
void
*
data
)
{
struct
die_args
*
args
=
(
struct
die_args
*
)
data
;
switch
(
val
)
{
case
DIE_DEBUG
:
if
(
kprobe_handler
(
args
->
regs
))
return
NOTIFY_OK
;
break
;
case
DIE_DEBUG_2
:
if
(
post_kprobe_handler
(
args
->
regs
))
return
NOTIFY_OK
;
break
;
case
DIE_GPF
:
if
(
kprobe_running
()
&&
kprobe_fault_handler
(
args
->
regs
,
args
->
trapnr
))
return
NOTIFY_OK
;
break
;
case
DIE_PAGE_FAULT
:
if
(
kprobe_running
()
&&
kprobe_fault_handler
(
args
->
regs
,
args
->
trapnr
))
return
NOTIFY_OK
;
break
;
default:
break
;
}
return
NOTIFY_BAD
;
}
asmlinkage
void
kprobe_trap
(
unsigned
long
trap_level
,
struct
pt_regs
*
regs
)
{
BUG_ON
(
trap_level
!=
0x170
&&
trap_level
!=
0x171
);
if
(
user_mode
(
regs
))
{
local_irq_enable
();
bad_trap
(
regs
,
trap_level
);
return
;
}
/* trap_level == 0x170 --> ta 0x70
* trap_level == 0x171 --> ta 0x71
*/
if
(
notify_die
((
trap_level
==
0x170
)
?
DIE_DEBUG
:
DIE_DEBUG_2
,
(
trap_level
==
0x170
)
?
"debug"
:
"debug_2"
,
regs
,
0
,
trap_level
,
SIGTRAP
)
!=
NOTIFY_OK
)
bad_trap
(
regs
,
trap_level
);
}
/* Jprobes support. */
static
struct
pt_regs
jprobe_saved_regs
;
static
struct
sparc_stackf
jprobe_saved_stack
;
int
setjmp_pre_handler
(
struct
kprobe
*
p
,
struct
pt_regs
*
regs
)
{
struct
jprobe
*
jp
=
container_of
(
p
,
struct
jprobe
,
kp
);
memcpy
(
&
jprobe_saved_regs
,
regs
,
sizeof
(
*
regs
));
/* Save a whole stack frame, this gets arguments
* pushed onto the stack after using up all the
* arg registers.
*/
memcpy
(
&
jprobe_saved_stack
,
(
char
*
)
(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
),
sizeof
(
jprobe_saved_stack
));
regs
->
tpc
=
(
unsigned
long
)
jp
->
entry
;
regs
->
tnpc
=
((
unsigned
long
)
jp
->
entry
)
+
0x4UL
;
return
1
;
}
void
jprobe_return
(
void
)
{
preempt_enable_no_resched
();
__asm__
__volatile__
(
".globl jprobe_return_trap_instruction
\n
"
"jprobe_return_trap_instruction:
\n\t
"
"ta 0x70"
);
}
extern
void
jprobe_return_trap_instruction
(
void
);
int
longjmp_break_handler
(
struct
kprobe
*
p
,
struct
pt_regs
*
regs
)
{
u32
*
addr
=
(
u32
*
)
regs
->
tpc
;
if
(
addr
==
(
u32
*
)
jprobe_return_trap_instruction
)
{
/* Restore old register state. Do pt_regs
* first so that UREG_FP is the original one for
* the stack frame restore.
*/
memcpy
(
regs
,
&
jprobe_saved_regs
,
sizeof
(
*
regs
));
memcpy
((
char
*
)
(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
),
&
jprobe_saved_stack
,
sizeof
(
jprobe_saved_stack
));
return
1
;
}
return
0
;
}
arch/sparc64/kernel/pci.c
View file @
a0adf3b1
...
...
@@ -41,7 +41,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn,
#else
/* List of all PCI controllers found in the system. */
spinlock_t
pci_controller_lock
=
SPIN_LOCK_UNLOCKED
;
struct
pci_controller_info
*
pci_controller_root
=
NULL
;
/* Each PCI controller found gets a unique index. */
...
...
@@ -298,12 +297,9 @@ static void __init pci_controller_probe(void)
static
void
__init
pci_scan_each_controller_bus
(
void
)
{
struct
pci_controller_info
*
p
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
pci_controller_lock
,
flags
);
for
(
p
=
pci_controller_root
;
p
;
p
=
p
->
next
)
p
->
scan_bus
(
p
);
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
}
/* Reorder the pci_dev chain, so that onboard devices come first
...
...
arch/sparc64/kernel/pci_common.c
View file @
a0adf3b1
...
...
@@ -15,18 +15,13 @@
*/
void
__init
pci_fixup_host_bridge_self
(
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
walk
=
walk
->
next
;
while
(
walk
!=
&
pbus
->
devices
)
{
struct
pci_dev
*
pdev
=
pci_dev_b
(
walk
);
struct
pci_dev
*
pdev
;
list_for_each_entry
(
pdev
,
&
pbus
->
devices
,
bus_list
)
{
if
(
pdev
->
class
>>
8
==
PCI_CLASS_BRIDGE_HOST
)
{
pbus
->
self
=
pdev
;
return
;
}
walk
=
walk
->
next
;
}
prom_printf
(
"PCI: Critical error, cannot find host bridge PDEV.
\n
"
);
...
...
@@ -217,31 +212,18 @@ void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
struct
pci_pbm_info
*
pbm
,
int
prom_node
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
/* This loop is coded like this because the cookie
* fillin routine can delete devices from the tree.
*/
walk
=
walk
->
next
;
while
(
walk
!=
&
pbus
->
devices
)
{
struct
pci_dev
*
pdev
=
pci_dev_b
(
walk
);
struct
list_head
*
walk_next
=
walk
->
next
;
struct
pci_dev
*
pdev
,
*
pdev_next
;
struct
pci_bus
*
this_pbus
,
*
pbus_next
;
/* This must be _safe because the cookie fillin
routine can delete devices from the tree. */
list_for_each_entry_safe
(
pdev
,
pdev_next
,
&
pbus
->
devices
,
bus_list
)
pdev_cookie_fillin
(
pbm
,
pdev
,
prom_node
);
walk
=
walk_next
;
}
walk
=
&
pbus
->
children
;
walk
=
walk
->
next
;
while
(
walk
!=
&
pbus
->
children
)
{
struct
pci_bus
*
this_pbus
=
pci_bus_b
(
walk
);
list_for_each_entry_safe
(
this_pbus
,
pbus_next
,
&
pbus
->
children
,
node
)
{
struct
pcidev_cookie
*
pcp
=
this_pbus
->
self
->
sysdata
;
struct
list_head
*
walk_next
=
walk
->
next
;
pci_fill_in_pbm_cookies
(
this_pbus
,
pbm
,
pcp
->
prom_node
);
walk
=
walk_next
;
}
}
...
...
@@ -431,14 +413,14 @@ static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
void
__init
pci_record_assignments
(
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
struct
pci_dev
*
dev
;
struct
pci_bus
*
bus
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
nex
t
)
pdev_record_assignments
(
pbm
,
pci_dev_b
(
walk
)
);
list_for_each_entry
(
dev
,
&
pbus
->
devices
,
bus_lis
t
)
pdev_record_assignments
(
pbm
,
dev
);
walk
=
&
pbus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
children
;
walk
=
walk
->
next
)
pci_record_assignments
(
pbm
,
pci_bus_b
(
walk
));
list_for_each_entry
(
bus
,
&
pbus
->
children
,
node
)
pci_record_assignments
(
pbm
,
bus
);
}
/* Return non-zero if PDEV has implicit I/O resources even
...
...
@@ -549,14 +531,14 @@ static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm,
void
__init
pci_assign_unassigned
(
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
struct
pci_dev
*
dev
;
struct
pci_bus
*
bus
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
nex
t
)
pdev_assign_unassigned
(
pbm
,
pci_dev_b
(
walk
)
);
list_for_each_entry
(
dev
,
&
pbus
->
devices
,
bus_lis
t
)
pdev_assign_unassigned
(
pbm
,
dev
);
walk
=
&
pbus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
children
;
walk
=
walk
->
next
)
pci_assign_unassigned
(
pbm
,
pci_bus_b
(
walk
));
list_for_each_entry
(
bus
,
&
pbus
->
children
,
node
)
pci_assign_unassigned
(
pbm
,
bus
);
}
static
int
__init
pci_intmap_match
(
struct
pci_dev
*
pdev
,
unsigned
int
*
interrupt
)
...
...
@@ -797,14 +779,14 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
void
__init
pci_fixup_irq
(
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
struct
pci_dev
*
dev
;
struct
pci_bus
*
bus
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
nex
t
)
pdev_fixup_irq
(
pci_dev_b
(
walk
)
);
list_for_each_entry
(
dev
,
&
pbus
->
devices
,
bus_lis
t
)
pdev_fixup_irq
(
dev
);
walk
=
&
pbus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
children
;
walk
=
walk
->
next
)
pci_fixup_irq
(
pbm
,
pci_bus_b
(
walk
));
list_for_each_entry
(
bus
,
&
pbus
->
children
,
node
)
pci_fixup_irq
(
pbm
,
bus
);
}
static
void
pdev_setup_busmastering
(
struct
pci_dev
*
pdev
,
int
is_66mhz
)
...
...
@@ -897,7 +879,7 @@ static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz)
void
pci_determine_66mhz_disposition
(
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
;
struct
pci_dev
*
pdev
;
int
all_are_66mhz
;
u16
status
;
...
...
@@ -906,11 +888,8 @@ void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm,
goto
out
;
}
walk
=
&
pbus
->
devices
;
all_are_66mhz
=
1
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
next
)
{
struct
pci_dev
*
pdev
=
pci_dev_b
(
walk
);
list_for_each_entry
(
pdev
,
&
pbus
->
devices
,
bus_list
)
{
pci_read_config_word
(
pdev
,
PCI_STATUS
,
&
status
);
if
(
!
(
status
&
PCI_STATUS_66MHZ
))
{
all_are_66mhz
=
0
;
...
...
@@ -929,17 +908,17 @@ void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm,
void
pci_setup_busmastering
(
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
struct
pci_dev
*
dev
;
struct
pci_bus
*
bus
;
int
is_66mhz
;
is_66mhz
=
pbm
->
is_66mhz_capable
&&
pbm
->
all_devs_66mhz
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
nex
t
)
pdev_setup_busmastering
(
pci_dev_b
(
walk
)
,
is_66mhz
);
list_for_each_entry
(
dev
,
&
pbus
->
devices
,
bus_lis
t
)
pdev_setup_busmastering
(
dev
,
is_66mhz
);
walk
=
&
pbus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
children
;
walk
=
walk
->
next
)
pci_setup_busmastering
(
pbm
,
pci_bus_b
(
walk
));
list_for_each_entry
(
bus
,
&
pbus
->
children
,
node
)
pci_setup_busmastering
(
pbm
,
bus
);
}
void
pci_register_legacy_regions
(
struct
resource
*
io_res
,
...
...
@@ -987,10 +966,10 @@ void pci_scan_for_target_abort(struct pci_controller_info *p,
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
struct
pci_dev
*
pdev
;
struct
pci_bus
*
bus
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
next
)
{
struct
pci_dev
*
pdev
=
pci_dev_b
(
walk
);
list_for_each_entry
(
pdev
,
&
pbus
->
devices
,
bus_list
)
{
u16
status
,
error_bits
;
pci_read_config_word
(
pdev
,
PCI_STATUS
,
&
status
);
...
...
@@ -1005,19 +984,18 @@ void pci_scan_for_target_abort(struct pci_controller_info *p,
}
}
walk
=
&
pbus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
children
;
walk
=
walk
->
next
)
pci_scan_for_target_abort
(
p
,
pbm
,
pci_bus_b
(
walk
));
list_for_each_entry
(
bus
,
&
pbus
->
children
,
node
)
pci_scan_for_target_abort
(
p
,
pbm
,
bus
);
}
void
pci_scan_for_master_abort
(
struct
pci_controller_info
*
p
,
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
struct
pci_dev
*
pdev
;
struct
pci_bus
*
bus
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
next
)
{
struct
pci_dev
*
pdev
=
pci_dev_b
(
walk
);
list_for_each_entry
(
pdev
,
&
pbus
->
devices
,
bus_list
)
{
u16
status
,
error_bits
;
pci_read_config_word
(
pdev
,
PCI_STATUS
,
&
status
);
...
...
@@ -1031,19 +1009,18 @@ void pci_scan_for_master_abort(struct pci_controller_info *p,
}
}
walk
=
&
pbus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
children
;
walk
=
walk
->
next
)
pci_scan_for_master_abort
(
p
,
pbm
,
pci_bus_b
(
walk
));
list_for_each_entry
(
bus
,
&
pbus
->
children
,
node
)
pci_scan_for_master_abort
(
p
,
pbm
,
bus
);
}
void
pci_scan_for_parity_error
(
struct
pci_controller_info
*
p
,
struct
pci_pbm_info
*
pbm
,
struct
pci_bus
*
pbus
)
{
struct
list_head
*
walk
=
&
pbus
->
devices
;
struct
pci_dev
*
pdev
;
struct
pci_bus
*
bus
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
devices
;
walk
=
walk
->
next
)
{
struct
pci_dev
*
pdev
=
pci_dev_b
(
walk
);
list_for_each_entry
(
pdev
,
&
pbus
->
devices
,
bus_list
)
{
u16
status
,
error_bits
;
pci_read_config_word
(
pdev
,
PCI_STATUS
,
&
status
);
...
...
@@ -1058,7 +1035,6 @@ void pci_scan_for_parity_error(struct pci_controller_info *p,
}
}
walk
=
&
pbus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
pbus
->
children
;
walk
=
walk
->
next
)
pci_scan_for_parity_error
(
p
,
pbm
,
pci_bus_b
(
walk
));
list_for_each_entry
(
bus
,
&
pbus
->
children
,
node
)
pci_scan_for_parity_error
(
p
,
pbm
,
bus
);
}
arch/sparc64/kernel/pci_impl.h
View file @
a0adf3b1
...
...
@@ -11,7 +11,6 @@
#include <linux/spinlock.h>
#include <asm/io.h>
extern
spinlock_t
pci_controller_lock
;
extern
struct
pci_controller_info
*
pci_controller_root
;
extern
int
pci_num_controllers
;
...
...
arch/sparc64/kernel/pci_psycho.c
View file @
a0adf3b1
...
...
@@ -1487,22 +1487,18 @@ void __init psycho_init(int node, char *model_name)
struct
linux_prom64_registers
pr_regs
[
3
];
struct
pci_controller_info
*
p
;
struct
pci_iommu
*
iommu
;
unsigned
long
flags
;
u32
upa_portid
;
int
is_pbm_a
,
err
;
upa_portid
=
prom_getintdefault
(
node
,
"upa-portid"
,
0xff
);
spin_lock_irqsave
(
&
pci_controller_lock
,
flags
);
for
(
p
=
pci_controller_root
;
p
;
p
=
p
->
next
)
{
if
(
p
->
pbm_A
.
portid
==
upa_portid
)
{
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
is_pbm_a
=
(
p
->
pbm_A
.
prom_node
==
0
);
psycho_pbm_init
(
p
,
node
,
is_pbm_a
);
return
;
}
}
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
p
=
kmalloc
(
sizeof
(
struct
pci_controller_info
),
GFP_ATOMIC
);
if
(
!
p
)
{
...
...
@@ -1518,10 +1514,8 @@ void __init psycho_init(int node, char *model_name)
memset
(
iommu
,
0
,
sizeof
(
*
iommu
));
p
->
pbm_A
.
iommu
=
p
->
pbm_B
.
iommu
=
iommu
;
spin_lock_irqsave
(
&
pci_controller_lock
,
flags
);
p
->
next
=
pci_controller_root
;
pci_controller_root
=
p
;
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
p
->
pbm_A
.
portid
=
upa_portid
;
p
->
pbm_B
.
portid
=
upa_portid
;
...
...
arch/sparc64/kernel/pci_sabre.c
View file @
a0adf3b1
...
...
@@ -1113,10 +1113,9 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
static
void
__init
apb_init
(
struct
pci_controller_info
*
p
,
struct
pci_bus
*
sabre_bus
)
{
struct
list_head
*
walk
=
&
sabre_bus
->
devices
;
struct
pci_dev
*
pdev
;
for
(
walk
=
walk
->
next
;
walk
!=
&
sabre_bus
->
devices
;
walk
=
walk
->
next
)
{
struct
pci_dev
*
pdev
=
pci_dev_b
(
walk
);
list_for_each_entry
(
pdev
,
&
sabre_bus
->
devices
,
bus_list
)
{
if
(
pdev
->
vendor
==
PCI_VENDOR_ID_SUN
&&
pdev
->
device
==
PCI_DEVICE_ID_SUN_SIMBA
)
{
...
...
@@ -1178,10 +1177,9 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
static
void
__init
sabre_scan_bus
(
struct
pci_controller_info
*
p
)
{
static
int
once
;
struct
pci_bus
*
sabre_bus
;
struct
pci_bus
*
sabre_bus
,
*
pbus
;
struct
pci_pbm_info
*
pbm
;
struct
pcidev_cookie
*
cookie
;
struct
list_head
*
walk
;
int
sabres_scanned
;
/* The APB bridge speaks to the Sabre host PCI bridge
...
...
@@ -1217,9 +1215,7 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
sabres_scanned
=
0
;
walk
=
&
sabre_bus
->
children
;
for
(
walk
=
walk
->
next
;
walk
!=
&
sabre_bus
->
children
;
walk
=
walk
->
next
)
{
struct
pci_bus
*
pbus
=
pci_bus_b
(
walk
);
list_for_each_entry
(
pbus
,
&
sabre_bus
->
children
,
node
)
{
if
(
pbus
->
number
==
p
->
pbm_A
.
pci_first_busno
)
{
pbm
=
&
p
->
pbm_A
;
...
...
@@ -1554,7 +1550,6 @@ void __init sabre_init(int pnode, char *model_name)
struct
linux_prom64_registers
pr_regs
[
2
];
struct
pci_controller_info
*
p
;
struct
pci_iommu
*
iommu
;
unsigned
long
flags
;
int
tsbsize
,
err
;
u32
busrange
[
2
];
u32
vdma
[
2
];
...
...
@@ -1602,10 +1597,8 @@ void __init sabre_init(int pnode, char *model_name)
upa_portid
=
prom_getintdefault
(
pnode
,
"upa-portid"
,
0xff
);
spin_lock_irqsave
(
&
pci_controller_lock
,
flags
);
p
->
next
=
pci_controller_root
;
pci_controller_root
=
p
;
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
p
->
pbm_A
.
portid
=
upa_portid
;
p
->
pbm_B
.
portid
=
upa_portid
;
...
...
arch/sparc64/kernel/pci_schizo.c
View file @
a0adf3b1
...
...
@@ -2081,13 +2081,11 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
{
struct
pci_controller_info
*
p
;
struct
pci_iommu
*
iommu
;
unsigned
long
flags
;
int
is_pbm_a
;
u32
portid
;
portid
=
prom_getintdefault
(
node
,
"portid"
,
0xff
);
spin_lock_irqsave
(
&
pci_controller_lock
,
flags
);
for
(
p
=
pci_controller_root
;
p
;
p
=
p
->
next
)
{
struct
pci_pbm_info
*
pbm
;
...
...
@@ -2099,13 +2097,11 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
&
p
->
pbm_B
);
if
(
portid_compare
(
pbm
->
portid
,
portid
,
chip_type
))
{
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
is_pbm_a
=
(
p
->
pbm_A
.
prom_node
==
0
);
schizo_pbm_init
(
p
,
node
,
portid
,
chip_type
);
return
;
}
}
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
p
=
kmalloc
(
sizeof
(
struct
pci_controller_info
),
GFP_ATOMIC
);
if
(
!
p
)
{
...
...
@@ -2130,10 +2126,8 @@ static void __init __schizo_init(int node, char *model_name, int chip_type)
memset
(
iommu
,
0
,
sizeof
(
*
iommu
));
p
->
pbm_B
.
iommu
=
iommu
;
spin_lock_irqsave
(
&
pci_controller_lock
,
flags
);
p
->
next
=
pci_controller_root
;
pci_controller_root
=
p
;
spin_unlock_irqrestore
(
&
pci_controller_lock
,
flags
);
p
->
index
=
pci_num_controllers
++
;
p
->
pbms_same_domain
=
0
;
...
...
arch/sparc64/kernel/signal32.c
View file @
a0adf3b1
...
...
@@ -86,9 +86,62 @@ struct new_signal_frame32 {
__siginfo_fpu_t
fpu_state
;
};
struct
siginfo32
{
int
si_signo
;
int
si_errno
;
int
si_code
;
union
{
int
_pad
[
SI_PAD_SIZE32
];
/* kill() */
struct
{
compat_pid_t
_pid
;
/* sender's pid */
unsigned
int
_uid
;
/* sender's uid */
}
_kill
;
/* POSIX.1b timers */
struct
{
timer_t
_tid
;
/* timer id */
int
_overrun
;
/* overrun count */
sigval_t32
_sigval
;
/* same as below */
int
_sys_private
;
/* not to be passed to user */
}
_timer
;
/* POSIX.1b signals */
struct
{
compat_pid_t
_pid
;
/* sender's pid */
unsigned
int
_uid
;
/* sender's uid */
sigval_t32
_sigval
;
}
_rt
;
/* SIGCHLD */
struct
{
compat_pid_t
_pid
;
/* which child */
unsigned
int
_uid
;
/* sender's uid */
int
_status
;
/* exit code */
compat_clock_t
_utime
;
compat_clock_t
_stime
;
struct
compat_rusage
_rusage
;
}
_sigchld
;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
struct
{
u32
_addr
;
/* faulting insn/memory ref. */
int
_trapno
;
}
_sigfault
;
/* SIGPOLL */
struct
{
int
_band
;
/* POLL_IN, POLL_OUT, POLL_MSG */
int
_fd
;
}
_sigpoll
;
}
_sifields
;
};
struct
rt_signal_frame32
{
struct
sparc_stackf32
ss
;
s
iginfo_t32
info
;
s
truct
siginfo32
info
;
struct
pt_regs32
regs
;
compat_sigset_t
mask
;
/* __siginfo_fpu32_t * */
u32
fpu_save
;
...
...
@@ -105,11 +158,11 @@ struct rt_signal_frame32 {
#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
int
copy_siginfo_to_user32
(
s
iginfo_t
32
__user
*
to
,
siginfo_t
*
from
)
int
copy_siginfo_to_user32
(
s
truct
siginfo
32
__user
*
to
,
siginfo_t
*
from
)
{
int
err
;
if
(
!
access_ok
(
VERIFY_WRITE
,
to
,
sizeof
(
s
iginfo_t
32
)))
if
(
!
access_ok
(
VERIFY_WRITE
,
to
,
sizeof
(
s
truct
siginfo
32
)))
return
-
EFAULT
;
/* If you change siginfo_t structure, please be sure
...
...
@@ -135,6 +188,8 @@ int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
err
|=
__put_user
(
from
->
si_utime
,
&
to
->
si_utime
);
err
|=
__put_user
(
from
->
si_stime
,
&
to
->
si_stime
);
err
|=
__put_user
(
from
->
si_status
,
&
to
->
si_status
);
err
|=
put_compat_rusage
(
&
from
->
si_rusage
,
&
to
->
si_rusage
);
default:
err
|=
__put_user
(
from
->
si_pid
,
&
to
->
si_pid
);
err
|=
__put_user
(
from
->
si_uid
,
&
to
->
si_uid
);
...
...
@@ -155,6 +210,22 @@ int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
return
err
;
}
/* CAUTION: This is just a very minimalist implementation for the
* sake of compat_sys_rt_sigqueueinfo()
*/
int
copy_siginfo_to_kernel32
(
siginfo_t
*
to
,
struct
siginfo32
__user
*
from
)
{
if
(
!
access_ok
(
VERIFY_WRITE
,
from
,
sizeof
(
struct
siginfo32
)))
return
-
EFAULT
;
if
(
copy_from_user
(
to
,
from
,
3
*
sizeof
(
int
))
||
copy_from_user
(
to
->
_sifields
.
_pad
,
from
->
_sifields
.
_pad
,
SI_PAD_SIZE
))
return
-
EFAULT
;
return
0
;
}
/*
* atomically swap in the new signal mask, and wait for a signal.
* This is really tricky on the Sparc, watch out...
...
...
arch/sparc64/kernel/sys_sparc32.c
View file @
a0adf3b1
...
...
@@ -1045,7 +1045,7 @@ asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set,
}
asmlinkage
long
sys32_rt_sigtimedwait
(
compat_sigset_t
__user
*
uthese
,
s
iginfo_t
32
__user
*
uinfo
,
s
truct
siginfo
32
__user
*
uinfo
,
struct
compat_timespec
__user
*
uts
,
compat_size_t
sigsetsize
)
{
...
...
@@ -1130,15 +1130,15 @@ asmlinkage long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese,
}
asmlinkage
long
compat_sys_rt_sigqueueinfo
(
int
pid
,
int
sig
,
s
iginfo_t
32
__user
*
uinfo
)
s
truct
siginfo
32
__user
*
uinfo
)
{
siginfo_t
info
;
int
ret
;
mm_segment_t
old_fs
=
get_fs
();
if
(
copy_from_user
(
&
info
,
uinfo
,
3
*
sizeof
(
int
))
||
copy_from_user
(
info
.
_sifields
.
_pad
,
uinfo
->
_sifields
.
_pad
,
SI_PAD_SIZE
))
if
(
copy_siginfo_to_kernel32
(
&
info
,
uinfo
))
return
-
EFAULT
;
set_fs
(
KERNEL_DS
);
ret
=
sys_rt_sigqueueinfo
(
pid
,
sig
,
(
siginfo_t
__user
*
)
&
info
);
set_fs
(
old_fs
);
...
...
@@ -1736,3 +1736,23 @@ sys32_timer_create(u32 clock, struct sigevent32 __user *se32,
return
err
;
}
asmlinkage
long
compat_sys_waitid
(
u32
which
,
u32
pid
,
struct
siginfo32
__user
*
uinfo
,
u32
options
)
{
siginfo_t
info
;
long
ret
;
mm_segment_t
old_fs
=
get_fs
();
memset
(
&
info
,
0
,
sizeof
(
info
));
set_fs
(
KERNEL_DS
);
ret
=
sys_waitid
((
int
)
which
,
(
compat_pid_t
)
pid
,
(
siginfo_t
__user
*
)
&
info
,
(
int
)
options
);
set_fs
(
old_fs
);
if
(
ret
<
0
||
info
.
si_signo
==
0
)
return
ret
;
BUG_ON
(
info
.
si_code
&
__SI_MASK
);
info
.
si_code
|=
__SI_CHLD
;
return
copy_siginfo_to_user32
(
uinfo
,
&
info
);
}
arch/sparc64/kernel/systbls.S
View file @
a0adf3b1
...
...
@@ -75,7 +75,7 @@ sys_call_table32:
/*
260
*/
.
word
compat_sys_sched_getaffinity
,
compat_sys_sched_setaffinity
,
sys32_timer_settime
,
compat_timer_gettime
,
sys_timer_getoverrun
.
word
sys_timer_delete
,
sys32_timer_create
,
sys_ni_syscall
,
compat_sys_io_setup
,
sys_io_destroy
/*
270
*/
.
word
sys32_io_submit
,
sys_io_cancel
,
compat_sys_io_getevents
,
sys32_mq_open
,
sys_mq_unlink
.
word
sys_mq_timedsend
,
sys_mq_timedreceive
,
compat_sys_mq_notify
,
compat_sys_mq_getsetattr
,
sys_ni_syscall
.
word
sys_mq_timedsend
,
sys_mq_timedreceive
,
compat_sys_mq_notify
,
compat_sys_mq_getsetattr
,
compat_sys_waitid
/*
280
*/
.
word
sys_ni_syscall
,
sys_ni_syscall
,
sys_ni_syscall
#endif /* CONFIG_COMPAT */
...
...
@@ -141,7 +141,7 @@ sys_call_table:
/*
260
*/
.
word
sys_sched_getaffinity
,
sys_sched_setaffinity
,
sys_timer_settime
,
sys_timer_gettime
,
sys_timer_getoverrun
.
word
sys_timer_delete
,
sys_timer_create
,
sys_ni_syscall
,
sys_io_setup
,
sys_io_destroy
/*
270
*/
.
word
sys_io_submit
,
sys_io_cancel
,
sys_io_getevents
,
sys_mq_open
,
sys_mq_unlink
.
word
sys_mq_timedsend
,
sys_mq_timedreceive
,
sys_mq_notify
,
sys_mq_getsetattr
,
sys_
ni_syscall
.
word
sys_mq_timedsend
,
sys_mq_timedreceive
,
sys_mq_notify
,
sys_mq_getsetattr
,
sys_
waitid
/*
280
*/
.
word
sys_ni_syscall
,
sys_ni_syscall
,
sys_ni_syscall
#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
...
...
arch/sparc64/kernel/traps.c
View file @
a0adf3b1
...
...
@@ -36,10 +36,24 @@
#include <asm/psrcompat.h>
#include <asm/processor.h>
#include <asm/timer.h>
#include <asm/kdebug.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
struct
notifier_block
*
sparc64die_chain
;
static
spinlock_t
die_notifier_lock
=
SPIN_LOCK_UNLOCKED
;
int
register_die_notifier
(
struct
notifier_block
*
nb
)
{
int
err
=
0
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
die_notifier_lock
,
flags
);
err
=
notifier_chain_register
(
&
sparc64die_chain
,
nb
);
spin_unlock_irqrestore
(
&
die_notifier_lock
,
flags
);
return
err
;
}
/* When an irrecoverable trap occurs at tl > 0, the trap entry
* code logs the trap state registers at every level in the trap
* stack. It is found at (pt_regs + sizeof(pt_regs)) and the layout
...
...
@@ -71,11 +85,20 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
}
}
void
bad_trap
(
struct
pt_regs
*
regs
,
long
lvl
)
void
do_call_debug
(
struct
pt_regs
*
regs
)
{
notify_die
(
DIE_CALL
,
"debug call"
,
regs
,
0
,
255
,
SIGINT
);
}
void
bad_trap
(
struct
pt_regs
*
regs
,
long
lvl
)
{
char
buffer
[
32
];
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"bad trap"
,
regs
,
0
,
lvl
,
SIGTRAP
)
==
NOTIFY_OK
)
return
;
if
(
lvl
<
0x100
)
{
sprintf
(
buffer
,
"Bad hw trap %lx at tl0
\n
"
,
lvl
);
die_if_kernel
(
buffer
,
regs
);
...
...
@@ -84,7 +107,7 @@ void bad_trap (struct pt_regs *regs, long lvl)
lvl
-=
0x100
;
if
(
regs
->
tstate
&
TSTATE_PRIV
)
{
sprintf
(
buffer
,
"Kernel bad sw trap %lx"
,
lvl
);
die_if_kernel
(
buffer
,
regs
);
die_if_kernel
(
buffer
,
regs
);
}
if
(
test_thread_flag
(
TIF_32BIT
))
{
regs
->
tpc
&=
0xffffffff
;
...
...
@@ -98,10 +121,14 @@ void bad_trap (struct pt_regs *regs, long lvl)
force_sig_info
(
SIGILL
,
&
info
,
current
);
}
void
bad_trap_tl1
(
struct
pt_regs
*
regs
,
long
lvl
)
void
bad_trap_tl1
(
struct
pt_regs
*
regs
,
long
lvl
)
{
char
buffer
[
32
];
if
(
notify_die
(
DIE_TRAP_TL1
,
"bad trap tl1"
,
regs
,
0
,
lvl
,
SIGTRAP
)
==
NOTIFY_OK
)
return
;
dump_tl1_traplog
((
struct
tl1_traplog
*
)(
regs
+
1
));
sprintf
(
buffer
,
"Bad trap %lx at tl>0"
,
lvl
);
...
...
@@ -121,6 +148,10 @@ void instruction_access_exception(struct pt_regs *regs,
{
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"instruction access exception"
,
regs
,
0
,
0x8
,
SIGTRAP
)
==
NOTIFY_OK
)
return
;
if
(
regs
->
tstate
&
TSTATE_PRIV
)
{
printk
(
"instruction_access_exception: SFSR[%016lx] SFAR[%016lx], going.
\n
"
,
sfsr
,
sfar
);
...
...
@@ -141,15 +172,23 @@ void instruction_access_exception(struct pt_regs *regs,
void
instruction_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_OK
)
return
;
dump_tl1_traplog
((
struct
tl1_traplog
*
)(
regs
+
1
));
instruction_access_exception
(
regs
,
sfsr
,
sfar
);
}
void
data_access_exception
(
struct
pt_regs
*
regs
,
unsigned
long
sfsr
,
unsigned
long
sfar
)
void
data_access_exception
(
struct
pt_regs
*
regs
,
unsigned
long
sfsr
,
unsigned
long
sfar
)
{
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"data access exception"
,
regs
,
0
,
0x30
,
SIGTRAP
)
==
NOTIFY_OK
)
return
;
if
(
regs
->
tstate
&
TSTATE_PRIV
)
{
/* Test if this comes from uaccess places. */
unsigned
long
fixup
;
...
...
@@ -220,6 +259,10 @@ void do_iae(struct pt_regs *regs)
spitfire_clean_and_reenable_l1_caches
();
if
(
notify_die
(
DIE_TRAP
,
"instruction access exception"
,
regs
,
0
,
0x8
,
SIGTRAP
)
==
NOTIFY_OK
)
return
;
info
.
si_signo
=
SIGBUS
;
info
.
si_errno
=
0
;
info
.
si_code
=
BUS_OBJERR
;
...
...
@@ -230,6 +273,8 @@ void do_iae(struct pt_regs *regs)
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
();
...
...
@@ -244,7 +289,18 @@ void do_dae(struct pt_regs *regs)
return
;
}
#endif
do_iae
(
regs
);
spitfire_clean_and_reenable_l1_caches
();
if
(
notify_die
(
DIE_TRAP
,
"data access exception"
,
regs
,
0
,
0x30
,
SIGTRAP
)
==
NOTIFY_OK
)
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
);
}
static
char
ecc_syndrome_table
[]
=
{
...
...
@@ -1638,6 +1694,10 @@ void do_fpe_common(struct pt_regs *regs)
void
do_fpieee
(
struct
pt_regs
*
regs
)
{
if
(
notify_die
(
DIE_TRAP
,
"fpu exception ieee"
,
regs
,
0
,
0x24
,
SIGFPE
)
==
NOTIFY_OK
)
return
;
do_fpe_common
(
regs
);
}
...
...
@@ -1648,6 +1708,10 @@ void do_fpother(struct pt_regs *regs)
struct
fpustate
*
f
=
FPUSTATE
;
int
ret
=
0
;
if
(
notify_die
(
DIE_TRAP
,
"fpu exception other"
,
regs
,
0
,
0x25
,
SIGFPE
)
==
NOTIFY_OK
)
return
;
switch
((
current_thread_info
()
->
xfsr
[
0
]
&
0x1c000
))
{
case
(
2
<<
14
):
/* unfinished_FPop */
case
(
3
<<
14
):
/* unimplemented_FPop */
...
...
@@ -1663,6 +1727,10 @@ void do_tof(struct pt_regs *regs)
{
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"tagged arithmetic overflow"
,
regs
,
0
,
0x26
,
SIGEMT
)
==
NOTIFY_OK
)
return
;
if
(
regs
->
tstate
&
TSTATE_PRIV
)
die_if_kernel
(
"Penguin overflow trap from kernel mode"
,
regs
);
if
(
test_thread_flag
(
TIF_32BIT
))
{
...
...
@@ -1681,6 +1749,10 @@ void do_div0(struct pt_regs *regs)
{
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"integer division by zero"
,
regs
,
0
,
0x28
,
SIGFPE
)
==
NOTIFY_OK
)
return
;
if
(
regs
->
tstate
&
TSTATE_PRIV
)
die_if_kernel
(
"TL0: Kernel divide by zero."
,
regs
);
if
(
test_thread_flag
(
TIF_32BIT
))
{
...
...
@@ -1786,6 +1858,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
"
\\
__U_/
\n
"
);
printk
(
"%s(%d): %s [#%d]
\n
"
,
current
->
comm
,
current
->
pid
,
str
,
++
die_counter
);
notify_die
(
DIE_OOPS
,
str
,
regs
,
0
,
255
,
SIGSEGV
);
__asm__
__volatile__
(
"flushw"
);
__show_regs
(
regs
);
if
(
regs
->
tstate
&
TSTATE_PRIV
)
{
...
...
@@ -1834,6 +1907,10 @@ void do_illegal_instruction(struct pt_regs *regs)
u32
insn
;
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"illegal instruction"
,
regs
,
0
,
0x10
,
SIGILL
)
==
NOTIFY_OK
)
return
;
if
(
tstate
&
TSTATE_PRIV
)
die_if_kernel
(
"Kernel illegal instruction"
,
regs
);
if
(
test_thread_flag
(
TIF_32BIT
))
...
...
@@ -1859,6 +1936,10 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo
{
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"memory address unaligned"
,
regs
,
0
,
0x34
,
SIGSEGV
)
==
NOTIFY_OK
)
return
;
if
(
regs
->
tstate
&
TSTATE_PRIV
)
{
extern
void
kernel_unaligned_trap
(
struct
pt_regs
*
regs
,
unsigned
int
insn
,
...
...
@@ -1881,6 +1962,10 @@ void do_privop(struct pt_regs *regs)
{
siginfo_t
info
;
if
(
notify_die
(
DIE_TRAP
,
"privileged operation"
,
regs
,
0
,
0x11
,
SIGILL
)
==
NOTIFY_OK
)
return
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
regs
->
tpc
&=
0xffffffff
;
regs
->
tnpc
&=
0xffffffff
;
...
...
arch/sparc64/kernel/ttable.S
View file @
a0adf3b1
...
...
@@ -158,7 +158,7 @@ tl0_resv164: BTRAP(0x164) BTRAP(0x165) BTRAP(0x166) BTRAP(0x167) BTRAP(0x168)
tl0_resv169
:
BTRAP
(0
x169
)
BTRAP
(
0x16a
)
BTRAP
(
0x16b
)
BTRAP
(
0x16c
)
tl0_linux64
:
LINUX_64BIT_SYSCALL_TRAP
tl0_gsctx
:
TRAP
(
sparc64_get_context
)
TRAP
(
sparc64_set_context
)
tl0_resv170
:
BTRAP
(0
x170
)
B
TRAP
(
0x171
)
BTRAP
(
0x172
)
tl0_resv170
:
KPROBES_TRAP
(0
x170
)
KPROBES_
TRAP
(
0x171
)
BTRAP
(
0x172
)
tl0_resv173
:
BTRAP
(0
x173
)
BTRAP
(
0x174
)
BTRAP
(
0x175
)
BTRAP
(
0x176
)
BTRAP
(
0x177
)
tl0_resv178
:
BTRAP
(0
x178
)
BTRAP
(
0x179
)
BTRAP
(
0x17a
)
BTRAP
(
0x17b
)
BTRAP
(
0x17c
)
tl0_resv17d
:
BTRAP
(0
x17d
)
BTRAP
(
0x17e
)
BTRAP
(
0x17f
)
...
...
arch/sparc64/mm/fault.c
View file @
a0adf3b1
...
...
@@ -27,6 +27,7 @@
#include <asm/asi.h>
#include <asm/lsu.h>
#include <asm/sections.h>
#include <asm/kdebug.h>
#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
...
...
@@ -147,6 +148,9 @@ static void unhandled_fault(unsigned long address, struct task_struct *tsk,
printk
(
KERN_ALERT
"tsk->{mm,active_mm}->pgd = %016lx
\n
"
,
(
tsk
->
mm
?
(
unsigned
long
)
tsk
->
mm
->
pgd
:
(
unsigned
long
)
tsk
->
active_mm
->
pgd
));
if
(
notify_die
(
DIE_GPF
,
"general protection fault"
,
regs
,
0
,
0
,
SIGSEGV
)
==
NOTIFY_OK
)
return
;
die_if_kernel
(
"Oops"
,
regs
);
}
...
...
@@ -318,8 +322,13 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs)
int
si_code
,
fault_code
;
unsigned
long
address
;
si_code
=
SEGV_MAPERR
;
fault_code
=
get_thread_fault_code
();
if
(
notify_die
(
DIE_PAGE_FAULT
,
"page_fault"
,
regs
,
fault_code
,
0
,
SIGSEGV
)
==
NOTIFY_OK
)
return
;
si_code
=
SEGV_MAPERR
;
address
=
current_thread_info
()
->
fault_address
;
if
((
fault_code
&
FAULT_CODE_ITLB
)
&&
...
...
arch/sparc64/solaris/misc.c
View file @
a0adf3b1
...
...
@@ -137,21 +137,34 @@ asmlinkage int solaris_brk(u32 brk)
return
sunos_brk
(
brk
);
}
#define set_utsfield(to, from, dotchop, countfrom) { \
char *p; \
int i, len = (countfrom) ? \
((sizeof(to) > sizeof(from) ? \
sizeof(from) : sizeof(to))) : sizeof(to); \
if (copy_to_user(to, from, len)) \
return -EFAULT; \
if (dotchop) \
for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
else \
i = len - 1; \
if (__put_user('\0', (char __user *)((to)+i))) \
return -EFAULT; \
static
int
__set_utsfield
(
char
__user
*
to
,
int
to_size
,
const
char
*
from
,
int
from_size
,
int
dotchop
,
int
countfrom
)
{
int
len
=
countfrom
?
(
to_size
>
from_size
?
from_size
:
to_size
)
:
to_size
;
int
off
;
if
(
copy_to_user
(
to
,
from
,
len
))
return
-
EFAULT
;
if
(
dotchop
)
{
off
=
(
strnchr
(
from
,
len
,
'.'
)
-
from
);
}
else
{
off
=
len
-
1
;
}
if
(
__put_user
(
'\0'
,
to
+
off
))
return
-
EFAULT
;
return
0
;
}
#define set_utsfield(to, from, dotchop, countfrom) \
__set_utsfield((to), sizeof(to), \
(from), sizeof(from), \
(dotchop), (countfrom))
struct
sol_uname
{
char
sysname
[
9
];
char
nodename
[
9
];
...
...
@@ -219,17 +232,20 @@ static char *serial(char *buffer)
asmlinkage
int
solaris_utssys
(
u32
buf
,
u32
flags
,
int
which
,
u32
buf2
)
{
struct
sol_uname
__user
*
v
=
A
(
buf
);
int
err
;
switch
(
which
)
{
case
0
:
/* old uname */
/* Let's cheat */
set_utsfield
(
v
->
sysname
,
"SunOS"
,
1
,
0
);
err
=
set_utsfield
(
v
->
sysname
,
"SunOS"
,
1
,
0
);
down_read
(
&
uts_sem
);
set_utsfield
(
v
->
nodename
,
system_utsname
.
nodename
,
1
,
1
);
err
|=
set_utsfield
(
v
->
nodename
,
system_utsname
.
nodename
,
1
,
1
);
up_read
(
&
uts_sem
);
set_utsfield
(
v
->
release
,
"2.6"
,
0
,
0
);
set_utsfield
(
v
->
version
,
"Generic"
,
0
,
0
);
set_utsfield
(
v
->
machine
,
machine
(),
0
,
0
);
return
0
;
err
|=
set_utsfield
(
v
->
release
,
"2.6"
,
0
,
0
);
err
|=
set_utsfield
(
v
->
version
,
"Generic"
,
0
,
0
);
err
|=
set_utsfield
(
v
->
machine
,
machine
(),
0
,
0
);
return
(
err
?
-
EFAULT
:
0
)
;
case
2
:
/* ustat */
return
-
ENOSYS
;
case
3
:
/* fusers */
...
...
@@ -242,15 +258,18 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
asmlinkage
int
solaris_utsname
(
u32
buf
)
{
struct
sol_utsname
__user
*
v
=
A
(
buf
);
int
err
;
/* Why should we not lie a bit? */
down_read
(
&
uts_sem
);
set_utsfield
(
v
->
sysname
,
"SunOS"
,
0
,
0
);
set_utsfield
(
v
->
nodename
,
system_utsname
.
nodename
,
1
,
1
);
set_utsfield
(
v
->
release
,
"5.6"
,
0
,
0
);
set_utsfield
(
v
->
version
,
"Generic"
,
0
,
0
);
set_utsfield
(
v
->
machine
,
machine
(),
0
,
0
);
err
=
set_utsfield
(
v
->
sysname
,
"SunOS"
,
0
,
0
);
err
|=
set_utsfield
(
v
->
nodename
,
system_utsname
.
nodename
,
1
,
1
);
err
|=
set_utsfield
(
v
->
release
,
"5.6"
,
0
,
0
);
err
|=
set_utsfield
(
v
->
version
,
"Generic"
,
0
,
0
);
err
|=
set_utsfield
(
v
->
machine
,
machine
(),
0
,
0
);
up_read
(
&
uts_sem
);
return
0
;
return
(
err
?
-
EFAULT
:
0
);
}
#define SI_SYSNAME 1
/* return name of operating system */
...
...
include/asm-sparc/unistd.h
View file @
a0adf3b1
...
...
@@ -290,11 +290,12 @@
#define __NR_io_cancel 271
#define __NR_io_getevents 272
#define __NR_mq_open 273
#define __NR_mq_unlink (__NR_mq_open+1)
#define __NR_mq_timedsend (__NR_mq_open+2)
#define __NR_mq_timedreceive (__NR_mq_open+3)
#define __NR_mq_notify (__NR_mq_open+4)
#define __NR_mq_getsetattr (__NR_mq_open+5)
#define __NR_mq_unlink 274
#define __NR_mq_timedsend 275
#define __NR_mq_timedreceive 276
#define __NR_mq_notify 277
#define __NR_mq_getsetattr 278
#define __NR_waitid 279
/* WARNING: You MAY NOT add syscall numbers larger than 282, since
* all of the syscall tables in the Sparc kernel are
...
...
include/asm-sparc64/kdebug.h
View file @
a0adf3b1
#ifndef _SPARC64_KDEBUG_H
#define _SPARC64_KDEBUG_H
/*
* No kernel debugger on sparc64. Kept here because drivers/sbus/char/
* includes it for sparc32 sake.
/* Nearly identical to x86_64/i386 code. */
#include <linux/notifier.h>
struct
pt_regs
;
struct
die_args
{
struct
pt_regs
*
regs
;
const
char
*
str
;
long
err
;
int
trapnr
;
int
signr
;
};
/* Note - you should never unregister because that can race with NMIs.
* If you really want to do it first unregister - then synchronize_kernel
* - then free.
*/
int
register_die_notifier
(
struct
notifier_block
*
nb
);
extern
struct
notifier_block
*
sparc64die_chain
;
extern
void
bad_trap
(
struct
pt_regs
*
,
long
);
/* Grossly misnamed. */
enum
die_val
{
DIE_OOPS
=
1
,
DIE_DEBUG
,
/* ta 0x70 */
DIE_DEBUG_2
,
/* ta 0x71 */
DIE_DIE
,
DIE_TRAP
,
DIE_TRAP_TL1
,
DIE_GPF
,
DIE_CALL
,
DIE_PAGE_FAULT
,
};
static
inline
int
notify_die
(
enum
die_val
val
,
char
*
str
,
struct
pt_regs
*
regs
,
long
err
,
int
trap
,
int
sig
)
{
struct
die_args
args
=
{
.
regs
=
regs
,
.
str
=
str
,
.
err
=
err
,
.
trapnr
=
trap
,
.
signr
=
sig
};
return
notifier_call_chain
(
&
sparc64die_chain
,
val
,
&
args
);
}
#endif
include/asm-sparc64/kprobes.h
0 → 100644
View file @
a0adf3b1
#ifndef _SPARC64_KPROBES_H
#define _SPARC64_KPROBES_H
#include <linux/config.h>
#include <linux/types.h>
typedef
u32
kprobe_opcode_t
;
#define BREAKPOINT_INSTRUCTION 0x91d02070
/* ta 0x70 */
#define BREAKPOINT_INSTRUCTION_2 0x91d02071
/* ta 0x71 */
#define MAX_INSN_SIZE 2
#ifdef CONFIG_KPROBES
extern
int
kprobe_exceptions_notify
(
struct
notifier_block
*
self
,
unsigned
long
val
,
void
*
data
);
#else
/* !CONFIG_KPROBES */
static
inline
int
kprobe_exceptions_notify
(
struct
notifier_block
*
self
,
unsigned
long
val
,
void
*
data
)
{
return
0
;
}
#endif
#endif
/* _SPARC64_KPROBES_H */
include/asm-sparc64/siginfo.h
View file @
a0adf3b1
...
...
@@ -24,57 +24,8 @@ typedef union sigval32 {
u32
sival_ptr
;
}
sigval_t32
;
typedef
struct
siginfo32
{
int
si_signo
;
int
si_errno
;
int
si_code
;
struct
siginfo32
;
union
{
int
_pad
[
SI_PAD_SIZE32
];
/* kill() */
struct
{
compat_pid_t
_pid
;
/* sender's pid */
unsigned
int
_uid
;
/* sender's uid */
}
_kill
;
/* POSIX.1b timers */
struct
{
timer_t
_tid
;
/* timer id */
int
_overrun
;
/* overrun count */
sigval_t32
_sigval
;
/* same as below */
int
_sys_private
;
/* not to be passed to user */
}
_timer
;
/* POSIX.1b signals */
struct
{
compat_pid_t
_pid
;
/* sender's pid */
unsigned
int
_uid
;
/* sender's uid */
sigval_t32
_sigval
;
}
_rt
;
/* SIGCHLD */
struct
{
compat_pid_t
_pid
;
/* which child */
unsigned
int
_uid
;
/* sender's uid */
int
_status
;
/* exit code */
compat_clock_t
_utime
;
compat_clock_t
_stime
;
}
_sigchld
;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
struct
{
u32
_addr
;
/* faulting insn/memory ref. */
int
_trapno
;
}
_sigfault
;
/* SIGPOLL */
struct
{
int
_band
;
/* POLL_IN, POLL_OUT, POLL_MSG */
int
_fd
;
}
_sigpoll
;
}
_sifields
;
}
siginfo_t32
;
#endif
/* CONFIG_COMPAT */
#endif
/* __KERNEL__ */
...
...
@@ -105,7 +56,8 @@ typedef struct sigevent32 {
}
_sigev_un
;
}
sigevent_t32
;
extern
int
copy_siginfo_to_user32
(
siginfo_t32
__user
*
to
,
siginfo_t
*
from
);
extern
int
copy_siginfo_to_user32
(
struct
siginfo32
__user
*
to
,
siginfo_t
*
from
);
extern
int
copy_siginfo_to_kernel32
(
siginfo_t
*
to
,
struct
siginfo32
__user
*
from
);
#endif
/* CONFIG_COMPAT */
...
...
include/asm-sparc64/ttable.h
View file @
a0adf3b1
...
...
@@ -176,6 +176,12 @@
ba,pt %xcc, rtrap_clr_l6; \
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC];
#ifdef CONFIG_KPROBES
#define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl)
#else
#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
#endif
/* Before touching these macros, you owe it to yourself to go and
* see how arch/sparc64/kernel/winfixup.S works... -DaveM
*
...
...
include/asm-sparc64/unistd.h
View file @
a0adf3b1
...
...
@@ -292,11 +292,13 @@
#define __NR_io_cancel 271
#define __NR_io_getevents 272
#define __NR_mq_open 273
#define __NR_mq_unlink (__NR_mq_open+1)
#define __NR_mq_timedsend (__NR_mq_open+2)
#define __NR_mq_timedreceive (__NR_mq_open+3)
#define __NR_mq_notify (__NR_mq_open+4)
#define __NR_mq_getsetattr (__NR_mq_open+5)
#define __NR_mq_unlink 274
#define __NR_mq_timedsend 275
#define __NR_mq_timedreceive 276
#define __NR_mq_notify 277
#define __NR_mq_getsetattr 278
#define __NR_waitid 279
/* WARNING: You MAY NOT add syscall numbers larger than 282, since
* all of the syscall tables in the Sparc kernel are
* sized to have 283 entries (starting at zero). Therefore
...
...
kernel/kprobes.c
View file @
a0adf3b1
...
...
@@ -88,7 +88,8 @@ int register_kprobe(struct kprobe *p)
arch_prepare_kprobe
(
p
);
p
->
opcode
=
*
p
->
addr
;
*
p
->
addr
=
BREAKPOINT_INSTRUCTION
;
flush_icache_range
(
p
->
addr
,
p
->
addr
+
sizeof
(
kprobe_opcode_t
));
flush_icache_range
((
unsigned
long
)
p
->
addr
,
(
unsigned
long
)
p
->
addr
+
sizeof
(
kprobe_opcode_t
));
out:
spin_unlock_irqrestore
(
&
kprobe_lock
,
flags
);
return
ret
;
...
...
@@ -100,7 +101,8 @@ void unregister_kprobe(struct kprobe *p)
spin_lock_irqsave
(
&
kprobe_lock
,
flags
);
*
p
->
addr
=
p
->
opcode
;
hlist_del
(
&
p
->
hlist
);
flush_icache_range
(
p
->
addr
,
p
->
addr
+
sizeof
(
kprobe_opcode_t
));
flush_icache_range
((
unsigned
long
)
p
->
addr
,
(
unsigned
long
)
p
->
addr
+
sizeof
(
kprobe_opcode_t
));
spin_unlock_irqrestore
(
&
kprobe_lock
,
flags
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment