Skip to contentSkip to conversation

ARM64: Kernel managed pages are only flushed

PATCH Superseded Bharat Bhushan 5 participants 11 messages Mar 5, 2014 – Mar 27, 2014 arm64

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

Kernel can only access pages which maps to managed memory. So flush only valid kernel pages.

I observed kernel crash direct assigning a device using VFIO and found that it was caused because of accessing invalid page

---
 arch/arm64/mm/flush.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)
arch/arm64/mm/flush.c +12 -1
index e4193e3..2b4e8b0 100644
@@ -72,7 +72,18 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
 
 void __sync_icache_dcache(pte_t pte, unsigned long addr)
 {
-	struct page *page = pte_page(pte);
+	struct page *page;
+
+#ifdef CONFIG_HAVE_ARCH_PFN_VALID
+	/*
+	 * We can only access pages that the kernel maps
+	 * as memory. Bail out for unmapped ones.
+	 */
+	if (!pfn_valid(pfn))
+		return;
+
+#endif
+	page = pte_page(pte);
 
 	/* no flushing needed for anonymous pages */
 	if (!page_mapping(page))
Signature · 1 line
1.7.0.4
maintainer
#1 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

Quoted 5 lines · Bharat Bhushan

Kernel can only access pages which maps to managed memory. So flush only valid kernel pages.

I observed kernel crash direct assigning a device using VFIO and found that it was caused because of accessing invalid page

I don't get this. Could you please share some kernel crash message to see the backtrace? The __sync_icache_dcache() function is called from set_pte_at() if the pte is valid, user and exec. If these are correct, why does it crash? Actually, does the cache maintenance crash or page_mapping()?

Signature · 1 line
Catalin
#2 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

Quoted 15 lines

-----Original Message-----
From: Catalin Marinas [mailto:catalin.marinas at gmail.com] On Behalf Of Catalin Marinas
Sent: Thursday, March 06, 2014 12:24 PM
To: Bhushan Bharat-R65777
Cc: will.deacon at arm.com; linux-arm-kernel at lists.infradead.org; Bhushan Bharat- R65777
Subject: Re: [PATCH] ARM64: Kernel managed pages are only flushed

Quoted 3 lines · Bharat Bhushan

Kernel can only access pages which maps to managed memory. So flush only valid kernel pages.

Quoted 7 lines
Quoted 2 lines

I observed kernel crash direct assigning a device using VFIO and found that it was caused because of accessing invalid page

I don't get this. Could you please share some kernel crash message to see the backtrace? The __sync_icache_dcache() function is called from set_pte_at() if the pte is valid, user and exec. If these are correct, why does it crash? Actually, does the cache maintenance crash or page_mapping()?

It fails in page_mapping() because it access page of non-kernel visible memory. I am not a memory management expert and according to my understanding there can be valid pte but may not a valid struct page. Valid struct page exists only for kernel managed memory.

Kernel crash dump (address 0x80c6a0, size: 0x1000; This is the physical address of a device which I am direct assigning to userspace application named Layerscape using VFIO):

Unable to handle kernel paging request at virtual address ffffffbc1c2b7308
pgd = ffffffc0595ea000
[ffffffbc1c2b7308] *pgd=0000000000000000
Internal error: Oops: 96000006 [#1]
Modules linked in:
CPU: 0 PID: 656 Comm: layerscape Not tainted 3.12.0+ #66
task: ffffffc059566e80 ti: ffffffc059294000 task.ti: ffffffc059294000
PC is at page_mapping+0x0/0x14
LR is at __sync_icache_dcache+0x2c/0xb8
pc : [<ffffffc0000f9cac>] lr : [<ffffffc000090554>] pstate: 60000145

sp : ffffffc059297bc0
x29: ffffffc059297bc0 x28: 0000007fb5cce000
x27: 0000000000000041 x26: 0020000000000c43
x25: 0000007fb5ccf000 x24: ffffffc0595b0670
x23: 000000000080c6a0 x22: 002000080c6a0c43
x21: 012000080c6a0c43 x20: 0000007fb5ccf000
x19: ffffffbc1c2b7300 x18: 0000007fd7b45500
x17: 0000000000412268 x16: 0000000000000004
x15: 0000000000000002 x14: 0000000000000000
x13: 0000000000003958 x12: 0000000000000048
x11: 0000000000000013 x10: 00000000000000f0
x9 : 0000000000000002 x8 : 0000007fb5ece000
x7 : 0000000000000028 x6 : ffffffc00051b590
x5 : 0000000000000670 x4 : 0020000000000c43
x3 : ffffffc000000000 x2 : ffffffc0595b0000
x1 : ffffffbc00000000 x0 : ffffffbc1c2b7300
Process layerscape (pid: 656, stack limit = 0xffffffc059294058)

Stack: (0xffffffc059297bc0 to 0xffffffc059298000)

7bc0: 59297be0 ffffffc0 00102510 ffffffc0 59766d70 ffffffc0 ffffffc8 00000000 7be0: 59297c70 ffffffc0 002b51fc ffffffc0 595fd2c0 ffffffc0 596e78d8 ffffffc0 7c00: 00001000 00000000 0c6a0000 00000008 5969c4f8 ffffffc0 00000001 00000000 7c20: 595b1a00 ffffffc0 00000000 00000000 0047e558 ffffffc0 0047e548 ffffffc0 7c40: 59cff080 ffffffc0 b5ccefff 0000007f b5ccf000 0000007f 595eaff0 ffffffc0 7c60: f88569d2 ffffffff b5ccefff 0000007f 59297d00 ffffffc0 002b1cc4 ffffffc0 7c80: 595fd448 ffffffc0 b5cce000 0000007f 595fd440 ffffffc0 00000001 00000000 7ca0: 000000ff 00000000 59294000 ffffffc0 59cff080 ffffffc0 00000000 00000000 7cc0: 00000000 00000000 595fd420 ffffffc0 59297ce0 ffffffc0 595b1000 ffffffc0 7ce0: 0c6a1000 00000008 00001000 00000000 0047e5a0 ffffffc0 0047e580 ffffffc0 7d00: 59297d20 ffffffc0 00108968 ffffffc0 00000000 00000000 00000001 00000000 7d20: 59297da0 ffffffc0 00108e34 ffffffc0 00000007 00000000 000000ff 00000000 7d40: 595d36c0 ffffffc0 00000001 00000000 59cff080 ffffffc0 00001000 00000000 7d60: 00000001 00000000 b5cce000 0000007f 00000007 00000000 59294000 ffffffc0 7d80: 00000007 00000000 595fd2c0 ffffffc0 0080c6a0 00000000 595d36c0 ffffffc0 7da0: 59297e10 ffffffc0 000f9c40 ffffffc0 59cff0d8 ffffffc0 595d36c0 ffffffc0 7dc0: 00000000 00000000 0080c6a0 00000000 595d36c0 ffffffc0 00000015 00000000 7de0: 00000112 00000000 000000de 00000000 004ed000 ffffffc0 000f9c20 ffffffc0 7e00: 59297e68 ffffffc0 0080c6a0 00000000 59297e70 ffffffc0 00107508 ffffffc0 7e20: 00000001 00000000 00001000 00000000 59297e80 ffffffc0 0080c6a0 00000000 7e40: 00000001 00000000 00000003 00000000 00001000 00000000 00000000 00000000 7e60: 60000000 00000000 00000000 00000000 59297ec0 ffffffc0 00086d80 ffffffc0 7e80: 00000000 00000000 00000000 00000000 ffffffff ffffffff b5c2355c 0000007f 7ea0: 80000000 00000000 b5c1ffcc 0000007f 80000000 00000000 00000003 00000000 7ec0: d7b45720 0000007f 000839ec ffffffc0 00000000 00000000 00001000 00000000 7ee0: 00000003 00000000 00000001 00000000 00000005 00000000 0c6a0000 00000008 7f00: 00401884 00000000 00000000 00000000 000000de 00000000 b5ca35d0 0000007f 7f20: ffffffff 00000000 00000008 00000000 00000038 00000000 ffffffff ffffffff 7f40: 00000040 00000000 b5cd3028 0000007f b5c23548 0000007f 00412268 00000000 7f60: d7b45500 0000007f 00000000 00000000 00000000 00000000 004008c0 00000000 7f80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7fa0: 00000000 00000000 00000000 00000000 00000000 00000000 d7b45720 0000007f 7fc0: 00400e38 00000000 d7b45720 0000007f b5c2355c 0000007f 80000000 00000000 7fe0: 00000000 00000000 000000de 00000000 00000000 00000000 00000000 00000000

Call trace:
[<ffffffc0000f9cac>] page_mapping+0x0/0x14
[<ffffffc000102510>] remap_pfn_range+0x1cc/0x324
[<ffffffc0002b51fc>] vfio_layerscape_mmap+0x22c/0x248
[<ffffffc0002b1cc4>] vfio_device_fops_mmap+0x20/0x30
[<ffffffc000108968>] mmap_region+0x320/0x538
[<ffffffc000108e34>] do_mmap_pgoff+0x2b4/0x320
[<ffffffc0000f9c40>] vm_mmap_pgoff+0x60/0x90
[<ffffffc000107508>] SyS_mmap_pgoff+0x88/0xc4
[<ffffffc000086d80>] sys_mmap+0x18/0x28
Code: a8c17bfd d65f03c0 928002a0 17fffffd (f9400400) 
---[ end trace 650769ec4955b30e ]---
Quoted 4 lines

--
Catalin

#3 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

In reply to Catalin Marinas

Hi Catalin,

Quoted 102 lines
Quoted 15 lines

-----Original Message-----
From: Catalin Marinas [mailto:catalin.marinas at gmail.com] On Behalf Of Catalin Marinas
Sent: Thursday, March 06, 2014 12:24 PM
To: Bhushan Bharat-R65777
Cc: will.deacon at arm.com; linux-arm-kernel at lists.infradead.org; Bhushan Bharat-
R65777
Subject: Re: [PATCH] ARM64: Kernel managed pages are only flushed

Quoted 3 lines · Bharat Bhushan

Kernel can only access pages which maps to managed memory. So flush only valid kernel pages.

Quoted 7 lines
Quoted 2 lines

I observed kernel crash direct assigning a device using VFIO and found that it was caused because of accessing invalid page

I don't get this. Could you please share some kernel crash message to see the backtrace? The __sync_icache_dcache() function is called from set_pte_at() if the pte is valid, user and exec. If these are correct, why does it crash? Actually, does the cache maintenance crash or

page_mapping()?

It fails in page_mapping() because it access page of non-kernel visible memory. I am not a memory management expert and according to my understanding there can be valid pte but may not a valid struct page. Valid struct page exists only for kernel managed memory.

Kernel crash dump (address 0x80c6a0, size: 0x1000; This is the physical address of a device which I am direct assigning to userspace application named Layerscape using VFIO):

Unable to handle kernel paging request at virtual address ffffffbc1c2b7308 pgd =
ffffffc0595ea000 [ffffffbc1c2b7308] *pgd=0000000000000000 Internal error: Oops:
96000006 [#1] Modules linked in:
CPU: 0 PID: 656 Comm: layerscape Not tainted 3.12.0+ #66
task: ffffffc059566e80 ti: ffffffc059294000 task.ti: ffffffc059294000 PC is at
page_mapping+0x0/0x14 LR is at __sync_icache_dcache+0x2c/0xb8 pc :

[<ffffffc0000f9cac>] lr : [<ffffffc000090554>] pstate: 60000145 sp :
ffffffc059297bc0
x29: ffffffc059297bc0 x28: 0000007fb5cce000
x27: 0000000000000041 x26: 0020000000000c43
x25: 0000007fb5ccf000 x24: ffffffc0595b0670
x23: 000000000080c6a0 x22: 002000080c6a0c43
x21: 012000080c6a0c43 x20: 0000007fb5ccf000
x19: ffffffbc1c2b7300 x18: 0000007fd7b45500
x17: 0000000000412268 x16: 0000000000000004
x15: 0000000000000002 x14: 0000000000000000
x13: 0000000000003958 x12: 0000000000000048
x11: 0000000000000013 x10: 00000000000000f0
x9 : 0000000000000002 x8 : 0000007fb5ece000
x7 : 0000000000000028 x6 : ffffffc00051b590
x5 : 0000000000000670 x4 : 0020000000000c43
x3 : ffffffc000000000 x2 : ffffffc0595b0000
x1 : ffffffbc00000000 x0 : ffffffbc1c2b7300 Process layerscape (pid: 656, stack limit = 0xffffffc059294058)

Stack: (0xffffffc059297bc0 to 0xffffffc059298000)

7bc0: 59297be0 ffffffc0 00102510 ffffffc0 59766d70 ffffffc0 ffffffc8 00000000 7be0: 59297c70 ffffffc0 002b51fc ffffffc0 595fd2c0 ffffffc0 596e78d8 ffffffc0 7c00: 00001000 00000000 0c6a0000 00000008 5969c4f8 ffffffc0 00000001 00000000 7c20: 595b1a00 ffffffc0 00000000 00000000 0047e558 ffffffc0 0047e548 ffffffc0 7c40: 59cff080 ffffffc0 b5ccefff 0000007f b5ccf000 0000007f 595eaff0 ffffffc0 7c60: f88569d2 ffffffff b5ccefff 0000007f 59297d00 ffffffc0 002b1cc4 ffffffc0 7c80: 595fd448 ffffffc0 b5cce000 0000007f 595fd440 ffffffc0 00000001 00000000 7ca0: 000000ff 00000000 59294000 ffffffc0 59cff080 ffffffc0 00000000 00000000 7cc0: 00000000 00000000 595fd420 ffffffc0 59297ce0 ffffffc0 595b1000 ffffffc0 7ce0: 0c6a1000 00000008 00001000 00000000 0047e5a0 ffffffc0 0047e580 ffffffc0 7d00: 59297d20 ffffffc0 00108968 ffffffc0 00000000 00000000 00000001 00000000 7d20: 59297da0 ffffffc0 00108e34 ffffffc0 00000007 00000000 000000ff 00000000 7d40: 595d36c0 ffffffc0 00000001 00000000 59cff080 ffffffc0 00001000 00000000 7d60: 00000001 00000000 b5cce000 0000007f 00000007 00000000 59294000 ffffffc0 7d80: 00000007 00000000 595fd2c0 ffffffc0 0080c6a0 00000000 595d36c0 ffffffc0 7da0: 59297e10 ffffffc0 000f9c40 ffffffc0 59cff0d8 ffffffc0 595d36c0 ffffffc0 7dc0: 00000000 00000000 0080c6a0 00000000 595d36c0 ffffffc0 00000015 00000000 7de0: 00000112 00000000 000000de 00000000 004ed000 ffffffc0 000f9c20 ffffffc0 7e00: 59297e68 ffffffc0 0080c6a0 00000000 59297e70 ffffffc0 00107508 ffffffc0 7e20: 00000001 00000000 00001000 00000000 59297e80 ffffffc0 0080c6a0 00000000 7e40: 00000001 00000000 00000003 00000000 00001000 00000000 00000000 00000000 7e60: 60000000 00000000 00000000 00000000 59297ec0 ffffffc0 00086d80 ffffffc0 7e80: 00000000 00000000 00000000 00000000 ffffffff ffffffff b5c2355c 0000007f 7ea0: 80000000 00000000 b5c1ffcc 0000007f 80000000 00000000 00000003 00000000 7ec0: d7b45720 0000007f 000839ec ffffffc0 00000000 00000000 00001000 00000000 7ee0: 00000003 00000000 00000001 00000000 00000005 00000000 0c6a0000 00000008 7f00: 00401884 00000000 00000000 00000000 000000de 00000000 b5ca35d0 0000007f 7f20: ffffffff 00000000 00000008 00000000 00000038 00000000 ffffffff ffffffff 7f40: 00000040 00000000 b5cd3028 0000007f b5c23548 0000007f 00412268 00000000 7f60: d7b45500 0000007f 00000000 00000000 00000000 00000000 004008c0 00000000 7f80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7fa0: 00000000 00000000 00000000 00000000 00000000 00000000 d7b45720 0000007f 7fc0: 00400e38 00000000 d7b45720 0000007f b5c2355c 0000007f 80000000 00000000 7fe0: 00000000 00000000 000000de 00000000 00000000 00000000 00000000 00000000

Call trace:
[<ffffffc0000f9cac>] page_mapping+0x0/0x14 [<ffffffc000102510>]
remap_pfn_range+0x1cc/0x324 [<ffffffc0002b51fc>]
vfio_layerscape_mmap+0x22c/0x248 [<ffffffc0002b1cc4>]
vfio_device_fops_mmap+0x20/0x30 [<ffffffc000108968>] mmap_region+0x320/0x538
[<ffffffc000108e34>] do_mmap_pgoff+0x2b4/0x320 [<ffffffc0000f9c40>]
vm_mmap_pgoff+0x60/0x90 [<ffffffc000107508>] SyS_mmap_pgoff+0x88/0xc4
[<ffffffc000086d80>] sys_mmap+0x18/0x28
Code: a8c17bfd d65f03c0 928002a0 17fffffd (f9400400) ---[ end trace
Quoted 1 line

650769ec4955b30e ]---

Did you get the chance to look into this? What is your take for this patch or you want to suggest some other solution?

Thanks
-Bharat

maintainer
#5 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

Quoted 9 lines · Will Deacon
Quoted 2 lines · Bharat.Bhushan at freescale.com

Did you get the chance to look into this? What is your take for this patch or you want to suggest some other solution?

See my reply to Laura here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/238510.html

We *really* don't want executable device mappings.

/dev/mem mapping use pgprot_noncached() but I think we could generalise any of the writecombine and dmacoherent mappings to XN like in the patch below:

arch/arm64/include/asm/pgtable.h +3 -3
index b524dcd17243..2d3cede62709 100644
@@ -286,11 +286,11 @@ static inline int has_transparent_hugepage(void)
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
 #define pgprot_writecombine(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 #define pgprot_dmacoherent(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
Signature · 1 line
Catalin
maintainer
#6 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

Quoted 24 lines · Catalin Marinas
Quoted 9 lines · Will Deacon
Quoted 2 lines · Bharat.Bhushan at freescale.com

Did you get the chance to look into this? What is your take for this patch or you want to suggest some other solution?

See my reply to Laura here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/238510.html

We *really* don't want executable device mappings.

/dev/mem mapping use pgprot_noncached() but I think we could generalise any of the writecombine and dmacoherent mappings to XN like in the patch below:

arch/arm64/include/asm/pgtable.h +0 -1
index b524dcd17243..2d3cede62709 100644
@@ -286,11 +286,11 @@ static inline int has_transparent_hugepage(void)
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))

arch/arm64/include/asm/pgtable.h static inline int has_transparent_hugepage(void) · line 296

Quoted 10 lines
arch/arm64/include/asm/pgtable.h +3 -2
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
 #define pgprot_writecombine(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 #define pgprot_dmacoherent(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,

And one more patch as suggested by Steve Capper. Both would be needed.

-------------8<----------------------

Quoted 1 line

From 31d84855d71778e4a0f615f61ab836be3a70a58b Mon Sep 17 00:00:00 2001

From: Catalin Marinas <[email protected]>
Date: Wed, 12 Mar 2014 16:28:09 +0000
Subject: [PATCH] arm64: Do not synchronise I and D caches for special ptes

Special pte mappings are not intended to be executable and do not even have an associated struct page. This patch ensures that we do not call __sync_icache_dcache() on such ptes.

---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/pgtable.h +1 -1
index 2d3cede62709..72c9ac38cdd9 100644
@@ -199,7 +199,7 @@ 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_exec(pte))
+		if (!pte_special(pte) && pte_exec(pte))
 			__sync_icache_dcache(pte, addr);
 		if (pte_dirty(pte) && pte_write(pte))
 			pte_val(pte) &= ~PTE_RDONLY;
