--- /dev/null
+From d4b9e0790aa764c0b01e18d4e8d33e93ba36d51f Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Thu, 28 Apr 2016 16:16:31 +0100
+Subject: arm/arm64: KVM: Enforce Break-Before-Make on Stage-2 page tables
+
+From: Marc Zyngier <marc.zyngier@arm.com>
+
+commit d4b9e0790aa764c0b01e18d4e8d33e93ba36d51f upstream.
+
+The ARM architecture mandates that when changing a page table entry
+from a valid entry to another valid entry, an invalid entry is first
+written, TLB invalidated, and only then the new entry being written.
+
+The current code doesn't respect this, directly writing the new
+entry and only then invalidating TLBs. Let's fix it up.
+
+Reported-by: Christoffer Dall <christoffer.dall@linaro.org>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/kvm/mmu.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/arch/arm/kvm/mmu.c
++++ b/arch/arm/kvm/mmu.c
+@@ -886,11 +886,14 @@ static int stage2_set_pmd_huge(struct kv
+ VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
+
+ old_pmd = *pmd;
+- kvm_set_pmd(pmd, *new_pmd);
+- if (pmd_present(old_pmd))
++ if (pmd_present(old_pmd)) {
++ pmd_clear(pmd);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+- else
++ } else {
+ get_page(virt_to_page(pmd));
++ }
++
++ kvm_set_pmd(pmd, *new_pmd);
+ return 0;
+ }
+
+@@ -939,12 +942,14 @@ static int stage2_set_pte(struct kvm *kv
+
+ /* Create 2nd stage page table mapping - Level 3 */
+ old_pte = *pte;
+- kvm_set_pte(pte, *new_pte);
+- if (pte_present(old_pte))
++ if (pte_present(old_pte)) {
++ kvm_set_pte(pte, __pte(0));
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+- else
++ } else {
+ get_page(virt_to_page(pte));
++ }
+
++ kvm_set_pte(pte, *new_pte);
+ return 0;
+ }
+
--- /dev/null
+From f228b494e56d949be8d8ea09d4f973d1979201bf Mon Sep 17 00:00:00 2001
+From: Julien Grall <julien.grall@arm.com>
+Date: Tue, 10 May 2016 15:40:31 +0100
+Subject: arm64: cpuinfo: Missing NULL terminator in compat_hwcap_str
+
+From: Julien Grall <julien.grall@arm.com>
+
+commit f228b494e56d949be8d8ea09d4f973d1979201bf upstream.
+
+The loop that browses the array compat_hwcap_str will stop when a NULL
+is encountered, however NULL is missing at the end of array. This will
+lead to overrun until a NULL is found somewhere in the following memory.
+In reality, this works out because the compat_hwcap2_str array tends to
+follow immediately in memory, and that *is* terminated correctly.
+Furthermore, the unsigned int compat_elf_hwcap is checked before
+printing each capability, so we end up doing the right thing because
+the size of the two arrays is less than 32. Still, this is an obvious
+mistake and should be fixed.
+
+Note for backporting: commit 12d11817eaafa414 ("arm64: Move
+/proc/cpuinfo handling code") moved this code in v4.4. Prior to that
+commit, the same change should be made in arch/arm64/kernel/setup.c.
+
+Fixes: 44b82b7700d0 "arm64: Fix up /proc/cpuinfo"
+Signed-off-by: Julien Grall <julien.grall@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/cpuinfo.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -85,7 +85,8 @@ static const char *const compat_hwcap_st
+ "idivt",
+ "vfpd32",
+ "lpae",
+- "evtstrm"
++ "evtstrm",
++ NULL
+ };
+
+ static const char *const compat_hwcap2_str[] = {
--- /dev/null
+From 5bb1cc0ff9a6b68871970737e6c4c16919928d8b Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Thu, 5 May 2016 10:44:02 +0100
+Subject: arm64: Ensure pmd_present() returns false after pmd_mknotpresent()
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit 5bb1cc0ff9a6b68871970737e6c4c16919928d8b upstream.
+
+Currently, pmd_present() only checks for a non-zero value, returning
+true even after pmd_mknotpresent() (which only clears the type bits).
+This patch converts pmd_present() to using pte_present(), similar to the
+other pmd_*() checks. As a side effect, it will return true for
+PROT_NONE mappings, though they are not yet used by the kernel with
+transparent huge pages.
+
+For consistency, also change pmd_mknotpresent() to only clear the
+PMD_SECT_VALID bit, even though the PMD_TABLE_BIT is already 0 for block
+mappings (no functional change). The unused PMD_SECT_PROT_NONE
+definition is removed as transparent huge pages use the pte page prot
+values.
+
+Fixes: 9c7e535fcc17 ("arm64: mm: Route pmd thp functions through pte equivalents")
+Reviewed-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/pgtable-hwdef.h | 1 -
+ arch/arm64/include/asm/pgtable.h | 4 ++--
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/include/asm/pgtable-hwdef.h
++++ b/arch/arm64/include/asm/pgtable-hwdef.h
+@@ -133,7 +133,6 @@
+ * Section
+ */
+ #define PMD_SECT_VALID (_AT(pmdval_t, 1) << 0)
+-#define PMD_SECT_PROT_NONE (_AT(pmdval_t, 1) << 58)
+ #define PMD_SECT_USER (_AT(pmdval_t, 1) << 6) /* AP[1] */
+ #define PMD_SECT_RDONLY (_AT(pmdval_t, 1) << 7) /* AP[2] */
+ #define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -356,6 +356,7 @@ static inline pgprot_t mk_sect_prot(pgpr
+ #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
+ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
++#define pmd_present(pmd) pte_present(pmd_pte(pmd))
+ #define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
+ #define pmd_young(pmd) pte_young(pmd_pte(pmd))
+ #define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+@@ -364,7 +365,7 @@ static inline pgprot_t mk_sect_prot(pgpr
+ #define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
+ #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+ #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+-#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) & ~PMD_TYPE_MASK))
++#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) & ~PMD_SECT_VALID))
+
+ #define __HAVE_ARCH_PMD_WRITE
+ #define pmd_write(pmd) pte_write(pmd_pte(pmd))
+@@ -403,7 +404,6 @@ extern pgprot_t phys_mem_access_prot(str
+ unsigned long size, pgprot_t vma_prot);
+
+ #define pmd_none(pmd) (!pmd_val(pmd))
+-#define pmd_present(pmd) (pmd_val(pmd))
+
+ #define pmd_bad(pmd) (!(pmd_val(pmd) & 2))
+
--- /dev/null
+From 911f56eeb87ee378f5e215469268a7a2f68a5a8a Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Thu, 5 May 2016 10:43:59 +0100
+Subject: arm64: Fix typo in the pmdp_huge_get_and_clear() definition
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit 911f56eeb87ee378f5e215469268a7a2f68a5a8a upstream.
+
+With hardware AF/DBM support, pmd modifications (transparent huge pages)
+should be performed atomically using load/store exclusive. The initial
+patches defined the get-and-clear function and __HAVE_ARCH_* macro
+without the "huge" word, leaving the pmdp_huge_get_and_clear() to the
+default, non-atomic implementation.
+
+Fixes: 2f4b829c625e ("arm64: Add support for hardware updates of the access and dirty pte bits")
+Reviewed-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/pgtable.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -599,9 +599,9 @@ static inline pte_t ptep_get_and_clear(s
+ }
+
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+-#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+-static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+- unsigned long address, pmd_t *pmdp)
++#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
++static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
++ unsigned long address, pmd_t *pmdp)
+ {
+ return pte_pmd(ptep_get_and_clear(mm, address, (pte_t *)pmdp));
+ }
--- /dev/null
+From 282aa7051b0169991b34716f0f22d9c2f59c46c4 Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Thu, 5 May 2016 10:44:00 +0100
+Subject: arm64: Implement pmdp_set_access_flags() for hardware AF/DBM
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit 282aa7051b0169991b34716f0f22d9c2f59c46c4 upstream.
+
+The update to the accessed or dirty states for block mappings must be
+done atomically on hardware with support for automatic AF/DBM. The
+ptep_set_access_flags() function has been fixed as part of commit
+66dbd6e61a52 ("arm64: Implement ptep_set_access_flags() for hardware
+AF/DBM"). This patch brings pmdp_set_access_flags() in line with the pte
+counterpart.
+
+Fixes: 2f4b829c625e ("arm64: Add support for hardware updates of the access and dirty pte bits")
+Reviewed-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/pgtable.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -552,6 +552,16 @@ extern int ptep_set_access_flags(struct
+ unsigned long address, pte_t *ptep,
+ pte_t entry, int dirty);
+
++#ifdef CONFIG_TRANSPARENT_HUGEPAGE
++#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
++static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
++ unsigned long address, pmd_t *pmdp,
++ pmd_t entry, int dirty)
++{
++ return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
++}
++#endif
++
+ /*
+ * Atomic pte/pmd modifications.
+ */
--- /dev/null
+From 66dbd6e61a526ae7d11a208238ae2c17e5cacb6b Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Wed, 13 Apr 2016 16:01:22 +0100
+Subject: arm64: Implement ptep_set_access_flags() for hardware AF/DBM
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit 66dbd6e61a526ae7d11a208238ae2c17e5cacb6b upstream.
+
+When hardware updates of the access and dirty states are enabled, the
+default ptep_set_access_flags() implementation based on calling
+set_pte_at() directly is potentially racy. This triggers the "racy dirty
+state clearing" warning in set_pte_at() because an existing writable PTE
+is overridden with a clean entry.
+
+There are two main scenarios for this situation:
+
+1. The CPU getting an access fault does not support hardware updates of
+ the access/dirty flags. However, a different agent in the system
+ (e.g. SMMU) can do this, therefore overriding a writable entry with a
+ clean one could potentially lose the automatically updated dirty
+ status
+
+2. A more complex situation is possible when all CPUs support hardware
+ AF/DBM:
+
+ a) Initial state: shareable + writable vma and pte_none(pte)
+ b) Read fault taken by two threads of the same process on different
+ CPUs
+ c) CPU0 takes the mmap_sem and proceeds to handling the fault. It
+ eventually reaches do_set_pte() which sets a writable + clean pte.
+ CPU0 releases the mmap_sem
+ d) CPU1 acquires the mmap_sem and proceeds to handle_pte_fault(). The
+ pte entry it reads is present, writable and clean and it continues
+ to pte_mkyoung()
+ e) CPU1 calls ptep_set_access_flags()
+
+ If between (d) and (e) the hardware (another CPU) updates the dirty
+ state (clears PTE_RDONLY), CPU1 will override the PTR_RDONLY bit
+ marking the entry clean again.
+
+This patch implements an arm64-specific ptep_set_access_flags() function
+to perform an atomic update of the PTE flags.
+
+Fixes: 2f4b829c625e ("arm64: Add support for hardware updates of the access and dirty pte bits")
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Reported-by: Ming Lei <tom.leiming@gmail.com>
+Tested-by: Julien Grall <julien.grall@arm.com>
+Cc: Will Deacon <will.deacon@arm.com>
+[will: reworded comment]
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/pgtable.h | 5 +++
+ arch/arm64/mm/fault.c | 50 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 55 insertions(+)
+
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -547,6 +547,11 @@ static inline pmd_t pmd_modify(pmd_t pmd
+ }
+
+ #ifdef CONFIG_ARM64_HW_AFDBM
++#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
++extern int ptep_set_access_flags(struct vm_area_struct *vma,
++ unsigned long address, pte_t *ptep,
++ pte_t entry, int dirty);
++
+ /*
+ * Atomic pte/pmd modifications.
+ */
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -81,6 +81,56 @@ void show_pte(struct mm_struct *mm, unsi
+ printk("\n");
+ }
+
++#ifdef CONFIG_ARM64_HW_AFDBM
++/*
++ * This function sets the access flags (dirty, accessed), as well as write
++ * permission, and only to a more permissive setting.
++ *
++ * It needs to cope with hardware update of the accessed/dirty state by other
++ * agents in the system and can safely skip the __sync_icache_dcache() call as,
++ * like set_pte_at(), the PTE is never changed from no-exec to exec here.
++ *
++ * Returns whether or not the PTE actually changed.
++ */
++int ptep_set_access_flags(struct vm_area_struct *vma,
++ unsigned long address, pte_t *ptep,
++ pte_t entry, int dirty)
++{
++ pteval_t old_pteval;
++ unsigned int tmp;
++
++ if (pte_same(*ptep, entry))
++ return 0;
++
++ /* only preserve the access flags and write permission */
++ pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY;
++
++ /*
++ * PTE_RDONLY is cleared by default in the asm below, so set it in
++ * back if necessary (read-only or clean PTE).
++ */
++ if (!pte_write(entry) || !dirty)
++ pte_val(entry) |= PTE_RDONLY;
++
++ /*
++ * Setting the flags must be done atomically to avoid racing with the
++ * hardware update of the access/dirty state.
++ */
++ asm volatile("// ptep_set_access_flags\n"
++ " prfm pstl1strm, %2\n"
++ "1: ldxr %0, %2\n"
++ " and %0, %0, %3 // clear PTE_RDONLY\n"
++ " orr %0, %0, %4 // set flags\n"
++ " stxr %w1, %0, %2\n"
++ " cbnz %w1, 1b\n"
++ : "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))
++ : "L" (~PTE_RDONLY), "r" (pte_val(entry)));
++
++ flush_tlb_fix_spurious_fault(vma, address);
++ return 1;
++}
++#endif
++
+ /*
+ * The kernel tried to access some page that wasn't present.
+ */
--- /dev/null
+From e4fe9e7dc3828bf6a5714eb3c55aef6260d823a2 Mon Sep 17 00:00:00 2001
+From: Matt Evans <matt.evans@arm.com>
+Date: Mon, 16 May 2016 13:54:56 +0100
+Subject: kvm: arm64: Fix EC field in inject_abt64
+
+From: Matt Evans <matt.evans@arm.com>
+
+commit e4fe9e7dc3828bf6a5714eb3c55aef6260d823a2 upstream.
+
+The EC field of the constructed ESR is conditionally modified by ORing in
+ESR_ELx_EC_DABT_LOW for a data abort. However, ESR_ELx_EC_SHIFT is missing
+from this condition.
+
+Signed-off-by: Matt Evans <matt.evans@arm.com>
+Acked-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kvm/inject_fault.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/kvm/inject_fault.c
++++ b/arch/arm64/kvm/inject_fault.c
+@@ -162,7 +162,7 @@ static void inject_abt64(struct kvm_vcpu
+ esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
+
+ if (!is_iabt)
+- esr |= ESR_ELx_EC_DABT_LOW;
++ esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
+
+ vcpu_sys_reg(vcpu, ESR_EL1) = esr | ESR_ELx_FSC_EXTABT;
+ }