All of lore.kernel.org
 help / color / mirror / Atom feed
* Dovetail/x86 still broken /wrt exception fixups
@ 2021-06-01 21:24 Jan Kiszka
  2021-06-02 15:29 ` Jan Kiszka
  2021-06-02 16:53 ` Philippe Gerum
  0 siblings, 2 replies; 4+ messages in thread
From: Jan Kiszka @ 2021-06-01 21:24 UTC (permalink / raw)
  To: Philippe Gerum, Xenomai

Hi Philippe,

we are leaking the inband stall state into user land when the kernel
takes a fixable exception in oob. The problem is either
cond_disable_irqs() or its (missing?) counterpart. Where is the stall
bit set in handle_page_fault->cond_disable_irqs supposed to be cleared
again?

I-pipe is fine in that regard, but it took us many years to get it into
that state - and it didn't have to deal with the impact of ca4c6a9858
("x86/traps: Make interrupt enable/disable symmetric in C code") anymore...

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Dovetail/x86 still broken /wrt exception fixups
  2021-06-01 21:24 Dovetail/x86 still broken /wrt exception fixups Jan Kiszka
@ 2021-06-02 15:29 ` Jan Kiszka
  2021-06-02 17:43   ` Philippe Gerum
  2021-06-02 16:53 ` Philippe Gerum
  1 sibling, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2021-06-02 15:29 UTC (permalink / raw)
  To: Philippe Gerum, Xenomai

On 01.06.21 23:24, Jan Kiszka via Xenomai wrote:
> Hi Philippe,
> 
> we are leaking the inband stall state into user land when the kernel
> takes a fixable exception in oob. The problem is either
> cond_disable_irqs() or its (missing?) counterpart. Where is the stall
> bit set in handle_page_fault->cond_disable_irqs supposed to be cleared
> again?
> 
> I-pipe is fine in that regard, but it took us many years to get it into
> that state - and it didn't have to deal with the impact of ca4c6a9858
> ("x86/traps: Make interrupt enable/disable symmetric in C code") anymore...
> 

A first attempt to fix the issue, but I'm only half-way through with 
understanding the related logic in dovetail:

diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index 5e33248453e7..9f8c51e5f51c 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -526,7 +526,8 @@ noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state)
 	 * irqentry_enter() raised it in order to mirror the hardware
 	 * state.
 	 */
-	if (state.stage_info & IRQENTRY_INBAND_STALLED)
+	if (state.stage_info == IRQENTRY_INBAND_STALLED ||
+	    (running_inband() && state.stage_info == IRQENTRY_OOB_ENTRY))
 		unstall_inband();
 #endif
 	return;

State seems now consistent again.

BTW, all those tests for bits in stage_info should likely be converted 
to testing for the state - IRQENTRY_INBAND_STALLED and IRQENTRY_OOB_ENTRY 
are mutually exclusive. Would make the code more readable.

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: Dovetail/x86 still broken /wrt exception fixups
  2021-06-01 21:24 Dovetail/x86 still broken /wrt exception fixups Jan Kiszka
  2021-06-02 15:29 ` Jan Kiszka
