* [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code
@ 2018-01-11 4:33 Benjamin Herrenschmidt
2018-01-11 4:33 ` [PATCH v3 02/16] powerpc: Remove DEBUG define in 64-bit early setup code Benjamin Herrenschmidt
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:33 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
WORD2 if the TIMA isn't byte accessible and
isn't that useful to know about, take out the
pr_devel statement.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/sysdev/xive/common.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
index a3b8d7d1316e..838ebdbfe4c5 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -1269,11 +1269,6 @@ static void xive_setup_cpu(void)
{
struct xive_cpu *xc = __this_cpu_read(xive_cpu);
- /* Debug: Dump the TM state */
- pr_devel("CPU %d [HW 0x%02x] VT=%02x\n",
- smp_processor_id(), hard_smp_processor_id(),
- in_8(xive_tima + xive_tima_offset + TM_WORD2));
-
/* The backend might have additional things to do */
if (xive_ops->setup_cpu)
xive_ops->setup_cpu(smp_processor_id(), xc);
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 02/16] powerpc: Remove DEBUG define in 64-bit early setup code
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
@ 2018-01-11 4:33 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 03/16] powerpc: Reduce log level of "OPAL detected !" message Benjamin Herrenschmidt
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:33 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
This statement causes some not very useful messages to always
be printed on the serial port at boot, even on quiet boots.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/setup_64.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 8956a9856604..d3124c302146 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -10,8 +10,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#define DEBUG
-
#include <linux/export.h>
#include <linux/string.h>
#include <linux/sched.h>
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 03/16] powerpc: Reduce log level of "OPAL detected !" message
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
2018-01-11 4:33 ` [PATCH v3 02/16] powerpc: Remove DEBUG define in 64-bit early setup code Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 04/16] powerpc/kvm/xive: Add more debugfs queues info Benjamin Herrenschmidt
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
This message isn't terribly useful.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/platforms/powernv/opal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 041ddbd1fc57..2479e3396ed8 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -127,7 +127,7 @@ int __init early_init_dt_scan_opal(unsigned long node,
if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
powerpc_firmware_features |= FW_FEATURE_OPAL;
- pr_info("OPAL detected !\n");
+ pr_debug("OPAL detected !\n");
} else {
panic("OPAL != V3 detected, no longer supported.\n");
}
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 04/16] powerpc/kvm/xive: Add more debugfs queues info
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
2018-01-11 4:33 ` [PATCH v3 02/16] powerpc: Remove DEBUG define in 64-bit early setup code Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 03/16] powerpc: Reduce log level of "OPAL detected !" message Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 05/16] powerpc/kvm/xive: Enable use of the new "single escalation" feature Benjamin Herrenschmidt
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
Add details about enabled queues and escalation interrupts
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kvm/book3s_xive.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index 0d750d274c4e..cd21c891be9e 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -1795,6 +1795,7 @@ static int xive_debug_show(struct seq_file *m, void *private)
kvm_for_each_vcpu(i, vcpu, kvm) {
struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
+ unsigned int i;
if (!xc)
continue;
@@ -1804,6 +1805,33 @@ static int xive_debug_show(struct seq_file *m, void *private)
xc->server_num, xc->cppr, xc->hw_cppr,
xc->mfrr, xc->pending,
xc->stat_rm_h_xirr, xc->stat_vm_h_xirr);
+ for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
+ struct xive_q *q = &xc->queues[i];
+ u32 i0, i1, idx;
+
+ if (!q->qpage && !xc->esc_virq[i])
+ continue;
+
+ seq_printf(m, " [q%d]: ", i);
+
+ if (q->qpage) {
+ idx = q->idx;
+ i0 = be32_to_cpup(q->qpage + idx);
+ idx = (idx + 1) & q->msk;
+ i1 = be32_to_cpup(q->qpage + idx);
+ seq_printf(m, "T=%d %08x %08x... \n", q->toggle, i0, i1);
+ }
+ if (xc->esc_virq[i]) {
+ struct irq_data *d = irq_get_irq_data(xc->esc_virq[i]);
+ struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+ u64 pq = xive_vm_esb_load(xd, XIVE_ESB_GET);
+ seq_printf(m, "E:%c%c I(%d:%llx:%llx)",
+ (pq & XIVE_ESB_VAL_P) ? 'P' : 'p',
+ (pq & XIVE_ESB_VAL_Q) ? 'Q' : 'q',
+ xc->esc_virq[i], pq, xd->eoi_page);
+ seq_printf(m, "\n");
+ }
+ }
t_rm_h_xirr += xc->stat_rm_h_xirr;
t_rm_h_ipoll += xc->stat_rm_h_ipoll;
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 05/16] powerpc/kvm/xive: Enable use of the new "single escalation" feature
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (2 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 04/16] powerpc/kvm/xive: Add more debugfs queues info Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 06/16] powerpc/kvm/xive: Don't use existing "prodded" flag for xive escalations Benjamin Herrenschmidt
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
That feature, provided by Power9 DDD2.0 and later, when supported
by newer OPAL versions, allows to sacrifice a queue (priority 7)
in favor of merging all the escalation interrupts of the queues
of a single VP into a single interrupt.
This reduces the number of host interrupts used up by KVM guests
especially when those guests use multiple priorities.
It will also enable a future change to control the masking of the
escalation interrupts more precisely to avoid spurrious ones.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/opal-api.h | 1 +
arch/powerpc/include/asm/xive.h | 3 ++-
arch/powerpc/kvm/book3s_xive.c | 48 ++++++++++++++++++++++++-------------
arch/powerpc/kvm/book3s_xive.h | 15 +++++-------
arch/powerpc/sysdev/xive/native.c | 18 ++++++++++++--
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 {
/* Flags for OPAL_XIVE_GET/SET_VP_INFO */
enum {
OPAL_XIVE_VP_ENABLED = 0x00000001,
+ OPAL_XIVE_VP_SINGLE_ESCALATION = 0x00000002,
};
/* "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 371fbebf1ec9..11d5edeb5c22 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -143,9 +143,10 @@ extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
extern void xive_native_sync_source(u32 hw_irq);
extern bool is_xive_irq(struct irq_chip *chip);
-extern int xive_native_enable_vp(u32 vp_id);
+extern int xive_native_enable_vp(u32 vp_id, bool single_escalation);
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);
#else
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index cd21c891be9e..87f814e81e7d 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)
return -EIO;
}
- /*
- * Future improvement: start with them disabled
- * and handle DD2 and later scheme of merged escalation
- * interrupts
- */
- name = kasprintf(GFP_KERNEL, "kvm-%d-%d-%d",
- vcpu->kvm->arch.lpid, xc->server_num, prio);
+ if (xc->xive->single_escalation)
+ name = kasprintf(GFP_KERNEL, "kvm-%d-%d",
+ vcpu->kvm->arch.lpid, xc->server_num);
+ else
+ name = kasprintf(GFP_KERNEL, "kvm-%d-%d-%d",
+ vcpu->kvm->arch.lpid, xc->server_num, prio);
if (!name) {
pr_err("Failed to allocate escalation irq name for queue %d of VCPU %d\n",
prio, xc->server_num);
rc = -ENOMEM;
goto error;
}
+
+ pr_devel("Escalation %s irq %d (prio %d)\n", name, xc->esc_virq[prio], prio);
+
rc = request_irq(xc->esc_virq[prio], xive_esc_irq,
IRQF_NO_THREAD, name, vcpu);
if (rc) {
@@ -191,12 +193,12 @@ static int xive_check_provisioning(struct kvm *kvm, u8 prio)
pr_devel("Provisioning prio... %d\n", prio);
- /* Provision each VCPU and enable escalations */
+ /* Provision each VCPU and enable escalations if needed */
kvm_for_each_vcpu(i, vcpu, kvm) {
if (!vcpu->arch.xive_vcpu)
continue;
rc = xive_provision_queue(vcpu, prio);
- if (rc == 0)
+ if (rc == 0 && !xive->single_escalation)
xive_attach_escalation(vcpu, prio);
if (rc)
return rc;
@@ -1082,6 +1084,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
/* Allocate IPI */
xc->vp_ipi = xive_native_alloc_irq();
if (!xc->vp_ipi) {
+ pr_err("Failed to allocate xive irq for VCPU IPI\n");
r = -EIO;
goto bail;
}
@@ -1091,19 +1094,34 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
if (r)
goto bail;
+ /*
+ * Enable the VP first as the single escalation mode will
+ * affect escalation interrupts numbering
+ */
+ r = xive_native_enable_vp(xc->vp_id, xive->single_escalation);
+ if (r) {
+ pr_err("Failed to enable VP in OPAL, err %d\n", r);
+ goto bail;
+ }
+
/*
* Initialize queues. Initially we set them all for no queueing
* and we enable escalation for queue 0 only which we'll use for
* our mfrr change notifications. If the VCPU is hot-plugged, we
- * do handle provisioning however.
+ * do handle provisioning however based on the existing "map"
+ * of enabled queues.
*/
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
struct xive_q *q = &xc->queues[i];
+ /* Single escalation, no queue 7 */
+ if (i == 7 && xive->single_escalation)
+ break;
+
/* Is queue already enabled ? Provision it */
if (xive->qmap & (1 << i)) {
r = xive_provision_queue(vcpu, i);
- if (r == 0)
+ if (r == 0 && !xive->single_escalation)
xive_attach_escalation(vcpu, i);
if (r)
goto bail;
@@ -1123,11 +1141,6 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
if (r)
goto bail;
- /* Enable the VP */
- r = xive_native_enable_vp(xc->vp_id);
- if (r)
- goto bail;
-
/* Route the IPI */
r = xive_native_configure_irq(xc->vp_ipi, xc->vp_id, 0, XICS_IPI);
if (!r)
@@ -1474,6 +1487,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr)
pr_devel(" val=0x016%llx (server=0x%x, guest_prio=%d)\n",
val, server, guest_prio);
+
/*
* If the source doesn't already have an IPI, allocate
* one and get the corresponding data
@@ -1762,6 +1776,8 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)
if (xive->vp_base == XIVE_INVALID_VP)
ret = -ENOMEM;
+ xive->single_escalation = xive_native_has_single_escalation();
+
if (ret) {
kfree(xive);
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 {
u32 q_order;
u32 q_page_order;
+ /* Flags */
+ u8 single_escalation;
};
#define KVMPPC_XIVE_Q_COUNT 8
@@ -201,25 +203,20 @@ static inline struct kvmppc_xive_src_block *kvmppc_xive_find_source(struct kvmpp
* is as follow.
*
* Guest request for 0...6 are honored. Guest request for anything
- * higher results in a priority of 7 being applied.
- *
- * However, when XIRR is returned via H_XIRR, 7 is translated to 0xb
- * in order to match AIX expectations
+ * higher results in a priority of 6 being applied.
*
* Similar mapping is done for CPPR values
*/
static inline u8 xive_prio_from_guest(u8 prio)
{
- if (prio == 0xff || prio < 8)
+ if (prio == 0xff || prio < 6)
return prio;
- return 7;
+ return 6;
}
static inline u8 xive_prio_to_guest(u8 prio)
{
- if (prio == 0xff || prio < 7)
- return prio;
- return 0xb;
+ return prio;
}
static 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;
static u32 xive_queue_shift;
static u32 xive_pool_vps = XIVE_INVALID_VP;
static struct kmem_cache *xive_provision_cache;
+static bool xive_has_single_esc;
int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
{
@@ -571,6 +572,10 @@ bool __init xive_native_init(void)
break;
}
+ /* Do we support single escalation */
+ if (of_get_property(np, "single-escalation-support", NULL) != NULL)
+ xive_has_single_esc = true;
+
/* Configure Thread Management areas for KVM */
for_each_possible_cpu(cpu)
kvmppc_set_xive_tima(cpu, r.start, tima);
@@ -667,12 +672,15 @@ void xive_native_free_vp_block(u32 vp_base)
}
EXPORT_SYMBOL_GPL(xive_native_free_vp_block);
-int xive_native_enable_vp(u32 vp_id)
+int xive_native_enable_vp(u32 vp_id, bool single_escalation)
{
s64 rc;
+ u64 flags = OPAL_XIVE_VP_ENABLED;
+ if (single_escalation)
+ flags |= OPAL_XIVE_VP_SINGLE_ESCALATION;
for (;;) {
- rc = opal_xive_set_vp_info(vp_id, OPAL_XIVE_VP_ENABLED, 0);
+ rc = opal_xive_set_vp_info(vp_id, flags, 0);
if (rc != OPAL_BUSY)
break;
msleep(1);
@@ -710,3 +718,9 @@ int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id)
return 0;
}
EXPORT_SYMBOL_GPL(xive_native_get_vp_info);
+
+bool xive_native_has_single_escalation(void)
+{
+ return xive_has_single_esc;
+}
+EXPORT_SYMBOL_GPL(xive_native_has_single_escalation);
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 06/16] powerpc/kvm/xive: Don't use existing "prodded" flag for xive escalations
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (3 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 05/16] powerpc/kvm/xive: Enable use of the new "single escalation" feature Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 07/16] powerpc/kvm/xive: Check DR not IR to chose real vs virt mode MMIOs Benjamin Herrenschmidt
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
The prodded flag is only cleared at the beginning of H_CEDE,
so every time we have an escalation, we will cause the *next*
H_CEDE to return immediately.
Instead use a dedicated "irq_pending" flag to indicate that
a guest interrupt is pending for the VCPU. We don't reuse the
existing exception bitmap as to avoid expensive atomic ops.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/kvm_host.h | 1 +
arch/powerpc/kernel/asm-offsets.c | 1 +
arch/powerpc/kvm/book3s_hv.c | 2 +-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 10 ++++++++++
arch/powerpc/kvm/book3s_xive.c | 3 +--
5 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 3aa5b577cd60..bfe51356af5e 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -709,6 +709,7 @@ struct kvm_vcpu_arch {
u8 ceded;
u8 prodded;
u8 doorbell_request;
+ u8 irq_pending; /* Used by XIVE to signal pending guest irqs */
u32 last_inst;
struct swait_queue_head *wqp;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 6b958414b4e0..825089cf3e23 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -514,6 +514,7 @@ int main(void)
OFFSET(VCPU_PENDING_EXC, kvm_vcpu, arch.pending_exceptions);
OFFSET(VCPU_CEDED, kvm_vcpu, arch.ceded);
OFFSET(VCPU_PRODDED, kvm_vcpu, arch.prodded);
+ OFFSET(VCPU_IRQ_PENDING, kvm_vcpu, arch.irq_pending);
OFFSET(VCPU_DBELL_REQ, kvm_vcpu, arch.doorbell_request);
OFFSET(VCPU_MMCR, kvm_vcpu, arch.mmcr);
OFFSET(VCPU_PMC, kvm_vcpu, arch.pmc);
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 2d46037ce936..eafd722dce56 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -2987,7 +2987,7 @@ static inline bool xive_interrupt_pending(struct kvm_vcpu *vcpu)
{
if (!xive_enabled())
return false;
- return vcpu->arch.xive_saved_state.pipr <
+ return vcpu->arch.irq_pending || vcpu->arch.xive_saved_state.pipr <
vcpu->arch.xive_saved_state.cppr;
}
#else
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 2659844784b8..142b820946dc 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1033,6 +1033,16 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
li r9, 1
stw r9, VCPU_XIVE_PUSHED(r4)
eieio
+
+ /*
+ * We clear the irq_pending flag. There is a small chance of a
+ * race vs. the escalation interrupt happening on another
+ * processor setting it again, but the only consequence is to
+ * cause a spurrious wakeup on the next H_CEDE which is not an
+ * issue.
+ */
+ li r0,0
+ stb r0, VCPU_IRQ_PENDING(r4);
no_xive:
#endif /* CONFIG_KVM_XICS */
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index 87f814e81e7d..de78ac38f7ed 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -84,8 +84,7 @@ static irqreturn_t xive_esc_irq(int irq, void *data)
{
struct kvm_vcpu *vcpu = data;
- /* We use the existing H_PROD mechanism to wake up the target */
- vcpu->arch.prodded = 1;
+ vcpu->arch.irq_pending = 1;
smp_mb();
if (vcpu->arch.ceded)
kvmppc_fast_vcpu_kick(vcpu);
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 07/16] powerpc/kvm/xive: Check DR not IR to chose real vs virt mode MMIOs
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (4 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 06/16] powerpc/kvm/xive: Don't use existing "prodded" flag for xive escalations Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 08/16] powerpc/kvm/xive: Make xive_pushed a byte, not a word Benjamin Herrenschmidt
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 142b820946dc..68a9b28dfd25 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1442,7 +1442,7 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
li r7, TM_SPC_PULL_OS_CTX
li r6, TM_QW1_OS
mfmsr r0
- andi. r0, r0, MSR_IR /* in real mode? */
+ andi. r0, r0, MSR_DR /* in real mode? */
beq 2f
ld r10, HSTATE_XIVE_TIMA_VIRT(r13)
cmpldi cr0, r10, 0
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 08/16] powerpc/kvm/xive: Make xive_pushed a byte, not a word
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (5 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 07/16] powerpc/kvm/xive: Check DR not IR to chose real vs virt mode MMIOs Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 09/16] powerpc/xive: Move definition of ESB bits Benjamin Herrenschmidt
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/kvm_host.h | 3 ++-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index bfe51356af5e..2cf2cc6b389a 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -739,7 +739,8 @@ struct kvm_vcpu_arch {
struct kvmppc_icp *icp; /* XICS presentation controller */
struct kvmppc_xive_vcpu *xive_vcpu; /* XIVE virtual CPU data */
__be32 xive_cam_word; /* Cooked W2 in proper endian with valid bit */
- u32 xive_pushed; /* Is the VP pushed on the physical CPU ? */
+ u8 xive_pushed; /* Is the VP pushed on the physical CPU ? */
+ u8 xive_esc_on; /* Is the escalation irq enabled ? */
union xive_tma_w01 xive_saved_state; /* W0..1 of XIVE thread state */
#endif
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 68a9b28dfd25..bc3fc39d482b 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1031,7 +1031,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
li r9, TM_QW1_OS + TM_WORD2
stwcix r11,r9,r10
li r9, 1
- stw r9, VCPU_XIVE_PUSHED(r4)
+ stb r9, VCPU_XIVE_PUSHED(r4)
eieio
/*
@@ -1436,7 +1436,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
#ifdef CONFIG_KVM_XICS
/* We are exiting, pull the VP from the XIVE */
- lwz r0, VCPU_XIVE_PUSHED(r9)
+ lbz r0, VCPU_XIVE_PUSHED(r9)
cmpwi cr0, r0, 0
beq 1f
li r7, TM_SPC_PULL_OS_CTX
@@ -1465,7 +1465,7 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
/* Fixup some of the state for the next load */
li r10, 0
li r0, 0xff
- stw r10, VCPU_XIVE_PUSHED(r9)
+ stb r10, VCPU_XIVE_PUSHED(r9)
stb r10, (VCPU_XIVE_SAVED_STATE+3)(r9)
stb r0, (VCPU_XIVE_SAVED_STATE+4)(r9)
eieio
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 09/16] powerpc/xive: Move definition of ESB bits
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (6 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 08/16] powerpc/kvm/xive: Make xive_pushed a byte, not a word Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 10/16] powerpc/xive: Add interrupt flag to disable automatic EOI Benjamin Herrenschmidt
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
>From xive.h to xive-regs.h since it's a HW register definition
and it can be used from assembly
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/xive-regs.h | 35 +++++++++++++++++++++++++++++++++++
arch/powerpc/include/asm/xive.h | 35 -----------------------------------
2 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/arch/powerpc/include/asm/xive-regs.h b/arch/powerpc/include/asm/xive-regs.h
index 1d3f2be5ae39..fa4288822b68 100644
--- a/arch/powerpc/include/asm/xive-regs.h
+++ b/arch/powerpc/include/asm/xive-regs.h
@@ -9,6 +9,41 @@
#ifndef _ASM_POWERPC_XIVE_REGS_H
#define _ASM_POWERPC_XIVE_REGS_H
+/*
+ * "magic" Event State Buffer (ESB) MMIO offsets.
+ *
+ * Each interrupt source has a 2-bit state machine called ESB
+ * which can be controlled by MMIO. It's made of 2 bits, P and
+ * Q. P indicates that an interrupt is pending (has been sent
+ * to a queue and is waiting for an EOI). Q indicates that the
+ * interrupt has been triggered while pending.
+ *
+ * This acts as a coalescing mechanism in order to guarantee
+ * that a given interrupt only occurs at most once in a queue.
+ *
+ * When doing an EOI, the Q bit will indicate if the interrupt
+ * needs to be re-triggered.
+ *
+ * The following offsets into the ESB MMIO allow to read or
+ * manipulate the PQ bits. They must be used with an 8-bytes
+ * load instruction. They all return the previous state of the
+ * interrupt (atomically).
+ *
+ * Additionally, some ESB pages support doing an EOI via a
+ * store at 0 and some ESBs support doing a trigger via a
+ * separate trigger page.
+ */
+#define XIVE_ESB_STORE_EOI 0x400 /* Store */
+#define XIVE_ESB_LOAD_EOI 0x000 /* Load */
+#define XIVE_ESB_GET 0x800 /* Load */
+#define XIVE_ESB_SET_PQ_00 0xc00 /* Load */
+#define XIVE_ESB_SET_PQ_01 0xd00 /* Load */
+#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */
+#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */
+
+#define XIVE_ESB_VAL_P 0x2
+#define XIVE_ESB_VAL_Q 0x1
+
/*
* Thread Management (aka "TM") registers
*/
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index 11d5edeb5c22..f786617ea8b7 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -72,41 +72,6 @@ struct xive_q {
atomic_t pending_count;
};
-/*
- * "magic" Event State Buffer (ESB) MMIO offsets.
- *
- * Each interrupt source has a 2-bit state machine called ESB
- * which can be controlled by MMIO. It's made of 2 bits, P and
- * Q. P indicates that an interrupt is pending (has been sent
- * to a queue and is waiting for an EOI). Q indicates that the
- * interrupt has been triggered while pending.
- *
- * This acts as a coalescing mechanism in order to guarantee
- * that a given interrupt only occurs at most once in a queue.
- *
- * When doing an EOI, the Q bit will indicate if the interrupt
- * needs to be re-triggered.
- *
- * The following offsets into the ESB MMIO allow to read or
- * manipulate the PQ bits. They must be used with an 8-bytes
- * load instruction. They all return the previous state of the
- * interrupt (atomically).
- *
- * Additionally, some ESB pages support doing an EOI via a
- * store at 0 and some ESBs support doing a trigger via a
- * separate trigger page.
- */
-#define XIVE_ESB_STORE_EOI 0x400 /* Store */
-#define XIVE_ESB_LOAD_EOI 0x000 /* Load */
-#define XIVE_ESB_GET 0x800 /* Load */
-#define XIVE_ESB_SET_PQ_00 0xc00 /* Load */
-#define XIVE_ESB_SET_PQ_01 0xd00 /* Load */
-#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */
-#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */
-
-#define XIVE_ESB_VAL_P 0x2
-#define XIVE_ESB_VAL_Q 0x1
-
/* Global enable flags for the XIVE support */
extern bool __xive_enabled;
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 10/16] powerpc/xive: Add interrupt flag to disable automatic EOI
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (7 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 09/16] powerpc/xive: Move definition of ESB bits Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 11/16] powerpc/kvm/xive: Keep escalation interrupt masked unless ceded Benjamin Herrenschmidt
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
This will be used by KVM in order to keep escalation interrupts
in the non-EOI (masked) state after they fire. They will be
re-enabled directly in HW by KVM when needed.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/xive.h | 3 +++
arch/powerpc/sysdev/xive/common.c | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index f786617ea8b7..e602903c3029 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -58,6 +58,9 @@ struct xive_irq_data {
#define XIVE_IRQ_FLAG_EOI_FW 0x10
#define XIVE_IRQ_FLAG_H_INT_ESB 0x20
+/* Special flag set by KVM for excalation interrupts */
+#define XIVE_IRQ_NO_EOI 0x80
+
#define XIVE_INVALID_CHIP_ID -1
/* A queue tracking structure in a CPU */
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
index 838ebdbfe4c5..40c06110821c 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -367,7 +367,8 @@ static void xive_irq_eoi(struct irq_data *d)
* EOI the source if it hasn't been disabled and hasn't
* been passed-through to a KVM guest
*/
- if (!irqd_irq_disabled(d) && !irqd_is_forwarded_to_vcpu(d))
+ if (!irqd_irq_disabled(d) && !irqd_is_forwarded_to_vcpu(d) &&
+ !(xd->flags & XIVE_IRQ_NO_EOI))
xive_do_source_eoi(irqd_to_hwirq(d), xd);
/*
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 11/16] powerpc/kvm/xive: Keep escalation interrupt masked unless ceded
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (8 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 10/16] powerpc/xive: Add interrupt flag to disable automatic EOI Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 12/16] powerpc/kvm: Make "no_xive:" label local Benjamin Herrenschmidt
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
This works on top of the single escalation support. When in single
escalation, with this change, we will keep the escalation interrupt
disabled unless the VCPU is in H_CEDE (idle). In any other case, we
know the VCPU will be rescheduled and thus there is no need to take
escalation interrupts in the host whenever a guest interrupt fires.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/kvm_host.h | 2 ++
arch/powerpc/kernel/asm-offsets.c | 3 ++
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 64 +++++++++++++++++++++++++++++++--
arch/powerpc/kvm/book3s_xive.c | 30 ++++++++++++++++
4 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 2cf2cc6b389a..fef8133becc8 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -742,6 +742,8 @@ struct kvm_vcpu_arch {
u8 xive_pushed; /* Is the VP pushed on the physical CPU ? */
u8 xive_esc_on; /* Is the escalation irq enabled ? */
union xive_tma_w01 xive_saved_state; /* W0..1 of XIVE thread state */
+ u64 xive_esc_raddr; /* Escalation interrupt ESB real addr */
+ u64 xive_esc_vaddr; /* Escalation interrupt ESB virt addr */
#endif
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 825089cf3e23..1672dffd94e2 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -734,6 +734,9 @@ int main(void)
DEFINE(VCPU_XIVE_CAM_WORD, offsetof(struct kvm_vcpu,
arch.xive_cam_word));
DEFINE(VCPU_XIVE_PUSHED, offsetof(struct kvm_vcpu, arch.xive_pushed));
+ DEFINE(VCPU_XIVE_ESC_ON, offsetof(struct kvm_vcpu, arch.xive_esc_on));
+ DEFINE(VCPU_XIVE_ESC_RADDR, offsetof(struct kvm_vcpu, arch.xive_esc_raddr));
+ DEFINE(VCPU_XIVE_ESC_VADDR, offsetof(struct kvm_vcpu, arch.xive_esc_vaddr));
#endif
#ifdef CONFIG_KVM_EXIT_TIMING
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index bc3fc39d482b..b76878a648ef 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1042,7 +1042,42 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
* issue.
*/
li r0,0
- stb r0, VCPU_IRQ_PENDING(r4);
+ stb r0, VCPU_IRQ_PENDING(r4)
+
+ /*
+ * In single escalation mode, if the escalation interrupt is
+ * on, we mask it.
+ */
+ lbz r0, VCPU_XIVE_ESC_ON(r4)
+ cmpwi r0,0
+ beq 1f
+ ld r10, VCPU_XIVE_ESC_RADDR(r4)
+ li r9, XIVE_ESB_SET_PQ_01
+ ldcix r0, r10, r9
+ sync
+
+ /* We have a possible subtle race here: The escalation interrupt might
+ * have fired and be on its way to the host queue while we mask it,
+ * and if we unmask it early enough (re-cede right away), there is
+ * a theorical possibility that it fires again, thus landing in the
+ * target queue more than once which is a big no-no.
+ *
+ * Fortunately, solving this is rather easy. If the above load setting
+ * PQ to 01 returns a previous value where P is set, then we know the
+ * escalation interrupt is somewhere on its way to the host. In that
+ * case we simply don't clear the xive_esc_on flag below. It will be
+ * eventually cleared by the handler for the escalation interrupt.
+ *
+ * Then, when doing a cede, we check that flag again before re-enabling
+ * the escalation interrupt, and if set, we abort the cede.
+ */
+ andi. r0, r0, XIVE_ESB_VAL_P
+ bne- 1f
+
+ /* Now P is 0, we can clear the flag */
+ li r0, 0
+ stb r0, VCPU_XIVE_ESC_ON(r4)
+1:
no_xive:
#endif /* CONFIG_KVM_XICS */
@@ -2755,7 +2790,32 @@ kvm_cede_prodded:
/* we've ceded but we want to give control to the host */
kvm_cede_exit:
ld r9, HSTATE_KVM_VCPU(r13)
- b guest_exit_cont
+#ifdef CONFIG_KVM_XICS
+ /* Abort if we still have a pending escalation */
+ lbz r5, VCPU_XIVE_ESC_ON(r9)
+ cmpwi r5, 0
+ beq 1f
+ li r0, 0
+ stb r0, VCPU_CEDED(r9)
+1: /* Enable XIVE escalation */
+ li r5, XIVE_ESB_SET_PQ_00
+ mfmsr r0
+ andi. r0, r0, MSR_DR /* in real mode? */
+ beq 1f
+ ld r10, VCPU_XIVE_ESC_VADDR(r9)
+ cmpdi r10, 0
+ beq 3f
+ ldx r0, r10, r5
+ b 2f
+1: ld r10, VCPU_XIVE_ESC_RADDR(r9)
+ cmpdi r10, 0
+ beq 3f
+ ldcix r0, r10, r5
+2: sync
+ li r0, 1
+ stb r0, VCPU_XIVE_ESC_ON(r9)
+#endif /* CONFIG_KVM_XICS */
+3: b guest_exit_cont
/* Try to handle a machine check in real mode */
machine_check_realmode:
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index de78ac38f7ed..badfdbb857a2 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -89,6 +89,17 @@ static irqreturn_t xive_esc_irq(int irq, void *data)
if (vcpu->arch.ceded)
kvmppc_fast_vcpu_kick(vcpu);
+ /* Since we have the no-EOI flag, the interrupt is effectively
+ * disabled now. Clearing xive_esc_on means we won't bother
+ * doing so on the next entry.
+ *
+ * This also allows the entry code to know that if a PQ combination
+ * of 10 is observed while xive_esc_on is true, it means the queue
+ * contains an unprocessed escalation interrupt. We don't make use of
+ * that knowledge today but might (see comment in book3s_hv_rmhandler.S)
+ */
+ vcpu->arch.xive_esc_on = false;
+
return IRQ_HANDLED;
}
@@ -134,6 +145,25 @@ static int xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio)
goto error;
}
xc->esc_virq_names[prio] = name;
+
+ /* In single escalation mode, we grab the ESB MMIO of the
+ * interrupt and mask it. Also populate the VCPU v/raddr
+ * of the ESB page for use by asm entry/exit code. Finally
+ * set the XIVE_IRQ_NO_EOI flag which will prevent the
+ * core code from performing an EOI on the escalation
+ * interrupt, thus leaving it effectively masked after
+ * it fires once.
+ */
+ if (xc->xive->single_escalation) {
+ struct irq_data *d = irq_get_irq_data(xc->esc_virq[prio]);
+ struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+
+ xive_vm_esb_load(xd, XIVE_ESB_SET_PQ_01);
+ vcpu->arch.xive_esc_raddr = xd->eoi_page;
+ vcpu->arch.xive_esc_vaddr = (__force u64)xd->eoi_mmio;
+ xd->flags |= XIVE_IRQ_NO_EOI;
+ }
+
return 0;
error:
irq_dispose_mapping(xc->esc_virq[prio]);
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 12/16] powerpc/kvm: Make "no_xive:" label local
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (9 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 11/16] powerpc/kvm/xive: Keep escalation interrupt masked unless ceded Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 13/16] powerpc: Use the TRAP macro whenever comparing a trap number Benjamin Herrenschmidt
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index b76878a648ef..a38df400c1b7 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1022,7 +1022,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
/* We are entering the guest on that thread, push VCPU to XIVE */
ld r10, HSTATE_XIVE_TIMA_PHYS(r13)
cmpldi cr0, r10, 0
- beq no_xive
+ beq .Lno_xive
ld r11, VCPU_XIVE_SAVED_STATE(r4)
li r9, TM_QW1_OS
eieio
@@ -1078,7 +1078,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
li r0, 0
stb r0, VCPU_XIVE_ESC_ON(r4)
1:
-no_xive:
+.Lno_xive:
#endif /* CONFIG_KVM_XICS */
deliver_guest_interrupt:
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 13/16] powerpc: Use the TRAP macro whenever comparing a trap number
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (10 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 12/16] powerpc/kvm: Make "no_xive:" label local Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 14/16] powerpc: Remove useless EXC_COMMON_HV Benjamin Herrenschmidt
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
Trap numbers can have extra bits at the bottom that need to
be filtered out. There are a few cases where we don't do that.
It's possible that we got lucky but better safe than sorry.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/process.c | 2 +-
arch/powerpc/kernel/traps.c | 2 +-
arch/powerpc/mm/fault.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 72be0c32e902..397d6e64e3df 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1409,7 +1409,7 @@ void show_regs(struct pt_regs * regs)
print_msr_bits(regs->msr);
pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
trap = TRAP(regs);
- if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
+ if ((TRAP(regs) != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
pr_cont("CFAR: "REG" ", regs->orig_gpr3);
if (trap == 0x200 || trap == 0x300 || trap == 0x600)
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f3eb61be0d30..d61989be28e1 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1564,7 +1564,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
u8 status;
bool hv;
- hv = (regs->trap == 0xf80);
+ hv = (TRAP(regs) == 0xf80);
if (hv)
value = mfspr(SPRN_HFSCR);
else
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 6e1e39035380..7b15fe2ac986 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -576,7 +576,7 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
/* kernel has accessed a bad area */
- switch (regs->trap) {
+ switch (TRAP(regs)) {
case 0x300:
case 0x380:
printk(KERN_ALERT "Unable to handle kernel paging request for "
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 14/16] powerpc: Remove useless EXC_COMMON_HV
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (11 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 13/16] powerpc: Use the TRAP macro whenever comparing a trap number Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 15/16] powerpc/kvm: Store the MMU mode in the PACA on KVM exit Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 16/16] powerpc/kvm: Use the PACA virt/real mode info instead of mfmsr Benjamin Herrenschmidt
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
The only difference between EXC_COMMON_HV and EXC_COMMON is that the
former adds "2" to the trap number which is supposed to represent the
fact that this is an "HV" interrupt which uses HSRR0/1.
However KVM is the only one who cares and it has its own separate macros.
In fact, we only have one user of EXC_COMMON_HV and it's for an
unknown interrupt case. All the other ones already using EXC_COMMON.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/head-64.h | 7 +------
arch/powerpc/kernel/exceptions-64s.S | 2 +-
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h
index fdcff76e9a25..0a663dfc28b5 100644
--- a/arch/powerpc/include/asm/head-64.h
+++ b/arch/powerpc/include/asm/head-64.h
@@ -178,7 +178,7 @@ end_##sname:
* TRAMP_REAL_* - real, unrelocated helpers (virt can call these)
* TRAMP_VIRT_* - virt, unreloc helpers (in practice, real can use)
* TRAMP_KVM - KVM handlers that get put into real, unrelocated
- * EXC_COMMON_* - virt, relocated common handlers
+ * EXC_COMMON - virt, relocated common handlers
*
* The EXC handlers are given a name, and branch to name_common, or the
* appropriate KVM or masking function. Vector handler verieties are as
@@ -211,7 +211,6 @@ end_##sname:
* EXC_COMMON_BEGIN/END - used to open-code the handler
* EXC_COMMON
* EXC_COMMON_ASYNC
- * EXC_COMMON_HV
*
* TRAMP_REAL and TRAMP_VIRT can be used with BEGIN/END. KVM
* and OOL handlers are implemented as types of TRAMP and TRAMP_VIRT handlers.
@@ -413,10 +412,6 @@ end_##sname:
EXC_COMMON_BEGIN(name); \
STD_EXCEPTION_COMMON_ASYNC(realvec, name, hdlr); \
-#define EXC_COMMON_HV(name, realvec, hdlr) \
- EXC_COMMON_BEGIN(name); \
- STD_EXCEPTION_COMMON(realvec + 0x2, name, hdlr); \
-
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_HEAD_64_H */
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index e441b469dc8f..175891c6909c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1318,7 +1318,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
b .
#endif
-EXC_COMMON_HV(denorm_common, 0x1500, unknown_exception)
+EXC_COMMON(denorm_common, 0x1500, unknown_exception)
#ifdef CONFIG_CBE_RAS
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 15/16] powerpc/kvm: Store the MMU mode in the PACA on KVM exit
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (12 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 14/16] powerpc: Remove useless EXC_COMMON_HV Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 16/16] powerpc/kvm: Use the PACA virt/real mode info instead of mfmsr Benjamin Herrenschmidt
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
This stores the MMU mode (real vs. virt) in the PACA on exceptions
by passing bit 0x4000 to the KVM trampoline. This unfortunately
forces us to add a few more trampolines due to how our macros
work.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/exception-64s.h | 35 +++++++++++++++----------
arch/powerpc/include/asm/head-64.h | 8 ++++++
arch/powerpc/include/asm/kvm_book3s_asm.h | 1 +
arch/powerpc/kernel/asm-offsets.c | 1 +
arch/powerpc/kernel/exceptions-64s.S | 43 +++++++++++++++++++++++++++----
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 9 +++++--
6 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index b27205297e1d..64936a89c79c 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -243,10 +243,10 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXCEPTION_PROLOG_1(area, extra, vec); \
EXCEPTION_PROLOG_PSERIES_1(label, h);
-#define __KVMTEST(h, n) \
+#define __KVMTEST(h, n, v) \
lbz r10,HSTATE_IN_GUEST(r13); \
cmpwi r10,0; \
- bne do_kvm_##h##n
+ bne do_kvm_##h##n##v
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
/*
@@ -353,12 +353,12 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
b kvmppc_skip_##h##interrupt
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
-#define KVMTEST(h, n) __KVMTEST(h, n)
+#define KVMTEST(h, n, v) __KVMTEST(h, n, v)
#define KVM_HANDLER(area, h, n) __KVM_HANDLER(area, h, n)
#define KVM_HANDLER_SKIP(area, h, n) __KVM_HANDLER_SKIP(area, h, n)
#else
-#define KVMTEST(h, n)
+#define KVMTEST(h, n, v)
#define KVM_HANDLER(area, h, n)
#define KVM_HANDLER_SKIP(area, h, n)
#endif
@@ -479,13 +479,13 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \
EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_STD)
-#define STD_RELON_EXCEPTION_HV(loc, vec, label) \
- SET_SCRATCH0(r13); /* save r13 */ \
+#define STD_RELON_EXCEPTION_HV(loc, vec, label) \
+ SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label, \
- EXC_HV, KVMTEST_HV, vec);
+ EXC_HV, KVMTEST_HV_VIRT, vec);
#define STD_RELON_EXCEPTION_HV_OOL(vec, label) \
- EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV_VIRT, vec); \
EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
/* This associate vector numbers with bits in paca->irq_happened */
@@ -506,18 +506,25 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec)
#define SOFTEN_TEST_PR(vec) \
- KVMTEST(EXC_STD, vec); \
+ KVMTEST(EXC_STD, vec,); \
_SOFTEN_TEST(EXC_STD, vec)
#define SOFTEN_TEST_HV(vec) \
- KVMTEST(EXC_HV, vec); \
+ KVMTEST(EXC_HV, vec,); \
+ _SOFTEN_TEST(EXC_HV, vec)
+
+#define SOFTEN_TEST_HV_VIRT(vec) \
+ KVMTEST(EXC_HV, vec, _VIRT); \
_SOFTEN_TEST(EXC_HV, vec)
#define KVMTEST_PR(vec) \
- KVMTEST(EXC_STD, vec)
+ KVMTEST(EXC_STD, vec,)
#define KVMTEST_HV(vec) \
- KVMTEST(EXC_HV, vec)
+ KVMTEST(EXC_HV, vec,)
+
+#define KVMTEST_HV_VIRT(vec) \
+ KVMTEST(EXC_HV, vec, _VIRT)
#define SOFTEN_NOTEST_PR(vec) _SOFTEN_TEST(EXC_STD, vec)
#define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec)
@@ -562,10 +569,10 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label) \
_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
- EXC_HV, SOFTEN_TEST_HV)
+ EXC_HV, SOFTEN_TEST_HV_VIRT)
#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label) \
- EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec); \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV_VIRT, vec); \
EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
/*
diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h
index 0a663dfc28b5..faf8d03f0797 100644
--- a/arch/powerpc/include/asm/head-64.h
+++ b/arch/powerpc/include/asm/head-64.h
@@ -404,6 +404,14 @@ end_##sname:
TRAMP_KVM_BEGIN(do_kvm_H##n); \
KVM_HANDLER_SKIP(area, EXC_HV, n + 0x2); \
+#define TRAMP_KVM_HV_VIRT(area, n) \
+ TRAMP_KVM_BEGIN(do_kvm_H##n##_VIRT); \
+ KVM_HANDLER(area, EXC_HV, n + 0x4002); \
+
+#define TRAMP_KVM_HV_VIRT_SKIP(area, n) \
+ TRAMP_KVM_BEGIN(do_kvm_H##n##_VIRT); \
+ KVM_HANDLER_SKIP(area, EXC_HV, n + 0x4002); \
+
#define EXC_COMMON(name, realvec, hdlr) \
EXC_COMMON_BEGIN(name); \
STD_EXCEPTION_COMMON(realvec, name, hdlr); \
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index ab386af2904f..c6afd99d91fb 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -125,6 +125,7 @@ struct kvmppc_host_state {
void __iomem *xive_tima_phys;
void __iomem *xive_tima_virt;
u32 saved_xirr;
+ u32 exit_virt;
u64 dabr;
u64 host_mmcr[7]; /* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */
u32 host_pmc[8];
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 1672dffd94e2..25ee619531c2 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -641,6 +641,7 @@ int main(void)
HSTATE_FIELD(HSTATE_XIVE_TIMA_PHYS, xive_tima_phys);
HSTATE_FIELD(HSTATE_XIVE_TIMA_VIRT, xive_tima_virt);
HSTATE_FIELD(HSTATE_SAVED_XIRR, saved_xirr);
+ HSTATE_FIELD(HSTATE_EXIT_VIRT, exit_virt);
HSTATE_FIELD(HSTATE_HOST_IPI, host_ipi);
HSTATE_FIELD(HSTATE_PTID, ptid);
HSTATE_FIELD(HSTATE_TID, tid);
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 175891c6909c..845426266e9a 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -702,7 +702,7 @@ EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100)
.globl hardware_interrupt_relon_hv;
hardware_interrupt_relon_hv:
BEGIN_FTR_SECTION
- _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, EXC_HV, SOFTEN_TEST_HV)
+ _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, EXC_HV, SOFTEN_TEST_HV_VIRT)
FTR_SECTION_ELSE
_MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, EXC_STD, SOFTEN_TEST_PR)
ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
@@ -710,6 +710,7 @@ EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100)
TRAMP_KVM(PACA_EXGEN, 0x500)
TRAMP_KVM_HV(PACA_EXGEN, 0x500)
+TRAMP_KVM_HV_VIRT(PACA_EXGEN, 0x500)
EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ)
@@ -809,6 +810,7 @@ EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
EXC_REAL_HV(hdecrementer, 0x980, 0x80)
EXC_VIRT_HV(hdecrementer, 0x4980, 0x80, 0x980)
TRAMP_KVM_HV(PACA_EXGEN, 0x980)
+TRAMP_KVM_HV_VIRT(PACA_EXGEN, 0x980)
EXC_COMMON(hdecrementer_common, 0x980, hdec_interrupt)
@@ -872,21 +874,31 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
* Userspace syscalls have already saved the PPR, hcalls must save
* it before setting HMT_MEDIUM.
*/
-#define SYSCALL_KVMTEST \
+#define __SYSCALL_KVMTEST(test) \
mtctr r13; \
GET_PACA(r13); \
std r10,PACA_EXGEN+EX_R10(r13); \
- KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \
+ test;/* uses r10, branch to do_kvm_0xc00_system_call */ \
HMT_MEDIUM; \
mfctr r9;
+/* 0xc00 is a normal real mode "PR" (uses STD SRR0/1) entry */
+#define SYSCALL_KVMTEST __SYSCALL_KVMTEST(KVMTEST_PR(0xc00))
+
+/* 0x4c00 is special, it can come from the guest using SRR0/1 in virtual
+ * mode. It's the only to do that and only with HV KVM so we open code
+ * the specific variant of KVMTEST macro for it
+ */
+#define SYSCALL_KVMTEST_RELON __SYSCALL_KVMTEST(KVMTEST(EXC_STD,0xc00,_VIRT))
+
#else
#define SYSCALL_KVMTEST \
HMT_MEDIUM; \
mr r9,r13; \
GET_PACA(r13);
+#define SYSCALL_KVMTEST_RELON SYSCALL_KVMTEST
#endif
-
+
#define LOAD_SYSCALL_HANDLER(reg) \
__LOAD_HANDLER(reg, system_call_common)
@@ -955,7 +967,7 @@ EXC_REAL_BEGIN(system_call, 0xc00, 0x100)
EXC_REAL_END(system_call, 0xc00, 0x100)
EXC_VIRT_BEGIN(system_call, 0x4c00, 0x100)
- SYSCALL_KVMTEST /* loads PACA into r13, and saves r13 to r9 */
+ SYSCALL_KVMTEST_RELON /* loads PACA into r13, and saves r13 to r9 */
SYSCALL_FASTENDIAN_TEST
SYSCALL_VIRT
SYSCALL_FASTENDIAN
@@ -983,6 +995,21 @@ TRAMP_KVM_BEGIN(do_kvm_0xc00)
std r9,PACA_EXGEN+EX_R9(r13)
mfcr r9
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
+
+TRAMP_KVM_BEGIN(do_kvm_0xc00_VIRT)
+ /*
+ * Save the PPR (on systems that support it) before changing to
+ * HMT_MEDIUM. That allows the KVM code to save that value into the
+ * guest state (it is the guest's PPR value).
+ */
+ OPT_GET_SPR(r10, SPRN_PPR, CPU_FTR_HAS_PPR)
+ HMT_MEDIUM
+ OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r10, CPU_FTR_HAS_PPR)
+ mfctr r10
+ SET_SCRATCH0(r10)
+ std r9,PACA_EXGEN+EX_R9(r13)
+ mfcr r9
+ KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x4c00)
#endif
@@ -994,6 +1021,7 @@ EXC_COMMON(single_step_common, 0xd00, single_step_exception)
EXC_REAL_OOL_HV(h_data_storage, 0xe00, 0x20)
EXC_VIRT_OOL_HV(h_data_storage, 0x4e00, 0x20, 0xe00)
TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0xe00)
+TRAMP_KVM_HV_VIRT_SKIP(PACA_EXGEN, 0xe00)
EXC_COMMON_BEGIN(h_data_storage_common)
mfspr r10,SPRN_HDAR
std r10,PACA_EXGEN+EX_DAR(r13)
@@ -1010,12 +1038,14 @@ EXC_COMMON_BEGIN(h_data_storage_common)
EXC_REAL_OOL_HV(h_instr_storage, 0xe20, 0x20)
EXC_VIRT_OOL_HV(h_instr_storage, 0x4e20, 0x20, 0xe20)
TRAMP_KVM_HV(PACA_EXGEN, 0xe20)
+TRAMP_KVM_HV_VIRT(PACA_EXGEN, 0xe20)
EXC_COMMON(h_instr_storage_common, 0xe20, unknown_exception)
EXC_REAL_OOL_HV(emulation_assist, 0xe40, 0x20)
EXC_VIRT_OOL_HV(emulation_assist, 0x4e40, 0x20, 0xe40)
TRAMP_KVM_HV(PACA_EXGEN, 0xe40)
+TRAMP_KVM_HV_VIRT(PACA_EXGEN, 0xe40)
EXC_COMMON(emulation_assist_common, 0xe40, emulation_assist_interrupt)
@@ -1086,6 +1116,7 @@ EXCEPTION_COMMON(PACA_EXGEN, 0xe60, hmi_exception_common, handle_hmi_exception,
EXC_REAL_OOL_MASKABLE_HV(h_doorbell, 0xe80, 0x20)
EXC_VIRT_OOL_MASKABLE_HV(h_doorbell, 0x4e80, 0x20, 0xe80)
TRAMP_KVM_HV(PACA_EXGEN, 0xe80)
+TRAMP_KVM_HV_VIRT(PACA_EXGEN, 0xe80)
#ifdef CONFIG_PPC_DOORBELL
EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, doorbell_exception)
#else
@@ -1096,6 +1127,7 @@ EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, unknown_exception)
EXC_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0, 0x20)
EXC_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0x4ea0, 0x20, 0xea0)
TRAMP_KVM_HV(PACA_EXGEN, 0xea0)
+TRAMP_KVM_HV_VIRT(PACA_EXGEN, 0xea0)
EXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ)
@@ -1193,6 +1225,7 @@ EXC_COMMON(facility_unavailable_common, 0xf60, facility_unavailable_exception)
EXC_REAL_OOL_HV(h_facility_unavailable, 0xf80, 0x20)
EXC_VIRT_OOL_HV(h_facility_unavailable, 0x4f80, 0x20, 0xf80)
TRAMP_KVM_HV(PACA_EXGEN, 0xf80)
+TRAMP_KVM_HV_VIRT(PACA_EXGEN, 0xf80)
EXC_COMMON(h_facility_unavailable_common, 0xf80, facility_unavailable_exception)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index a38df400c1b7..1e32e188ba17 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -95,6 +95,8 @@ BEGIN_FTR_SECTION
46:
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+ li r0,0
+ stw r0,HSTATE_EXIT_VIRT(r13)
ld r4, HSTATE_KVM_VCPU(r13)
bl kvmppc_hv_entry
@@ -1312,8 +1314,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
mfspr r11, SPRN_SRR1
std r10, VCPU_SRR0(r9)
std r11, VCPU_SRR1(r9)
- /* trap is in the low half of r12, clear CR from the high half */
- clrldi r12, r12, 32
+ /* Recover bit 0x4000 from trap (virt vs real mode) */
+ rlwinm r0,r12,18,31,31
+ stw r0,HSTATE_EXIT_VIRT(r13)
+ /* trap is in the low half of r12, clear CR in high half and virt mode bit */
+ clrldi r12, r12, 50
andi. r0, r12, 2 /* need to read HSRR0/1? */
beq 1f
mfspr r10, SPRN_HSRR0
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 16/16] powerpc/kvm: Use the PACA virt/real mode info instead of mfmsr
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
` (13 preceding siblings ...)
2018-01-11 4:34 ` [PATCH v3 15/16] powerpc/kvm: Store the MMU mode in the PACA on KVM exit Benjamin Herrenschmidt
@ 2018-01-11 4:34 ` Benjamin Herrenschmidt
14 siblings, 0 replies; 16+ messages in thread
From: Benjamin Herrenschmidt @ 2018-01-11 4:34 UTC (permalink / raw)
To: kvm-ppc, kvm; +Cc: Benjamin Herrenschmidt
This shaves off a bunch of cycles from the KVM exit path
and the XIVE related hypercall.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kvm/book3s_hv_builtin.c | 5 ++---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 14 ++++++++------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 49a2c7825e04..5fbaa8710e0c 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -209,8 +209,7 @@ long kvmppc_h_random(struct kvm_vcpu *vcpu)
{
int r;
- /* Only need to do the expensive mfmsr() on radix */
- if (kvm_is_radix(vcpu->kvm) && (mfmsr() & MSR_IR))
+ if (local_paca->kvm_hstate.exit_virt)
r = powernv_get_random_long(&vcpu->arch.gpr[4]);
else
r = powernv_get_random_real_mode(&vcpu->arch.gpr[4]);
@@ -541,7 +540,7 @@ static long kvmppc_read_one_intr(bool *again)
#ifdef CONFIG_KVM_XICS
static inline bool is_rm(void)
{
- return !(mfmsr() & MSR_DR);
+ return !local_paca->kvm_hstate.exit_virt;
}
unsigned long kvmppc_rm_h_xirr(struct kvm_vcpu *vcpu)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 1e32e188ba17..0024c449340b 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -190,8 +190,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
* we will be in virtual mode at this point, which makes it a
* little easier to get back to the caller.
*/
- mfmsr r0
- andi. r0, r0, MSR_IR /* in real mode? */
+ lbz r0,HSTATE_EXIT_VIRT(r13)
+ cmpwi r0,0
bne .Lvirt_return
/* RFI into the highmem handler */
@@ -1481,8 +1481,9 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
beq 1f
li r7, TM_SPC_PULL_OS_CTX
li r6, TM_QW1_OS
- mfmsr r0
- andi. r0, r0, MSR_DR /* in real mode? */
+ /* Are we in virtual or real mode ? */
+ lbz r0,HSTATE_EXIT_VIRT(r13)
+ cmpwi r0,0
beq 2f
ld r10, HSTATE_XIVE_TIMA_VIRT(r13)
cmpldi cr0, r10, 0
@@ -2804,8 +2805,9 @@ kvm_cede_exit:
stb r0, VCPU_CEDED(r9)
1: /* Enable XIVE escalation */
li r5, XIVE_ESB_SET_PQ_00
- mfmsr r0
- andi. r0, r0, MSR_DR /* in real mode? */
+ /* Are we in virtual or real mode ? */
+ lbz r0,HSTATE_EXIT_VIRT(r13)
+ cmpwi r0,0
beq 1f
ld r10, VCPU_XIVE_ESC_VADDR(r9)
cmpdi r10, 0
--
2.14.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2018-01-11 4:35 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-11 4:33 [PATCH v3 01/16] powerpc/xive: Remove incorrect debug code Benjamin Herrenschmidt
2018-01-11 4:33 ` [PATCH v3 02/16] powerpc: Remove DEBUG define in 64-bit early setup code Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 03/16] powerpc: Reduce log level of "OPAL detected !" message Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 04/16] powerpc/kvm/xive: Add more debugfs queues info Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 05/16] powerpc/kvm/xive: Enable use of the new "single escalation" feature Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 06/16] powerpc/kvm/xive: Don't use existing "prodded" flag for xive escalations Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 07/16] powerpc/kvm/xive: Check DR not IR to chose real vs virt mode MMIOs Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 08/16] powerpc/kvm/xive: Make xive_pushed a byte, not a word Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 09/16] powerpc/xive: Move definition of ESB bits Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 10/16] powerpc/xive: Add interrupt flag to disable automatic EOI Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 11/16] powerpc/kvm/xive: Keep escalation interrupt masked unless ceded Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 12/16] powerpc/kvm: Make "no_xive:" label local Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 13/16] powerpc: Use the TRAP macro whenever comparing a trap number Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 14/16] powerpc: Remove useless EXC_COMMON_HV Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 15/16] powerpc/kvm: Store the MMU mode in the PACA on KVM exit Benjamin Herrenschmidt
2018-01-11 4:34 ` [PATCH v3 16/16] powerpc/kvm: Use the PACA virt/real mode info instead of mfmsr Benjamin Herrenschmidt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox