From: hev <r@hev.cc>
To: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Huacai Chen <chenhuacai@kernel.org>,
Jiaxun Yang <jiaxun.yang@flygoat.com>,
linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org,
wangrui <wangrui@loongson.cn>, hev <r@hev.cc>
Subject: [RFC PATCH v1] MIPS: tlbex: Avoid access invalid address when pmd is modifying
Date: Mon, 8 Feb 2021 11:37:43 +0800 [thread overview]
Message-ID: <20210208033743.1105739-1-r@hev.cc> (raw)
From: wangrui <wangrui@loongson.cn>
When modifying pmd through THP, invalid address access may occurs in the tlb
handler. Because the tlb handler loads value of pmd twice, one is used for huge
page testing and the other is used to load pte. So these two values may be
different:
CPU 0: (app) CPU 1: (khugepaged)
1: scan hit: set pmd to invalid_pmd_table
(pmd_clear)
2: tlb invalid: handle_tlbl,
load pmd for huge page testing,
is not a huge page
3: collapsed: set pmd to huge page
4: handle_tlbl: load pmd again for
load pte(as base address), the
value of pmd is not an address,
access invalid address!
This patch avoids the inconsistency of two memory loads by reusing the result
of one load.
Signed-off-by: hev <r@hev.cc>
Signed-off-by: wangrui <wangrui@loongson.cn>
---
arch/mips/mm/tlbex.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index a7521b8f7658..66ca219b4457 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -720,14 +720,14 @@ static void build_huge_tlb_write_entry(u32 **p, struct uasm_label **l,
* Check if Huge PTE is present, if so then jump to LABEL.
*/
static void
-build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
- unsigned int pmd, int lid)
+build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int out,
+ unsigned int tmp, unsigned int pmd, int lid)
{
- UASM_i_LW(p, tmp, 0, pmd);
+ UASM_i_LW(p, out, 0, pmd);
if (use_bbit_insns()) {
- uasm_il_bbit1(p, r, tmp, ilog2(_PAGE_HUGE), lid);
+ uasm_il_bbit1(p, r, out, ilog2(_PAGE_HUGE), lid);
} else {
- uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
+ uasm_i_andi(p, tmp, out, _PAGE_HUGE);
uasm_il_bnez(p, r, tmp, lid);
}
}
@@ -1103,7 +1103,6 @@ EXPORT_SYMBOL_GPL(build_update_entries);
struct mips_huge_tlb_info {
int huge_pte;
int restore_scratch;
- bool need_reload_pte;
};
static struct mips_huge_tlb_info
@@ -1118,7 +1117,6 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
rv.huge_pte = scratch;
rv.restore_scratch = 0;
- rv.need_reload_pte = false;
if (check_for_high_segbits) {
UASM_i_MFC0(p, tmp, C0_BADVADDR);
@@ -1323,7 +1321,6 @@ static void build_r4000_tlb_refill_handler(void)
} else {
htlb_info.huge_pte = K0;
htlb_info.restore_scratch = 0;
- htlb_info.need_reload_pte = true;
vmalloc_mode = refill_noscratch;
/*
* create the plain linear handler
@@ -1349,19 +1346,19 @@ static void build_r4000_tlb_refill_handler(void)
#endif
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
- build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
+ build_is_huge_pte(&p, &r, K0, K1, K1, label_tlb_huge_update);
#endif
- build_get_ptep(&p, K0, K1);
- build_update_entries(&p, K0, K1);
+ GET_CONTEXT(&p, K1); /* get context reg */
+ build_adjust_context(&p, K1);
+ UASM_i_ADDU(&p, K0, K0, K1); /* add in offset */
+ build_update_entries(&p, K1, K0);
build_tlb_write_entry(&p, &l, &r, tlb_random);
uasm_l_leave(&l, p);
uasm_i_eret(&p); /* return from trap */
}
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
uasm_l_tlb_huge_update(&l, p);
- if (htlb_info.need_reload_pte)
- UASM_i_LW(&p, htlb_info.huge_pte, 0, K1);
build_huge_update_entries(&p, htlb_info.huge_pte, K1);
build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
htlb_info.restore_scratch);
@@ -2065,14 +2062,13 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
* instead contains the tlb pte. Check the PAGE_HUGE bit and
* see if we need to jump to huge tlb processing.
*/
- build_is_huge_pte(p, r, wr.r1, wr.r2, label_tlb_huge_update);
+ build_is_huge_pte(p, r, wr.r3, wr.r1, wr.r2, label_tlb_huge_update);
#endif
UASM_i_MFC0(p, wr.r1, C0_BADVADDR);
- UASM_i_LW(p, wr.r2, 0, wr.r2);
UASM_i_SRL(p, wr.r1, wr.r1, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
uasm_i_andi(p, wr.r1, wr.r1, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
- UASM_i_ADDU(p, wr.r2, wr.r2, wr.r1);
+ UASM_i_ADDU(p, wr.r2, wr.r3, wr.r1);
#ifdef CONFIG_SMP
uasm_l_smp_pgtable_change(l, *p);
--
2.30.0
reply other threads:[~2021-02-08 3:38 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20210208033743.1105739-1-r@hev.cc \
--to=r@hev.cc \
--cc=chenhuacai@kernel.org \
--cc=jiaxun.yang@flygoat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=tsbogend@alpha.franken.de \
--cc=wangrui@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®