@@ -2,6 +2,7 @@
#define __ASMARM_MMU_API_H_
extern pgd_t *mmu_idmap;
extern bool mmu_enabled(void);
+extern void mmu_set_enabled(void);
extern void mmu_enable(pgd_t *pgtable);
extern void mmu_enable_idmap(void);
extern void mmu_init_io_sect(pgd_t *pgtable, unsigned long virt_offset);
@@ -6,16 +6,25 @@
* This work is licensed under the terms of the GNU LGPL, version 2.
*/
#include <asm/setup.h>
+#include <asm/thread_info.h>
+#include <asm/cpumask.h>
#include <asm/mmu.h>
extern unsigned long etext;
pgd_t *mmu_idmap;
-static bool mmu_on;
+static cpumask_t mmu_enabled_cpumask;
bool mmu_enabled(void)
{
- return mmu_on;
+ struct thread_info *ti = current_thread_info();
+ return cpumask_test_cpu(ti->cpu, &mmu_enabled_cpumask);
+}
+
+void mmu_set_enabled(void)
+{
+ struct thread_info *ti = current_thread_info();
+ cpumask_set_cpu(ti->cpu, &mmu_enabled_cpumask);
}
extern void asm_mmu_enable(phys_addr_t pgtable);
@@ -23,7 +32,7 @@ void mmu_enable(pgd_t *pgtable)
{
asm_mmu_enable(__pa(pgtable));
flush_tlb_all();
- mmu_on = true;
+ mmu_set_enabled();
}
void mmu_set_range_ptes(pgd_t *pgtable, unsigned long virt_offset,
We introduced a variable called mmu_on to the mmu implementation because unit tests may want to run with the mmu off, yet still call into common code that could lead to {Load,Store}-Exclusive instructions - which is illegal. So, the mmu_on variable was added and made query-able (through mmu_enabled()) in order to guard those paths. But, mmu_on is really a per cpu concept, so for smp we need to change it. As it's just a bool, we can easily make it per cpu by changing it into a cpumask. We rename it more appropriately too. Signed-off-by: Andrew Jones <drjones@redhat.com> --- lib/arm/asm/mmu-api.h | 1 + lib/arm/mmu.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-)