XIVE interrupt controller maintains a Event-Queue(EQ) page. This page is
used to communicate events with the Hypervisor/Qemu. In Secure-VM,
unless a page is shared with the Hypervisor, the Hypervisor will
not be able to read/write to that page.

Explicitly share the EQ page with the Hypervisor, and unshare it
during cleanup.  This enables SVM to use XIVE.

(NOTE: If the Hypervisor/Ultravisor is unable to target interrupts
 directly to Secure VM, use "kernel_irqchip=off" on the qemu command
 line).

Cc: kvm-...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Michael Ellerman <m...@ellerman.id.au>
Cc: Thiago Jung Bauermann <bauer...@linux.ibm.com>
Cc: Michael Anderson <andm...@linux.ibm.com>
Cc: Sukadev Bhattiprolu <suka...@linux.vnet.ibm.com>
Cc: Alexey Kardashevskiy <a...@ozlabs.ru>
Cc: Paul Mackerras <pau...@ozlabs.org>
Cc: Greg Kurz <gr...@kaod.org>
Cc: Cedric Le Goater <c...@fr.ibm.com>
Cc: David Gibson <da...@gibson.dropbear.id.au>
Signed-off-by: Ram Pai <linux...@us.ibm.com>
---
 arch/powerpc/sysdev/xive/spapr.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
index 55dc61c..608b52f 100644
--- a/arch/powerpc/sysdev/xive/spapr.c
+++ b/arch/powerpc/sysdev/xive/spapr.c
@@ -26,6 +26,8 @@
 #include <asm/xive.h>
 #include <asm/xive-regs.h>
 #include <asm/hvcall.h>
+#include <asm/svm.h>
+#include <asm/ultravisor.h>
 
 #include "xive-internal.h"
 
@@ -501,6 +503,9 @@ static int xive_spapr_configure_queue(u32 target, struct 
xive_q *q, u8 prio,
                rc = -EIO;
        } else {
                q->qpage = qpage;
+               if (is_secure_guest())
+                       uv_share_page(PHYS_PFN(qpage_phys),
+                                       1 << xive_alloc_order(order));
        }
 fail:
        return rc;
@@ -534,6 +539,8 @@ static void xive_spapr_cleanup_queue(unsigned int cpu, 
struct xive_cpu *xc,
                       hw_cpu, prio);
 
        alloc_order = xive_alloc_order(xive_queue_shift);
+       if (is_secure_guest())
+               uv_unshare_page(PHYS_PFN(__pa(q->qpage)), 1 << alloc_order);
        free_pages((unsigned long)q->qpage, alloc_order);
        q->qpage = NULL;
 }
-- 
1.8.3.1

Reply via email to