Skip to content

Commit

Permalink
powerpc/book3e: Resend doorbell exceptions to ourself
Browse files Browse the repository at this point in the history
If we are soft disabled and receive a doorbell exception we don't process
it immediately. This means we need to check on the way out of irq restore
if there are any doorbell exceptions to process.

The problem is at that point we don't know what our regs are, and that
in turn makes xmon unhappy. To workaround the problem, instead of checking
for and processing doorbells, we check for any doorbells and if there were
any we send ourselves another.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Michael Ellerman authored and Benjamin Herrenschmidt committed Jul 9, 2010
1 parent 0e37d25 commit 850f22d
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 2 deletions.
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/dbell.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum ppc_dbell {

extern void doorbell_message_pass(int target, int msg);
extern void doorbell_exception(struct pt_regs *regs);
extern void doorbell_check_self(void);
extern void doorbell_setup_this_cpu(void);

static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
Expand Down
10 changes: 10 additions & 0 deletions arch/powerpc/kernel/dbell.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ void doorbell_exception(struct pt_regs *regs)
set_irq_regs(old_regs);
}

void doorbell_check_self(void)
{
struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);

if (!info->messages)
return;

ppc_msgsnd(PPC_DBELL, 0, info->tag);
}

#else /* CONFIG_SMP */
void doorbell_exception(struct pt_regs *regs)
{
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ notrace void raw_local_irq_restore(unsigned long en)
return;

#if defined(CONFIG_BOOKE) && defined(CONFIG_SMP)
/* Check for pending doorbell interrupts on SMP */
doorbell_exception(NULL);
/* Check for pending doorbell interrupts and resend to ourself */
doorbell_check_self();
#endif

/*
Expand Down

0 comments on commit 850f22d

Please sign in to comment.