#7 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

Quoted 69 lines · Catalin Marinas
Quoted 24 lines · Catalin Marinas
Quoted 9 lines · Will Deacon
Quoted 2 lines · Bharat.Bhushan at freescale.com

Did you get the chance to look into this? What is your take for this patch or you want to suggest some other solution?

See my reply to Laura here:

   http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/238510.html

We *really* don't want executable device mappings.

/dev/mem mapping use pgprot_noncached() but I think we could generalise any of the writecombine and dmacoherent mappings to XN like in the patch below:

arch/arm64/include/asm/pgtable.h +0 -1
index b524dcd17243..2d3cede62709 100644
@@ -286,11 +286,11 @@ static inline int has_transparent_hugepage(void)
   * Mark the prot value as uncacheable and unbufferable.
   */
  #define pgprot_noncached(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))

arch/arm64/include/asm/pgtable.h static inline int has_transparent_hugepage(void) · line 296

Quoted 10 lines
arch/arm64/include/asm/pgtable.h +3 -2
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
  #define pgprot_writecombine(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
  #define pgprot_dmacoherent(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
  #define __HAVE_PHYS_MEM_ACCESS_PROT
  struct file;
  extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,

And one more patch as suggested by Steve Capper. Both would be needed.

-------------8<----------------------

