aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/opal-api.h1
-rw-r--r--arch/powerpc/include/asm/xive.h3
-rw-r--r--arch/powerpc/kvm/book3s_xive.c48
-rw-r--r--arch/powerpc/kvm/book3s_xive.h15
-rw-r--r--arch/powerpc/sysdev/xive/native.c18
5 files changed, 57 insertions, 28 deletions
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 233c7504b1f2..fc926743647e 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -1073,6 +1073,7 @@ enum {
1073/* Flags for OPAL_XIVE_GET/SET_VP_INFO */ 1073/* Flags for OPAL_XIVE_GET/SET_VP_INFO */
1074enum { 1074enum {
1075 OPAL_XIVE_VP_ENABLED = 0x00000001, 1075 OPAL_XIVE_VP_ENABLED = 0x00000001,
1076 OPAL_XIVE_VP_SINGLE_ESCALATION = 0x00000002,
1076}; 1077};
1077 1078
1078/* "Any chip" replacement for chip ID for allocation functions */ 1079/* "Any chip" replacement for chip ID for allocation functions */
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index b619a5585cd6..e602903c3029 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -111,9 +111,10 @@ extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
111 111
112extern void xive_native_sync_source(u32 hw_irq); 112extern void xive_native_sync_source(u32 hw_irq);
113extern bool is_xive_irq(struct irq_chip *chip); 113extern bool is_xive_irq(struct irq_chip *chip);
114extern int xive_native_enable_vp(u32 vp_id); 114extern int xive_native_enable_vp(u32 vp_id, bool single_escalation);
115extern int xive_native_disable_vp(u32 vp_id); 115extern int xive_native_disable_vp(u32 vp_id);
116extern 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);
117extern bool xive_native_has_single_escalation(void);
117 118
118#else 119#else
119 120
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index 6cff5bdfd6b7..a102efeabf05 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -112,19 +112,21 @@ static int xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio)
112 return -EIO; 112 return -EIO;
113 } 113 }
114 114
115 /* 115 if (xc->xive->single_escalation)
116 * Future improvement: start with them disabled 116 name = kasprintf(GFP_KERNEL, "kvm-%d-%d",
117 * and handle DD2 and later scheme of merged escalation 117 vcpu->kvm->arch.lpid, xc->server_num);
118 * interrupts 118 else
119 */ 119 name = kasprintf(GFP_KERNEL, "kvm-%d-%d-%d",
120 name = kasprintf(GFP_KERNEL, "kvm-%d-%d-%d", 120 vcpu->kvm->arch.lpid, xc->server_num, prio);
121 vcpu->kvm->arch.lpid, xc->server_num, prio);
122 if (!name) { 121 if (!name) {
123 pr_err("Failed to allocate escalation irq name for queue %d of VCPU %d\n", 122 pr_err("Failed to allocate escalation irq name for queue %d of VCPU %d\n",
124 prio, xc->server_num); 123 prio, xc->server_num);
125 rc = -ENOMEM; 124 rc = -ENOMEM;
126 goto error; 125 goto error;
127 } 126 }
127
128 pr_devel("Escalation %s irq %d (prio %d)\n", name, xc->esc_virq[prio], prio);
129
128 rc = request_irq(xc->esc_virq[prio], xive_esc_irq, 130 rc = request_irq(xc->esc_virq[prio], xive_esc_irq,
129 IRQF_NO_THREAD, name, vcpu); 131 IRQF_NO_THREAD, name, vcpu);
130 if (rc) { 132 if (rc) {
@@ -191,12 +193,12 @@ static int xive_check_provisioning(struct kvm *kvm, u8 prio)
191 193
192 pr_devel("Provisioning prio... %d\n", prio); 194 pr_devel("Provisioning prio... %d\n", prio);
193 195
194 /* Provision each VCPU and enable escalations */ 196 /* Provision each VCPU and enable escalations if needed */
195 kvm_for_each_vcpu(i, vcpu, kvm) { 197 kvm_for_each_vcpu(i, vcpu, kvm) {
196 if (!vcpu->arch.xive_vcpu) 198 if (!vcpu->arch.xive_vcpu)
197 continue; 199 continue;
198 rc = xive_provision_queue(vcpu, prio); 200 rc = xive_provision_queue(vcpu, prio);
199 if (rc == 0) 201 if (rc == 0 && !xive->single_escalation)
200 xive_attach_escalation(vcpu, prio); 202 xive_attach_escalation(vcpu, prio);
201 if (rc) 203 if (rc)
202 return rc; 204 return rc;
@@ -1081,6 +1083,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
1081 /* Allocate IPI */ 1083 /* Allocate IPI */
1082 xc->vp_ipi = xive_native_alloc_irq(); 1084 xc->vp_ipi = xive_native_alloc_irq();
1083 if (!xc->vp_ipi) { 1085 if (!xc->vp_ipi) {
1086 pr_err("Failed to allocate xive irq for VCPU IPI\n");
1084 r = -EIO; 1087 r = -EIO;
1085 goto bail; 1088 goto bail;
1086 } 1089 }
@@ -1091,18 +1094,33 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
1091 goto bail; 1094 goto bail;
1092 1095
1093 /* 1096 /*
1097 * Enable the VP first as the single escalation mode will
1098 * affect escalation interrupts numbering
1099 */
1100 r = xive_native_enable_vp(xc->vp_id, xive->single_escalation);
1101 if (r) {
1102 pr_err("Failed to enable VP in OPAL, err %d\n", r);
1103 goto bail;
1104 }
1105
1106 /*
1094 * Initialize queues. Initially we set them all for no queueing 1107 * Initialize queues. Initially we set them all for no queueing
1095 * and we enable escalation for queue 0 only which we'll use for 1108 * and we enable escalation for queue 0 only which we'll use for
1096 * our mfrr change notifications. If the VCPU is hot-plugged, we 1109 * our mfrr change notifications. If the VCPU is hot-plugged, we
1097 * do handle provisioning however. 1110 * do handle provisioning however based on the existing "map"
1111 * of enabled queues.
1098 */ 1112 */
1099 for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) { 1113 for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
1100 struct xive_q *q = &xc->queues[i]; 1114 struct xive_q *q = &xc->queues[i];
1101 1115
1116 /* Single escalation, no queue 7 */
1117 if (i == 7 && xive->single_escalation)
1118 break;
1119
1102 /* Is queue already enabled ? Provision it */ 1120 /* Is queue already enabled ? Provision it */
1103 if (xive->qmap & (1 << i)) { 1121 if (xive->qmap & (1 << i)) {
1104 r = xive_provision_queue(vcpu, i); 1122 r = xive_provision_queue(vcpu, i);
1105 if (r == 0) 1123 if (r == 0 && !xive->single_escalation)
1106 xive_attach_escalation(vcpu, i); 1124 xive_attach_escalation(vcpu, i);
1107 if (r) 1125 if (r)
1108 goto bail; 1126 goto bail;
@@ -1122,11 +1140,6 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
1122 if (r) 1140 if (r)
1123 goto bail; 1141 goto bail;
1124 1142
1125 /* Enable the VP */
1126 r = xive_native_enable_vp(xc->vp_id);
1127 if (r)
1128 goto bail;
1129
1130 /* Route the IPI */ 1143 /* Route the IPI */
1131 r = xive_native_configure_irq(xc->vp_ipi, xc->vp_id, 0, XICS_IPI); 1144 r = xive_native_configure_irq(xc->vp_ipi, xc->vp_id, 0, XICS_IPI);
1132 if (!r) 1145 if (!r)
@@ -1473,6 +1486,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr)
1473 1486
1474 pr_devel(" val=0x016%llx (server=0x%x, guest_prio=%d)\n", 1487 pr_devel(" val=0x016%llx (server=0x%x, guest_prio=%d)\n",
1475 val, server, guest_prio); 1488 val, server, guest_prio);
1489
1476 /* 1490 /*
1477 * If the source doesn't already have an IPI, allocate 1491 * If the source doesn't already have an IPI, allocate
1478 * one and get the corresponding data 1492 * one and get the corresponding data
@@ -1761,6 +1775,8 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)
1761 if (xive->vp_base == XIVE_INVALID_VP) 1775 if (xive->vp_base == XIVE_INVALID_VP)
1762 ret = -ENOMEM; 1776 ret = -ENOMEM;
1763 1777
1778 xive->single_escalation = xive_native_has_single_escalation();
1779
1764 if (ret) { 1780 if (ret) {
1765 kfree(xive); 1781 kfree(xive);
1766 return ret; 1782 return ret;
diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h
index 6ba63f8e8a61..a08ae6fd4c51 100644
--- a/arch/powerpc/kvm/book3s_xive.h
+++ b/arch/powerpc/kvm/book3s_xive.h
@@ -120,6 +120,8 @@ struct kvmppc_xive {
120 u32 q_order; 120 u32 q_order;
121 u32 q_page_order; 121 u32 q_page_order;
122 122
123 /* Flags */
124 u8 single_escalation;
123}; 125};
124 126
125#define KVMPPC_XIVE_Q_COUNT 8 127#define KVMPPC_XIVE_Q_COUNT 8
@@ -201,25 +203,20 @@ static inline struct kvmppc_xive_src_block *kvmppc_xive_find_source(struct kvmpp
201 * is as follow. 203 * is as follow.
202 * 204 *
203 * Guest request for 0...6 are honored. Guest request for anything 205 * Guest request for 0...6 are honored. Guest request for anything
204 * higher results in a priority of 7 being applied. 206 * higher results in a priority of 6 being applied.
205 *
206 * However, when XIRR is returned via H_XIRR, 7 is translated to 0xb
207 * in order to match AIX expectations
208 * 207 *
209 * Similar mapping is done for CPPR values 208 * Similar mapping is done for CPPR values
210 */ 209 */
211static inline u8 xive_prio_from_guest(u8 prio) 210static inline u8 xive_prio_from_guest(u8 prio)
212{ 211{
213 if (prio == 0xff || prio < 8) 212 if (prio == 0xff || prio < 6)
214 return prio; 213 return prio;
215 return 7; 214 return 6;
216} 215}
217 216
218static inline u8 xive_prio_to_guest(u8 prio) 217static inline u8 xive_prio_to_guest(u8 prio)
219{ 218{
220 if (prio == 0xff || prio < 7) 219 return prio;
221 return prio;
222 return 0xb;
223} 220}
224 221
225static inline u32 __xive_read_eq(__be32 *qpage, u32 msk, u32 *idx, u32 *toggle) 222static inline u32 __xive_read_eq(__be32 *qpage, u32 msk, u32 *idx, u32 *toggle)
diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
index ebc244b08d67..d22aeb0b69e1 100644
--- a/arch/powerpc/sysdev/xive/native.c
+++ b/arch/powerpc/sysdev/xive/native.c
@@ -42,6 +42,7 @@ static u32 xive_provision_chip_count;
42static u32 xive_queue_shift; 42static u32 xive_queue_shift;
43static u32 xive_pool_vps = XIVE_INVALID_VP; 43static u32 xive_pool_vps = XIVE_INVALID_VP;
44static struct kmem_cache *xive_provision_cache; 44static struct kmem_cache *xive_provision_cache;
45static bool xive_has_single_esc;
45 46
46int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) 47int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
47{ 48{
@@ -571,6 +572,10 @@ bool __init xive_native_init(void)
571 break; 572 break;
572 } 573 }
573 574
575 /* Do we support single escalation */
576 if (of_get_property(np, "single-escalation-support", NULL) != NULL)
577 xive_has_single_esc = true;
578
574 /* Configure Thread Management areas for KVM */ 579 /* Configure Thread Management areas for KVM */
575 for_each_possible_cpu(cpu) 580 for_each_possible_cpu(cpu)
576 kvmppc_set_xive_tima(cpu, r.start, tima); 581 kvmppc_set_xive_tima(cpu, r.start, tima);
@@ -667,12 +672,15 @@ void xive_native_free_vp_block(u32 vp_base)
667} 672}
668EXPORT_SYMBOL_GPL(xive_native_free_vp_block); 673EXPORT_SYMBOL_GPL(xive_native_free_vp_block);
669 674
670int xive_native_enable_vp(u32 vp_id) 675int xive_native_enable_vp(u32 vp_id, bool single_escalation)
671{ 676{
672 s64 rc; 677 s64 rc;
678 u64 flags = OPAL_XIVE_VP_ENABLED;
673 679
680 if (single_escalation)
681 flags |= OPAL_XIVE_VP_SINGLE_ESCALATION;
674 for (;;) { 682 for (;;) {
675 rc = opal_xive_set_vp_info(vp_id, OPAL_XIVE_VP_ENABLED, 0); 683 rc = opal_xive_set_vp_info(vp_id, flags, 0);
676 if (rc != OPAL_BUSY) 684 if (rc != OPAL_BUSY)
677 break; 685 break;
678 msleep(1); 686 msleep(1);
@@ -710,3 +718,9 @@ int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id)
710 return 0; 718 return 0;
711} 719}
712EXPORT_SYMBOL_GPL(xive_native_get_vp_info); 720EXPORT_SYMBOL_GPL(xive_native_get_vp_info);
721
722bool xive_native_has_single_escalation(void)
723{
724 return xive_has_single_esc;
725}
726EXPORT_SYMBOL_GPL(xive_native_has_single_escalation);