Merge branch 'fixes' into for-linus
authorRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 11 Oct 2012 09:55:04 +0000 (10:55 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 11 Oct 2012 09:55:04 +0000 (10:55 +0100)
Conflicts:
arch/arm/kernel/smp.c

40 files changed:
Documentation/arm/Booting
arch/arm/boot/compressed/.gitignore
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head.S
arch/arm/include/asm/assembler.h
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/glue-cache.h
arch/arm/include/asm/opcodes-virt.h
arch/arm/include/asm/ptrace.h
arch/arm/include/asm/virt.h [new file with mode: 0644]
arch/arm/kernel/Makefile
arch/arm/kernel/head.S
arch/arm/kernel/hyp-stub.S [new file with mode: 0644]
arch/arm/kernel/setup.c
arch/arm/kernel/smp.c
arch/arm/kernel/suspend.c
arch/arm/mm/Kconfig
arch/arm/mm/cache-fa.S
arch/arm/mm/cache-v3.S
arch/arm/mm/cache-v4.S
arch/arm/mm/cache-v4wb.S
arch/arm/mm/cache-v4wt.S
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/proc-arm1020.S
arch/arm/mm/proc-arm1020e.S
arch/arm/mm/proc-arm1022.S
arch/arm/mm/proc-arm1026.S
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm922.S
arch/arm/mm/proc-arm925.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-arm940.S
arch/arm/mm/proc-arm946.S
arch/arm/mm/proc-feroceon.S
arch/arm/mm/proc-macros.S
arch/arm/mm/proc-mohawk.S
arch/arm/mm/proc-v7.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S

index a341d87d276eb1bf3904aec38896f87174b36561..0c1f475fdf36e140d28bcdc26d880546f8a8bdc4 100644 (file)
@@ -154,13 +154,33 @@ In either case, the following conditions must be met:
 
 - CPU mode
   All forms of interrupts must be disabled (IRQs and FIQs)
-  The CPU must be in SVC mode.  (A special exception exists for Angel)
+
+  For CPUs which do not include the ARM virtualization extensions, the
+  CPU must be in SVC mode.  (A special exception exists for Angel)
+
+  CPUs which include support for the virtualization extensions can be
+  entered in HYP mode in order to enable the kernel to make full use of
+  these extensions.  This is the recommended boot method for such CPUs,
+  unless the virtualisations are already in use by a pre-installed
+  hypervisor.
+
+  If the kernel is not entered in HYP mode for any reason, it must be
+  entered in SVC mode.
 
 - Caches, MMUs
   The MMU must be off.
   Instruction cache may be on or off.
   Data cache must be off.
 
+  If the kernel is entered in HYP mode, the above requirements apply to
+  the HYP mode configuration in addition to the ordinary PL1 (privileged
+  kernel modes) configuration.  In addition, all traps into the
+  hypervisor must be disabled, and PL1 access must be granted for all
+  peripherals and CPU resources for which this is architecturally
+  possible.  Except for entering in HYP mode, the system configuration
+  should be such that a kernel which does not include support for the
+  virtualization extensions can boot correctly without extra help.
+
 - The boot loader is expected to call the kernel image by jumping
   directly to the first instruction of the kernel image.
 
index d0d441c429ae3e4e6c438fad1c51c7079c6eda5b..f79a08efe000aa490c1c010715cd0147baa869c0 100644 (file)
@@ -1,6 +1,7 @@
 ashldi3.S
 font.c
 lib1funcs.S
+hyp-stub.S
 piggy.gzip
 piggy.lzo
 piggy.lzma
index bb267562e7ed9a763218c83eaeb2c5c8645debb9..a517153a13eabdad582b6b6f75080cf93f699595 100644 (file)
@@ -30,6 +30,10 @@ FONTC        = $(srctree)/drivers/video/console/font_acorn_8x8.c
 OBJS           += string.o
 CFLAGS_string.o        := -Os
 
+ifeq ($(CONFIG_ARM_VIRT_EXT),y)
+OBJS           += hyp-stub.o
+endif
+
 #
 # Architecture dependencies
 #
@@ -126,7 +130,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
 
 ccflags-y := -fpic -fno-builtin -I$(obj)
-asflags-y := -Wa,-march=all
+asflags-y := -Wa,-march=all -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
 KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
@@ -198,3 +202,6 @@ $(obj)/font.c: $(FONTC)
 
 $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
        @sed "$(SEDFLAGS)" < $< > $@
+
+$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
+       $(call cmd,shipped)
index bc67cbff39448ff84a3f0c14cd22876975ee1965..90275f036cd14517affdb724ea4c6adf5194b72c 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/linkage.h>
+#include <asm/assembler.h>
 
 /*
  * Debugging stuff
@@ -132,7 +133,12 @@ start:
                .word   start                   @ absolute load/run zImage address
                .word   _edata                  @ zImage end address
  THUMB(                .thumb                  )
-1:             mov     r7, r1                  @ save architecture ID
+1:
+               mrs     r9, cpsr
+#ifdef CONFIG_ARM_VIRT_EXT
+               bl      __hyp_stub_install      @ get into SVC mode, reversibly
+#endif
+               mov     r7, r1                  @ save architecture ID
                mov     r8, r2                  @ save atags pointer
 
 #ifndef __ARM_ARCH_2__
@@ -148,9 +154,9 @@ start:
  ARM(          swi     0x123456        )       @ angel_SWI_ARM
  THUMB(                svc     0xab            )       @ angel_SWI_THUMB
 not_angel:
-               mrs     r2, cpsr                @ turn off interrupts to
-               orr     r2, r2, #0xc0           @ prevent angel from running
-               msr     cpsr_c, r2
+               safe_svcmode_maskall r0
+               msr     spsr_cxsf, r9           @ Save the CPU boot mode in
+                                               @ SPSR
 #else
                teqp    pc, #0x0c000003         @ turn off interrupts
 #endif
@@ -350,6 +356,20 @@ dtb_check_done:
                adr     r5, restart
                bic     r5, r5, #31
 
+/* Relocate the hyp vector base if necessary */
+#ifdef CONFIG_ARM_VIRT_EXT
+               mrs     r0, spsr
+               and     r0, r0, #MODE_MASK
+               cmp     r0, #HYP_MODE
+               bne     1f
+
+               bl      __hyp_get_vectors
+               sub     r0, r0, r5
+               add     r0, r0, r10
+               bl      __hyp_set_vectors
+1:
+#endif
+
                sub     r9, r6, r5              @ size to copy
                add     r9, r9, #31             @ rounded up to a multiple
                bic     r9, r9, #31             @ ... of 32 bytes
@@ -458,11 +478,29 @@ not_relocated:    mov     r0, #0
                bl      decompress_kernel
                bl      cache_clean_flush
                bl      cache_off
-               mov     r0, #0                  @ must be zero
                mov     r1, r7                  @ restore architecture number
                mov     r2, r8                  @ restore atags pointer
- ARM(          mov     pc, r4  )               @ call kernel
- THUMB(                bx      r4      )               @ entry point is always ARM
+
+#ifdef CONFIG_ARM_VIRT_EXT
+               mrs     r0, spsr                @ Get saved CPU boot mode
+               and     r0, r0, #MODE_MASK
+               cmp     r0, #HYP_MODE           @ if not booted in HYP mode...
+               bne     __enter_kernel          @ boot kernel directly
+
+               adr     r12, .L__hyp_reentry_vectors_offset
+               ldr     r0, [r12]
+               add     r0, r0, r12
+
+               bl      __hyp_set_vectors
+               __HVC(0)                        @ otherwise bounce to hyp mode
+
+               b       .                       @ should never be reached
+
+               .align  2
+.L__hyp_reentry_vectors_offset:        .long   __hyp_reentry_vectors - .
+#else
+               b       __enter_kernel
+#endif
 
                .align  2
                .type   LC0, #object
@@ -1196,6 +1234,25 @@ memdump: mov     r12, r0
 #endif
 
                .ltorg
+
+#ifdef CONFIG_ARM_VIRT_EXT
+.align 5
+__hyp_reentry_vectors:
+               W(b)    .                       @ reset
+               W(b)    .                       @ undef
+               W(b)    .                       @ svc
+               W(b)    .                       @ pabort
+               W(b)    .                       @ dabort
+               W(b)    __enter_kernel          @ hyp
+               W(b)    .                       @ irq
+               W(b)    .                       @ fiq
+#endif /* CONFIG_ARM_VIRT_EXT */
+
+__enter_kernel:
+               mov     r0, #0                  @ must be 0
+ ARM(          mov     pc, r4  )               @ call kernel
+ THUMB(                bx      r4      )               @ entry point is always ARM
+
 reloc_code_end:
 
                .align
index 5c8b3bf4d8252f1013af6fea25848ce9c41dcfeb..2ef95813fce00b887dbd05020b35675870a7c929 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/domain.h>
+#include <asm/opcodes-virt.h>
 
 #define IOMEM(x)       (x)
 
        .endm
 #endif
 
+/*
+ * Helper macro to enter SVC mode cleanly and mask interrupts. reg is
+ * a scratch register for the macro to overwrite.
+ *
+ * This macro is intended for forcing the CPU into SVC mode at boot time.
+ * you cannot return to the original mode.
+ *
+ * Beware, it also clobers LR.
+ */
+.macro safe_svcmode_maskall reg:req
+       mrs     \reg , cpsr
+       mov     lr , \reg
+       and     lr , lr , #MODE_MASK
+       cmp     lr , #HYP_MODE
+       orr     \reg , \reg , #PSR_I_BIT | PSR_F_BIT
+       bic     \reg , \reg , #MODE_MASK
+       orr     \reg , \reg , #SVC_MODE
+THUMB( orr     \reg , \reg , #PSR_T_BIT        )
+       bne     1f
+       orr     \reg, \reg, #PSR_A_BIT
+       adr     lr, BSYM(2f)
+       msr     spsr_cxsf, \reg
+       __MSR_ELR_HYP(14)
+       __ERET
+1:     msr     cpsr_c, \reg
+2:
+.endm
+
 /*
  * STRT/LDRT access macros with ARM and Thumb-2 variants
  */
index e4448e16046dd32ab69ca17ef65a6b21745a3e0b..e1489c54cd12b4dcb8b997e8e327e2875b183b0c 100644 (file)
  *
  *             Unconditionally clean and invalidate the entire cache.
  *
+ *     flush_kern_louis()
+ *
+ *             Flush data cache levels up to the level of unification
+ *             inner shareable and invalidate the I-cache.
+ *             Only needed from v7 onwards, falls back to flush_cache_all()
+ *             for all other processor versions.
+ *
  *     flush_user_all()
  *
  *             Clean and invalidate all user space cache entries
 struct cpu_cache_fns {
        void (*flush_icache_all)(void);
        void (*flush_kern_all)(void);
+       void (*flush_kern_louis)(void);
        void (*flush_user_all)(void);
        void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
 
@@ -119,6 +127,7 @@ extern struct cpu_cache_fns cpu_cache;
 
 #define __cpuc_flush_icache_all                cpu_cache.flush_icache_all
 #define __cpuc_flush_kern_all          cpu_cache.flush_kern_all
+#define __cpuc_flush_kern_louis                cpu_cache.flush_kern_louis
 #define __cpuc_flush_user_all          cpu_cache.flush_user_all
 #define __cpuc_flush_user_range                cpu_cache.flush_user_range
 #define __cpuc_coherent_kern_range     cpu_cache.coherent_kern_range
@@ -139,6 +148,7 @@ extern struct cpu_cache_fns cpu_cache;
 
 extern void __cpuc_flush_icache_all(void);
 extern void __cpuc_flush_kern_all(void);
+extern void __cpuc_flush_kern_louis(void);
 extern void __cpuc_flush_user_all(void);
 extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
 extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
@@ -204,6 +214,11 @@ static inline void __flush_icache_all(void)
        __flush_icache_preferred();
 }
 
+/*
+ * Flush caches up to Level of Unification Inner Shareable
+ */
+#define flush_cache_louis()            __cpuc_flush_kern_louis()
+
 #define flush_cache_all()              __cpuc_flush_kern_all()
 
 static inline void vivt_flush_cache_mm(struct mm_struct *mm)
index 4f8d2c0dc4419f702449132e46ae7f89bcf2865a..cca9f15704ed82bb2726ce8898611be42d28b5ff 100644 (file)
 #ifndef MULTI_CACHE
 #define __cpuc_flush_icache_all                __glue(_CACHE,_flush_icache_all)
 #define __cpuc_flush_kern_all          __glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_kern_louis                __glue(_CACHE,_flush_kern_cache_louis)
 #define __cpuc_flush_user_all          __glue(_CACHE,_flush_user_cache_all)
 #define __cpuc_flush_user_range                __glue(_CACHE,_flush_user_cache_range)
 #define __cpuc_coherent_kern_range     __glue(_CACHE,_coherent_kern_range)
index b85665a96f8e329e2dc2494da1afb831f80f07e4..efcfdf92d9d5991ac618bf2ae608be27c44dc493 100644 (file)
        0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF)     \
 )
 