From 31d84855d71778e4a0f615f61ab836be3a70a58b Mon Sep 17 00:00:00 2001
From: Catalin Marinas <[email protected]>
Date: Wed, 12 Mar 2014 16:28:09 +0000
Subject: [PATCH] arm64: Do not synchronise I and D caches for special ptes

Special pte mappings are not intended to be executable and do not even have an associated struct page. This patch ensures that we do not call __sync_icache_dcache() on such ptes.

---
  arch/arm64/include/asm/pgtable.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/pgtable.h +1 -1
index 2d3cede62709..72c9ac38cdd9 100644
@@ -199,7 +199,7 @@ 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_exec(pte))
+		if (!pte_special(pte) && pte_exec(pte))
  			__sync_icache_dcache(pte, addr);
  		if (pte_dirty(pte) && pte_write(pte))
  			pte_val(pte) &= ~PTE_RDONLY;
Quoted 5 lines

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Both let my simple test case pass (remap_pfn_range on io memory). You can add my Tested-by to both patches.

Thanks,
Laura

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#8 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

In reply to Catalin Marinas
Quoted 86 lines

-----Original Message-----
From: Catalin Marinas [mailto:catalin.marinas at arm.com]
Sent: Wednesday, March 12, 2014 10:57 PM
To: Will Deacon
Cc: Bhushan Bharat-R65777; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH] ARM64: Kernel managed pages are only flushed

