powerpc/xive: add OPAL extensions for the XIVE native exploitation support
authorCédric Le Goater <clg@kaod.org>
Wed, 10 Apr 2019 17:04:33 +0000 (19:04 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 11 Apr 2019 05:31:41 +0000 (15:31 +1000)
The support for XIVE native exploitation mode in Linux/KVM needs a
couple more OPAL calls to get and set the state of the XIVE internal
structures being used by a sPAPR guest.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/opal-api.h
arch/powerpc/include/asm/opal.h
arch/powerpc/include/asm/xive.h
arch/powerpc/platforms/powernv/opal-call.c
arch/powerpc/sysdev/xive/native.c

index 870fb7b239ea420b0f4d5b8d5c4ba3e356f5542c..e1d118ac61dc8ddbc6204f1757683f4a95264d35 100644 (file)
 #define OPAL_XIVE_FREE_IRQ                     140
 #define OPAL_XIVE_SYNC                         141
 #define OPAL_XIVE_DUMP                         142
-#define OPAL_XIVE_RESERVED3                    143
-#define OPAL_XIVE_RESERVED4                    144
+#define OPAL_XIVE_GET_QUEUE_STATE              143
+#define OPAL_XIVE_SET_QUEUE_STATE              144
 #define OPAL_SIGNAL_SYSTEM_RESET               145
 #define OPAL_NPU_INIT_CONTEXT                  146
 #define OPAL_NPU_DESTROY_CONTEXT               147
 #define OPAL_PCI_GET_PBCQ_TUNNEL_BAR           164
 #define OPAL_PCI_SET_PBCQ_TUNNEL_BAR           165
 #define        OPAL_NX_COPROC_INIT                     167
-#define OPAL_LAST                              167
+#define OPAL_XIVE_GET_VP_STATE                 170
+#define OPAL_LAST                              170
 
 #define QUIESCE_HOLD                   1 /* Spin all calls at entry */
 #define QUIESCE_REJECT                 2 /* Fail all calls with OPAL_BUSY */
index a55b01c90bb13b5bad7431bb127b2fdb92123ff6..4e978d4dea5ce446e6a359d0b4e9127d98e746c9 100644 (file)
@@ -279,6 +279,13 @@ int64_t opal_xive_allocate_irq(uint32_t chip_id);
 int64_t opal_xive_free_irq(uint32_t girq);
 int64_t opal_xive_sync(uint32_t type, uint32_t id);
 int64_t opal_xive_dump(uint32_t type, uint32_t id);
+int64_t opal_xive_get_queue_state(uint64_t vp, uint32_t prio,
+                                 __be32 *out_qtoggle,
+                                 __be32 *out_qindex);
+int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio,
+                                 uint32_t qtoggle,
+                                 uint32_t qindex);
+int64_t opal_xive_get_vp_state(uint64_t vp, __be64 *out_w01);
 int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target,
                        uint64_t desc, uint16_t pe_number);
 
index 3c704f5dd3ae3dbcbcab58a6ecbb384129386f48..b579a943407bbc0a63c34d53fc73662e9e99db7a 100644 (file)
@@ -109,12 +109,26 @@ extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
 extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
 
 extern void xive_native_sync_source(u32 hw_irq);
+extern void xive_native_sync_queue(u32 hw_irq);
 extern bool is_xive_irq(struct irq_chip *chip);
 extern int xive_native_enable_vp(u32 vp_id, bool single_escalation);
 extern int xive_native_disable_vp(u32 vp_id);
 extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id);
 extern bool xive_native_has_single_escalation(void);
 
+extern int xive_native_get_queue_info(u32 vp_id, uint32_t prio,
+                                     u64 *out_qpage,
+                                     u64 *out_qsize,
+                                     u64 *out_qeoi_page,
+                                     u32 *out_escalate_irq,
+                                     u64 *out_qflags);
+
+extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle,
+                                      u32 *qindex);
+extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle,
+                                      u32 qindex);
+extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state);
+
 #else
 
 static inline bool xive_enabled(void) { return false; }
index daad8c45c8e729d53cf83c3a5011024be178affa..7472244e7f301c154704b51161e1afec9c108816 100644 (file)
@@ -260,6 +260,9 @@ OPAL_CALL(opal_xive_get_vp_info,            OPAL_XIVE_GET_VP_INFO);
 OPAL_CALL(opal_xive_set_vp_info,               OPAL_XIVE_SET_VP_INFO);
 OPAL_CALL(opal_xive_sync,                      OPAL_XIVE_SYNC);
 OPAL_CALL(opal_xive_dump,                      OPAL_XIVE_DUMP);
