]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 May 2016 21:49:59 +0000 (14:49 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 May 2016 21:49:59 +0000 (14:49 -0700)
added patches:
arm64-honour-pte_write-in-set_pte_at-for-kernel-mappings.patch
arm64-update-pte_rdonly-in-set_pte_at-for-prot_none-permission.patch

queue-4.4/arm64-honour-pte_write-in-set_pte_at-for-kernel-mappings.patch [new file with mode: 0644]
queue-4.4/arm64-update-pte_rdonly-in-set_pte_at-for-prot_none-permission.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/arm64-honour-pte_write-in-set_pte_at-for-kernel-mappings.patch b/queue-4.4/arm64-honour-pte_write-in-set_pte_at-for-kernel-mappings.patch
new file mode 100644 (file)
index 0000000..a1cfb6c
--- /dev/null
@@ -0,0 +1,96 @@
+From ac15bd63bbb24238f763ec5b24ee175ec301e8cd Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Thu, 7 Jan 2016 16:07:20 +0000
+Subject: arm64: Honour !PTE_WRITE in set_pte_at() for kernel mappings
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit ac15bd63bbb24238f763ec5b24ee175ec301e8cd upstream.
+
+Currently, set_pte_at() only checks the software PTE_WRITE bit for user
+mappings when it sets or clears the hardware PTE_RDONLY accordingly. The
+kernel ptes are written directly without any modification, relying
+solely on the protection bits in macros like PAGE_KERNEL. However,
+modifying kernel pte attributes via pte_wrprotect() would be ignored by
+set_pte_at(). Since pte_wrprotect() does not set PTE_RDONLY (it only
+clears PTE_WRITE), the new permission is not taken into account.
+
+This patch changes set_pte_at() to adjust the read-only permission for
+kernel ptes as well. As a side effect, existing PROT_* definitions used
+for kernel ioremap*() need to include PTE_DIRTY | PTE_WRITE.
+
+(additionally, white space fix for PTE_KERNEL_ROX)
+
+Acked-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
+Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/pgtable.h |   21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -69,11 +69,11 @@ extern void __pgd_error(const char *file
+ #define PROT_DEFAULT          (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
+ #define PROT_SECT_DEFAULT     (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
+-#define PROT_DEVICE_nGnRnE    (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+-#define PROT_DEVICE_nGnRE     (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
+-#define PROT_NORMAL_NC                (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC))
+-#define PROT_NORMAL_WT                (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_WT))
+-#define PROT_NORMAL           (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL))
++#define PROT_DEVICE_nGnRnE    (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
++#define PROT_DEVICE_nGnRE     (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
++#define PROT_NORMAL_NC                (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
++#define PROT_NORMAL_WT                (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
++#define PROT_NORMAL           (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
+ #define PROT_SECT_DEVICE_nGnRE        (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
+ #define PROT_SECT_NORMAL      (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
+@@ -83,7 +83,7 @@ extern void __pgd_error(const char *file
+ #define PAGE_KERNEL           __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
+ #define PAGE_KERNEL_RO                __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
+-#define PAGE_KERNEL_ROX       __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
++#define PAGE_KERNEL_ROX               __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
+ #define PAGE_KERNEL_EXEC      __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
+ #define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT)
+@@ -155,6 +155,7 @@ extern struct page *empty_zero_page;
+ #define pte_write(pte)                (!!(pte_val(pte) & PTE_WRITE))
+ #define pte_exec(pte)         (!(pte_val(pte) & PTE_UXN))
+ #define pte_cont(pte)         (!!(pte_val(pte) & PTE_CONT))
++#define pte_user(pte)         (!!(pte_val(pte) & PTE_USER))
+ #ifdef CONFIG_ARM64_HW_AFDBM
+ #define pte_hw_dirty(pte)     (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY))
+@@ -165,8 +166,6 @@ extern struct page *empty_zero_page;
+ #define pte_dirty(pte)                (pte_sw_dirty(pte) || pte_hw_dirty(pte))
+ #define pte_valid(pte)                (!!(pte_val(pte) & PTE_VALID))
+-#define pte_valid_user(pte) \
+-      ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
+ #define pte_valid_not_user(pte) \
+       ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID)
+@@ -264,13 +263,13 @@ extern void __sync_icache_dcache(pte_t p
+ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep, pte_t pte)
+ {
+-      if (pte_valid_user(pte)) {
+-              if (!pte_special(pte) && pte_exec(pte))
+-                      __sync_icache_dcache(pte, addr);
++      if (pte_valid(pte)) {
+               if (pte_sw_dirty(pte) && pte_write(pte))
+                       pte_val(pte) &= ~PTE_RDONLY;
+               else
+                       pte_val(pte) |= PTE_RDONLY;
++              if (pte_user(pte) && pte_exec(pte) && !pte_special(pte))
++                      __sync_icache_dcache(pte, addr);
+       }
+       /*
diff --git a/queue-4.4/arm64-update-pte_rdonly-in-set_pte_at-for-prot_none-permission.patch b/queue-4.4/arm64-update-pte_rdonly-in-set_pte_at-for-prot_none-permission.patch
new file mode 100644 (file)
index 0000000..4535550
--- /dev/null
@@ -0,0 +1,57 @@
+From fdc69e7df3cb24f18a93192641786e5b7ecd1dfe Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Wed, 9 Mar 2016 16:31:29 +0000
+Subject: arm64: Update PTE_RDONLY in set_pte_at() for PROT_NONE permission
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit fdc69e7df3cb24f18a93192641786e5b7ecd1dfe upstream.
+
+The set_pte_at() function must update the hardware PTE_RDONLY bit
+depending on the state of the PTE_WRITE and PTE_DIRTY bits of the given
+entry value. However, it currently only performs this for pte_valid()
+entries, ignoring PTE_PROT_NONE. The side-effect is that PROT_NONE
+mappings would not have the PTE_RDONLY bit set. Without
+CONFIG_ARM64_HW_AFDBM, this is not an issue since such PROT_NONE pages
+are not accessible anyway.
+
+With commit 2f4b829c625e ("arm64: Add support for hardware updates of
+the access and dirty pte bits"), the ptep_set_wrprotect() function was
+re-written to cope with automatic hardware updates of the dirty state.
+As an optimisation, only PTE_RDONLY is checked to assess the "dirty"
+status. Since set_pte_at() does not set this bit for PROT_NONE mappings,
+such pages may be considered "dirty" as a result of
+ptep_set_wrprotect().
+
+This patch updates the pte_valid() check to pte_present() in
+set_pte_at(). It also adds PTE_PROT_NONE to the swap entry bits comment.
+
+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: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
+Tested-by: Ganapatrao Kulkarni <gkulkarni@cavium.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/pgtable.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -263,7 +263,7 @@ extern void __sync_icache_dcache(pte_t p
+ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep, pte_t pte)
+ {
+-      if (pte_valid(pte)) {
++      if (pte_present(pte)) {
+               if (pte_sw_dirty(pte) && pte_write(pte))
+                       pte_val(pte) &= ~PTE_RDONLY;
+               else
+@@ -640,6 +640,7 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
+  *    bits 0-1:       present (must be zero)
+  *    bits 2-7:       swap type
+  *    bits 8-57:      swap offset
++ *    bit  58:        PTE_PROT_NONE (must be zero)
+  */
+ #define __SWP_TYPE_SHIFT      2
+ #define __SWP_TYPE_BITS               6
index d4e200911e3454f7aafaf151fb207904734e6753..696b9e30cee130241b6ca315aed18687dfa494a3 100644 (file)
@@ -23,3 +23,5 @@ dmaengine-hsu-correct-use-of-channel-status-register.patch
 dmaengine-pxa_dma-fix-the-maximum-requestor-line.patch
 mtd-nand-pxa3xx_nand-fix-dmaengine-initialization.patch
 sched-cgroup-fix-cleanup-cgroup-teardown-init.patch
+arm64-honour-pte_write-in-set_pte_at-for-kernel-mappings.patch
+arm64-update-pte_rdonly-in-set_pte_at-for-prot_none-permission.patch