| From 8e036c8d30a2cd9d8fc7442fbf6824e0a3e986e7 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@kaod.org> |
| Date: Tue, 13 Feb 2018 09:47:12 +0100 |
| Subject: powerpc/xive: Use hw CPU ids when configuring the CPU queues |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Cédric Le Goater <clg@kaod.org> |
| |
| commit 8e036c8d30a2cd9d8fc7442fbf6824e0a3e986e7 upstream. |
| |
| The CPU event notification queues on sPAPR should be configured using |
| a hardware CPU identifier. |
| |
| The problem did not show up on the Power Hypervisor because pHyp |
| supports 8 threads per core which keeps CPU number contiguous. This is |
| not the case on all sPAPR virtual machines, some use SMT=1. |
| |
| Also improve error logging by adding the CPU number. |
| |
| Fixes: eac1e731b59e ("powerpc/xive: guest exploitation of the XIVE interrupt controller") |
| Cc: stable@vger.kernel.org # v4.14+ |
| Signed-off-by: Cédric Le Goater <clg@kaod.org> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/powerpc/sysdev/xive/spapr.c | 16 ++++++++++------ |
| 1 file changed, 10 insertions(+), 6 deletions(-) |
| |
| --- a/arch/powerpc/sysdev/xive/spapr.c |
| +++ b/arch/powerpc/sysdev/xive/spapr.c |
| @@ -356,7 +356,8 @@ static int xive_spapr_configure_queue(u3 |
| |
| rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size); |
| if (rc) { |
| - pr_err("Error %lld getting queue info prio %d\n", rc, prio); |
| + pr_err("Error %lld getting queue info CPU %d prio %d\n", rc, |
| + target, prio); |
| rc = -EIO; |
| goto fail; |
| } |
| @@ -370,7 +371,8 @@ static int xive_spapr_configure_queue(u3 |
| /* Configure and enable the queue in HW */ |
| rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); |
| if (rc) { |
| - pr_err("Error %lld setting queue for prio %d\n", rc, prio); |
| + pr_err("Error %lld setting queue for CPU %d prio %d\n", rc, |
| + target, prio); |
| rc = -EIO; |
| } else { |
| q->qpage = qpage; |
| @@ -389,8 +391,8 @@ static int xive_spapr_setup_queue(unsign |
| if (IS_ERR(qpage)) |
| return PTR_ERR(qpage); |
| |
| - return xive_spapr_configure_queue(cpu, q, prio, qpage, |
| - xive_queue_shift); |
| + return xive_spapr_configure_queue(get_hard_smp_processor_id(cpu), |
| + q, prio, qpage, xive_queue_shift); |
| } |
| |
| static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, |
| @@ -399,10 +401,12 @@ static void xive_spapr_cleanup_queue(uns |
| struct xive_q *q = &xc->queue[prio]; |
| unsigned int alloc_order; |
| long rc; |
| + int hw_cpu = get_hard_smp_processor_id(cpu); |
| |
| - rc = plpar_int_set_queue_config(0, cpu, prio, 0, 0); |
| + rc = plpar_int_set_queue_config(0, hw_cpu, prio, 0, 0); |
| if (rc) |
| - pr_err("Error %ld setting queue for prio %d\n", rc, prio); |
| + pr_err("Error %ld setting queue for CPU %d prio %d\n", rc, |
| + hw_cpu, prio); |
| |
| alloc_order = xive_alloc_order(xive_queue_shift); |
| free_pages((unsigned long)q->qpage, alloc_order); |