+OPAL_CALL(opal_xive_get_queue_state,           OPAL_XIVE_GET_QUEUE_STATE);
+OPAL_CALL(opal_xive_set_queue_state,           OPAL_XIVE_SET_QUEUE_STATE);
+OPAL_CALL(opal_xive_get_vp_state,              OPAL_XIVE_GET_VP_STATE);
 OPAL_CALL(opal_signal_system_reset,            OPAL_SIGNAL_SYSTEM_RESET);
 OPAL_CALL(opal_npu_init_context,               OPAL_NPU_INIT_CONTEXT);
 OPAL_CALL(opal_npu_destroy_context,            OPAL_NPU_DESTROY_CONTEXT);
index 1ca127d052a67724e172b82d80e34b3a4c6ffa1b..0c037e933e55967ac75a6b486d52465a89165bae 100644 (file)
@@ -437,6 +437,12 @@ void xive_native_sync_source(u32 hw_irq)
 }
 EXPORT_SYMBOL_GPL(xive_native_sync_source);
 
+void xive_native_sync_queue(u32 hw_irq)
+{
+       opal_xive_sync(XIVE_SYNC_QUEUE, hw_irq);
+}
+EXPORT_SYMBOL_GPL(xive_native_sync_queue);
+
 static const struct xive_ops xive_native_ops = {
        .populate_irq_data      = xive_native_populate_irq_data,
        .configure_irq          = xive_native_configure_irq,
@@ -711,3 +717,96 @@ bool xive_native_has_single_escalation(void)
        return xive_has_single_esc;
 }
 EXPORT_SYMBOL_GPL(xive_native_has_single_escalation);
+
+int xive_native_get_queue_info(u32 vp_id, u32 prio,
+                              u64 *out_qpage,
+                              u64 *out_qsize,
+                              u64 *out_qeoi_page,
+                              u32 *out_escalate_irq,
+                              u64 *out_qflags)
+{
+       __be64 qpage;
+       __be64 qsize;
+       __be64 qeoi_page;
+       __be32 escalate_irq;
+       __be64 qflags;
+       s64 rc;
+
+       rc = opal_xive_get_queue_info(vp_id, prio, &qpage, &qsize,
+                                     &qeoi_page, &escalate_irq, &qflags);
+       if (rc) {
+               pr_err("OPAL failed to get queue info for VCPU %d/%d : %lld\n",
+                      vp_id, prio, rc);
+               return -EIO;
+       }
+
+       if (out_qpage)
+               *out_qpage = be64_to_cpu(qpage);
+       if (out_qsize)
+               *out_qsize = be32_to_cpu(qsize);
+       if (out_qeoi_page)
+               *out_qeoi_page = be64_to_cpu(qeoi_page);
+       if (out_escalate_irq)
+               *out_escalate_irq = be32_to_cpu(escalate_irq);
+       if (out_qflags)
+               *out_qflags = be64_to_cpu(qflags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(xive_native_get_queue_info);
+
+int xive_native_get_queue_state(u32 vp_id, u32 prio, u32 *qtoggle, u32 *qindex)
+{
+       __be32 opal_qtoggle;
+       __be32 opal_qindex;
+       s64 rc;
+
+       rc = opal_xive_get_queue_state(vp_id, prio, &opal_qtoggle,
+                                      &opal_qindex);
+       if (rc) {
+               pr_err("OPAL failed to get queue state for VCPU %d/%d : %lld\n",
+                      vp_id, prio, rc);
+               return -EIO;
+       }
+
+       if (qtoggle)
+               *qtoggle = be32_to_cpu(opal_qtoggle);
+       if (qindex)
+               *qindex = be32_to_cpu(opal_qindex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(xive_native_get_queue_state);
+
+int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex)
+{
+       s64 rc;
+
+       rc = opal_xive_set_queue_state(vp_id, prio, qtoggle, qindex);
+       if (rc) {
+               pr_err("OPAL failed to set queue state for VCPU %d/%d : %lld\n",
+                      vp_id, prio, rc);
+               return -EIO;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(xive_native_set_queue_state);
+
+int xive_native_get_vp_state(u32 vp_id, u64 *out_state)
+{
+       __be64 state;
+       s64 rc;
+
+       rc = opal_xive_get_vp_state(vp_id, &state);
+       if (rc) {
+               pr_err("OPAL failed to get vp state for VCPU %d : %lld\n",
+                      vp_id, rc);
+               return -EIO;
+       }
+
+       if (out_state)
+               *out_state = be64_to_cpu(state);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(xive_native_get_vp_state);