Quoted 2 lines · Catalin Marinas
Quoted 1 line · Will Deacon

On Wed, Mar 12, 2014 at 02:41:31PM +0000, Bharat.Bhushan at freescale.com

Quoted 39 lines · wrote:
Quoted 10 lines
Quoted 2 lines

Did you get the chance to look into this? What is your take for this patch or you want to suggest some other solution?

See my reply to Laura here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/238
510.html

We *really* don't want executable device mappings.

/dev/mem mapping use pgprot_noncached() but I think we could generalise any of the writecombine and dmacoherent mappings to XN like in the patch
below:

arch/arm64/include/asm/pgtable.h +6 -3
index b524dcd17243..2d3cede62709 100644
@@ -286,11 +286,11 @@ static inline int has_transparent_hugepage(void)
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK,
+PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
 #define pgprot_writecombine(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)
+| PTE_PXN | PTE_UXN)
 #define pgprot_dmacoherent(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)
+| PTE_PXN | PTE_UXN)
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long
Quoted 1 line

pfn,

And one more patch as suggested by Steve Capper. Both would be needed.

-------------8<----------------------

From 31d84855d71778e4a0f615f61ab836be3a70a58b Mon Sep 17 00:00:00 2001
From: Catalin Marinas <[email protected]>
Date: Wed, 12 Mar 2014 16:28:09 +0000
Subject: [PATCH] arm64: Do not synchronise I and D caches for special ptes

