mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-03 19:24:02 +08:00
powerpc/64/syscall: Reconcile interrupts
This reconciles interrupts in the system call case like all other interrupts. This allows system_call_common to be shared with the scv system call implementation in a subsequent patch. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200225173541.1549955-31-npiggin@gmail.com
This commit is contained in:
parent
702f098052
commit
5f0b6ac390
@ -119,6 +119,17 @@ END_BTB_FLUSH_SECTION
|
|||||||
ld r11,exception_marker@toc(r2)
|
ld r11,exception_marker@toc(r2)
|
||||||
std r11,-16(r10) /* "regshere" marker */
|
std r11,-16(r10) /* "regshere" marker */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which
|
||||||
|
* would clobber syscall parameters. Also we always enter with IRQs
|
||||||
|
* enabled and nothing pending. system_call_exception() will call
|
||||||
|
* trace_hardirqs_off().
|
||||||
|
*/
|
||||||
|
li r11,IRQS_ALL_DISABLED
|
||||||
|
li r12,PACA_IRQ_HARD_DIS
|
||||||
|
stb r11,PACAIRQSOFTMASK(r13)
|
||||||
|
stb r12,PACAIRQHAPPENED(r13)
|
||||||
|
|
||||||
/* Calling convention has r9 = orig r0, r10 = regs */
|
/* Calling convention has r9 = orig r0, r10 = regs */
|
||||||
mr r9,r0
|
mr r9,r0
|
||||||
bl system_call_exception
|
bl system_call_exception
|
||||||
|
@ -17,13 +17,19 @@
|
|||||||
|
|
||||||
typedef long (*syscall_fn)(long, long, long, long, long, long);
|
typedef long (*syscall_fn)(long, long, long, long, long, long);
|
||||||
|
|
||||||
/* Has to run notrace because it is entered "unreconciled" */
|
/* Has to run notrace because it is entered not completely "reconciled" */
|
||||||
notrace long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8,
|
notrace long system_call_exception(long r3, long r4, long r5,
|
||||||
|
long r6, long r7, long r8,
|
||||||
unsigned long r0, struct pt_regs *regs)
|
unsigned long r0, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned long ti_flags;
|
unsigned long ti_flags;
|
||||||
syscall_fn f;
|
syscall_fn f;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
|
||||||
|
BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
|
||||||
|
|
||||||
|
trace_hardirqs_off(); /* finish reconciling */
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_PPC_BOOK3S))
|
if (IS_ENABLED(CONFIG_PPC_BOOK3S))
|
||||||
BUG_ON(!(regs->msr & MSR_RI));
|
BUG_ON(!(regs->msr & MSR_RI));
|
||||||
BUG_ON(!(regs->msr & MSR_PR));
|
BUG_ON(!(regs->msr & MSR_PR));
|
||||||
@ -44,16 +50,6 @@ notrace long system_call_exception(long r3, long r4, long r5, long r6, long r7,
|
|||||||
|
|
||||||
kuap_check_amr();
|
kuap_check_amr();
|
||||||
|
|
||||||
/*
|
|
||||||
* A syscall should always be called with interrupts enabled
|
|
||||||
* so we just unconditionally hard-enable here. When some kind
|
|
||||||
* of irq tracing is used, we additionally check that condition
|
|
||||||
* is correct
|
|
||||||
*/
|
|
||||||
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) {
|
|
||||||
WARN_ON(irq_soft_mask_return() != IRQS_ENABLED);
|
|
||||||
WARN_ON(local_paca->irq_happened);
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* This is not required for the syscall exit path, but makes the
|
* This is not required for the syscall exit path, but makes the
|
||||||
* stack frame look nicer. If this was initialised in the first stack
|
* stack frame look nicer. If this was initialised in the first stack
|
||||||
@ -62,7 +58,7 @@ notrace long system_call_exception(long r3, long r4, long r5, long r6, long r7,
|
|||||||
*/
|
*/
|
||||||
regs->softe = IRQS_ENABLED;
|
regs->softe = IRQS_ENABLED;
|
||||||
|
|
||||||
__hard_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
ti_flags = current_thread_info()->flags;
|
ti_flags = current_thread_info()->flags;
|
||||||
if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) {
|
if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user