Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xenomai
ipipe-arm
Commits
479f1e8c
Commit
479f1e8c
authored
Sep 10, 2018
by
Philippe Gerum
Browse files
ARM: ipipe: reconcile lockdep with interrupt pipelining
parent
6129b4e7
Changes
3
Hide whitespace changes
Inline
Side-by-side
arch/arm/Kconfig
View file @
479f1e8c
...
...
@@ -190,7 +190,6 @@ config STACKTRACE_SUPPORT
config LOCKDEP_SUPPORT
bool
depends on !IPIPE
default y
config TRACE_IRQFLAGS_SUPPORT
...
...
arch/arm/kernel/entry-header.S
View file @
479f1e8c
...
...
@@ -208,7 +208,11 @@
#ifdef CONFIG_TRACE_IRQFLAGS
@
The
parent
context
IRQs
must
have
been
enabled
to
get
here
in
@
the
first
place
,
so
there
's no point checking the PSR I bit.
#ifdef CONFIG_IPIPE
bl
trace_hardirqs_on_virt
#else
bl
trace_hardirqs_on
#endif
#endif
.
else
@
IRQs
off
again
before
pulling
preserved
data
off
the
stack
...
...
arch/arm/mm/fault.c
View file @
479f1e8c
...
...
@@ -31,37 +31,66 @@
#ifdef CONFIG_MMU
#ifdef CONFIG_IPIPE
static
inline
unsigned
long
ipipe_fault_entry
(
void
)
/*
* We need to synchronize the virtual interrupt state with the hard
* interrupt state we received on entry, then turn hardirqs back on to
* allow code which does not require strict serialization to be
* preempted by an out-of-band activity.
*
* TRACING: the entry code already told lockdep and tracers about the
* hard interrupt state on entry to fault handlers, so no need to
* reflect changes to that state via calls to trace_hardirqs_*
* helpers. From the main kernel's point of view, there is no change.
*/
static
inline
unsigned
long
fault_entry
(
struct
pt_regs
*
regs
)
{
unsigned
long
flags
;
int
s
;
int
nosync
=
1
;
flags
=
hard_local_irq_save
();
s
=
__test_and_set_bit
(
IPIPE_STALL_FLAG
,
&
__ipipe_root_status
);
if
(
hard_irqs_disabled_flags
(
flags
))
nosync
=
__test_and_set_bit
(
IPIPE_STALL_FLAG
,
&
__ipipe_root_status
);
hard_local_irq_enable
();
return
arch_mangle_irq_bits
(
s
,
flags
);
return
arch_mangle_irq_bits
(
flags
,
nosync
);
}
static
inline
void
ipipe_
fault_exit
(
unsigned
long
x
)
static
inline
void
fault_exit
(
unsigned
long
flags
)
{
if
(
!
arch_demangle_irq_bits
(
&
x
))
local_irq_enable
();
else
hard_local_irq_restore
(
x
);
int
nosync
;
IPIPE_WARN_ONCE
(
hard_irqs_disabled
());
/*
* '!nosync' here means that we had to turn on the stall bit
* in fault_entry() to mirror the hard interrupt state,
* because hard irqs were off but the stall bit was
* clear. Conversely, nosync in fault_exit() means that the
* stall bit state currently reflects the hard interrupt state
* we received on fault_entry().
*/
nosync
=
arch_demangle_irq_bits
(
&
flags
);
if
(
!
nosync
)
{
hard_local_irq_disable
();
__clear_bit
(
IPIPE_STALL_FLAG
,
&
__ipipe_root_status
);
if
(
!
hard_irqs_disabled_flags
(
flags
))
hard_local_irq_enable
();
}
else
if
(
hard_irqs_disabled_flags
(
flags
))
hard_local_irq_disable
();
}
#else
static
inline
unsigned
long
ipipe_
fault_entry
(
void
)
static
inline
unsigned
long
fault_entry
(
struct
pt_regs
*
regs
)
{
return
0
;
}
static
inline
void
ipipe_
fault_exit
(
unsigned
long
x
)
{
}
static
inline
void
fault_exit
(
unsigned
long
x
)
{
}
#endif
#endif
/* !CONFIG_IPIPE */
#ifdef CONFIG_KPROBES
static
inline
int
notify_page_fault
(
struct
pt_regs
*
regs
,
unsigned
int
fsr
)
...
...
@@ -305,7 +334,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if
(
__ipipe_report_trap
(
IPIPE_TRAP_ACCESS
,
regs
))
return
0
;
irqflags
=
ipipe_
fault_entry
();
irqflags
=
fault_entry
(
regs
);
if
(
notify_page_fault
(
regs
,
fsr
))
goto
out
;
...
...
@@ -439,7 +468,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
no_context:
__do_kernel_fault
(
mm
,
addr
,
fsr
,
regs
);
out:
ipipe_
fault_exit
(
irqflags
);
fault_exit
(
irqflags
);
return
0
;
}
...
...
@@ -535,11 +564,11 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
if
(
__ipipe_report_trap
(
IPIPE_TRAP_ACCESS
,
regs
))
return
0
;
irqflags
=
ipipe_
fault_entry
();
irqflags
=
fault_entry
(
regs
);
do_bad_area
(
addr
,
fsr
,
regs
);
ipipe_
fault_exit
(
irqflags
);
fault_exit
(
irqflags
);
return
0
;
}
...
...
@@ -565,11 +594,11 @@ do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if
(
__ipipe_report_trap
(
IPIPE_TRAP_SECTION
,
regs
))
return
0
;
irqflags
=
ipipe_
fault_entry
();
irqflags
=
fault_entry
(
regs
);
do_bad_area
(
addr
,
fsr
,
regs
);
ipipe_
fault_exit
(
irqflags
);
fault_exit
(
irqflags
);
return
0
;
}
...
...
@@ -630,7 +659,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if
(
__ipipe_report_trap
(
IPIPE_TRAP_UNKNOWN
,
regs
))
return
;
irqflags
=
ipipe_
fault_entry
();
irqflags
=
fault_entry
(
regs
);
pr_alert
(
"Unhandled fault: %s (0x%03x) at 0x%08lx
\n
"
,
inf
->
name
,
fsr
,
addr
);
...
...
@@ -643,7 +672,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
info
.
si_addr
=
(
void
__user
*
)
addr
;
arm_notify_die
(
""
,
regs
,
&
info
,
fsr
,
0
);
ipipe_
fault_exit
(
irqflags
);
fault_exit
(
irqflags
);
}
void
__init
...
...
@@ -672,7 +701,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
if
(
__ipipe_report_trap
(
IPIPE_TRAP_UNKNOWN
,
regs
))
return
;
irqflags
=
ipipe_
fault_entry
();
irqflags
=
fault_entry
(
regs
);
pr_alert
(
"Unhandled prefetch abort: %s (0x%03x) at 0x%08lx
\n
"
,
inf
->
name
,
ifsr
,
addr
);
...
...
@@ -684,7 +713,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
info
.
si_addr
=
(
void
__user
*
)
addr
;
arm_notify_die
(
""
,
regs
,
&
info
,
ifsr
,
0
);
ipipe_
fault_exit
(
irqflags
);
fault_exit
(
irqflags
);
}
/*
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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