Special pte mappings are not intended to be executable and do not even have an associated struct page. This patch ensures that we do not call __sync_icache_dcache() on such ptes.

---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/pgtable.h +1 -1
index 2d3cede62709..72c9ac38cdd9 100644
@@ -199,7 +199,7 @@ 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_exec(pte))
+		if (!pte_special(pte) && pte_exec(pte))
 			__sync_icache_dcache(pte, addr);
 		if (pte_dirty(pte) && pte_write(pte))
Quoted 2 lines

pte_val(pte) &= ~PTE_RDONLY;

Thanks
-Bharat

#9 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

In reply to Catalin Marinas
Quoted 86 lines

-----Original Message-----
From: Catalin Marinas [mailto:catalin.marinas at arm.com]
Sent: Wednesday, March 12, 2014 10:57 PM
To: Will Deacon
Cc: Bhushan Bharat-R65777; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH] ARM64: Kernel managed pages are only flushed

Quoted 2 lines · Catalin Marinas
Quoted 1 line · Will Deacon

On Wed, Mar 12, 2014 at 02:41:31PM +0000, Bharat.Bhushan at freescale.com

Quoted 39 lines · wrote:
Quoted 10 lines
Quoted 2 lines

Did you get the chance to look into this? What is your take for this patch or you want to suggest some other solution?

