Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
30052c41
Commit
30052c41
authored
Sep 16, 2009
by
Stephen Rothwell
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit 'ia64/test'
parents
01a741a4
932d6180
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
136 additions
and
30 deletions
+136
-30
arch/ia64/include/asm/mca.h
arch/ia64/include/asm/mca.h
+2
-0
arch/ia64/kernel/crash.c
arch/ia64/kernel/crash.c
+57
-26
arch/ia64/kernel/head.S
arch/ia64/kernel/head.S
+1
-1
arch/ia64/kernel/machine_kexec.c
arch/ia64/kernel/machine_kexec.c
+15
-0
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca.c
+13
-2
arch/ia64/kernel/mca_asm.S
arch/ia64/kernel/mca_asm.S
+47
-0
arch/ia64/kernel/relocate_kernel.S
arch/ia64/kernel/relocate_kernel.S
+1
-1
No files found.
arch/ia64/include/asm/mca.h
View file @
30052c41
...
@@ -145,12 +145,14 @@ extern void ia64_mca_ucmc_handler(struct pt_regs *, struct ia64_sal_os_state *);
...
@@ -145,12 +145,14 @@ extern void ia64_mca_ucmc_handler(struct pt_regs *, struct ia64_sal_os_state *);
extern
void
ia64_init_handler
(
struct
pt_regs
*
,
extern
void
ia64_init_handler
(
struct
pt_regs
*
,
struct
switch_stack
*
,
struct
switch_stack
*
,
struct
ia64_sal_os_state
*
);
struct
ia64_sal_os_state
*
);
extern
void
ia64_os_init_on_kdump
(
void
);
extern
void
ia64_monarch_init_handler
(
void
);
extern
void
ia64_monarch_init_handler
(
void
);
extern
void
ia64_slave_init_handler
(
void
);
extern
void
ia64_slave_init_handler
(
void
);
extern
void
ia64_mca_cmc_vector_setup
(
void
);
extern
void
ia64_mca_cmc_vector_setup
(
void
);
extern
int
ia64_reg_MCA_extension
(
int
(
*
fn
)(
void
*
,
struct
ia64_sal_os_state
*
));
extern
int
ia64_reg_MCA_extension
(
int
(
*
fn
)(
void
*
,
struct
ia64_sal_os_state
*
));
extern
void
ia64_unreg_MCA_extension
(
void
);
extern
void
ia64_unreg_MCA_extension
(
void
);
extern
unsigned
long
ia64_get_rnat
(
unsigned
long
*
);
extern
unsigned
long
ia64_get_rnat
(
unsigned
long
*
);
extern
void
ia64_set_psr_mc
(
void
);
extern
void
ia64_mca_printk
(
const
char
*
fmt
,
...)
extern
void
ia64_mca_printk
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
__attribute__
((
format
(
printf
,
1
,
2
)));
...
...
arch/ia64/kernel/crash.c
View file @
30052c41
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
int
kdump_status
[
NR_CPUS
];
int
kdump_status
[
NR_CPUS
];
static
atomic_t
kdump_cpu_frozen
;
static
atomic_t
kdump_cpu_frozen
;
atomic_t
kdump_in_progress
;
atomic_t
kdump_in_progress
;
static
int
kdump_freeze_monarch
;
static
int
kdump_on_init
=
1
;
static
int
kdump_on_init
=
1
;
static
int
kdump_on_fatal_mca
=
1
;
static
int
kdump_on_fatal_mca
=
1
;
...
@@ -108,10 +109,38 @@ machine_crash_shutdown(struct pt_regs *pt)
...
@@ -108,10 +109,38 @@ machine_crash_shutdown(struct pt_regs *pt)
*/
*/
kexec_disable_iosapic
();
kexec_disable_iosapic
();
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
/*
* If kdump_on_init is set and an INIT is asserted here, kdump will
* be started again via INIT monarch.
*/
local_irq_disable
();
ia64_set_psr_mc
();
/* mask MCA/INIT */
if
(
atomic_inc_return
(
&
kdump_in_progress
)
!=
1
)
unw_init_running
(
kdump_cpu_freeze
,
NULL
);
/*
* Now this cpu is ready for kdump.
* Stop all others by IPI or INIT. They could receive INIT from
* outside and might be INIT monarch, but only thing they have to
* do is falling into kdump_cpu_freeze().
*
* If an INIT is asserted here:
* - All receivers might be slaves, since some of cpus could already
* be frozen and INIT might be masked on monarch. In this case,
* all slaves will be frozen soon since kdump_in_progress will let
* them into DIE_INIT_SLAVE_LEAVE.
* - One might be a monarch, but INIT rendezvous will fail since
* at least this cpu already have INIT masked so it never join
* to the rendezvous. In this case, all slaves and monarch will
* be frozen soon with no wait since the INIT rendezvous is skipped
* by kdump_in_progress.
*/
kdump_smp_send_stop
();
kdump_smp_send_stop
();
/* not all cpu response to IPI, send INIT to freeze them */
/* not all cpu response to IPI, send INIT to freeze them */
if
(
kdump_wait_cpu_freeze
()
&&
kdump_on_init
)
{
if
(
kdump_wait_cpu_freeze
()
)
{
kdump_smp_send_init
();
kdump_smp_send_init
();
/* wait again, don't go ahead if possible */
kdump_wait_cpu_freeze
();
}
}
#endif
#endif
}
}
...
@@ -129,17 +158,17 @@ void
...
@@ -129,17 +158,17 @@ void
kdump_cpu_freeze
(
struct
unw_frame_info
*
info
,
void
*
arg
)
kdump_cpu_freeze
(
struct
unw_frame_info
*
info
,
void
*
arg
)
{
{
int
cpuid
;
int
cpuid
;
local_irq_disable
();
local_irq_disable
();
cpuid
=
smp_processor_id
();
cpuid
=
smp_processor_id
();
crash_save_this_cpu
();
crash_save_this_cpu
();
current
->
thread
.
ksp
=
(
__u64
)
info
->
sw
-
16
;
current
->
thread
.
ksp
=
(
__u64
)
info
->
sw
-
16
;
ia64_set_psr_mc
();
/* mask MCA/INIT and stop reentrance */
atomic_inc
(
&
kdump_cpu_frozen
);
atomic_inc
(
&
kdump_cpu_frozen
);
kdump_status
[
cpuid
]
=
1
;
kdump_status
[
cpuid
]
=
1
;
mb
();
mb
();
#ifdef CONFIG_HOTPLUG_CPU
if
(
cpuid
!=
0
)
ia64_jump_to_sal
(
&
sal_boot_rendez_state
[
cpuid
]);
#endif
for
(;;)
for
(;;)
cpu_relax
();
cpu_relax
();
}
}
...
@@ -150,6 +179,20 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
...
@@ -150,6 +179,20 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
struct
ia64_mca_notify_die
*
nd
;
struct
ia64_mca_notify_die
*
nd
;
struct
die_args
*
args
=
data
;
struct
die_args
*
args
=
data
;
if
(
atomic_read
(
&
kdump_in_progress
))
{
switch
(
val
)
{
case
DIE_INIT_MONARCH_LEAVE
:
if
(
!
kdump_freeze_monarch
)
break
;
/* fall through */
case
DIE_INIT_SLAVE_LEAVE
:
case
DIE_INIT_MONARCH_ENTER
:
case
DIE_MCA_RENDZVOUS_LEAVE
:
unw_init_running
(
kdump_cpu_freeze
,
NULL
);
break
;
}
}
if
(
!
kdump_on_init
&&
!
kdump_on_fatal_mca
)
if
(
!
kdump_on_init
&&
!
kdump_on_fatal_mca
)
return
NOTIFY_DONE
;
return
NOTIFY_DONE
;
...
@@ -162,43 +205,31 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
...
@@ -162,43 +205,31 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
}
}
if
(
val
!=
DIE_INIT_MONARCH_LEAVE
&&
if
(
val
!=
DIE_INIT_MONARCH_LEAVE
&&
val
!=
DIE_INIT_SLAVE_LEAVE
&&
val
!=
DIE_INIT_MONARCH_PROCESS
&&
val
!=
DIE_INIT_MONARCH_PROCESS
&&
val
!=
DIE_MCA_RENDZVOUS_LEAVE
&&
val
!=
DIE_MCA_MONARCH_LEAVE
)
val
!=
DIE_MCA_MONARCH_LEAVE
)
return
NOTIFY_DONE
;
return
NOTIFY_DONE
;
nd
=
(
struct
ia64_mca_notify_die
*
)
args
->
err
;
nd
=
(
struct
ia64_mca_notify_die
*
)
args
->
err
;
/* Reason code 1 means machine check rendezvous*/
if
((
val
==
DIE_INIT_MONARCH_LEAVE
||
val
==
DIE_INIT_SLAVE_LEAVE
||
val
==
DIE_INIT_MONARCH_PROCESS
)
&&
nd
->
sos
->
rv_rc
==
1
)
return
NOTIFY_DONE
;
switch
(
val
)
{
switch
(
val
)
{
case
DIE_INIT_MONARCH_PROCESS
:
case
DIE_INIT_MONARCH_PROCESS
:
if
(
kdump_on_init
)
{
/* Reason code 1 means machine check rendezvous*/
atomic_set
(
&
kdump_in_progress
,
1
);
if
(
kdump_on_init
&&
(
nd
->
sos
->
rv_rc
!=
1
))
{
*
(
nd
->
monarch_cpu
)
=
-
1
;
if
(
atomic_inc_return
(
&
kdump_in_progress
)
!=
1
)
kdump_freeze_monarch
=
1
;
}
}
break
;
break
;
case
DIE_INIT_MONARCH_LEAVE
:
case
DIE_INIT_MONARCH_LEAVE
:
if
(
kdump_on_init
)
/* Reason code 1 means machine check rendezvous*/
if
(
kdump_on_init
&&
(
nd
->
sos
->
rv_rc
!=
1
))
machine_kdump_on_init
();
machine_kdump_on_init
();
break
;
break
;
case
DIE_INIT_SLAVE_LEAVE
:
if
(
atomic_read
(
&
kdump_in_progress
))
unw_init_running
(
kdump_cpu_freeze
,
NULL
);
break
;
case
DIE_MCA_RENDZVOUS_LEAVE
:
if
(
atomic_read
(
&
kdump_in_progress
))
unw_init_running
(
kdump_cpu_freeze
,
NULL
);
break
;
case
DIE_MCA_MONARCH_LEAVE
:
case
DIE_MCA_MONARCH_LEAVE
:
/* *(nd->data) indicate if MCA is recoverable */
/* *(nd->data) indicate if MCA is recoverable */
if
(
kdump_on_fatal_mca
&&
!
(
*
(
nd
->
data
)))
{
if
(
kdump_on_fatal_mca
&&
!
(
*
(
nd
->
data
)))
{
atomic_set
(
&
kdump_in_progress
,
1
);
if
(
atomic_inc_return
(
&
kdump_in_progress
)
==
1
)
*
(
nd
->
monarch_cpu
)
=
-
1
;
machine_kdump_on_init
()
;
machine_kdump_on_init
();
/* We got fatal MCA while kdump!? No way!! */
}
}
break
;
break
;
}
}
...
...
arch/ia64/kernel/head.S
View file @
30052c41
...
@@ -1243,7 +1243,7 @@ GLOBAL_ENTRY(ia64_jump_to_sal)
...
@@ -1243,7 +1243,7 @@ GLOBAL_ENTRY(ia64_jump_to_sal)
movl
r16
=
SAL_PSR_BITS_TO_SET
;;
movl
r16
=
SAL_PSR_BITS_TO_SET
;;
mov
cr
.
ipsr
=
r16
mov
cr
.
ipsr
=
r16
mov
cr
.
ifs
=
r0
;;
mov
cr
.
ifs
=
r0
;;
rfi
;;
rfi
;;
// note: this unmask MCA/INIT (psr.mc)
1
:
1
:
/
*
/
*
*
Invalidate
all
TLB
data
/
inst
*
Invalidate
all
TLB
data
/
inst
...
...
arch/ia64/kernel/machine_kexec.c
View file @
30052c41
...
@@ -24,6 +24,8 @@
...
@@ -24,6 +24,8 @@
#include <asm/delay.h>
#include <asm/delay.h>
#include <asm/meminit.h>
#include <asm/meminit.h>
#include <asm/processor.h>
#include <asm/processor.h>
#include <asm/sal.h>
#include <asm/mca.h>
typedef
NORET_TYPE
void
(
*
relocate_new_kernel_t
)(
typedef
NORET_TYPE
void
(
*
relocate_new_kernel_t
)(
unsigned
long
indirection_page
,
unsigned
long
indirection_page
,
...
@@ -85,13 +87,26 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
...
@@ -85,13 +87,26 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
void
*
pal_addr
=
efi_get_pal_addr
();
void
*
pal_addr
=
efi_get_pal_addr
();
unsigned
long
code_addr
=
(
unsigned
long
)
page_address
(
image
->
control_code_page
);
unsigned
long
code_addr
=
(
unsigned
long
)
page_address
(
image
->
control_code_page
);
int
ii
;
int
ii
;
u64
fp
,
gp
;
ia64_fptr_t
*
init_handler
=
(
ia64_fptr_t
*
)
ia64_os_init_on_kdump
;
BUG_ON
(
!
image
);
BUG_ON
(
!
image
);
if
(
image
->
type
==
KEXEC_TYPE_CRASH
)
{
if
(
image
->
type
==
KEXEC_TYPE_CRASH
)
{
crash_save_this_cpu
();
crash_save_this_cpu
();
current
->
thread
.
ksp
=
(
__u64
)
info
->
sw
-
16
;
current
->
thread
.
ksp
=
(
__u64
)
info
->
sw
-
16
;
/* Register noop init handler */
fp
=
ia64_tpa
(
init_handler
->
fp
);
gp
=
ia64_tpa
(
ia64_getreg
(
_IA64_REG_GP
));
ia64_sal_set_vectors
(
SAL_VECTOR_OS_INIT
,
fp
,
gp
,
0
,
fp
,
gp
,
0
);
}
else
{
/* Unregister init handlers of current kernel */
ia64_sal_set_vectors
(
SAL_VECTOR_OS_INIT
,
0
,
0
,
0
,
0
,
0
,
0
);
}
}
/* Unregister mca handler - No more recovery on current kernel */
ia64_sal_set_vectors
(
SAL_VECTOR_OS_MCA
,
0
,
0
,
0
,
0
,
0
,
0
);
/* Interrupts aren't acceptable while we reboot */
/* Interrupts aren't acceptable while we reboot */
local_irq_disable
();
local_irq_disable
();
...
...
arch/ia64/kernel/mca.c
View file @
30052c41
...
@@ -1682,14 +1682,25 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
...
@@ -1682,14 +1682,25 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
if
(
!
sos
->
monarch
)
{
if
(
!
sos
->
monarch
)
{
ia64_mc_info
.
imi_rendez_checkin
[
cpu
]
=
IA64_MCA_RENDEZ_CHECKIN_INIT
;
ia64_mc_info
.
imi_rendez_checkin
[
cpu
]
=
IA64_MCA_RENDEZ_CHECKIN_INIT
;
#ifdef CONFIG_KEXEC
while
(
monarch_cpu
==
-
1
&&
!
atomic_read
(
&
kdump_in_progress
))
udelay
(
1000
);
#else
while
(
monarch_cpu
==
-
1
)
while
(
monarch_cpu
==
-
1
)
cpu_relax
();
/* spin until monarch enters */
cpu_relax
();
/* spin until monarch enters */
#endif
NOTIFY_INIT
(
DIE_INIT_SLAVE_ENTER
,
regs
,
(
long
)
&
nd
,
1
);
NOTIFY_INIT
(
DIE_INIT_SLAVE_ENTER
,
regs
,
(
long
)
&
nd
,
1
);
NOTIFY_INIT
(
DIE_INIT_SLAVE_PROCESS
,
regs
,
(
long
)
&
nd
,
1
);
NOTIFY_INIT
(
DIE_INIT_SLAVE_PROCESS
,
regs
,
(
long
)
&
nd
,
1
);
#ifdef CONFIG_KEXEC
while
(
monarch_cpu
!=
-
1
&&
!
atomic_read
(
&
kdump_in_progress
))
udelay
(
1000
);
#else
while
(
monarch_cpu
!=
-
1
)
while
(
monarch_cpu
!=
-
1
)
cpu_relax
();
/* spin until monarch leaves */
cpu_relax
();
/* spin until monarch leaves */
#endif
NOTIFY_INIT
(
DIE_INIT_SLAVE_LEAVE
,
regs
,
(
long
)
&
nd
,
1
);
NOTIFY_INIT
(
DIE_INIT_SLAVE_LEAVE
,
regs
,
(
long
)
&
nd
,
1
);
...
...
arch/ia64/kernel/mca_asm.S
View file @
30052c41
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
.
global
ia64_do_tlb_purge
.
global
ia64_do_tlb_purge
.
global
ia64_os_mca_dispatch
.
global
ia64_os_mca_dispatch
.
global
ia64_os_init_on_kdump
.
global
ia64_os_init_dispatch_monarch
.
global
ia64_os_init_dispatch_monarch
.
global
ia64_os_init_dispatch_slave
.
global
ia64_os_init_dispatch_slave
...
@@ -298,6 +299,25 @@ END(ia64_os_mca_virtual_begin)
...
@@ -298,6 +299,25 @@ END(ia64_os_mca_virtual_begin)
//
StartMain
////////////////////////////////////////////////////////////////////
//
StartMain
////////////////////////////////////////////////////////////////////
//
//
NOP
init
handler
for
kdump
.
In
panic
situation
,
we
may
receive
INIT
//
while
kernel
transition
.
Since
we
initialize
registers
on
leave
from
//
current
kernel
,
no
longer
monarch
/
slave
handlers
of
current
kernel
in
//
virtual
mode
are
called
safely
.
//
We
can
unregister
these
init
handlers
from
SAL
,
however
then
the
INIT
//
will
result
in
warmboot
by
SAL
and
we
cannot
retrieve
the
crashdump
.
//
Therefore
register
this
NOP
function
to
SAL
,
to
prevent
entering
virtual
//
mode
and
resulting
warmboot
by
SAL
.
//
ia64_os_init_on_kdump
:
mov
r8
=
r0
//
IA64_INIT_RESUME
mov
r9
=
r10
//
SAL_GP
mov
r22
=
r17
//
*
minstate
;;
mov
r10
=
r0
//
return
to
same
context
mov
b0
=
r12
//
SAL_CHECK
return
address
br
b0
//
//
//
SAL
to
OS
entry
point
for
INIT
on
all
processors
.
This
has
been
defined
for
//
SAL
to
OS
entry
point
for
INIT
on
all
processors
.
This
has
been
defined
for
//
registration
purposes
with
SAL
as
a
part
of
ia64_mca_init
.
Monarch
and
//
registration
purposes
with
SAL
as
a
part
of
ia64_mca_init
.
Monarch
and
...
@@ -1073,3 +1093,30 @@ GLOBAL_ENTRY(ia64_get_rnat)
...
@@ -1073,3 +1093,30 @@ GLOBAL_ENTRY(ia64_get_rnat)
mov
ar
.
rsc
=
3
mov
ar
.
rsc
=
3
br.ret.sptk.many
rp
br.ret.sptk.many
rp
END
(
ia64_get_rnat
)
END
(
ia64_get_rnat
)
//
void
ia64_set_psr_mc
(
void
)
//
//
Set
psr
.
mc
bit
to
mask
MCA
/
INIT
.
GLOBAL_ENTRY
(
ia64_set_psr_mc
)
rsm
psr
.
i
|
psr
.
ic
//
disable
interrupts
;;
srlz.d
;;
mov
r14
=
psr
//
get
psr
{
36
:
35
,
31
:
0
}
movl
r15
=
1
f
;;
dep
r14
=
-
1
,
r14
,
PSR_MC
,
1
//
set
psr
.
mc
;;
dep
r14
=
-
1
,
r14
,
PSR_IC
,
1
//
set
psr
.
ic
;;
dep
r14
=
-
1
,
r14
,
PSR_BN
,
1
//
keep
bank1
in
use
;;
mov
cr
.
ipsr
=
r14
mov
cr
.
ifs
=
r0
mov
cr
.
iip
=
r15
;;
rfi
1
:
br.ret.sptk.many
rp
END
(
ia64_set_psr_mc
)
arch/ia64/kernel/relocate_kernel.S
View file @
30052c41
...
@@ -52,7 +52,7 @@ GLOBAL_ENTRY(relocate_new_kernel)
...
@@ -52,7 +52,7 @@ GLOBAL_ENTRY(relocate_new_kernel)
srlz.i
srlz.i
;;
;;
mov
ar
.
rnat
=
r18
mov
ar
.
rnat
=
r18
rfi
rfi
//
note
:
this
unmask
MCA
/
INIT
(
psr
.
mc
)
;;
;;
1
:
1
:
//
physical
mode
code
begin
//
physical
mode
code
begin
...
...
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