KVM: PPC: Book3S HV: Don't access XIVE PIPR register using byte accesses
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 6 Sep 2017 05:20:55 +0000 (15:20 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 12 Sep 2017 06:02:07 +0000 (16:02 +1000)
The XIVE interrupt controller on POWER9 machines doesn't support byte
accesses to any register in the thread management area other than the
CPPR (current processor priority register).  In particular, when
reading the PIPR (pending interrupt priority register), we need to
do a 32-bit or 64-bit load.

Cc: stable@vger.kernel.org # v4.13
Fixes: 2c4fb78f78b6 ("KVM: PPC: Book3S HV: Workaround POWER9 DD1.0 bug causing IPB bit loss")
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/kvm/book3s_hv_rm_xive.c
arch/powerpc/kvm/book3s_xive.c
arch/powerpc/kvm/book3s_xive_template.c

index abf5f01b6eb1f04b05d0643ddc46bb8ded237d8f..5b81a807d742c8b11018ead176b60590064f5d7f 100644 (file)
@@ -38,7 +38,6 @@ static inline void __iomem *get_tima_phys(void)
 #define __x_tima               get_tima_phys()
 #define __x_eoi_page(xd)       ((void __iomem *)((xd)->eoi_page))
 #define __x_trig_page(xd)      ((void __iomem *)((xd)->trig_page))
-#define __x_readb      __raw_rm_readb
 #define __x_writeb     __raw_rm_writeb
 #define __x_readw      __raw_rm_readw
 #define __x_readq      __raw_rm_readq
index 08b200a0bbcec8c47a3128f4685ffcbfad261552..13304622ab1c78682fa18f06120f5eb0970f57fb 100644 (file)
@@ -48,7 +48,6 @@
 #define __x_tima               xive_tima
 #define __x_eoi_page(xd)       ((void __iomem *)((xd)->eoi_mmio))
 #define __x_trig_page(xd)      ((void __iomem *)((xd)->trig_mmio))
-#define __x_readb      __raw_readb
 #define __x_writeb     __raw_writeb
 #define __x_readw      __raw_readw
 #define __x_readq      __raw_readq
index d1ed2c41b5d246dde6d53c34530bc30dc63656b9..c7a5deadd1cc782ddd45667c9fc29f96166e85e7 100644 (file)
@@ -28,7 +28,8 @@ static void GLUE(X_PFX,ack_pending)(struct kvmppc_xive_vcpu *xc)
         * bit.
         */
        if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
-               u8 pipr = __x_readb(__x_tima + TM_QW1_OS + TM_PIPR);
+               __be64 qw1 = __x_readq(__x_tima + TM_QW1_OS);
+               u8 pipr = be64_to_cpu(qw1) & 0xff;
                if (pipr >= xc->hw_cppr)
                        return;
        }
@@ -336,7 +337,6 @@ X_STATIC unsigned long GLUE(X_PFX,h_ipoll)(struct kvm_vcpu *vcpu, unsigned long
        struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
        u8 pending = xc->pending;
        u32 hirq;
-       u8 pipr;
 
        pr_devel("H_IPOLL(server=%ld)\n", server);
 
@@ -353,7 +353,8 @@ X_STATIC unsigned long GLUE(X_PFX,h_ipoll)(struct kvm_vcpu *vcpu, unsigned long
                pending = 0xff;
        } else {
                /* Grab pending interrupt if any */
-               pipr = __x_readb(__x_tima + TM_QW1_OS + TM_PIPR);
+               __be64 qw1 = __x_readq(__x_tima + TM_QW1_OS);
+               u8 pipr = be64_to_cpu(qw1) & 0xff;
                if (pipr < 8)
                        pending |= 1 << pipr;
        }