@ 2021-06-02 16:53 ` Philippe Gerum
  1 sibling, 0 replies; 4+ messages in thread
From: Philippe Gerum @ 2021-06-02 16:53 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai


Jan Kiszka <jan.kiszka@siemens.com> writes:

> Hi Philippe,
>
> we are leaking the inband stall state into user land when the kernel
> takes a fixable exception in oob. The problem is either
> cond_disable_irqs() or its (missing?) counterpart. Where is the stall
> bit set in handle_page_fault->cond_disable_irqs supposed to be cleared
> again?
>

It depends: irqentry_exit_to_user_mode if the fault was triggered by
user, otherwise the assumption is made that any entry from kernel
context, unstalled _and_ in_band would lead to IRQENTRY_INBAND_STALLED
being set into the stage info bits.

Which is unfortunately wrong in one case: when the execution stage was
downgraded by the companion core from oob to in-band as a result of
handling the fault (oob_trap_notify). This is basically what you are
looking at ATM.

i.e.

oob exec from kernel:
        raw_copy_to/from_user(bad_u_pointer)
                irqentry_enter, IRQENTRY_OOB_ENTRY is set
                       handle_page_fault
                           do_user_addr_fault
                                oob_trap_notify, switching in-band
in-band:                   cond_disable_irqs
                irqentry_exit
                        in-band but !IRQENTRY_INBAND_STALLED => bummer,
                                            won't unstall

Would the fault have happened from in-band kernel context, and
IRQENTRY_INBAND_STALLED would have been set, preventing the issue.

This also means that this particular issue is different from the RCU
stall bug we mentioned this morning during the community call: that
setup never exercises stage transition between oob and in-band task
contexts, so we could not observe it with CONFIG_DOVETAIL off.

> I-pipe is fine in that regard, but it took us many years to get it into
> that state - and it didn't have to deal with the impact of ca4c6a9858
> ("x86/traps: Make interrupt enable/disable symmetric in C code") anymore...
>

The I-pipe required many years of fixing because it does way too many
things from the asm code, which is error-prone and caused painful merges
in many occasions. There is no valid reason for the fault handling path
to require years of fixing pipeline-wise in any case.

The logic of #ca4c6a9858 makes a lot of sense. Dovetail never assumed
anything wrt what the asm might do regarding the IRQ state anyway,
framing what happens from C code is much easier.

-- 
Philippe.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Dovetail/x86 still broken /wrt exception fixups
  2021-06-02 15:29 ` Jan Kiszka
@ 2021-06-02 17:43   ` Philippe Gerum
  0 siblings, 0 replies; 4+ messages in thread
From: Philippe Gerum @ 2021-06-02 17:43 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai


Jan Kiszka <jan.kiszka@siemens.com> writes:

> On 01.06.21 23:24, Jan Kiszka via Xenomai wrote:
>> Hi Philippe,
>> 
>> we are leaking the inband stall state into user land when the kernel
>> takes a fixable exception in oob. The problem is either
>> cond_disable_irqs() or its (missing?) counterpart. Where is the stall
>> bit set in handle_page_fault->cond_disable_irqs supposed to be cleared
>> again?
>> 
>> I-pipe is fine in that regard, but it took us many years to get it into
>> that state - and it didn't have to deal with the impact of ca4c6a9858
>> ("x86/traps: Make interrupt enable/disable symmetric in C code") anymore...
>> 
>
> A first attempt to fix the issue, but I'm only half-way through with 
> understanding the related logic in dovetail:
>
> diff --git a/kernel/entry/common.c b/kernel/entry/common.c
> index 5e33248453e7..9f8c51e5f51c 100644
> --- a/kernel/entry/common.c
> +++ b/kernel/entry/common.c
> @@ -526,7 +526,8 @@ noinstr void irqentry_exit(struct pt_regs *regs, irqentry_state_t state)
>  	 * irqentry_enter() raised it in order to mirror the hardware
>  	 * state.
>  	 */
> -	if (state.stage_info & IRQENTRY_INBAND_STALLED)
> +	if (state.stage_info == IRQENTRY_INBAND_STALLED ||
> +	    (running_inband() && state.stage_info == IRQENTRY_OOB_ENTRY))
>  		unstall_inband();

You can drop the check for running_inband(), this is always true at this
point.

>  #endif
>  	return;
>
> State seems now consistent again.
>

Yes, that should cover the case described earlier.

> BTW, all those tests for bits in stage_info should likely be converted 
> to testing for the state - IRQENTRY_INBAND_STALLED and IRQENTRY_OOB_ENTRY 
> are mutually exclusive. Would make the code more readable.
>

Ack.

-- 
Philippe.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-06-02 17:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-01 21:24 Dovetail/x86 still broken /wrt exception fixups Jan Kiszka
2021-06-02 15:29 ` Jan Kiszka
2021-06-02 17:43   ` Philippe Gerum
2021-06-02 16:53 ` Philippe Gerum

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.