@@ -186,8 +186,8 @@
#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
@@ -204,7 +204,14 @@
#define OPAL_NPU_SPA_SETUP 159
#define OPAL_NPU_SPA_CLEAR_CACHE 160
#define OPAL_NPU_TL_SET 161
-#define OPAL_LAST 161
+#define OPAL_SENSOR_READ_U64 162
+#define OPAL_SENSOR_GROUP_ENABLE 163
+#define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164
+#define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165
+#define OPAL_HANDLE_HMI2 166
+#define OPAL_XIVE_GET_VP_STATE 167
+#define OPAL_XIVE_SET_VP_STATE 168
+#define OPAL_LAST 168
/* Device tree flags */
@@ -273,6 +273,18 @@ 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_version,
+ __be64 *out_state);
+int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio,
+ uint32_t version,
+ uint64_t new_state);
+int64_t opal_xive_get_vp_state(uint64_t vp,
+ __be32 *out_version,
+ __be64 *out_state);
+int64_t opal_xive_set_vp_state(uint64_t vp,
+ uint32_t version,
+ uint64_t new_state);
int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target,
uint64_t desc, uint16_t pe_number);
@@ -139,6 +139,25 @@ 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);
+
+/* Version is 1, backward compatible to 1 */
+#define XIVE_STATE_VERSION 0x00010001
+#define XIVE_STATE_COMPAT(v) ((v) & 0xffff)
+
+extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *out_version,
+ u64 *out_state);
+extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 version,
+ u64 state);
+extern int xive_native_get_vp_state(u32 vp_id, u32 *out_version,
+ u64 *out_state);
+extern int xive_native_set_vp_state(u32 vp_id, u32 version, u64 state);
+
#else
static inline bool xive_enabled(void) { return false; }
@@ -307,6 +307,10 @@ 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_xive_set_vp_state, OPAL_XIVE_SET_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);
@@ -724,3 +724,110 @@ 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;
+ }
+ *out_qpage = be64_to_cpu(qpage);
+ *out_qsize = be32_to_cpu(qsize);
+ *out_qeoi_page = be64_to_cpu(qeoi_page);
+ *out_escalate_irq = be32_to_cpu(escalate_irq);
+ *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 *out_version,
+ u64 *out_state)
+{
+ __be32 version;
+ __be64 state;
+ s64 rc;
+
+ rc = opal_xive_get_queue_state(vp_id, prio, &version, &state);
+ if (rc) {
+ pr_err("OPAL failed to get queue state for VCPU %d/%d : %lld\n",
+ vp_id, prio, rc);
+ return -EIO;
+ }
+
+ *out_version = be32_to_cpu(version);
+ *out_state = be64_to_cpu(state);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(xive_native_get_queue_state);
+
+int xive_native_set_queue_state(u32 vp_id, u32 prio,
+ u32 version,
+ u64 state)
+{
+ s64 rc;
+
+ rc = opal_xive_set_queue_state(vp_id, prio, version, state);
+ 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,
+ u32 *out_version,
+ u64 *out_state)
+{
+ __be32 version;
+ __be64 state;
+ s64 rc;
+
+ rc = opal_xive_get_vp_state(vp_id, &version, &state);
+ if (rc) {
+ pr_err("OPAL failed to get vp state for VCPU %d : %lld\n",
+ vp_id, rc);
+ return -EIO;
+ }
+
+ *out_version = be32_to_cpu(version);
+ *out_state = be64_to_cpu(state);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(xive_native_get_vp_state);
+
+int xive_native_set_vp_state(u32 vp_id,
+ u32 version,
+ u64 state)
+{
+ s64 rc;
+
+ rc = opal_xive_set_vp_state(vp_id, version, state);
+ if (rc) {
+ pr_err("OPAL failed to set vp state for VCPU %d : %lld\n",
+ vp_id, rc);
+ return -EIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(xive_native_set_vp_state);
The support for XIVE native exploitation mode in Linux/KVM needs a couple more OPAL calls to configure the sPAPR guest and to save/restore the state of the XIVE internals. Signed-off-by: Cédric Le Goater <clg@kaod.org> --- arch/powerpc/include/asm/opal-api.h | 13 ++- arch/powerpc/include/asm/opal.h | 12 +++ arch/powerpc/include/asm/xive.h | 19 +++++ arch/powerpc/platforms/powernv/opal-wrappers.S | 4 + arch/powerpc/sysdev/xive/native.c | 107 +++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 3 deletions(-)