+#define __ERET __inst_arm_thumb32(                                     \
+       0xE160006E,                                                     \
+       0xF3DE8F00                                                      \
+)
+
+#define __MSR_ELR_HYP(regnum)  __inst_arm_thumb32(                     \
+       0xE12EF300 | regnum,                                            \
+       0xF3808E30 | (regnum << 16)                                     \
+)
+
 #endif /* ! __ASM_ARM_OPCODES_VIRT_H */
index 355ece523f41f98d623f2c9af8d4d290a02af737..91ef6c231c478901f4c0fc39369ea158100b9f64 100644 (file)
@@ -44,6 +44,7 @@
 #define IRQ_MODE       0x00000012
 #define SVC_MODE       0x00000013
 #define ABT_MODE       0x00000017
+#define HYP_MODE       0x0000001a
 #define UND_MODE       0x0000001b
 #define SYSTEM_MODE    0x0000001f
 #define MODE32_BIT     0x00000010
diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
new file mode 100644 (file)
index 0000000..86164df
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef VIRT_H
+#define VIRT_H
+
+#include <asm/ptrace.h>
+
+/*
+ * Flag indicating that the kernel was not entered in the same mode on every
+ * CPU.  The zImage loader stashes this value in an SPSR, so we need an
+ * architecturally defined flag bit here (the N flag, as it happens)
+ */
+#define BOOT_CPU_MODE_MISMATCH (1<<31)
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ARM_VIRT_EXT
+/*
+ * __boot_cpu_mode records what mode the primary CPU was booted in.
+ * A correctly-implemented bootloader must start all CPUs in the same mode:
+ * if it fails to do this, the flag BOOT_CPU_MODE_MISMATCH is set to indicate
+ * that some CPU(s) were booted in a different mode.
+ *
+ * This allows the kernel to flag an error when the secondaries have come up.
+ */
+extern int __boot_cpu_mode;
+
+void __hyp_set_vectors(unsigned long phys_vector_base);
+unsigned long __hyp_get_vectors(void);
+#else
+#define __boot_cpu_mode        (SVC_MODE)
+#endif
+
+#ifndef ZIMAGE
+void hyp_mode_check(void);
+
+/* Reports the availability of HYP mode */
+static inline bool is_hyp_mode_available(void)
+{
+       return ((__boot_cpu_mode & MODE_MASK) == HYP_MODE &&
+               !(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH));
+}
+
+/* Check if the bootloader has booted CPUs in different modes */
+static inline bool is_hyp_mode_mismatched(void)
+{
+       return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* ! VIRT_H */
index 5dfef9d97ed92b960d8d359997a20108759d60c8..5bbec7b8183e46e0d5ba4f078ba146789f409be1 100644 (file)
@@ -81,4 +81,6 @@ head-y                        := head$(MMUEXT).o
 obj-$(CONFIG_DEBUG_LL) += debug.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
 
+obj-$(CONFIG_ARM_VIRT_EXT)     += hyp-stub.o
+
 extra-y := $(head-y) vmlinux.lds
index 9874d074119118f1d42abeee662beaa3433ca052..4eee351f4668e2bbee54c3771a5389ce8900c10c 100644 (file)
@@ -83,8 +83,12 @@ ENTRY(stext)
  THUMB(        .thumb                  )       @ switch to Thumb now.
  THUMB(1:                      )
 
-       setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
-                                               @ and irqs disabled
+#ifdef CONFIG_ARM_VIRT_EXT
+       bl      __hyp_stub_install
+#endif
+       @ ensure svc mode and all interrupts masked
+       safe_svcmode_maskall r9
+
        mrc     p15, 0, r9, c0, c0              @ get processor id
        bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
        movs    r10, r5                         @ invalid processor (r5=0)?
@@ -326,7 +330,11 @@ ENTRY(secondary_startup)
         * the processor type - there is no need to check the machine type
         * as it has already been validated by the primary processor.
         */
-       setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+#ifdef CONFIG_ARM_VIRT_EXT
+       bl      __hyp_stub_install
+#endif
+       safe_svcmode_maskall r9
+
        mrc     p15, 0, r9, c0, c0              @ get processor id
        bl      __lookup_processor_type
        movs    r10, r5                         @ invalid processor?
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
new file mode 100644 (file)
index 0000000..65b2417
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2012 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/virt.h>
+
+#ifndef ZIMAGE
+/*
+ * For the kernel proper, we need to find out the CPU boot mode long after
+ * boot, so we need to store it in a writable variable.
+ *
+ * This is not in .bss, because we set it sufficiently early that the boot-time
+ * zeroing of .bss would clobber it.
+ */
+.data
+ENTRY(__boot_cpu_mode)
+       .long   0
+.text
+
+       /*
+        * Save the primary CPU boot mode. Requires 3 scratch registers.
+        */
+       .macro  store_primary_cpu_mode  reg1, reg2, reg3
+       mrs     \reg1, cpsr
+       and     \reg1, \reg1, #MODE_MASK
+       adr     \reg2, .L__boot_cpu_mode_offset
+       ldr     \reg3, [\reg2]
+       str     \reg1, [\reg2, \reg3]
+       .endm
+
+       /*
+        * Compare the current mode with the one saved on the primary CPU.
+        * If they don't match, record that fact. The Z bit indicates
+        * if there's a match or not.
+        * Requires 3 additionnal scratch registers.
+        */
+       .macro  compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+       adr     \reg2, .L__boot_cpu_mode_offset
+       ldr     \reg3, [\reg2]
+       ldr     \reg1, [\reg2, \reg3]
+       cmp     \mode, \reg1            @ matches primary CPU boot mode?
+       orrne   r7, r7, #BOOT_CPU_MODE_MISMATCH
+       strne   r7, [r5, r6]            @ record what happened and give up
+       .endm
+
+#else  /* ZIMAGE */
+
+       .macro  store_primary_cpu_mode  reg1:req, reg2:req, reg3:req
+       .endm
+
+/*
+ * The zImage loader only runs on one CPU, so we don't bother with mult-CPU
+ * consistency checking:
+ */
+       .macro  compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+       cmp     \mode, \mode
+       .endm
+
+#endif /* ZIMAGE */
+
+/*
+ * Hypervisor stub installation functions.
+ *
+ * These must be called with the MMU and D-cache off.
+ * They are not ABI compliant and are only intended to be called from the kernel
+ * entry points in head.S.
+ */
+@ Call this from the primary CPU
+ENTRY(__hyp_stub_install)
+       store_primary_cpu_mode  r4, r5, r6
+ENDPROC(__hyp_stub_install)
+
+       @ fall through...
+
+@ Secondary CPUs should call here
+ENTRY(__hyp_stub_install_secondary)
+       mrs     r4, cpsr
+       and     r4, r4, #MODE_MASK
+
+       /*
+        * If the secondary has booted with a different mode, give up
+        * immediately.
+        */
+       compare_cpu_mode_with_primary   r4, r5, r6, r7
+       bxne    lr
+
+       /*
+        * Once we have given up on one CPU, we do not try to install the
+        * stub hypervisor on the remaining ones: because the saved boot mode
+        * is modified, it can't compare equal to the CPSR mode field any
+        * more.
+        *
+        * Otherwise...
+        */
+
+       cmp     r4, #HYP_MODE
+       bxne    lr                      @ give up if the CPU is not in HYP mode
+
+/*
+ * Configure HSCTLR to set correct exception endianness/instruction set
+ * state etc.
+ * Turn off all traps
+ * Eventually, CPU-specific code might be needed -- assume not for now
+ *
+ * This code relies on the "eret" instruction to synchronize the
+ * various coprocessor accesses.
+ */
+       @ Now install the hypervisor stub:
+       adr     r7, __hyp_stub_vectors
+       mcr     p15, 4, r7, c12, c0, 0  @ set hypervisor vector base (HVBAR)
+
+       @ Disable all traps, so we don't get any nasty surprise
+       mov     r7, #0
+       mcr     p15, 4, r7, c1, c1, 0   @ HCR
+       mcr     p15, 4, r7, c1, c1, 2   @ HCPTR
+       mcr     p15, 4, r7, c1, c1, 3   @ HSTR
+
+THUMB( orr     r7, #(1 << 30)  )       @ HSCTLR.TE
+#ifdef CONFIG_CPU_BIG_ENDIAN
+       orr     r7, #(1 << 9)           @ HSCTLR.EE
+#endif
+       mcr     p15, 4, r7, c1, c0, 0   @ HSCTLR
+
+       mrc     p15, 4, r7, c1, c1, 1   @ HDCR
+       and     r7, #0x1f               @ Preserve HPMN
+       mcr     p15, 4, r7, c1, c1, 1   @ HDCR
+
+#if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER)
+       @ make CNTP_* and CNTPCT accessible from PL1
+       mrc     p15, 0, r7, c0, c1, 1   @ ID_PFR1
+       lsr     r7, #16
+       and     r7, #0xf
+       cmp     r7, #1
+       bne     1f
+       mrc     p15, 4, r7, c14, c1, 0  @ CNTHCTL
+       orr     r7, r7, #3              @ PL1PCEN | PL1PCTEN
+       mcr     p15, 4, r7, c14, c1, 0  @ CNTHCTL
+1:
+#endif
+
+       bic     r7, r4, #MODE_MASK
+       orr     r7, r7, #SVC_MODE
+THUMB( orr     r7, r7, #PSR_T_BIT      )
+       msr     spsr_cxsf, r7           @ This is SPSR_hyp.
+
+       __MSR_ELR_HYP(14)               @ msr elr_hyp, lr
+       __ERET                          @ return, switching to SVC mode
+                                       @ The boot CPU mode is left in r4.
+ENDPROC(__hyp_stub_install_secondary)
+
+__hyp_stub_do_trap:
+       cmp     r0, #-1
+       mrceq   p15, 4, r0, c12, c0, 0  @ get HVBAR
+       mcrne   p15, 4, r0, c12, c0, 0  @ set HVBAR
+       __ERET
+ENDPROC(__hyp_stub_do_trap)
+
+/*
+ * __hyp_set_vectors: Call this after boot to set the initial hypervisor
+ * vectors as part of hypervisor installation.  On an SMP system, this should
+ * be called on each CPU.
+ *
+ * r0 must be the physical address of the new vector table (which must lie in
+ * the bottom 4GB of physical address space.
+ *
+ * r0 must be 32-byte aligned.
+ *
+ * Before calling this, you must check that the stub hypervisor is installed
+ * everywhere, by waiting for any secondary CPUs to be brought up and then
+ * checking that BOOT_CPU_MODE_HAVE_HYP(__boot_cpu_mode) is true.
+ *
+ * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or
+ * something else went wrong... in such cases, trying to install a new
+ * hypervisor is unlikely to work as desired.
+ *
+ * When you call into your shiny new hypervisor, sp_hyp will contain junk,
+ * so you will need to set that to something sensible at the new hypervisor's
+ * initialisation entry point.
+ */
+ENTRY(__hyp_get_vectors)
+       mov     r0, #-1
+ENDPROC(__hyp_get_vectors)
+       @ fall through
+ENTRY(__hyp_set_vectors)
+       __HVC(0)
+       bx      lr
+ENDPROC(__hyp_set_vectors)
+
+#ifndef ZIMAGE
+.align 2
+.L__boot_cpu_mode_offset:
+       .long   __boot_cpu_mode - .
+#endif
+
+.align 5
+__hyp_stub_vectors:
+__hyp_stub_reset:      W(b)    .
+__hyp_stub_und:                W(b)    .
+__hyp_stub_svc:                W(b)    .
+__hyp_stub_pabort:     W(b)    .
+__hyp_stub_dabort:     W(b)    .
+__hyp_stub_trap:       W(b)    __hyp_stub_do_trap
+__hyp_stub_irq:                W(b)    .
+__hyp_stub_fiq:                W(b)    .
+ENDPROC(__hyp_stub_vectors)
+
index febafa0f552d6a75e2bc51755054a8b6e68cf5a8..da1d1aa20ad957ccd7021815014d12530de4f3a1 100644 (file)
@@ -53,6 +53,7 @@
 #include <asm/traps.h>
 #include <asm/unwind.h>
 #include <asm/memblock.h>
+#include <asm/virt.h>
 
 #include "atags.h"
 #include "tcm.h"
@@ -703,6 +704,21 @@ static int __init meminfo_cmp(const void *_a, const void *_b)
        return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
 }
 
+void __init hyp_mode_check(void)
+{
+#ifdef CONFIG_ARM_VIRT_EXT
+       if (is_hyp_mode_available()) {
+               pr_info("CPU: All CPU(s) started in HYP mode.\n");
+               pr_info("CPU: Virtualization extensions available.\n");
+       } else if (is_hyp_mode_mismatched()) {
+               pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n",
+                       __boot_cpu_mode & MODE_MASK);
+               pr_warn("CPU: This may indicate a broken bootloader or firmware.\n");
+       } else
+               pr_info("CPU: All CPU(s) started in SVC mode.\n");
+#endif
+}
+
 void __init setup_arch(char **cmdline_p)
 {
        struct machine_desc *mdesc;
@@ -748,6 +764,10 @@ void __init setup_arch(char **cmdline_p)
                smp_init_cpus();
        }
 #endif
+
+       if (!is_smp())
+               hyp_mode_check();
+
        reserve_crashkernel();
 
        tcm_init();
index d100eacdb7983f8e490a8dc88d4f830b7fab3b8c..8e20754dd31d5946f5297aae2023ae2c8d5cd572 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/ptrace.h>
 #include <asm/localtimer.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 #include <asm/mach/arch.h>
 
 /*
@@ -202,8 +203,11 @@ int __cpuinit __cpu_disable(void)
        /*
         * Flush user cache and TLB mappings, and then remove this CPU
         * from the vm mask set of all processes.
+        *
+        * Caches are flushed to the Level of Unification Inner Shareable
+        * to write-back dirty lines to unified caches shared by all CPUs.
         */
-       flush_cache_all();
+       flush_cache_louis();
        local_flush_tlb_all();
 
        clear_tasks_mm_cpumask(cpu);
@@ -355,6 +359,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
               num_online_cpus(),
               bogosum / (500000/HZ),
               (bogosum / (5000/HZ)) % 100);
