summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2019-04-10 13:04:33 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2019-04-11 01:31:41 -0400
commit88ec6b93c8e7d6d4ffaf6ad6395ceb3bf552de15 (patch)
tree7ecd1492c4ec25868724001ff186004929cb6c11
parent8c2ffd9174779014c3fe1f96d9dc3641d9175f00 (diff)
powerpc/xive: add OPAL extensions for the XIVE native exploitation support
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>
-rw-r--r--arch/powerpc/include/asm/opal-api.h7
-rw-r--r--arch/powerpc/include/asm/opal.h7
-rw-r--r--arch/powerpc/include/asm/xive.h14
-rw-r--r--arch/powerpc/platforms/powernv/opal-call.c3
-rw-r--r--arch/powerpc/sysdev/xive/native.c99
5 files changed, 127 insertions, 3 deletions
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 870fb7b239ea..e1d118ac61dc 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -186,8 +186,8 @@
186#define OPAL_XIVE_FREE_IRQ 140 186#define OPAL_XIVE_FREE_IRQ 140
187#define OPAL_XIVE_SYNC 141 187#define OPAL_XIVE_SYNC 141
188#define OPAL_XIVE_DUMP 142 188#define OPAL_XIVE_DUMP 142
189#define OPAL_XIVE_RESERVED3 143 189#define OPAL_XIVE_GET_QUEUE_STATE 143
190#define OPAL_XIVE_RESERVED4 144 190#define OPAL_XIVE_SET_QUEUE_STATE 144
191#define OPAL_SIGNAL_SYSTEM_RESET 145 191#define OPAL_SIGNAL_SYSTEM_RESET 145
192#define OPAL_NPU_INIT_CONTEXT 146 192#define OPAL_NPU_INIT_CONTEXT 146
193#define OPAL_NPU_DESTROY_CONTEXT 147 193#define OPAL_NPU_DESTROY_CONTEXT 147
@@ -210,7 +210,8 @@
210#define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164 210#define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164
211#define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165 211#define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165
212#define OPAL_NX_COPROC_INIT 167 212#define OPAL_NX_COPROC_INIT 167
213#define OPAL_LAST 167 213#define OPAL_XIVE_GET_VP_STATE 170
214#define OPAL_LAST 170
214 215
215#define QUIESCE_HOLD 1 /* Spin all calls at entry */ 216#define QUIESCE_HOLD 1 /* Spin all calls at entry */
216#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ 217#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index a55b01c90bb1..4e978d4dea5c 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -279,6 +279,13 @@ int64_t opal_xive_allocate_irq(uint32_t chip_id);
279int64_t opal_xive_free_irq(uint32_t girq); 279int64_t opal_xive_free_irq(uint32_t girq);
280int64_t opal_xive_sync(uint32_t type, uint32_t id); 280int64_t opal_xive_sync(uint32_t type, uint32_t id);
281int64_t opal_xive_dump(uint32_t type, uint32_t id); 281int64_t opal_xive_dump(uint32_t type, uint32_t id);
282int64_t opal_xive_get_queue_state(uint64_t vp, uint32_t prio,
283 __be32 *out_qtoggle,
284 __be32 *out_qindex);
285int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio,
286 uint32_t qtoggle,
287 uint32_t qindex);
288int64_t opal_xive_get_vp_state(uint64_t vp, __be64 *out_w01);
282int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target, 289int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target,
283 uint64_t desc, uint16_t pe_number); 290 uint64_t desc, uint16_t pe_number);
284 291
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index 3c704f5dd3ae..b579a943407b 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -109,12 +109,26 @@ extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
109extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio); 109extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
110 110
111extern void xive_native_sync_source(u32 hw_irq); 111extern void xive_native_sync_source(u32 hw_irq);
112extern void xive_native_sync_queue(u32 hw_irq);
112extern bool is_xive_irq(struct irq_chip *chip); 113extern bool is_xive_irq(struct irq_chip *chip);
113extern int xive_native_enable_vp(u32 vp_id, bool single_escalation); 114extern int xive_native_enable_vp(u32 vp_id, bool single_escalation);
114extern int xive_native_disable_vp(u32 vp_id); 115extern int xive_native_disable_vp(u32 vp_id);
115extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id); 116extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id);
116extern bool xive_native_has_single_escalation(void); 117extern bool xive_native_has_single_escalation(void);
117 118
119extern int xive_native_get_queue_info(u32 vp_id, uint32_t prio,
120 u64 *out_qpage,
121 u64 *out_qsize,
122 u64 *out_qeoi_page,
123 u32 *out_escalate_irq,
124 u64 *out_qflags);
125
126extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle,
127 u32 *qindex);
128extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle,
129 u32 qindex);
130extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state);
131
118#else 132#else
119 133
120static inline bool xive_enabled(void) { return false; } 134static inline bool xive_enabled(void) { return false; }
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index daad8c45c8e7..7472244e7f30 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -260,6 +260,9 @@ OPAL_CALL(opal_xive_get_vp_info, OPAL_XIVE_GET_VP_INFO);
260OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO); 260OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO);
261OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC); 261OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC);
262OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP); 262OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP);
263OPAL_CALL(opal_xive_get_queue_state, OPAL_XIVE_GET_QUEUE_STATE);
264OPAL_CALL(opal_xive_set_queue_state, OPAL_XIVE_SET_QUEUE_STATE);
265OPAL_CALL(opal_xive_get_vp_state, OPAL_XIVE_GET_VP_STATE);
263OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET); 266OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET);
264OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT); 267OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT);
265OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT); 268OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT);
diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
index 1ca127d052a6..0c037e933e55 100644
--- a/arch/powerpc/sysdev/xive/native.c
+++ b/arch/powerpc/sysdev/xive/native.c
@@ -437,6 +437,12 @@ void xive_native_sync_source(u32 hw_irq)
437} 437}
438EXPORT_SYMBOL_GPL(xive_native_sync_source); 438EXPORT_SYMBOL_GPL(xive_native_sync_source);
439 439
440void xive_native_sync_queue(u32 hw_irq)
441{
442 opal_xive_sync(XIVE_SYNC_QUEUE, hw_irq);
443}
444EXPORT_SYMBOL_GPL(xive_native_sync_queue);
445
440static const struct xive_ops xive_native_ops = { 446static const struct xive_ops xive_native_ops = {
441 .populate_irq_data = xive_native_populate_irq_data, 447 .populate_irq_data = xive_native_populate_irq_data,
442 .configure_irq = xive_native_configure_irq, 448 .configure_irq = xive_native_configure_irq,
@@ -711,3 +717,96 @@ bool xive_native_has_single_escalation(void)
711 return xive_has_single_esc; 717 return xive_has_single_esc;
712} 718}
713EXPORT_SYMBOL_GPL(xive_native_has_single_escalation); 719EXPORT_SYMBOL_GPL(xive_native_has_single_escalation);
720
721int xive_native_get_queue_info(u32 vp_id, u32 prio,
722 u64 *out_qpage,
723 u64 *out_qsize,
724 u64 *out_qeoi_page,
725 u32 *out_escalate_irq,
726 u64 *out_qflags)
727{
728 __be64 qpage;
729 __be64 qsize;
730 __be64 qeoi_page;
731 __be32 escalate_irq;
732 __be64 qflags;
733 s64 rc;
734
735 rc = opal_xive_get_queue_info(vp_id, prio, &qpage, &qsize,
736 &qeoi_page, &escalate_irq, &qflags);
737 if (rc) {
738 pr_err("OPAL failed to get queue info for VCPU %d/%d : %lld\n",
739 vp_id, prio, rc);
740 return -EIO;
741 }
742
743 if (out_qpage)
744 *out_qpage = be64_to_cpu(qpage);
745 if (out_qsize)
746 *out_qsize = be32_to_cpu(qsize);
747 if (out_qeoi_page)
748 *out_qeoi_page = be64_to_cpu(qeoi_page);
749 if (out_escalate_irq)
750 *out_escalate_irq = be32_to_cpu(escalate_irq);
751 if (out_qflags)
752 *out_qflags = be64_to_cpu(qflags);
753
754 return 0;
755}
756EXPORT_SYMBOL_GPL(xive_native_get_queue_info);
757
758int xive_native_get_queue_state(u32 vp_id, u32 prio, u32 *qtoggle, u32 *qindex)
759{
760 __be32 opal_qtoggle;
761 __be32 opal_qindex;
762 s64 rc;
763
764 rc = opal_xive_get_queue_state(vp_id, prio, &opal_qtoggle,
765 &opal_qindex);
766 if (rc) {
767 pr_err("OPAL failed to get queue state for VCPU %d/%d : %lld\n",
768 vp_id, prio, rc);
769 return -EIO;
770 }
771
772 if (qtoggle)
773 *qtoggle = be32_to_cpu(opal_qtoggle);
774 if (qindex)
775 *qindex = be32_to_cpu(opal_qindex);
776
777 return 0;
778}
779EXPORT_SYMBOL_GPL(xive_native_get_queue_state);
780
781int xive_native_set_queue_state(u32 vp_id, u32 prio, u32 qtoggle, u32 qindex)
782{
783 s64 rc;
784
785 rc = opal_xive_set_queue_state(vp_id, prio, qtoggle, qindex);
786 if (rc) {
787 pr_err("OPAL failed to set queue state for VCPU %d/%d : %lld\n",
788 vp_id, prio, rc);
789 return -EIO;
790 }
791
792 return 0;
793}
794EXPORT_SYMBOL_GPL(xive_native_set_queue_state);
795
796int xive_native_get_vp_state(u32 vp_id, u64 *out_state)
797{
798 __be64 state;
799 s64 rc;
800
801 rc = opal_xive_get_vp_state(vp_id, &state);
802 if (rc) {
803 pr_err("OPAL failed to get vp state for VCPU %d : %lld\n",
804 vp_id, rc);
805 return -EIO;
806 }
807
808 if (out_state)
809 *out_state = be64_to_cpu(state);
810 return 0;
811}
812EXPORT_SYMBOL_GPL(xive_native_get_vp_state);