ARM: suspend: fix CPU suspend code for !CONFIG_MMU configurations
authorWill Deacon <will.deacon@arm.com>
Thu, 23 Feb 2012 13:51:38 +0000 (13:51 +0000)
committerJonathan Austin <jonathan.austin@arm.com>
Fri, 7 Jun 2013 16:02:44 +0000 (17:02 +0100)
The ARM CPU suspend code can be selected even for a !CONFIG_MMU
configuration. The resulting kernel will not compile and, even if it did,
would access undefined co-processor registers when executing.

This patch fixes the v6 and v7 CPU suspend code for the nommu case.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Tested-by: Jonathan Austin <jonathan.austin@arm.com>
CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> (commit_signer:1/3=33%)
CC: Santosh Shilimkar <santosh.shilimkar@ti.com> (commit_signer:1/3=33%)
CC: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
arch/arm/kernel/suspend.c
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-v7.S

index c59c97ea8268b461b45b8d46066b2f4208f9afe5..38a50676213bb133ebe1ac120a8517625b2854fc 100644 (file)
 extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
 extern void cpu_resume_mmu(void);
 
+#ifdef CONFIG_MMU
+/*
+ * Hide the first two arguments to __cpu_suspend - these are an implementation
+ * detail which platform code shouldn't have to know about.
+ */
+int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+       struct mm_struct *mm = current->active_mm;
+       int ret;
+
+       if (!idmap_pgd)
+               return -EINVAL;
+
+       /*
+        * Provide a temporary page table with an identity mapping for
+        * the MMU-enable code, required for resuming.  On successful
+        * resume (indicated by a zero return code), we need to switch
+        * back to the correct page tables.
+        */
+       ret = __cpu_suspend(arg, fn);
+       if (ret == 0) {
+               cpu_switch_mm(mm->pgd, mm);
+               local_flush_bp_all();
+               local_flush_tlb_all();
+       }
+
+       return ret;
+}
+#else
+int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+       return __cpu_suspend(arg, fn);
+}
+#define        idmap_pgd       NULL
+#endif
+
 /*
  * This is called by __cpu_suspend() to save the state, and do whatever
  * flushing is required to ensure that when the CPU goes to sleep we have
@@ -46,31 +82,3 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
        outer_clean_range(virt_to_phys(save_ptr),
                          virt_to_phys(save_ptr) + sizeof(*save_ptr));
 }
-
-/*
- * Hide the first two arguments to __cpu_suspend - these are an implementation
- * detail which platform code shouldn't have to know about.
- */
-int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
-{
-       struct mm_struct *mm = current->active_mm;
-       int ret;
-
-       if (!idmap_pgd)
-               return -EINVAL;
-
-       /*
-        * Provide a temporary page table with an identity mapping for
-        * the MMU-enable code, required for resuming.  On successful
-        * resume (indicated by a zero return code), we need to switch
-        * back to the correct page tables.
-        */
-       ret = __cpu_suspend(arg, fn);
-       if (ret == 0) {
-               cpu_switch_mm(mm->pgd, mm);
-               local_flush_bp_all();
-               local_flush_tlb_all();
-       }
-
-       return ret;
-}
index 919405e20b80e73272a519a7c3b377b9eccc2dd0..2d1ef87328a1783d309296a25889d8a37d2a9ae6 100644 (file)
@@ -140,8 +140,10 @@ ENTRY(cpu_v6_set_pte_ext)
 ENTRY(cpu_v6_do_suspend)
        stmfd   sp!, {r4 - r9, lr}
        mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+#ifdef CONFIG_MMU
        mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
        mrc     p15, 0, r6, c2, c0, 1   @ Translation table base 1
+#endif
        mrc     p15, 0, r7, c1, c0, 1   @ auxiliary control register
        mrc     p15, 0, r8, c1, c0, 2   @ co-processor access control
        mrc     p15, 0, r9, c1, c0, 0   @ control register
