powerpc/xive: Remove incorrect debug code
Subsystems (3)
PATCH v3 1/16 powerpc/xive: Remove incorrect debug code
WORD2 if the TIMA isn't byte accessible and
isn't that useful to know about, take out thepr_devel statement.
--- arch/powerpc/sysdev/xive/common.c | 5 ----- 1 file changed, 5 deletions(-)
arch/powerpc/sysdev/xive/common.c +0 -5
@@ -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);
Signature · 1 line
2.14.3
PATCH v3 2/16 powerpc: Remove DEBUG define in 64-bit early setup code
This statement causes some not very useful messages to always be printed on the serial port at boot, even on quiet boots.
--- arch/powerpc/kernel/setup_64.c | 2 -- 1 file changed, 2 deletions(-)
arch/powerpc/kernel/setup_64.c +0 -2
@@ -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>
Signature · 1 line
2.14.3
PATCH v3 3/16 powerpc: Reduce log level of "OPAL detected !" message
In reply to Benjamin HerrenschmidtThis message isn't terribly useful.
--- arch/powerpc/platforms/powernv/opal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/powernv/opal.c +1 -1
@@ -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" ); }
Signature · 1 line
2.14.3
PATCH v3 4/16 powerpc/kvm/xive: Add more debugfs queues info
In reply to Benjamin HerrenschmidtAdd details about enabled queues and escalation interrupts
--- arch/powerpc/kvm/book3s_xive.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
arch/powerpc/kvm/book3s_xive.c +28 -0
@@ -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;
Signature · 1 line
2.14.3
PATCH v3 5/16 powerpc/kvm/xive: Enable use of the new "single escalation" feature
In reply to Benjamin HerrenschmidtThat 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.
--- 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(-)
arch/powerpc/include/asm/opal-api.h +1 -0
@@ -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 */
arch/powerpc/include/asm/xive.h +2 -1
@@ -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
arch/powerpc/kvm/book3s_xive.c +32 -16
111 lines not on this page · raw message
arch/powerpc/kvm/book3s_xive.h +6 -9
@@ -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)
arch/powerpc/sysdev/xive/native.c +16 -2
@@ -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);
Signature · 1 line
2.14.3
PATCH v3 6/16 powerpc/kvm/xive: Don't use existing "prodded" flag for xive escalations
In reply to Benjamin HerrenschmidtThe 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.
--- 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(-)
arch/powerpc/include/asm/kvm_host.h +1 -0
@@ -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;
arch/powerpc/kernel/asm-offsets.c +1 -0
@@ -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);
arch/powerpc/kvm/book3s_hv.c +1 -1
@@ -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
arch/powerpc/kvm/book3s_hv_rmhandlers.S +10 -0
@@ -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 */
arch/powerpc/kvm/book3s_xive.c +1 -2
@@ -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);
Signature · 1 line
2.14.3
PATCH v3 7/16 powerpc/kvm/xive: Check DR not IR to chose real vs virt mode MMIOs
In reply to Benjamin Herrenschmidt--- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kvm/book3s_hv_rmhandlers.S +1 -1
@@ -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
Signature · 1 line
2.14.3
PATCH v3 8/16 powerpc/kvm/xive: Make xive_pushed a byte, not a word
In reply to Benjamin Herrenschmidt--- arch/powerpc/include/asm/kvm_host.h | 3 ++- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-)
arch/powerpc/include/asm/kvm_host.h +2 -1
@@ -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
arch/powerpc/kvm/book3s_hv_rmhandlers.S +3 -3
@@ -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
Signature · 1 line
2.14.3
PATCH v3 9/16 powerpc/xive: Move definition of ESB bits
In reply to Benjamin HerrenschmidtFrom xive.h to xive-regs.h since it's a HW register definition and it can be used from assembly
--- arch/powerpc/include/asm/xive-regs.h | 35 +++++++++++++++++++++++++++++++++++ arch/powerpc/include/asm/xive.h | 35 ----------------------------------- 2 files changed, 35 insertions(+), 35 deletions(-)
arch/powerpc/include/asm/xive-regs.h +35 -0
@@ -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 */
arch/powerpc/include/asm/xive.h +0 -35
@@ -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;
Signature · 1 line
2.14.3
PATCH v3 10/16 powerpc/xive: Add interrupt flag to disable automatic EOI
In reply to Benjamin HerrenschmidtThis 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.
--- arch/powerpc/include/asm/xive.h | 3 +++ arch/powerpc/sysdev/xive/common.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/xive.h +3 -0
@@ -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 */
arch/powerpc/sysdev/xive/common.c +2 -1
@@ -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);/*
Signature · 1 line
2.14.3
PATCH v3 11/16 powerpc/kvm/xive: Keep escalation interrupt masked unless ceded
In reply to Benjamin HerrenschmidtThis 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.
--- 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(-)
arch/powerpc/include/asm/kvm_host.h +2 -0
@@ -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
arch/powerpc/kernel/asm-offsets.c +3 -0
@@ -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
arch/powerpc/kvm/book3s_hv_rmhandlers.S +62 -2
76 lines not on this page · raw message
arch/powerpc/kvm/book3s_xive.c +30 -0
@@ -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]);
Signature · 1 line
2.14.3
PATCH v3 12/16 powerpc/kvm: Make "no_xive:" label local
In reply to Benjamin Herrenschmidt--- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/kvm/book3s_hv_rmhandlers.S +2 -2
@@ -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:
Signature · 1 line
2.14.3
PATCH v3 13/16 powerpc: Use the TRAP macro whenever comparing a trap number
In reply to Benjamin HerrenschmidtTrap 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.
--- 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(-)
arch/powerpc/kernel/process.c +1 -1
@@ -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 )
arch/powerpc/kernel/traps.c +1 -1
@@ -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
arch/powerpc/mm/fault.c +1 -1
@@ -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 "
Signature · 1 line
2.14.3
PATCH v3 14/16 powerpc: Remove useless EXC_COMMON_HV
In reply to Benjamin HerrenschmidtThe 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.
--- arch/powerpc/include/asm/head-64.h | 7 +------ arch/powerpc/kernel/exceptions-64s.S | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-)
arch/powerpc/include/asm/head-64.h +1 -6
@@ -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 */
arch/powerpc/kernel/exceptions-64s.S +1 -1
@@ -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
Signature · 1 line
2.14.3
PATCH v3 15/16 powerpc/kvm: Store the MMU mode in the PACA on KVM exit
In reply to Benjamin HerrenschmidtThis 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.
--- 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(-)
arch/powerpc/include/asm/exception-64s.h +21 -14
@@ -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)/*
arch/powerpc/include/asm/head-64.h +8 -0
@@ -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); \
arch/powerpc/include/asm/kvm_book3s_asm.h +1 -0
@@ -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 ];
arch/powerpc/kernel/asm-offsets.c +1 -0
@@ -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);
arch/powerpc/kernel/exceptions-64s.S +38 -5
127 lines not on this page · raw message
arch/powerpc/kvm/book3s_hv_rmhandlers.S +7 -2
@@ -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
Signature · 1 line
2.14.3
PATCH v3 16/16 powerpc/kvm: Use the PACA virt/real mode info instead of mfmsr
In reply to Benjamin HerrenschmidtThis shaves off a bunch of cycles from the KVM exit path and the XIVE related hypercall.
--- arch/powerpc/kvm/book3s_hv_builtin.c | 5 ++--- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 14 ++++++++------ 2 files changed, 10 insertions(+), 9 deletions(-)
arch/powerpc/kvm/book3s_hv_builtin.c +2 -3
@@ -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)
arch/powerpc/kvm/book3s_hv_rmhandlers.S +8 -6
@@ -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
Signature · 1 line
2.14.3