--- /dev/null
+From 68925176296a8b995e503349200e256674bfe5ac Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Fri, 17 Feb 2017 14:32:18 +0000
+Subject: arm64: KVM: VHE: Clear HCR_TGE when invalidating guest TLBs
+
+From: Marc Zyngier <marc.zyngier@arm.com>
+
+commit 68925176296a8b995e503349200e256674bfe5ac upstream.
+
+When invalidating guest TLBs, special care must be taken to
+actually shoot the guest TLBs and not the host ones if we're
+running on a VHE system. This is controlled by the HCR_EL2.TGE
+bit, which we forget to clear before invalidating TLBs.
+
+Address the issue by introducing two wrappers (__tlb_switch_to_guest
+and __tlb_switch_to_host) that take care of both the VTTBR_EL2
+and HCR_EL2.TGE switching.
+
+Reported-by: Tomasz Nowicki <tnowicki@caviumnetworks.com>
+Tested-by: Tomasz Nowicki <tnowicki@caviumnetworks.com>
+Reviewed-by: Christoffer Dall <cdall@linaro.org>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kvm/hyp/tlb.c | 64 ++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 55 insertions(+), 9 deletions(-)
+
+--- a/arch/arm64/kvm/hyp/tlb.c
++++ b/arch/arm64/kvm/hyp/tlb.c
+@@ -17,14 +17,62 @@
+
+ #include <asm/kvm_hyp.h>
+
++static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm)
++{
++ u64 val;
++
++ /*
++ * With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and
++ * most TLB operations target EL2/EL0. In order to affect the
++ * guest TLBs (EL1/EL0), we need to change one of these two
++ * bits. Changing E2H is impossible (goodbye TTBR1_EL2), so
++ * let's flip TGE before executing the TLB operation.
++ */
++ write_sysreg(kvm->arch.vttbr, vttbr_el2);
++ val = read_sysreg(hcr_el2);
++ val &= ~HCR_TGE;
++ write_sysreg(val, hcr_el2);
++ isb();
++}
++
++static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm)
++{
++ write_sysreg(kvm->arch.vttbr, vttbr_el2);
++ isb();
++}
++
++static hyp_alternate_select(__tlb_switch_to_guest,
++ __tlb_switch_to_guest_nvhe,
++ __tlb_switch_to_guest_vhe,
++ ARM64_HAS_VIRT_HOST_EXTN);
++
++static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm)
++{
++ /*
++ * We're done with the TLB operation, let's restore the host's
++ * view of HCR_EL2.
++ */
++ write_sysreg(0, vttbr_el2);
++ write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
++}
++
++static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm)
++{
++ write_sysreg(0, vttbr_el2);
++}
++
++static hyp_alternate_select(__tlb_switch_to_host,
++ __tlb_switch_to_host_nvhe,
++ __tlb_switch_to_host_vhe,
++ ARM64_HAS_VIRT_HOST_EXTN);
++
+ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
+ {
+ dsb(ishst);
+
+ /* Switch to requested VMID */
+ kvm = kern_hyp_va(kvm);
+- write_sysreg(kvm->arch.vttbr, vttbr_el2);
+- isb();
++ __tlb_switch_to_guest()(kvm);
+
+ /*
+ * We could do so much better if we had the VA as well.
+@@ -45,7 +93,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa
+ dsb(ish);
+ isb();
+
+- write_sysreg(0, vttbr_el2);
++ __tlb_switch_to_host()(kvm);
+ }
+
+ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
+@@ -54,14 +102,13 @@ void __hyp_text __kvm_tlb_flush_vmid(str
+
+ /* Switch to requested VMID */
+ kvm = kern_hyp_va(kvm);
+- write_sysreg(kvm->arch.vttbr, vttbr_el2);
+- isb();
++ __tlb_switch_to_guest()(kvm);
+
+ asm volatile("tlbi vmalls12e1is" : : );
+ dsb(ish);
+ isb();
+
+- write_sysreg(0, vttbr_el2);
++ __tlb_switch_to_host()(kvm);
+ }
+
+ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
+@@ -69,14 +116,13 @@ void __hyp_text __kvm_tlb_flush_local_vm
+ struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
+
+ /* Switch to requested VMID */
+- write_sysreg(kvm->arch.vttbr, vttbr_el2);
+- isb();
++ __tlb_switch_to_guest()(kvm);
+
+ asm volatile("tlbi vmalle1" : : );
+ dsb(nsh);
+ isb();
+
+- write_sysreg(0, vttbr_el2);
++ __tlb_switch_to_host()(kvm);
+ }
+
+ void __hyp_text __kvm_flush_vm_context(void)
--- /dev/null
+From 90922a2d03d84de36bf8a9979d62580102f31a92 Mon Sep 17 00:00:00 2001
+From: Shanker Donthineni <shankerd@codeaurora.org>
+Date: Tue, 7 Mar 2017 08:20:38 -0600
+Subject: irqchip/gicv3-its: Add workaround for QDF2400 ITS erratum 0065
+
+From: Shanker Donthineni <shankerd@codeaurora.org>
+
+commit 90922a2d03d84de36bf8a9979d62580102f31a92 upstream.
+
+On Qualcomm Datacenter Technologies QDF2400 SoCs, the ITS hardware
+implementation uses 16Bytes for Interrupt Translation Entry (ITE),
+but reports an incorrect value of 8Bytes in GITS_TYPER.ITTE_size.
+
+It might cause kernel memory corruption depending on the number
+of MSI(x) that are configured and the amount of memory that has
+been allocated for ITEs in its_create_device().
+
+This patch fixes the potential memory corruption by setting the
+correct ITE size to 16Bytes.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/arm64/silicon-errata.txt | 44 +++++++++++++++++----------------
+ arch/arm64/Kconfig | 10 +++++++
+ drivers/irqchip/irq-gic-v3-its.c | 16 ++++++++++++
+ 3 files changed, 49 insertions(+), 21 deletions(-)
+
+--- a/Documentation/arm64/silicon-errata.txt
++++ b/Documentation/arm64/silicon-errata.txt
+@@ -42,24 +42,26 @@ file acts as a registry of software work
+ will be updated when new workarounds are committed and backported to
+ stable kernels.
+
+-| Implementor | Component | Erratum ID | Kconfig |
+-+----------------+-----------------+-----------------+-------------------------+
+-| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
+-| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
+-| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
+-| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
+-| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
+-| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
+-| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
+-| ARM | Cortex-A57 | #852523 | N/A |
+-| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
+-| ARM | Cortex-A72 | #853709 | N/A |
+-| ARM | MMU-500 | #841119,#826419 | N/A |
+-| | | | |
+-| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
+-| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
+-| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
+-| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
+-| Cavium | ThunderX SMMUv2 | #27704 | N/A |
+-| | | | |
+-| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
++| Implementor | Component | Erratum ID | Kconfig |
+++----------------+-----------------+-----------------+-----------------------------+
++| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
++| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
++| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
++| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
++| ARM | Cortex-A53 | #845719 | ARM64_ERRATUM_845719 |
++| ARM | Cortex-A53 | #843419 | ARM64_ERRATUM_843419 |
++| ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 |
++| ARM | Cortex-A57 | #852523 | N/A |
++| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
++| ARM | Cortex-A72 | #853709 | N/A |
++| ARM | MMU-500 | #841119,#826419 | N/A |
++| | | | |
++| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
++| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
++| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
++| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
++| Cavium | ThunderX SMMUv2 | #27704 | N/A |
++| | | | |
++| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
++| | | | |
++| Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 |
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -474,6 +474,16 @@ config CAVIUM_ERRATUM_27456
+
+ If unsure, say Y.
+
++config QCOM_QDF2400_ERRATUM_0065
++ bool "QDF2400 E0065: Incorrect GITS_TYPER.ITT_Entry_size"
++ default y
++ help
++ On Qualcomm Datacenter Technologies QDF2400 SoC, ITS hardware reports
++ ITE size incorrectly. The GITS_TYPER.ITT_Entry_size field should have
++ been indicated as 16Bytes (0xf), not 8Bytes (0x7).
++
++ If unsure, say Y.
++
+ endmenu
+
+
+--- a/drivers/irqchip/irq-gic-v3-its.c
++++ b/drivers/irqchip/irq-gic-v3-its.c
+@@ -1598,6 +1598,14 @@ static void __maybe_unused its_enable_qu
+ its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144;
+ }
+
++static void __maybe_unused its_enable_quirk_qdf2400_e0065(void *data)
++{
++ struct its_node *its = data;
++
++ /* On QDF2400, the size of the ITE is 16Bytes */
++ its->ite_size = 16;
++}
++
+ static const struct gic_quirk its_quirks[] = {
+ #ifdef CONFIG_CAVIUM_ERRATUM_22375
+ {
+@@ -1615,6 +1623,14 @@ static const struct gic_quirk its_quirks
+ .init = its_enable_quirk_cavium_23144,
+ },
+ #endif
++#ifdef CONFIG_QCOM_QDF2400_ERRATUM_0065
++ {
++ .desc = "ITS: QDF2400 erratum 0065",
++ .iidr = 0x00001070, /* QDF2400 ITS rev 1.x */
++ .mask = 0xffffffff,
++ .init = its_enable_quirk_qdf2400_e0065,
++ },
++#endif
+ {
+ }
+ };