diff options
| author | 2017-07-31 20:20:29 +1000 | |
|---|---|---|
| committer | 2017-07-31 20:20:29 +1000 | |
| commit | bb272221e9db79f13d454e1f3fb6b05013be985e (patch) | |
| tree | 36f4acc50e3fabac71fadd34c720c0a6011db470 /arch/mips/mm/tlbex.c | |
| parent | powerpc/powernv/pci: Return failure for some uses of dma_set_mask() (diff) | |
| parent | Linux v4.13-rc1 (diff) | |
| download | wireguard-linux-bb272221e9db79f13d454e1f3fb6b05013be985e.tar.xz wireguard-linux-bb272221e9db79f13d454e1f3fb6b05013be985e.zip | |
Merge tag 'v4.13-rc1' into fixes
The fixes branch is based off a random pre-rc1 commit, because we had
some fixes that needed to go in before rc1 was released.
However we now need to fix some code that went in after that point, but
before rc1, so merge rc1 to get that code into fixes so we can fix it!
Diffstat (limited to 'arch/mips/mm/tlbex.c')
| -rw-r--r-- | arch/mips/mm/tlbex.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index ed1c5297547a..5aadc69c8ce3 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -153,8 +153,7 @@ static int scratchpad_offset(int i) */ static int m4kc_tlbp_war(void) { - return (current_cpu_data.processor_id & 0xffff00) == - (PRID_COMP_MIPS | PRID_IMP_4KC); + return current_cpu_type() == CPU_4KC; } /* Handle labels (which must be positive integers). */ @@ -2015,6 +2014,26 @@ static void build_r3000_tlb_modify_handler(void) } #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ +static bool cpu_has_tlbex_tlbp_race(void) +{ + /* + * When a Hardware Table Walker is running it can replace TLB entries + * at any time, leading to a race between it & the CPU. + */ + if (cpu_has_htw) + return true; + + /* + * If the CPU shares FTLB RAM with its siblings then our entry may be + * replaced at any time by a sibling performing a write to the FTLB. + */ + if (cpu_has_shared_ftlb_ram) + return true; + + /* In all other cases there ought to be no race condition to handle */ + return false; +} + /* * R4000 style TLB load/store/modify handlers. */ @@ -2051,7 +2070,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, iPTE_LW(p, wr.r1, wr.r2); /* get even pte */ if (!m4kc_tlbp_war()) { build_tlb_probe_entry(p); - if (cpu_has_htw) { + if (cpu_has_tlbex_tlbp_race()) { /* race condition happens, leaving */ uasm_i_ehb(p); uasm_i_mfc0(p, wr.r3, C0_INDEX); @@ -2125,6 +2144,14 @@ static void build_r4000_tlb_load_handler(void) } uasm_i_nop(&p); + /* + * Warn if something may race with us & replace the TLB entry + * before we read it here. Everything with such races should + * also have dedicated RiXi exception handlers, so this + * shouldn't be hit. + */ + WARN(cpu_has_tlbex_tlbp_race(), "Unhandled race in RiXi path"); + uasm_i_tlbr(&p); switch (current_cpu_type()) { @@ -2192,6 +2219,14 @@ static void build_r4000_tlb_load_handler(void) } uasm_i_nop(&p); + /* + * Warn if something may race with us & replace the TLB entry + * before we read it here. Everything with such races should + * also have dedicated RiXi exception handlers, so this + * shouldn't be hit. + */ + WARN(cpu_has_tlbex_tlbp_race(), "Unhandled race in RiXi path"); + uasm_i_tlbr(&p); switch (current_cpu_type()) { |