See my reply to Laura here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/238
510.html

We *really* don't want executable device mappings.

/dev/mem mapping use pgprot_noncached() but I think we could generalise any of the writecombine and dmacoherent mappings to XN like in the patch
below:

arch/arm64/include/asm/pgtable.h +6 -3
index b524dcd17243..2d3cede62709 100644
@@ -286,11 +286,11 @@ static inline int has_transparent_hugepage(void)
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK,
+PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
 #define pgprot_writecombine(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)
+| PTE_PXN | PTE_UXN)
 #define pgprot_dmacoherent(prot) \
-	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)
+| PTE_PXN | PTE_UXN)
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long
Quoted 1 line

pfn,

And one more patch as suggested by Steve Capper. Both would be needed.

-------------8<----------------------

From 31d84855d71778e4a0f615f61ab836be3a70a58b Mon Sep 17 00:00:00 2001
From: Catalin Marinas <[email protected]>
Date: Wed, 12 Mar 2014 16:28:09 +0000
Subject: [PATCH] arm64: Do not synchronise I and D caches for special ptes

Special pte mappings are not intended to be executable and do not even have an associated struct page. This patch ensures that we do not call __sync_icache_dcache() on such ptes.

---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/pgtable.h +1 -1
index 2d3cede62709..72c9ac38cdd9 100644
@@ -199,7 +199,7 @@ 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_exec(pte))
+		if (!pte_special(pte) && pte_exec(pte))
 			__sync_icache_dcache(pte, addr);
 		if (pte_dirty(pte) && pte_write(pte))