+
+       hyp_mode_check();
 }
 
 void __init smp_prepare_boot_cpu(void)
index 1794cc3b0f1836583fec297ee484c554fdefffcd..358bca3a995ed37ec66da93ec40841abd99fa804 100644 (file)
@@ -17,6 +17,8 @@ extern void cpu_resume_mmu(void);
  */
 void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
 {
+       u32 *ctx = ptr;
+
        *save_ptr = virt_to_phys(ptr);
 
        /* This must correspond to the LDM in cpu_resume() assembly */
@@ -26,7 +28,20 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
 
        cpu_do_suspend(ptr);
 
-       flush_cache_all();
+       flush_cache_louis();
+
+       /*
+        * flush_cache_louis does not guarantee that
+        * save_ptr and ptr are cleaned to main memory,
+        * just up to the Level of Unification Inner Shareable.
+        * Since the context pointer and context itself
+        * are to be retrieved with the MMU off that
+        * data must be cleaned from all cache levels
+        * to main memory using "area" cache primitives.
+       */
+       __cpuc_flush_dcache_area(ctx, ptrsz);
+       __cpuc_flush_dcache_area(save_ptr, sizeof(*save_ptr));
+
        outer_clean_range(*save_ptr, *save_ptr + ptrsz);
        outer_clean_range(virt_to_phys(save_ptr),
                          virt_to_phys(save_ptr) + sizeof(*save_ptr));
index 101b9681c08c238a4487afca05df11fff15c9d23..c9a4963b5c3d3363210a53d11cc55d63d77965fd 100644 (file)
@@ -624,6 +624,23 @@ config ARM_THUMBEE
          Say Y here if you have a CPU with the ThumbEE extension and code to
          make use of it. Say N for code that can run on CPUs without ThumbEE.
 
+config ARM_VIRT_EXT
+       bool "Native support for the ARM Virtualization Extensions"
+       depends on MMU && CPU_V7
+       help
+         Enable the kernel to make use of the ARM Virtualization
+         Extensions to install hypervisors without run-time firmware
+         assistance.
+
+         A compliant bootloader is required in order to make maximum
+         use of this feature.  Refer to Documentation/arm/Booting for
+         details.
+
+         It is safe to enable this option even if the kernel may not be
+         booted in HYP mode, may not have support for the
+         virtualization extensions, or may be booted with a
+         non-compliant bootloader.
+
 config SWP_EMULATE
        bool "Emulate SWP/SWPB instructions"
        depends on !CPU_USE_DOMAINS && CPU_V7
index 072016371093546cc95519289b30a66b381d79a9..e505befe51b54b77e850049f38633c5d1c2c20af 100644 (file)
@@ -240,6 +240,9 @@ ENTRY(fa_dma_unmap_area)
        mov     pc, lr
 ENDPROC(fa_dma_unmap_area)
 
+       .globl  fa_flush_kern_cache_louis
+       .equ    fa_flush_kern_cache_louis, fa_flush_kern_cache_all
+
        __INITDATA
 
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
index 52e35f32eefb293589ce6c8ce11b4871cf178c62..8a3fadece8d3739b9d3199c5fa7d6de45bf385f4 100644 (file)
@@ -128,6 +128,9 @@ ENTRY(v3_dma_map_area)
 ENDPROC(v3_dma_unmap_area)
 ENDPROC(v3_dma_map_area)
 
+       .globl  v3_flush_kern_cache_louis
+       .equ    v3_flush_kern_cache_louis, v3_flush_kern_cache_all
+
        __INITDATA
 
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
index 022135d2b7e4394313e1bad6ad3deb67ab8e4e14..43e5d77be677a329f497f9829364f392b254fa75 100644 (file)
@@ -140,6 +140,9 @@ ENTRY(v4_dma_map_area)
 ENDPROC(v4_dma_unmap_area)
 ENDPROC(v4_dma_map_area)
 
+       .globl  v4_flush_kern_cache_louis
+       .equ    v4_flush_kern_cache_louis, v4_flush_kern_cache_all
+
        __INITDATA
 
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
index 8f1eeae340c84b6b948d3ca4a4f0af91250facb3..cd49453214070f24b8cab5c64b583c5aff8309e0 100644 (file)
@@ -251,6 +251,9 @@ ENTRY(v4wb_dma_unmap_area)
        mov     pc, lr
 ENDPROC(v4wb_dma_unmap_area)
 
+       .globl  v4wb_flush_kern_cache_louis
+       .equ    v4wb_flush_kern_cache_louis, v4wb_flush_kern_cache_all
+
        __INITDATA
 
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
index b34a5f908a82345bd6f4c4eb8b20f44f587cad48..11e5e5838bc59eb8d99e2e5d5d74830e86c652f0 100644 (file)
@@ -196,6 +196,9 @@ ENTRY(v4wt_dma_map_area)
 ENDPROC(v4wt_dma_unmap_area)
 ENDPROC(v4wt_dma_map_area)
 
+       .globl  v4wt_flush_kern_cache_louis
+       .equ    v4wt_flush_kern_cache_louis, v4wt_flush_kern_cache_all
+
        __INITDATA
 
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
index 4b10760c56d6fe081dd9ab0988119d2378cd9369..d8fd4d4bd3d45ecdc66ad2c74885795df9681ea7 100644 (file)
@@ -326,6 +326,9 @@ ENTRY(v6_dma_unmap_area)
        mov     pc, lr
 ENDPROC(v6_dma_unmap_area)
 
+       .globl  v6_flush_kern_cache_louis
+       .equ    v6_flush_kern_cache_louis, v6_flush_kern_cache_all
+
        __INITDATA
 
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
index 3b172275262e2c87070af4047a1123c2a6a1a6aa..cd956647c21a800d69ed3215a774b086fed008a1 100644 (file)
@@ -33,6 +33,24 @@ ENTRY(v7_flush_icache_all)
        mov     pc, lr
 ENDPROC(v7_flush_icache_all)
 
+ /*
+ *     v7_flush_dcache_louis()
+ *
+ *     Flush the D-cache up to the Level of Unification Inner Shareable
+ *
+ *     Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ */
+
+ENTRY(v7_flush_dcache_louis)
+       dmb                                     @ ensure ordering with previous memory accesses
+       mrc     p15, 1, r0, c0, c0, 1           @ read clidr, r0 = clidr
+       ands    r3, r0, #0xe00000               @ extract LoUIS from clidr
+       mov     r3, r3, lsr #20                 @ r3 = LoUIS * 2
+       moveq   pc, lr                          @ return if level == 0
+       mov     r10, #0                         @ r10 (starting level) = 0
+       b       flush_levels                    @ start flushing cache levels
+ENDPROC(v7_flush_dcache_louis)
+
 /*
  *     v7_flush_dcache_all()
  *
@@ -49,7 +67,7 @@ ENTRY(v7_flush_dcache_all)
        mov     r3, r3, lsr #23                 @ left align loc bit field
        beq     finished                        @ if loc is 0, then no need to clean
        mov     r10, #0                         @ start clean at cache level 0
-loop1:
+flush_levels:
        add     r2, r10, r10, lsr #1            @ work out 3x current cache level
        mov     r1, r0, lsr r2                  @ extract cache type bits from clidr
        and     r1, r1, #7                      @ mask of the bits for current cache only
@@ -71,9 +89,9 @@ loop1:
        clz     r5, r4                          @ find bit position of way size increment
        ldr     r7, =0x7fff
        ands    r7, r7, r1, lsr #13             @ extract max number of the index size
-loop2:
+loop1:
        mov     r9, r4                          @ create working copy of max way size
-loop3:
+loop2:
  ARM(  orr     r11, r10, r9, lsl r5    )       @ factor way and cache number into r11
  THUMB(        lsl     r6, r9, r5              )
  THUMB(        orr     r11, r10, r6            )       @ factor way and cache number into r11
@@ -82,13 +100,13 @@ loop3:
  THUMB(        orr     r11, r11, r6            )       @ factor index number into r11
        mcr     p15, 0, r11, c7, c14, 2         @ clean & invalidate by set/way
        subs    r9, r9, #1                      @ decrement the way
-       bge     loop3
-       subs    r7, r7, #1                      @ decrement the index
        bge     loop2
+       subs    r7, r7, #1                      @ decrement the index
+       bge     loop1
 skip:
        add     r10, r10, #2                    @ increment cache number
        cmp     r3, r10
-       bgt     loop1
+       bgt     flush_levels
 finished:
        mov     r10, #0                         @ swith back to cache level 0
        mcr     p15, 2, r10, c0, c0, 0          @ select current cache level in cssr
@@ -120,6 +138,24 @@ ENTRY(v7_flush_kern_cache_all)
        mov     pc, lr
 ENDPROC(v7_flush_kern_cache_all)
 
+ /*
+ *     v7_flush_kern_cache_louis(void)
+ *
+ *     Flush the data cache up to Level of Unification Inner Shareable.
+ *     Invalidate the I-cache to the point of unification.
+ */
+ENTRY(v7_flush_kern_cache_louis)
+ ARM(  stmfd   sp!, {r4-r5, r7, r9-r11, lr}    )
+ THUMB(        stmfd   sp!, {r4-r7, r9-r11, lr}        )
+       bl      v7_flush_dcache_louis
+       mov     r0, #0
+       ALT_SMP(mcr     p15, 0, r0, c7, c1, 0)  @ invalidate I-cache inner shareable
+       ALT_UP(mcr      p15, 0, r0, c7, c5, 0)  @ I+BTB cache invalidate
+ ARM(  ldmfd   sp!, {r4-r5, r7, r9-r11, lr}    )
+ THUMB(        ldmfd   sp!, {r4-r7, r9-r11, lr}        )
+       mov     pc, lr
+ENDPROC(v7_flush_kern_cache_louis)
+
 /*
  *     v7_flush_cache_all()
  *
index 0650bb87c1e3a68feb64f465bf547c2e3de52771..2bb61e703d6c4d042cbbb86e6c655cbc0e94d762 100644 (file)
@@ -368,6 +368,9 @@ ENTRY(arm1020_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm1020_dma_unmap_area)
 
+       .globl  arm1020_flush_kern_cache_louis
+       .equ    arm1020_flush_kern_cache_louis, arm1020_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm1020
 
index 4188478325a6398fbe8ada36c109694b81f177ea..8f96aa40f5107987edf065c451d4d0879e5e108c 100644 (file)
@@ -354,6 +354,9 @@ ENTRY(arm1020e_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm1020e_dma_unmap_area)
 
+       .globl  arm1020e_flush_kern_cache_louis
+       .equ    arm1020e_flush_kern_cache_louis, arm1020e_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm1020e
 
index 33c68824bff0999d6f718eb065f1c5b1daad9cac..8ebe4a469a22534c9a828681d57552a546fb820b 100644 (file)
@@ -343,6 +343,9 @@ ENTRY(arm1022_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm1022_dma_unmap_area)
 
+       .globl  arm1022_flush_kern_cache_louis
+       .equ    arm1022_flush_kern_cache_louis, arm1022_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm1022
 
index fbc1d5fc24dcd0b5df37e4f508b4ea7fb9c4bafc..093fc7e520c341fb270b45e3ef2f4fbed694ae3c 100644 (file)
@@ -337,6 +337,9 @@ ENTRY(arm1026_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm1026_dma_unmap_area)
 
+       .globl  arm1026_flush_kern_cache_louis
+       .equ    arm1026_flush_kern_cache_louis, arm1026_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm1026
 
index 1a8c138eb8975697b8d15dee01f71ad2e9e5917c..2c3b9421ab5eca938dfe9289fc39472259ada3c1 100644 (file)
@@ -319,6 +319,9 @@ ENTRY(arm920_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm920_dma_unmap_area)
 
+       .globl  arm920_flush_kern_cache_louis
+       .equ    arm920_flush_kern_cache_louis, arm920_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm920
 #endif
index 4c44d7e1c3ca214f4debab4538928ef68113bafd..4464c49d7449b386b04c017f33fdeb79ef718f05 100644 (file)
@@ -321,6 +321,9 @@ ENTRY(arm922_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm922_dma_unmap_area)
 
+       .globl  arm922_flush_kern_cache_louis
+       .equ    arm922_flush_kern_cache_louis, arm922_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm922
 #endif
index ec5b1180994fb7b01779a8c457737f803f613e75..281eb9b9c1d654061e0bc8d2e6d350f6d7a3b2ff 100644 (file)
@@ -376,6 +376,9 @@ ENTRY(arm925_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm925_dma_unmap_area)
 
+       .globl  arm925_flush_kern_cache_louis
+       .equ    arm925_flush_kern_cache_louis, arm925_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm925
 
index c31e62c606c0b6eebf5390c2de640a7fb63ad949..f1803f7e29728460965675b6722a978d0cc33dcd 100644 (file)
@@ -339,6 +339,9 @@ ENTRY(arm926_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm926_dma_unmap_area)
 
+       .globl  arm926_flush_kern_cache_louis
+       .equ    arm926_flush_kern_cache_louis, arm926_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm926
 
index a613a7dd71465c994f6d57093954d9110aee12e4..8da189d4a4021a9184d1c78ac4cda76209406f02 100644 (file)
@@ -267,6 +267,9 @@ ENTRY(arm940_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm940_dma_unmap_area)
 
+       .globl  arm940_flush_kern_cache_louis
+       .equ    arm940_flush_kern_cache_louis, arm940_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm940
 
index 9f4f2999fdd076e5c13aceaa9e5f3734c6ec65ba..f666cf34075a1a8e7e496fd9c0a09657a0627040 100644 (file)
@@ -310,6 +310,9 @@ ENTRY(arm946_dma_unmap_area)
        mov     pc, lr
 ENDPROC(arm946_dma_unmap_area)
 
+       .globl  arm946_flush_kern_cache_louis
+       .equ    arm946_flush_kern_cache_louis, arm946_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions arm946
 
index 23a8e4c7f2bdc5c8a2431e3aba75eea54e08a6b7..4106b09e0c29ad07530e095ca361e84f92489d32 100644 (file)
@@ -415,6 +415,9 @@ ENTRY(feroceon_dma_unmap_area)
        mov     pc, lr
 ENDPROC(feroceon_dma_unmap_area)
 
+       .globl  feroceon_flush_kern_cache_louis
+       .equ    feroceon_flush_kern_cache_louis, feroceon_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions feroceon
 
@@ -431,6 +434,7 @@ ENDPROC(feroceon_dma_unmap_area)
        range_alias flush_icache_all
        range_alias flush_user_cache_all
        range_alias flush_kern_cache_all
+       range_alias flush_kern_cache_louis
        range_alias flush_user_cache_range
        range_alias coherent_kern_range
        range_alias coherent_user_range
index 2d8ff3ad86d3e1a2b9d9abd83a1bdd3ab42eba3a..b29a2265af01b56f4c911b4c74fdd2cfadc3f892 100644 (file)
@@ -299,6 +299,7 @@ ENTRY(\name\()_processor_functions)
 ENTRY(\name\()_cache_fns)
        .long   \name\()_flush_icache_all
        .long   \name\()_flush_kern_cache_all
+       .long   \name\()_flush_kern_cache_louis
        .long   \name\()_flush_user_cache_all
        .long   \name\()_flush_user_cache_range
        .long   \name\()_coherent_kern_range
index fbb2124a547d125266d35cbce88348506c1eab65..82f9cdc751d6421d01bcb4eca3de51dd211f1868 100644 (file)
@@ -303,6 +303,9 @@ ENTRY(mohawk_dma_unmap_area)
        mov     pc, lr
 ENDPROC(mohawk_dma_unmap_area)
 
+       .globl  mohawk_flush_kern_cache_louis
+       .equ    mohawk_flush_kern_cache_louis, mohawk_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions mohawk
 
index c2e2b66f72b5cd08648085c28ffc5d8c2ee8359a..846d279f31764d7803fc6144df9517087286c768 100644 (file)
@@ -172,7 +172,7 @@ __v7_ca15mp_setup:
 __v7_setup:
        adr     r12, __v7_setup_stack           @ the local stack
        stmia   r12, {r0-r5, r7, r9, r11, lr}
-       bl      v7_flush_dcache_all
+       bl      v7_flush_dcache_louis
        ldmia   r12, {r0-r5, r7, r9, r11, lr}
 
        mrc     p15, 0, r0, c0, c0, 0           @ read main ID register
index b0d57869da2d95f1af47702bf039f3ef90ad5f02..eb93d6487f3598fcb0cc6e92c0f3e23faa36fb11 100644 (file)
@@ -337,6 +337,9 @@ ENTRY(xsc3_dma_unmap_area)
        mov     pc, lr
 ENDPROC(xsc3_dma_unmap_area)
 
+       .globl  xsc3_flush_kern_cache_louis
+       .equ    xsc3_flush_kern_cache_louis, xsc3_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions xsc3
 
index 4ffebaa595eec597d37e556bd66edc4af28f2a20..25510361aa181e7200d6f69a64d41ff6b8f8a8a6 100644 (file)
@@ -410,6 +410,9 @@ ENTRY(xscale_dma_unmap_area)
        mov     pc, lr
 ENDPROC(xscale_dma_unmap_area)
 
+       .globl  xscale_flush_kern_cache_louis
+       .equ    xscale_flush_kern_cache_louis, xscale_flush_kern_cache_all
+
        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
        define_cache_functions xscale
 
@@ -439,6 +442,7 @@ ENDPROC(xscale_dma_unmap_area)
        a0_alias flush_icache_all
        a0_alias flush_user_cache_all
        a0_alias flush_kern_cache_all
+       a0_alias flush_kern_cache_louis
        a0_alias flush_user_cache_range
        a0_alias coherent_kern_range
        a0_alias coherent_user_range