Skip to content

Commit 88ec6b9

Browse files
legoatermpe
authored andcommitted
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 <[email protected]> Reviewed-by: David Gibson <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent 8c2ffd9 commit 88ec6b9

File tree

5 files changed

+127
-3
lines changed

5 files changed

+127
-3
lines changed

arch/powerpc/include/asm/opal-api.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@
186186
#define OPAL_XIVE_FREE_IRQ 140
187187
#define OPAL_XIVE_SYNC 141
188188
#define OPAL_XIVE_DUMP 142
189-
#define OPAL_XIVE_RESERVED3 143
190-
#define OPAL_XIVE_RESERVED4 144
189+
#define OPAL_XIVE_GET_QUEUE_STATE 143
190+
#define OPAL_XIVE_SET_QUEUE_STATE 144
191191
#define OPAL_SIGNAL_SYSTEM_RESET 145
192192
#define OPAL_NPU_INIT_CONTEXT 146
193193
#define OPAL_NPU_DESTROY_CONTEXT 147
@@ -210,7 +210,8 @@
210210
#define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164
211211
#define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165
212212
#define OPAL_NX_COPROC_INIT 167
213-
#define OPAL_LAST 167
213+
#define OPAL_XIVE_GET_VP_STATE 170
214+
#define OPAL_LAST 170
214215

215216
#define QUIESCE_HOLD 1 /* Spin all calls at entry */
216217
#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */

arch/powerpc/include/asm/opal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ int64_t opal_xive_allocate_irq(uint32_t chip_id);
279279
int64_t opal_xive_free_irq(uint32_t girq);
280280
int64_t opal_xive_sync(uint32_t type, uint32_t id);
281281
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);
282289
int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target,
283290
uint64_t desc, uint16_t pe_number);
284291

arch/powerpc/include/asm/xive.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,26 @@ extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
109109
extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
110110

111111
extern void xive_native_sync_source(u32 hw_irq);
112+
extern void xive_native_sync_queue(u32 hw_irq);
112113
extern bool is_xive_irq(struct irq_chip *chip);
113114
extern int xive_native_enable_vp(u32 vp_id, bool single_escalation);
114115
extern int xive_native_disable_vp(u32 vp_id);
115116
extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id);
116117
extern bool xive_native_has_single_escalation(void);
117118

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+
118132
#else
119133

120134
static inline bool xive_enabled(void) { return false; }

arch/powerpc/platforms/powernv/opal-call.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ OPAL_CALL(opal_xive_get_vp_info, OPAL_XIVE_GET_VP_INFO);
260260
OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO);
261261
OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC);
262262
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);
263266
OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET);
264267
OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT);
265268
OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT);

arch/powerpc/sysdev/xive/native.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,12 @@ void xive_native_sync_source(u32 hw_irq)
437437
}
438438
EXPORT_SYMBOL_GPL(xive_native_sync_source);
439439

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+
440446
static const struct xive_ops xive_native_ops = {
441447
.populate_irq_data = xive_native_populate_irq_data,
442448
.configure_irq = xive_native_configure_irq,
@@ -711,3 +717,96 @@ bool xive_native_has_single_escalation(void)
711717
return xive_has_single_esc;
712718
}
713719
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);

0 commit comments

Comments
 (0)