diff options
author | Cédric Le Goater <clg@kaod.org> | 2019-04-10 13:04:33 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2019-04-11 01:31:41 -0400 |
commit | 88ec6b93c8e7d6d4ffaf6ad6395ceb3bf552de15 (patch) | |
tree | 7ecd1492c4ec25868724001ff186004929cb6c11 | |
parent | 8c2ffd9174779014c3fe1f96d9dc3641d9175f00 (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.h | 7 | ||||
-rw-r--r-- | arch/powerpc/include/asm/opal.h | 7 | ||||
-rw-r--r-- | arch/powerpc/include/asm/xive.h | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-call.c | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xive/native.c | 99 |
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); | |||
279 | int64_t opal_xive_free_irq(uint32_t girq); | 279 | int64_t opal_xive_free_irq(uint32_t girq); |
280 | int64_t opal_xive_sync(uint32_t type, uint32_t id); | 280 | int64_t opal_xive_sync(uint32_t type, uint32_t id); |
281 | int64_t opal_xive_dump(uint32_t type, uint32_t id); | 281 | int64_t opal_xive_dump(uint32_t type, uint32_t id); |
282 | int64_t opal_xive_get_queue_state(uint64_t vp, uint32_t prio, | ||
283 | __be32 *out_qtoggle, | ||
284 | __be32 *out_qindex); | ||
285 | int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio, | ||
286 | uint32_t qtoggle, | ||
287 | uint32_t qindex); | ||
288 | int64_t opal_xive_get_vp_state(uint64_t vp, __be64 *out_w01); | ||
282 | int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target, | 289 | int64_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, | |||
109 | extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio); | 109 | extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio); |
110 | 110 | ||
111 | extern void xive_native_sync_source(u32 hw_irq); | 111 | extern void xive_native_sync_source(u32 hw_irq); |
112 | extern void xive_native_sync_queue(u32 hw_irq); | ||
112 | extern bool is_xive_irq(struct irq_chip *chip); | 113 | extern bool is_xive_irq(struct irq_chip *chip); |
113 | extern int xive_native_enable_vp(u32 vp_id, bool single_escalation); | 114 | extern int xive_native_enable_vp(u32 vp_id, bool single_escalation); |
114 | extern int xive_native_disable_vp(u32 vp_id); | 115 | extern int xive_native_disable_vp(u32 vp_id); |
115 | extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id); | 116 | extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id); |
116 | extern bool xive_native_has_single_escalation(void); | 117 | extern bool xive_native_has_single_escalation(void); |
117 | 118 | ||
119 | extern 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 | |||
126 | extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle, | ||
127 | u32 *qindex); | ||
128 | extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle, | ||
129 | u32 qindex); | ||
130 | extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state); | ||
131 | |||
118 | #else | 132 | #else |
119 | 133 | ||
120 | static inline bool xive_enabled(void) { return false; } | 134 | static 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); | |||
260 | OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO); | 260 | OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO); |
261 | OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC); | 261 | OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC); |
262 | OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP); | 262 | OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP); |
263 | OPAL_CALL(opal_xive_get_queue_state, OPAL_XIVE_GET_QUEUE_STATE); | ||
264 | OPAL_CALL(opal_xive_set_queue_state, OPAL_XIVE_SET_QUEUE_STATE); | ||
265 | OPAL_CALL(opal_xive_get_vp_state, OPAL_XIVE_GET_VP_STATE); | ||
263 | OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET); | 266 | OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET); |
264 | OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT); | 267 | OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT); |
265 | OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT); | 268 | OPAL_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 | } |
438 | EXPORT_SYMBOL_GPL(xive_native_sync_source); | 438 | EXPORT_SYMBOL_GPL(xive_native_sync_source); |
439 | 439 | ||
440 | void xive_native_sync_queue(u32 hw_irq) | ||
441 | { | ||
442 | opal_xive_sync(XIVE_SYNC_QUEUE, hw_irq); | ||
443 | } | ||
444 | EXPORT_SYMBOL_GPL(xive_native_sync_queue); | ||
445 | |||
440 | static const struct xive_ops xive_native_ops = { | 446 | static 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 | } |
713 | EXPORT_SYMBOL_GPL(xive_native_has_single_escalation); | 719 | EXPORT_SYMBOL_GPL(xive_native_has_single_escalation); |
720 | |||
721 | int 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 | } | ||
756 | EXPORT_SYMBOL_GPL(xive_native_get_queue_info); | ||
757 | |||
758 | int 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 | } | ||
779 | EXPORT_SYMBOL_GPL(xive_native_get_queue_state); | ||
780 | |||
781 | int 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 | } | ||
794 | EXPORT_SYMBOL_GPL(xive_native_set_queue_state); | ||
795 | |||
796 | int 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 | } | ||
812 | EXPORT_SYMBOL_GPL(xive_native_get_vp_state); | ||