summaryrefslogtreecommitdiff
path: root/arch/powerpc/kvm/book3s_hv_builtin.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/book3s_hv_builtin.c')
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 5bb24be0b346..fe08fea54b70 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -29,6 +29,11 @@
#include <asm/opal.h>
#include <asm/smp.h>
+static bool in_realmode(void)
+{
+ return !(mfmsr() & MSR_IR);
+}
+
#define KVM_CMA_CHUNK_ORDER 18
/*
@@ -200,7 +205,6 @@ static inline void rm_writeb(unsigned long paddr, u8 val)
/*
* Send an interrupt or message to another CPU.
- * This can only be called in real mode.
* The caller needs to include any barrier needed to order writes
* to memory vs. the IPI/message.
*/
@@ -226,7 +230,9 @@ void kvmhv_rm_send_ipi(int cpu)
/* Else poke the target with an IPI */
xics_phys = paca[cpu].kvm_hstate.xics_phys;
- if (xics_phys)
+ if (!in_realmode())
+ opal_int_set_mfrr(get_hard_smp_processor_id(cpu), IPI_PRIORITY);
+ else if (xics_phys)
rm_writeb(xics_phys + XICS_MFRR, IPI_PRIORITY);
else
opal_rm_int_set_mfrr(get_hard_smp_processor_id(cpu),
@@ -412,14 +418,15 @@ static long kvmppc_read_one_intr(bool *again)
/* Now read the interrupt from the ICP */
xics_phys = local_paca->kvm_hstate.xics_phys;
- if (!xics_phys) {
- /* Use OPAL to read the XIRR */
+ rc = 0;
+ if (!in_realmode())
+ rc = opal_int_get_xirr(&xirr, false);
+ else if (!xics_phys)
rc = opal_rm_int_get_xirr(&xirr, false);
- if (rc < 0)
- return 1;
- } else {
+ else
xirr = _lwzcix(xics_phys + XICS_XIRR);
- }
+ if (rc < 0)
+ return 1;
/*
* Save XIRR for later. Since we get control in reverse endian
@@ -445,15 +452,19 @@ static long kvmppc_read_one_intr(bool *again)
* If it is an IPI, clear the MFRR and EOI it.
*/
if (xisr == XICS_IPI) {
- if (xics_phys) {
+ rc = 0;
+ if (!in_realmode()) {
+ opal_int_set_mfrr(hard_smp_processor_id(), 0xff);
+ rc = opal_int_eoi(h_xirr);
+ } else if (xics_phys) {
_stbcix(xics_phys + XICS_MFRR, 0xff);
_stwcix(xics_phys + XICS_XIRR, xirr);
} else {
opal_rm_int_set_mfrr(hard_smp_processor_id(), 0xff);
rc = opal_rm_int_eoi(h_xirr);
- /* If rc > 0, there is another interrupt pending */
- *again = rc > 0;
}
+ /* If rc > 0, there is another interrupt pending */
+ *again = rc > 0;
/*
* Need to ensure side effects of above stores
@@ -471,7 +482,10 @@ static long kvmppc_read_one_intr(bool *again)
/* We raced with the host,
* we need to resend that IPI, bummer
*/
- if (xics_phys)
+ if (!in_realmode())
+ opal_int_set_mfrr(hard_smp_processor_id(),
+ IPI_PRIORITY);
+ else if (xics_phys)
_stbcix(xics_phys + XICS_MFRR, IPI_PRIORITY);
else
opal_rm_int_set_mfrr(hard_smp_processor_id(),