diff options
Diffstat (limited to 'arch/powerpc/kernel/rtas.c')
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 1f42aabbbab3..9bb43aa53d43 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -24,9 +24,10 @@ #include <linux/slab.h> #include <linux/reboot.h> #include <linux/syscalls.h> +#include <linux/of.h> +#include <linux/of_fdt.h> #include <asm/interrupt.h> -#include <asm/prom.h> #include <asm/rtas.h> #include <asm/hvcall.h> #include <asm/machdep.h> @@ -49,6 +50,19 @@ void enter_rtas(unsigned long); static inline void do_enter_rtas(unsigned long args) { + unsigned long msr; + + /* + * Make sure MSR[RI] is currently enabled as it will be forced later + * in enter_rtas. + */ + msr = mfmsr(); + BUG_ON(!(msr & MSR_RI)); + + BUG_ON(!irqs_disabled()); + + hard_irq_disable(); /* Ensure MSR[EE] is disabled on PPC64 */ + enter_rtas(args); srr_regs_clobbered(); /* rtas uses SRRs, invalidate */ @@ -462,6 +476,11 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) return -1; + if ((mfmsr() & (MSR_IR|MSR_DR)) != (MSR_IR|MSR_DR)) { + WARN_ON_ONCE(1); + return -1; + } + s = lock_rtas(); /* We use the global rtas args buffer */ |