All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lichao Liu <liulichao@loongson.cn>
To: tsbogend@alpha.franken.de, yuanjunqing@loongson.cn,
	chenhc@lemote.com, jiaxun.yang@flygoat.com
Cc: linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org,
	Lichao Liu <liulichao@loongson.cn>
Subject: [PATCH] MIPS: Grant pte read permission, even if vma only have VM_WRITE permission.
Date: Tue, 30 Jun 2020 08:58:45 +0800	[thread overview]
Message-ID: <20200630005845.1239974-1-liulichao@loongson.cn> (raw)

Background:
a cpu have RIXI feature.

Now, if a vma only have VM_WRITE permission, the vma->vm_page_prot will
set _PAGE_NO_READ. In general case, someone read the vma will trigger
RI exception, then do_page_fault will handle it.

But in the following scene, program will hang.

example scene(a trinity test case):
futex_wake_op() will read uaddr, which is passed from user space.
If a program mmap a vma, which only have VM_WRITE permission,
then call futex, and use an address belonging to the vma as uaddr
argument. futex_wake_op() will read the address after disable
pagefault and set correct __ex_table(return -14 directly),
do_page_fault will find the correct __ex_table, and then return -14.
Then futex_wake_op() will try to fixup this error by call
fault_in_user_writeable(), because the pte have write permission,
so handle_mm_fault will do nothing, and return success.
But the RI bit in pte and tlb entry still exsits.
The program will deadloop:
do_page_fault -> find __ex_table success -> return -14;
futex_wake_op -> call fault_in_user_writeable() to fix the error -> retry;
do_page_fault -> find __ex_table success -> return -14;
futex_wake_op -> call fault_in_user_writeable() to fix the error -> retry;
.....

The first perspective of root cause:
Futex think a pte have write permission will have read permission.
When page fault, it only try to fixup with FAULT_FLAG_WRITE.

The second perspective of root cause:
MIPS platform doesn't grant pte read permission, if vma only have
VM_WRITE permission.But X86 and arm64 will.

Most of the architecture will grant pte read permission, even if
the vma only have VM_WRITE permission.
And if the cpu doesn't have RIXI feature, MIPS platform will
grant pte read permission by set _PAGE_READ.
So I think we should fixup thix problem by grant pte read permission,
even if vma only have VM_WRITE permission.

Signed-off-by: Lichao Liu <liulichao@loongson.cn>
---
 arch/mips/mm/cache.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index ad6df1cea866..72b60c44a962 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -160,7 +160,7 @@ static inline void setup_protection_map(void)
 	if (cpu_has_rixi) {
 		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
 		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
 		protection_map[3]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
 		protection_map[4]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
 		protection_map[5]  = __pgprot(_page_cachable_default | _PAGE_PRESENT);
@@ -169,7 +169,7 @@ static inline void setup_protection_map(void)
 
 		protection_map[8]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
 		protection_map[9]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
-		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
+		protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
 		protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
 		protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
 		protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
-- 
2.25.1


             reply	other threads:[~2020-06-30  0:59 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-30  0:58 Lichao Liu [this message]
2020-07-17  9:55 [PATCH] MIPS: Grant pte read permission, even if vma only have VM_WRITE permission Lichao Liu
2020-07-22  9:36 ` Thomas Bogendoerfer
2020-07-24  1:50   ` Lichao Liu
2020-07-31 22:37     ` Maciej W. Rozycki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200630005845.1239974-1-liulichao@loongson.cn \
    --to=liulichao@loongson.cn \
    --cc=chenhc@lemote.com \
    --cc=jiaxun.yang@flygoat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=tsbogend@alpha.franken.de \
    --cc=yuanjunqing@loongson.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.