Quoted 1 line

pte_val(pte) &= ~PTE_RDONLY;

Hi Catalin,

These patches are not yet posted if I have not missed. Also a little bit of confusion, will you be posting these patches or you want me/someone to post these couple of patches? I am assuming you will be posting these patches, if so any idea when we can see these patches?

Thanks
-Bharat

Quoted 1 line
maintainer
#10 lore raw

PATCH 1/1 ARM64: Kernel managed pages are only flushed

Quoted 26 lines · Bharat.Bhushan at freescale.com
Quoted 26 lines

From 31d84855d71778e4a0f615f61ab836be3a70a58b Mon Sep 17 00:00:00 2001
From: Catalin Marinas <[email protected]>
Date: Wed, 12 Mar 2014 16:28:09 +0000
Subject: [PATCH] arm64: Do not synchronise I and D caches for special ptes

Special pte mappings are not intended to be executable and do not even have an associated struct page. This patch ensures that we do not call __sync_icache_dcache() on such ptes.

---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/pgtable.h +1 -1
index 2d3cede62709..72c9ac38cdd9 100644
@@ -199,7 +199,7 @@ 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_exec(pte))
+		if (!pte_special(pte) && pte_exec(pte))
Quoted 8 lines
Quoted 3 lines
arch/arm64/include/asm/pgtable.h +0 -0
 			__sync_icache_dcache(pte, addr);
 		if (pte_dirty(pte) && pte_write(pte))

pte_val(pte) &= ~PTE_RDONLY;

These patches are not yet posted if I have not missed. Also a little bit of confusion, will you be posting these patches or you want me/someone to post these couple of patches? I am assuming you will be posting these patches, if so any idea when we can see these patches?

I added them in the arm64 for-next/core branch (on git.kernel.org) and they are in linux-next (with a cc stable, though I didn't bother sending a late -rc pull request for them).

Signature · 1 line
Catalin