@@ -158,14 +160,16 @@ ENTRY(cpu_v6_do_resume)
        mcr     p15, 0, ip, c13, c0, 1  @ set reserved context ID
        ldmia   r0, {r4 - r9}
        mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+#ifdef CONFIG_MMU
        mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
        ALT_SMP(orr     r1, r1, #TTB_FLAGS_SMP)
        ALT_UP(orr      r1, r1, #TTB_FLAGS_UP)
        mcr     p15, 0, r1, c2, c0, 0   @ Translation table base 0
        mcr     p15, 0, r6, c2, c0, 1   @ Translation table base 1
+       mcr     p15, 0, ip, c2, c0, 2   @ TTB control register
+#endif
        mcr     p15, 0, r7, c1, c0, 1   @ auxiliary control register
        mcr     p15, 0, r8, c1, c0, 2   @ co-processor access control
-       mcr     p15, 0, ip, c2, c0, 2   @ TTB control register
        mcr     p15, 0, ip, c7, c5, 4   @ ISB
        mov     r0, r9                  @ control register
        b       cpu_resume_mmu
index 2c73a7301ff7017eea046df2f2b67e475ab653de..a851e3433afe1f1d31323d54df60122a7cbd0a5b 100644 (file)
@@ -98,9 +98,11 @@ ENTRY(cpu_v7_do_suspend)
        mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
        mrc     p15, 0, r5, c13, c0, 3  @ User r/o thread ID
        stmia   r0!, {r4 - r5}
+#ifdef CONFIG_MMU
        mrc     p15, 0, r6, c3, c0, 0   @ Domain ID
        mrc     p15, 0, r7, c2, c0, 1   @ TTB 1
        mrc     p15, 0, r11, c2, c0, 2  @ TTB control register
+#endif
        mrc     p15, 0, r8, c1, c0, 0   @ Control register
        mrc     p15, 0, r9, c1, c0, 1   @ Auxiliary control register
        mrc     p15, 0, r10, c1, c0, 2  @ Co-processor access control
@@ -110,13 +112,14 @@ ENDPROC(cpu_v7_do_suspend)
 
 ENTRY(cpu_v7_do_resume)
        mov     ip, #0
-       mcr     p15, 0, ip, c8, c7, 0   @ invalidate TLBs
        mcr     p15, 0, ip, c7, c5, 0   @ invalidate I cache
        mcr     p15, 0, ip, c13, c0, 1  @ set reserved context ID
        ldmia   r0!, {r4 - r5}
        mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
        mcr     p15, 0, r5, c13, c0, 3  @ User r/o thread ID
        ldmia   r0, {r6 - r11}
+#ifdef CONFIG_MMU
+       mcr     p15, 0, ip, c8, c7, 0   @ invalidate TLBs
        mcr     p15, 0, r6, c3, c0, 0   @ Domain ID
 #ifndef CONFIG_ARM_LPAE
        ALT_SMP(orr     r1, r1, #TTB_FLAGS_SMP)
@@ -125,14 +128,15 @@ ENTRY(cpu_v7_do_resume)
        mcr     p15, 0, r1, c2, c0, 0   @ TTB 0
        mcr     p15, 0, r7, c2, c0, 1   @ TTB 1
        mcr     p15, 0, r11, c2, c0, 2  @ TTB control register
-       mrc     p15, 0, r4, c1, c0, 1   @ Read Auxiliary control register
-       teq     r4, r9                  @ Is it already set?
-       mcrne   p15, 0, r9, c1, c0, 1   @ No, so write it
-       mcr     p15, 0, r10, c1, c0, 2  @ Co-processor access control
        ldr     r4, =PRRR               @ PRRR
        ldr     r5, =NMRR               @ NMRR
        mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
        mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
+#endif /* CONFIG_MMU */
+       mrc     p15, 0, r4, c1, c0, 1   @ Read Auxiliary control register
+       teq     r4, r9                  @ Is it already set?
+       mcrne   p15, 0, r9, c1, c0, 1   @ No, so write it
+       mcr     p15, 0, r10, c1, c0, 2  @ Co-processor access control
        isb
        dsb
        mov     r0, r8                  @ control register