* [PATCH 3.18 066/151] KVM: MIPS: Disable HTW while in guest
[not found] <20150304055457.084276421@linuxfoundation.org>
@ 2015-03-04 6:13 ` Greg Kroah-Hartman
2015-03-04 6:13 ` [PATCH 3.18 067/151] KVM: MIPS: Dont leak FPU/DSP to guest Greg Kroah-Hartman
` (6 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:13 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, James Hogan, Paolo Bonzini,
Ralf Baechle, Markos Chandras, Gleb Natapov, kvm, linux-mips
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <james.hogan@imgtec.com>
commit c4c6f2cad9e1d4cc076bc183c3689cc9e7019c75 upstream.
Ensure any hardware page table walker (HTW) is disabled while in KVM
guest mode, as KVM doesn't yet set up hardware page table walking for
guest mappings so the wrong mappings would get loaded, resulting in the
guest hanging or crashing once it reaches userland.
The HTW is disabled and re-enabled around the call to
__kvm_mips_vcpu_run() which does the initial switch into guest mode and
the final switch out of guest context. Additionally it is enabled for
the duration of guest exits (i.e. kvm_mips_handle_exit()), getting
disabled again before returning back to guest or host.
In all cases the HTW is only disabled in normal kernel mode while
interrupts are disabled, so that the HTW doesn't get left disabled if
the process is preempted.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/kvm/mips.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -18,6 +18,7 @@
#include <asm/page.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
#include <linux/kvm_host.h>
@@ -385,8 +386,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
kvm_guest_enter();
+ /* Disable hardware page table walking while in guest */
+ htw_stop();
+
r = __kvm_mips_vcpu_run(run, vcpu);
+ /* Re-enable HTW before enabling interrupts */
+ htw_start();
+
kvm_guest_exit();
local_irq_enable();
@@ -1002,6 +1009,9 @@ int kvm_mips_handle_exit(struct kvm_run
enum emulation_result er = EMULATE_DONE;
int ret = RESUME_GUEST;
+ /* re-enable HTW before enabling interrupts */
+ htw_start();
+
/* Set a default exit reason */
run->exit_reason = KVM_EXIT_UNKNOWN;
run->ready_for_interrupt_injection = 1;
@@ -1136,6 +1146,9 @@ skip_emul:
}
}
+ /* Disable HTW before returning to guest or host */
+ htw_stop();
+
return ret;
}
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3.18 067/151] KVM: MIPS: Dont leak FPU/DSP to guest
[not found] <20150304055457.084276421@linuxfoundation.org>
2015-03-04 6:13 ` [PATCH 3.18 066/151] KVM: MIPS: Disable HTW while in guest Greg Kroah-Hartman
@ 2015-03-04 6:13 ` Greg Kroah-Hartman
2015-03-04 6:13 ` [PATCH 3.18 068/151] MIPS: Alchemy: Fix cpu clock calculation Greg Kroah-Hartman
` (5 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:13 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, James Hogan, Paolo Bonzini,
Ralf Baechle, Sanjay Lal, Gleb Natapov, kvm, linux-mips
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <james.hogan@imgtec.com>
commit f798217dfd038af981a18bbe4bc57027a08bb182 upstream.
The FPU and DSP are enabled via the CP0 Status CU1 and MX bits by
kvm_mips_set_c0_status() on a guest exit, presumably in case there is
active state that needs saving if pre-emption occurs. However neither of
these bits are cleared again when returning to the guest.
This effectively gives the guest access to the FPU/DSP hardware after
the first guest exit even though it is not aware of its presence,
allowing FP instructions in guest user code to intermittently actually
execute instead of trapping into the guest OS for emulation. It will
then read & manipulate the hardware FP registers which technically
belong to the user process (e.g. QEMU), or are stale from another user
process. It can also crash the guest OS by causing an FP exception, for
which a guest exception handler won't have been registered.
First lets save and disable the FPU (and MSA) state with lose_fpu(1)
before entering the guest. This simplifies the problem, especially for
when guest FPU/MSA support is added in the future, and prevents FR=1 FPU
state being live when the FR bit gets cleared for the guest, which
according to the architecture causes the contents of the FPU and vector
registers to become UNPREDICTABLE.
We can then safely remove the enabling of the FPU in
kvm_mips_set_c0_status(), since there should never be any active FPU or
MSA state to save at pre-emption, which should plug the FPU leak.
DSP state is always live rather than being lazily restored, so for that
it is simpler to just clear the MX bit again when re-entering the guest.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Sanjay Lal <sanjayl@kymasys.com>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/kvm/locore.S | 2 +-
arch/mips/kvm/mips.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/mips/kvm/locore.S
+++ b/arch/mips/kvm/locore.S
@@ -434,7 +434,7 @@ __kvm_mips_return_to_guest:
/* Setup status register for running guest in UM */
.set at
or v1, v1, (ST0_EXL | KSU_USER | ST0_IE)
- and v1, v1, ~ST0_CU0
+ and v1, v1, ~(ST0_CU0 | ST0_MX)
.set noat
mtc0 v1, CP0_STATUS
ehb
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -15,6 +15,7 @@
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/bootmem.h>
+#include <asm/fpu.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
@@ -379,6 +380,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
vcpu->mmio_needed = 0;
}
+ lose_fpu(1);
+
local_irq_disable();
/* Check if we have any exceptions/interrupts pending */
kvm_mips_deliver_interrupts(vcpu,
@@ -987,9 +990,6 @@ static void kvm_mips_set_c0_status(void)
{
uint32_t status = read_c0_status();
- if (cpu_has_fpu)
- status |= (ST0_CU1);
-
if (cpu_has_dsp)
status |= (ST0_MX);
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3.18 068/151] MIPS: Alchemy: Fix cpu clock calculation
[not found] <20150304055457.084276421@linuxfoundation.org>
2015-03-04 6:13 ` [PATCH 3.18 066/151] KVM: MIPS: Disable HTW while in guest Greg Kroah-Hartman
2015-03-04 6:13 ` [PATCH 3.18 067/151] KVM: MIPS: Dont leak FPU/DSP to guest Greg Kroah-Hartman
@ 2015-03-04 6:13 ` Greg Kroah-Hartman
2015-03-04 6:13 ` [PATCH 3.18 071/151] MIPS: asm: pgtable: Add c0 hazards on HTW start/stop sequences Greg Kroah-Hartman
` (4 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:13 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manuel Lauss, John Crispin,
Bruno Randolf, Linux-MIPS, Ralf Baechle
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manuel Lauss <manuel.lauss@gmail.com>
commit 69e4e63ec816a7e22cc3aa14bc7ef4ac734d370c upstream.
The current code uses bits 0-6 of the sys_cpupll register to calculate
core clock speed. However this is only valid on Au1300, on all earlier
models the hardware only uses bits 0-5 to generate core clock.
This fixes clock calculation on the MTX1 (Au1500), where bit 6 of cpupll
is set as well, which ultimately lead the code to calculate a bogus cpu
core clock and also uart base clock down the line.
Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
Reported-by: John Crispin <blogic@openwrt.org>
Tested-by: Bruno Randolf <br1@einfach.org>
Cc: Linux-MIPS <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/9279/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/alchemy/common/clock.c | 2 ++
1 file changed, 2 insertions(+)
--- a/arch/mips/alchemy/common/clock.c
+++ b/arch/mips/alchemy/common/clock.c
@@ -128,6 +128,8 @@ static unsigned long alchemy_clk_cpu_rec
t = 396000000;
else {
t = alchemy_rdsys(AU1000_SYS_CPUPLL) & 0x7f;
+ if (alchemy_get_cputype() < ALCHEMY_CPU_AU1300)
+ t &= 0x3f;
t *= parent_rate;
}
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3.18 071/151] MIPS: asm: pgtable: Add c0 hazards on HTW start/stop sequences
[not found] <20150304055457.084276421@linuxfoundation.org>
` (2 preceding siblings ...)
2015-03-04 6:13 ` [PATCH 3.18 068/151] MIPS: Alchemy: Fix cpu clock calculation Greg Kroah-Hartman
@ 2015-03-04 6:13 ` Greg Kroah-Hartman
2015-03-04 6:13 ` [PATCH 3.18 072/151] MIPS: asm: pgtable: Prevent HTW race when updating PTEs Greg Kroah-Hartman
` (3 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:13 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Markos Chandras, linux-mips,
Ralf Baechle
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markos Chandras <markos.chandras@imgtec.com>
commit 461d1597ffad7a826f8aaa63ab0727c37b632e34 upstream.
When we use htw_{start,stop}() outside of htw_reset(), we need
to ensure that c0 changes have been propagated properly before
we attempt to continue with subsequence memory operations.
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9114/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/include/asm/pgtable.h | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -99,16 +99,20 @@ extern void paging_init(void);
#define htw_stop() \
do { \
- if (cpu_has_htw) \
+ if (cpu_has_htw) { \
write_c0_pwctl(read_c0_pwctl() & \
~(1 << MIPS_PWCTL_PWEN_SHIFT)); \
+ back_to_back_c0_hazard(); \
+ } \
} while(0)
#define htw_start() \
do { \
- if (cpu_has_htw) \
+ if (cpu_has_htw) { \
write_c0_pwctl(read_c0_pwctl() | \
(1 << MIPS_PWCTL_PWEN_SHIFT)); \
+ back_to_back_c0_hazard(); \
+ } \
} while(0)
@@ -116,9 +120,7 @@ do { \
do { \
if (cpu_has_htw) { \
htw_stop(); \
- back_to_back_c0_hazard(); \
htw_start(); \
- back_to_back_c0_hazard(); \
} \
} while(0)
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3.18 072/151] MIPS: asm: pgtable: Prevent HTW race when updating PTEs
[not found] <20150304055457.084276421@linuxfoundation.org>
` (3 preceding siblings ...)
2015-03-04 6:13 ` [PATCH 3.18 071/151] MIPS: asm: pgtable: Add c0 hazards on HTW start/stop sequences Greg Kroah-Hartman
@ 2015-03-04 6:13 ` Greg Kroah-Hartman
2015-03-04 6:13 ` [PATCH 3.18 073/151] MIPS: Export FP functions used by lose_fpu(1) for KVM Greg Kroah-Hartman
` (2 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:13 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Markos Chandras, linux-mips,
Ralf Baechle
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markos Chandras <markos.chandras@imgtec.com>
commit fde3538a8a711aedf1173ecb2d45aed868f51c97 upstream.
Whenever we modify a page table entry, we need to ensure that the HTW
will not fetch a stable entry. And for that to happen we need to ensure
that HTW is stopped before we modify the said entry otherwise the HTW
may already be in the process of reading that entry and fetching the
old information. As a result of which, we replace the htw_reset() calls
with htw_{stop,start} in more appropriate places. This also removes the
remaining users of htw_reset() and as a result we drop that macro
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9116/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/include/asm/pgtable.h | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -116,14 +116,6 @@ do { \
} while(0)
-#define htw_reset() \
-do { \
- if (cpu_has_htw) { \
- htw_stop(); \
- htw_start(); \
- } \
-} while(0)
-
extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
pte_t pteval);
@@ -155,12 +147,13 @@ static inline void pte_clear(struct mm_s
{
pte_t null = __pte(0);
+ htw_stop();
/* Preserve global status for the pair */
if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL)
null.pte_low = null.pte_high = _PAGE_GLOBAL;
set_pte_at(mm, addr, ptep, null);
- htw_reset();
+ htw_start();
}
#else
@@ -190,6 +183,7 @@ static inline void set_pte(pte_t *ptep,
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
+ htw_stop();
#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
/* Preserve global status for the pair */
if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
@@ -197,7 +191,7 @@ static inline void pte_clear(struct mm_s
else
#endif
set_pte_at(mm, addr, ptep, __pte(0));
- htw_reset();
+ htw_start();
}
#endif
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3.18 073/151] MIPS: Export FP functions used by lose_fpu(1) for KVM
[not found] <20150304055457.084276421@linuxfoundation.org>
` (4 preceding siblings ...)
2015-03-04 6:13 ` [PATCH 3.18 072/151] MIPS: asm: pgtable: Prevent HTW race when updating PTEs Greg Kroah-Hartman
@ 2015-03-04 6:13 ` Greg Kroah-Hartman
2015-03-04 6:13 ` [PATCH 3.18 074/151] MIPS: Export MSA " Greg Kroah-Hartman
2015-03-04 6:14 ` [PATCH 3.18 121/151] MIPS: HTW: Prevent accidental HTW start due to nested htw_{start, stop} Greg Kroah-Hartman
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:13 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, James Hogan, Paolo Bonzini,
Ralf Baechle, Paul Burton, Gleb Natapov, kvm, linux-mips
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <james.hogan@imgtec.com>
commit 3ce465e04bfd8de9956d515d6e9587faac3375dc upstream.
Export the _save_fp asm function used by the lose_fpu(1) macro to GPL
modules so that KVM can make use of it when it is built as a module.
This fixes the following build error when CONFIG_KVM=m due to commit
f798217dfd03 ("KVM: MIPS: Don't leak FPU/DSP to guest"):
ERROR: "_save_fp" [arch/mips/kvm/kvm.ko] undefined!
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Fixes: f798217dfd03 (KVM: MIPS: Don't leak FPU/DSP to guest)
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9260/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/kernel/mips_ksyms.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <asm/uaccess.h>
#include <asm/ftrace.h>
+#include <asm/fpu.h>
extern void *__bzero(void *__s, size_t __count);
extern long __strncpy_from_kernel_nocheck_asm(char *__to,
@@ -34,6 +35,11 @@ extern long __strnlen_user_nocheck_asm(c
extern long __strnlen_user_asm(const char *s);
/*
+ * Core architecture code
+ */
+EXPORT_SYMBOL_GPL(_save_fp);
+
+/*
* String functions
*/
EXPORT_SYMBOL(memset);
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3.18 074/151] MIPS: Export MSA functions used by lose_fpu(1) for KVM
[not found] <20150304055457.084276421@linuxfoundation.org>
` (5 preceding siblings ...)
2015-03-04 6:13 ` [PATCH 3.18 073/151] MIPS: Export FP functions used by lose_fpu(1) for KVM Greg Kroah-Hartman
@ 2015-03-04 6:13 ` Greg Kroah-Hartman
2015-03-04 6:14 ` [PATCH 3.18 121/151] MIPS: HTW: Prevent accidental HTW start due to nested htw_{start, stop} Greg Kroah-Hartman
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:13 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, James Hogan, Paolo Bonzini,
Ralf Baechle, Paul Burton, Gleb Natapov, kvm, linux-mips
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <james.hogan@imgtec.com>
commit ca5d25642e212f73492d332d95dc90ef46a0e8dc upstream.
Export the _save_msa asm function used by the lose_fpu(1) macro to GPL
modules so that KVM can make use of it when it is built as a module.
This fixes the following build error when CONFIG_KVM=m and
CONFIG_CPU_HAS_MSA=y due to commit f798217dfd03 ("KVM: MIPS: Don't leak
FPU/DSP to guest"):
ERROR: "_save_msa" [arch/mips/kvm/kvm.ko] undefined!
Fixes: f798217dfd03 (KVM: MIPS: Don't leak FPU/DSP to guest)
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: kvm@vger.kernel.org
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9261/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/kernel/mips_ksyms.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -15,6 +15,7 @@
#include <asm/uaccess.h>
#include <asm/ftrace.h>
#include <asm/fpu.h>
+#include <asm/msa.h>
extern void *__bzero(void *__s, size_t __count);
extern long __strncpy_from_kernel_nocheck_asm(char *__to,
@@ -38,6 +39,9 @@ extern long __strnlen_user_asm(const cha
* Core architecture code
*/
EXPORT_SYMBOL_GPL(_save_fp);
+#ifdef CONFIG_CPU_HAS_MSA
+EXPORT_SYMBOL_GPL(_save_msa);
+#endif
/*
* String functions
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3.18 121/151] MIPS: HTW: Prevent accidental HTW start due to nested htw_{start, stop}
[not found] <20150304055457.084276421@linuxfoundation.org>
` (6 preceding siblings ...)
2015-03-04 6:13 ` [PATCH 3.18 074/151] MIPS: Export MSA " Greg Kroah-Hartman
@ 2015-03-04 6:14 ` Greg Kroah-Hartman
7 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2015-03-04 6:14 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Markos Chandras, linux-mips,
Ralf Baechle
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markos Chandras <markos.chandras@imgtec.com>
commit ed4cbc81addbc076b016c5b979fd1a02f0897f0a upstream.
activate_mm() and switch_mm() call get_new_mmu_context() which in turn
can enable the HTW before the entryhi is changed with the new ASID.
Since the latter will enable the HTW in local_flush_tlb_all(),
then there is a small timing window where the HTW is running with the
new ASID but with an old pgd since the TLBMISS_HANDLER_SETUP_PGD
hasn't assigned a new one yet. In order to prevent that, we introduce a
simple htw counter to avoid starting HTW accidentally due to nested
htw_{start,stop}() sequences. Moreover, since various IPI calls can
enforce TLB flushing operations on a different core, such an operation
may interrupt another htw_{stop,start} in progress leading inconsistent
updates of the htw_seq variable. In order to avoid that, we disable the
interrupts whenever we update that variable.
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9118/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/include/asm/cpu-info.h | 5 +++++
arch/mips/include/asm/mmu_context.h | 7 ++++++-
arch/mips/include/asm/pgtable.h | 24 ++++++++++++++++++------
arch/mips/kernel/cpu-probe.c | 4 +++-
4 files changed, 32 insertions(+), 8 deletions(-)
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -84,6 +84,11 @@ struct cpuinfo_mips {
* (shifted by _CACHE_SHIFT)
*/
unsigned int writecombine;
+ /*
+ * Simple counter to prevent enabling HTW in nested
+ * htw_start/htw_stop calls
+ */
+ unsigned int htw_seq;
} __attribute__((aligned(SMP_CACHE_BYTES)));
extern struct cpuinfo_mips cpu_data[];
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -25,7 +25,6 @@ do { \
if (cpu_has_htw) { \
write_c0_pwbase(pgd); \
back_to_back_c0_hazard(); \
- htw_reset(); \
} \
} while (0)
@@ -142,6 +141,7 @@ static inline void switch_mm(struct mm_s
unsigned long flags;
local_irq_save(flags);
+ htw_stop();
/* Check if our ASID is of an older version and thus invalid */
if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK)
get_new_mmu_context(next, cpu);
@@ -154,6 +154,7 @@ static inline void switch_mm(struct mm_s
*/
cpumask_clear_cpu(cpu, mm_cpumask(prev));
cpumask_set_cpu(cpu, mm_cpumask(next));
+ htw_start();
local_irq_restore(flags);
}
@@ -180,6 +181,7 @@ activate_mm(struct mm_struct *prev, stru
local_irq_save(flags);
+ htw_stop();
/* Unconditionally get a new ASID. */
get_new_mmu_context(next, cpu);
@@ -189,6 +191,7 @@ activate_mm(struct mm_struct *prev, stru
/* mark mmu ownership change */
cpumask_clear_cpu(cpu, mm_cpumask(prev));
cpumask_set_cpu(cpu, mm_cpumask(next));
+ htw_start();
local_irq_restore(flags);
}
@@ -203,6 +206,7 @@ drop_mmu_context(struct mm_struct *mm, u
unsigned long flags;
local_irq_save(flags);
+ htw_stop();
if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
get_new_mmu_context(mm, cpu);
@@ -211,6 +215,7 @@ drop_mmu_context(struct mm_struct *mm, u
/* will get a new context next time */
cpu_context(cpu, mm) = 0;
}
+ htw_start();
local_irq_restore(flags);
}
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -99,19 +99,31 @@ extern void paging_init(void);
#define htw_stop() \
do { \
+ unsigned long flags; \
+ \
if (cpu_has_htw) { \
- write_c0_pwctl(read_c0_pwctl() & \
- ~(1 << MIPS_PWCTL_PWEN_SHIFT)); \
- back_to_back_c0_hazard(); \
+ local_irq_save(flags); \
+ if(!raw_current_cpu_data.htw_seq++) { \
+ write_c0_pwctl(read_c0_pwctl() & \
+ ~(1 << MIPS_PWCTL_PWEN_SHIFT)); \
+ back_to_back_c0_hazard(); \
+ } \
+ local_irq_restore(flags); \
} \
} while(0)
#define htw_start() \
do { \
+ unsigned long flags; \
+ \
if (cpu_has_htw) { \
- write_c0_pwctl(read_c0_pwctl() | \
- (1 << MIPS_PWCTL_PWEN_SHIFT)); \
- back_to_back_c0_hazard(); \
+ local_irq_save(flags); \
+ if (!--raw_current_cpu_data.htw_seq) { \
+ write_c0_pwctl(read_c0_pwctl() | \
+ (1 << MIPS_PWCTL_PWEN_SHIFT)); \
+ back_to_back_c0_hazard(); \
+ } \
+ local_irq_restore(flags); \
} \
} while(0)
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -367,8 +367,10 @@ static inline unsigned int decode_config
if (config3 & MIPS_CONF3_MSA)
c->ases |= MIPS_ASE_MSA;
/* Only tested on 32-bit cores */
- if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT))
+ if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT)) {
+ c->htw_seq = 0;
c->options |= MIPS_CPU_HTW;
+ }
return config3 & MIPS_CONF_M;
}
^ permalink raw reply [flat|nested] 8+ messages in thread