diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-01 12:14:20 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-01 12:14:20 -0400 |
| commit | 445c682b93479c06d1b062b63ed79202f3ed5503 (patch) | |
| tree | b780cf9d9794f9efe0692ba214a4c11c27f0fe0d | |
| parent | c7681f4637df65082aeee1ea1ff0479607d71982 (diff) | |
| parent | ca3865bae5ff86f5670edc9beebbd1f58c29de85 (diff) | |
Merge branch 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze
* 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze: (35 commits)
microblaze: Support word copying in copy_tofrom_user
microblaze: Print early printk information to log buffer
microblaze: head.S typo fix
microblaze: Use MICROBLAZE_TLB_SIZE in asm code
microblaze: Kconfig Fix - pci
microblaze: Adding likely macros
microblaze: Add .type and .size to ASM functions
microblaze: Fix TLB macros
microblaze: Use instruction with delay slot
microblaze: Remove additional resr and rear loading
microblaze: Change register usage for ESR and EAR
microblaze: Prepare work for optimization in exception code
microblaze: Add DEBUG option
microblaze: Support systems without lmb bram
microblaze: uaccess: Sync strlen, strnlen, copy_to/from_user
microblaze: uaccess: Unify __copy_tofrom_user
microblaze: uaccess: Move functions to generic location
microblaze: uaccess: Fix put_user for noMMU
microblaze: uaccess: Fix get_user macro for noMMU
microblaze: uaccess: fix clear_user for noMMU kernel
...
24 files changed, 407 insertions, 446 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 203ec61c6d4c..76818f926539 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig | |||
| @@ -75,9 +75,6 @@ config LOCKDEP_SUPPORT | |||
| 75 | config HAVE_LATENCYTOP_SUPPORT | 75 | config HAVE_LATENCYTOP_SUPPORT |
| 76 | def_bool y | 76 | def_bool y |
| 77 | 77 | ||
| 78 | config PCI | ||
| 79 | def_bool n | ||
| 80 | |||
| 81 | config DTC | 78 | config DTC |
| 82 | def_bool y | 79 | def_bool y |
| 83 | 80 | ||
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 836832dd9b26..72f6e8583746 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile | |||
| @@ -84,7 +84,7 @@ define archhelp | |||
| 84 | echo '* linux.bin - Create raw binary' | 84 | echo '* linux.bin - Create raw binary' |
| 85 | echo ' linux.bin.gz - Create compressed raw binary' | 85 | echo ' linux.bin.gz - Create compressed raw binary' |
| 86 | echo ' simpleImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in' | 86 | echo ' simpleImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in' |
| 87 | echo ' - stripped elf with fdt blob | 87 | echo ' - stripped elf with fdt blob' |
| 88 | echo ' simpleImage.<dt>.unstrip - full ELF image with fdt blob' | 88 | echo ' simpleImage.<dt>.unstrip - full ELF image with fdt blob' |
| 89 | echo ' *_defconfig - Select default config from arch/microblaze/configs' | 89 | echo ' *_defconfig - Select default config from arch/microblaze/configs' |
| 90 | echo '' | 90 | echo '' |
| @@ -94,3 +94,5 @@ define archhelp | |||
| 94 | echo ' name of a dts file from the arch/microblaze/boot/dts/ directory' | 94 | echo ' name of a dts file from the arch/microblaze/boot/dts/ directory' |
| 95 | echo ' (minus the .dts extension).' | 95 | echo ' (minus the .dts extension).' |
| 96 | endef | 96 | endef |
| 97 | |||
| 98 | MRPROPER_FILES += $(boot)/simpleImage.* | ||
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile index 902cf9846c3c..57f50c2371c6 100644 --- a/arch/microblaze/boot/Makefile +++ b/arch/microblaze/boot/Makefile | |||
| @@ -23,8 +23,6 @@ $(obj)/system.dtb: $(obj)/$(DTB).dtb | |||
| 23 | endif | 23 | endif |
| 24 | 24 | ||
| 25 | $(obj)/linux.bin: vmlinux FORCE | 25 | $(obj)/linux.bin: vmlinux FORCE |
| 26 | [ -n $(CONFIG_INITRAMFS_SOURCE) ] && [ ! -e $(CONFIG_INITRAMFS_SOURCE) ] && \ | ||
| 27 | touch $(CONFIG_INITRAMFS_SOURCE) || echo "No CPIO image" | ||
| 28 | $(call if_changed,objcopy) | 26 | $(call if_changed,objcopy) |
| 29 | $(call if_changed,uimage) | 27 | $(call if_changed,uimage) |
| 30 | @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' | 28 | @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' |
| @@ -62,6 +60,4 @@ quiet_cmd_dtc = DTC $@ | |||
| 62 | $(obj)/%.dtb: $(dtstree)/%.dts FORCE | 60 | $(obj)/%.dtb: $(dtstree)/%.dts FORCE |
| 63 | $(call if_changed,dtc) | 61 | $(call if_changed,dtc) |
| 64 | 62 | ||
| 65 | clean-kernel += linux.bin linux.bin.gz simpleImage.* | 63 | clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub |
| 66 | |||
| 67 | clean-files += *.dtb simpleImage.*.unstrip | ||
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index 563c6b9453f0..8eeb09211ece 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <asm/ptrace.h> | 14 | #include <asm/ptrace.h> |
| 15 | #include <asm/setup.h> | 15 | #include <asm/setup.h> |
| 16 | #include <asm/registers.h> | 16 | #include <asm/registers.h> |
| 17 | #include <asm/segment.h> | ||
| 18 | #include <asm/entry.h> | 17 | #include <asm/entry.h> |
| 19 | #include <asm/current.h> | 18 | #include <asm/current.h> |
| 20 | 19 | ||
diff --git a/arch/microblaze/include/asm/segment.h b/arch/microblaze/include/asm/segment.h deleted file mode 100644 index 0e7102c3fb11..000000000000 --- a/arch/microblaze/include/asm/segment.h +++ /dev/null | |||
| @@ -1,49 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
| 3 | * Copyright (C) 2008-2009 PetaLogix | ||
| 4 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
| 5 | * | ||
| 6 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 7 | * License. See the file "COPYING" in the main directory of this archive | ||
| 8 | * for more details. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef _ASM_MICROBLAZE_SEGMENT_H | ||
| 12 | #define _ASM_MICROBLAZE_SEGMENT_H | ||
| 13 | |||
| 14 | # ifndef __ASSEMBLY__ | ||
| 15 | |||
| 16 | typedef struct { | ||
| 17 | unsigned long seg; | ||
| 18 | } mm_segment_t; | ||
| 19 | |||
| 20 | /* | ||
| 21 | * On Microblaze the fs value is actually the top of the corresponding | ||
| 22 | * address space. | ||
| 23 | * | ||
| 24 | * The fs value determines whether argument validity checking should be | ||
| 25 | * performed or not. If get_fs() == USER_DS, checking is performed, with | ||
| 26 | * get_fs() == KERNEL_DS, checking is bypassed. | ||
| 27 | * | ||
| 28 | * For historical reasons, these macros are grossly misnamed. | ||
| 29 | * | ||
| 30 | * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal. | ||
| 31 | */ | ||
| 32 | # define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) | ||
| 33 | |||
| 34 | # ifndef CONFIG_MMU | ||
| 35 | # define KERNEL_DS MAKE_MM_SEG(0) | ||
| 36 | # define USER_DS KERNEL_DS | ||
| 37 | # else | ||
| 38 | # define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) | ||
| 39 | # define USER_DS MAKE_MM_SEG(TASK_SIZE - 1) | ||
| 40 | # endif | ||
| 41 | |||
| 42 | # define get_ds() (KERNEL_DS) | ||
| 43 | # define get_fs() (current_thread_info()->addr_limit) | ||
| 44 | # define set_fs(val) (current_thread_info()->addr_limit = (val)) | ||
| 45 | |||
| 46 | # define segment_eq(a, b) ((a).seg == (b).seg) | ||
| 47 | |||
| 48 | # endif /* __ASSEMBLY__ */ | ||
| 49 | #endif /* _ASM_MICROBLAZE_SEGMENT_H */ | ||
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h index 6e92885d381a..b2ca80f64640 100644 --- a/arch/microblaze/include/asm/thread_info.h +++ b/arch/microblaze/include/asm/thread_info.h | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #ifndef __ASSEMBLY__ | 19 | #ifndef __ASSEMBLY__ |
| 20 | # include <linux/types.h> | 20 | # include <linux/types.h> |
| 21 | # include <asm/processor.h> | 21 | # include <asm/processor.h> |
| 22 | # include <asm/segment.h> | ||
| 23 | 22 | ||
| 24 | /* | 23 | /* |
| 25 | * low level task data that entry.S needs immediate access to | 24 | * low level task data that entry.S needs immediate access to |
| @@ -60,6 +59,10 @@ struct cpu_context { | |||
| 60 | __u32 fsr; | 59 | __u32 fsr; |
| 61 | }; | 60 | }; |
| 62 | 61 | ||
| 62 | typedef struct { | ||
| 63 | unsigned long seg; | ||
| 64 | } mm_segment_t; | ||
| 65 | |||
| 63 | struct thread_info { | 66 | struct thread_info { |
| 64 | struct task_struct *task; /* main task structure */ | 67 | struct task_struct *task; /* main task structure */ |
| 65 | struct exec_domain *exec_domain; /* execution domain */ | 68 | struct exec_domain *exec_domain; /* execution domain */ |
diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h index bcb8b41d55af..2e1353c2d18d 100644 --- a/arch/microblaze/include/asm/tlbflush.h +++ b/arch/microblaze/include/asm/tlbflush.h | |||
| @@ -24,6 +24,7 @@ extern void _tlbie(unsigned long address); | |||
| 24 | extern void _tlbia(void); | 24 | extern void _tlbia(void); |
| 25 | 25 | ||
| 26 | #define __tlbia() { preempt_disable(); _tlbia(); preempt_enable(); } | 26 | #define __tlbia() { preempt_disable(); _tlbia(); preempt_enable(); } |
| 27 | #define __tlbie(x) { _tlbie(x); } | ||
| 27 | 28 | ||
| 28 | static inline void local_flush_tlb_all(void) | 29 | static inline void local_flush_tlb_all(void) |
| 29 | { __tlbia(); } | 30 | { __tlbia(); } |
| @@ -31,7 +32,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) | |||
| 31 | { __tlbia(); } | 32 | { __tlbia(); } |
| 32 | static inline void local_flush_tlb_page(struct vm_area_struct *vma, | 33 | static inline void local_flush_tlb_page(struct vm_area_struct *vma, |
| 33 | unsigned long vmaddr) | 34 | unsigned long vmaddr) |
| 34 | { _tlbie(vmaddr); } | 35 | { __tlbie(vmaddr); } |
| 35 | static inline void local_flush_tlb_range(struct vm_area_struct *vma, | 36 | static inline void local_flush_tlb_range(struct vm_area_struct *vma, |
| 36 | unsigned long start, unsigned long end) | 37 | unsigned long start, unsigned long end) |
| 37 | { __tlbia(); } | 38 | { __tlbia(); } |
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 371bd6e56d9a..446bec29b142 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h | |||
| @@ -22,101 +22,73 @@ | |||
| 22 | #include <asm/mmu.h> | 22 | #include <asm/mmu.h> |
| 23 | #include <asm/page.h> | 23 | #include <asm/page.h> |
| 24 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
| 25 | #include <asm/segment.h> | ||
| 26 | #include <linux/string.h> | 25 | #include <linux/string.h> |
| 27 | 26 | ||
| 28 | #define VERIFY_READ 0 | 27 | #define VERIFY_READ 0 |
| 29 | #define VERIFY_WRITE 1 | 28 | #define VERIFY_WRITE 1 |
| 30 | 29 | ||
| 31 | #define __clear_user(addr, n) (memset((void *)(addr), 0, (n)), 0) | 30 | /* |
| 32 | 31 | * On Microblaze the fs value is actually the top of the corresponding | |
| 33 | #ifndef CONFIG_MMU | 32 | * address space. |
| 34 | 33 | * | |
| 35 | extern int ___range_ok(unsigned long addr, unsigned long size); | 34 | * The fs value determines whether argument validity checking should be |
| 36 | 35 | * performed or not. If get_fs() == USER_DS, checking is performed, with | |
| 37 | #define __range_ok(addr, size) \ | 36 | * get_fs() == KERNEL_DS, checking is bypassed. |
| 38 | ___range_ok((unsigned long)(addr), (unsigned long)(size)) | 37 | * |
| 39 | 38 | * For historical reasons, these macros are grossly misnamed. | |
| 40 | #define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) | 39 | * |
| 41 | #define __access_ok(add, size) (__range_ok((addr), (size)) == 0) | 40 | * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal. |
| 42 | 41 | */ | |
| 43 | /* Undefined function to trigger linker error */ | 42 | # define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) |
| 44 | extern int bad_user_access_length(void); | ||
| 45 | |||
| 46 | /* FIXME this is function for optimalization -> memcpy */ | ||
| 47 | #define __get_user(var, ptr) \ | ||
| 48 | ({ \ | ||
| 49 | int __gu_err = 0; \ | ||
| 50 | switch (sizeof(*(ptr))) { \ | ||
| 51 | case 1: \ | ||
| 52 | case 2: \ | ||
| 53 | case 4: \ | ||
| 54 | (var) = *(ptr); \ | ||
| 55 | break; \ | ||
| 56 | case 8: \ | ||
| 57 | memcpy((void *) &(var), (ptr), 8); \ | ||
| 58 | break; \ | ||
| 59 | default: \ | ||
| 60 | (var) = 0; \ | ||
| 61 | __gu_err = __get_user_bad(); \ | ||
| 62 | break; \ | ||
| 63 | } \ | ||
| 64 | __gu_err; \ | ||
| 65 | }) | ||
| 66 | 43 | ||
| 67 | #define __get_user_bad() (bad_user_access_length(), (-EFAULT)) | 44 | # ifndef CONFIG_MMU |
| 45 | # define KERNEL_DS MAKE_MM_SEG(0) | ||
| 46 | # define USER_DS KERNEL_DS | ||
| 47 | # else | ||
| 48 | # define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) | ||
| 49 | # define USER_DS MAKE_MM_SEG(TASK_SIZE - 1) | ||
| 50 | # endif | ||
| 68 | 51 | ||
| 69 | /* FIXME is not there defined __pu_val */ | 52 | # define get_ds() (KERNEL_DS) |
| 70 | #define __put_user(var, ptr) \ | 53 | # define get_fs() (current_thread_info()->addr_limit) |
| 71 | ({ \ | 54 | # define set_fs(val) (current_thread_info()->addr_limit = (val)) |
| 72 | int __pu_err = 0; \ | ||
| 73 | switch (sizeof(*(ptr))) { \ | ||
| 74 | case 1: \ | ||
| 75 | case 2: \ | ||
| 76 | case 4: \ | ||
| 77 | *(ptr) = (var); \ | ||
| 78 | break; \ | ||
| 79 | case 8: { \ | ||
| 80 | typeof(*(ptr)) __pu_val = (var); \ | ||
| 81 | memcpy(ptr, &__pu_val, sizeof(__pu_val)); \ | ||
| 82 | } \ | ||
| 83 | break; \ | ||
| 84 | default: \ | ||
| 85 | __pu_err = __put_user_bad(); \ | ||
| 86 | break; \ | ||
| 87 | } \ | ||
| 88 | __pu_err; \ | ||
| 89 | }) | ||
| 90 | 55 | ||
| 91 | #define __put_user_bad() (bad_user_access_length(), (-EFAULT)) | 56 | # define segment_eq(a, b) ((a).seg == (b).seg) |
| 92 | 57 | ||
| 93 | #define put_user(x, ptr) __put_user((x), (ptr)) | 58 | /* |
| 94 | #define get_user(x, ptr) __get_user((x), (ptr)) | 59 | * The exception table consists of pairs of addresses: the first is the |
| 60 | * address of an instruction that is allowed to fault, and the second is | ||
| 61 | * the address at which the program should continue. No registers are | ||
| 62 | * modified, so it is entirely up to the continuation code to figure out | ||
| 63 | * what to do. | ||
| 64 | * | ||
| 65 | * All the routines below use bits of fixup code that are out of line | ||
| 66 | * with the main instruction path. This means when everything is well, | ||
| 67 | * we don't even have to jump over them. Further, they do not intrude | ||
| 68 | * on our cache or tlb entries. | ||
| 69 | */ | ||
| 70 | struct exception_table_entry { | ||
| 71 | unsigned long insn, fixup; | ||
| 72 | }; | ||
| 95 | 73 | ||
| 96 | #define copy_to_user(to, from, n) (memcpy((to), (from), (n)), 0) | 74 | /* Returns 0 if exception not found and fixup otherwise. */ |
| 97 | #define copy_from_user(to, from, n) (memcpy((to), (from), (n)), 0) | 75 | extern unsigned long search_exception_table(unsigned long); |
| 98 | 76 | ||
| 99 | #define __copy_to_user(to, from, n) (copy_to_user((to), (from), (n))) | 77 | #ifndef CONFIG_MMU |
| 100 | #define __copy_from_user(to, from, n) (copy_from_user((to), (from), (n))) | ||
| 101 | #define __copy_to_user_inatomic(to, from, n) \ | ||
| 102 | (__copy_to_user((to), (from), (n))) | ||
| 103 | #define __copy_from_user_inatomic(to, from, n) \ | ||
| 104 | (__copy_from_user((to), (from), (n))) | ||
| 105 | 78 | ||
| 106 | static inline unsigned long clear_user(void *addr, unsigned long size) | 79 | /* Check against bounds of physical memory */ |
| 80 | static inline int ___range_ok(unsigned long addr, unsigned long size) | ||
| 107 | { | 81 | { |
| 108 | if (access_ok(VERIFY_WRITE, addr, size)) | 82 | return ((addr < memory_start) || |
| 109 | size = __clear_user(addr, size); | 83 | ((addr + size) > memory_end)); |
| 110 | return size; | ||
| 111 | } | 84 | } |
| 112 | 85 | ||
| 113 | /* Returns 0 if exception not found and fixup otherwise. */ | 86 | #define __range_ok(addr, size) \ |
| 114 | extern unsigned long search_exception_table(unsigned long); | 87 | ___range_ok((unsigned long)(addr), (unsigned long)(size)) |
| 115 | 88 | ||
| 116 | extern long strncpy_from_user(char *dst, const char *src, long count); | 89 | #define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) |
| 117 | extern long strnlen_user(const char *src, long count); | ||
| 118 | 90 | ||
| 119 | #else /* CONFIG_MMU */ | 91 | #else |
| 120 | 92 | ||
| 121 | /* | 93 | /* |
| 122 | * Address is valid if: | 94 | * Address is valid if: |
| @@ -129,24 +101,88 @@ extern long strnlen_user(const char *src, long count); | |||
| 129 | /* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n", | 101 | /* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n", |
| 130 | type?"WRITE":"READ",addr,size,get_fs().seg)) */ | 102 | type?"WRITE":"READ",addr,size,get_fs().seg)) */ |
| 131 | 103 | ||
| 132 | /* | 104 | #endif |
| 133 | * All the __XXX versions macros/functions below do not perform | ||
| 134 | * access checking. It is assumed that the necessary checks have been | ||
| 135 | * already performed before the finction (macro) is called. | ||
| 136 | */ | ||
| 137 | 105 | ||
| 138 | #define get_user(x, ptr) \ | 106 | #ifdef CONFIG_MMU |
| 139 | ({ \ | 107 | # define __FIXUP_SECTION ".section .fixup,\"ax\"\n" |
| 140 | access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \ | 108 | # define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n" |
| 141 | ? __get_user((x), (ptr)) : -EFAULT; \ | 109 | #else |
| 142 | }) | 110 | # define __FIXUP_SECTION ".section .discard,\"ax\"\n" |
| 111 | # define __EX_TABLE_SECTION ".section .discard,\"a\"\n" | ||
| 112 | #endif | ||
| 143 | 113 | ||
| 144 | #define put_user(x, ptr) \ | 114 | extern unsigned long __copy_tofrom_user(void __user *to, |
| 145 | ({ \ | 115 | const void __user *from, unsigned long size); |
| 146 | access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) \ | 116 | |
| 147 | ? __put_user((x), (ptr)) : -EFAULT; \ | 117 | /* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */ |
| 118 | static inline unsigned long __must_check __clear_user(void __user *to, | ||
| 119 | unsigned long n) | ||
| 120 | { | ||
| 121 | /* normal memset with two words to __ex_table */ | ||
| 122 | __asm__ __volatile__ ( \ | ||
| 123 | "1: sb r0, %2, r0;" \ | ||
| 124 | " addik %0, %0, -1;" \ | ||
| 125 | " bneid %0, 1b;" \ | ||
| 126 | " addik %2, %2, 1;" \ | ||
| 127 | "2: " \ | ||
| 128 | __EX_TABLE_SECTION \ | ||
| 129 | ".word 1b,2b;" \ | ||
| 130 | ".previous;" \ | ||
| 131 | : "=r"(n) \ | ||
| 132 | : "0"(n), "r"(to) | ||
| 133 | ); | ||
| 134 | return n; | ||
| 135 | } | ||
| 136 | |||
| 137 | static inline unsigned long __must_check clear_user(void __user *to, | ||
| 138 | unsigned long n) | ||
| 139 | { | ||
| 140 | might_sleep(); | ||
| 141 | if (unlikely(!access_ok(VERIFY_WRITE, to, n))) | ||
| 142 | return n; | ||
| 143 | |||
| 144 | return __clear_user(to, n); | ||
| 145 | } | ||
| 146 | |||
| 147 | /* put_user and get_user macros */ | ||
| 148 | extern long __user_bad(void); | ||
| 149 | |||
| 150 | #define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ | ||
| 151 | ({ \ | ||
| 152 | __asm__ __volatile__ ( \ | ||
| 153 | "1:" insn " %1, %2, r0;" \ | ||
| 154 | " addk %0, r0, r0;" \ | ||
| 155 | "2: " \ | ||
| 156 | __FIXUP_SECTION \ | ||
| 157 | "3: brid 2b;" \ | ||
| 158 | " addik %0, r0, %3;" \ | ||
| 159 | ".previous;" \ | ||
| 160 | __EX_TABLE_SECTION \ | ||
| 161 | ".word 1b,3b;" \ | ||
| 162 | ".previous;" \ | ||
| 163 | : "=&r"(__gu_err), "=r"(__gu_val) \ | ||
| 164 | : "r"(__gu_ptr), "i"(-EFAULT) \ | ||
| 165 | ); \ | ||
| 148 | }) | 166 | }) |
| 149 | 167 | ||
| 168 | /** | ||
| 169 | * get_user: - Get a simple variable from user space. | ||
| 170 | * @x: Variable to store result. | ||
| 171 | * @ptr: Source address, in user space. | ||
| 172 | * | ||
| 173 | * Context: User context only. This function may sleep. | ||
| 174 | * | ||
| 175 | * This macro copies a single simple variable from user space to kernel | ||
| 176 | * space. It supports simple types like char and int, but not larger | ||
| 177 | * data types like structures or arrays. | ||
| 178 | * | ||
| 179 | * @ptr must have pointer-to-simple-variable type, and the result of | ||
| 180 | * dereferencing @ptr must be assignable to @x without a cast. | ||
| 181 | * | ||
| 182 | * Returns zero on success, or -EFAULT on error. | ||
| 183 | * On error, the variable @x is set to zero. | ||
| 184 | */ | ||
| 185 | |||
| 150 | #define __get_user(x, ptr) \ | 186 | #define __get_user(x, ptr) \ |
| 151 | ({ \ | 187 | ({ \ |
| 152 | unsigned long __gu_val; \ | 188 | unsigned long __gu_val; \ |
| @@ -163,30 +199,74 @@ extern long strnlen_user(const char *src, long count); | |||
| 163 | __get_user_asm("lw", (ptr), __gu_val, __gu_err); \ | 199 | __get_user_asm("lw", (ptr), __gu_val, __gu_err); \ |
| 164 | break; \ | 200 | break; \ |
| 165 | default: \ | 201 | default: \ |
| 166 | __gu_val = 0; __gu_err = -EINVAL; \ | 202 | /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\ |
| 167 | } \ | 203 | } \ |
| 168 | x = (__typeof__(*(ptr))) __gu_val; \ | 204 | x = (__typeof__(*(ptr))) __gu_val; \ |
| 169 | __gu_err; \ | 205 | __gu_err; \ |
| 170 | }) | 206 | }) |
| 171 | 207 | ||
| 172 | #define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ | 208 | |
| 209 | #define get_user(x, ptr) \ | ||
| 173 | ({ \ | 210 | ({ \ |
| 174 | __asm__ __volatile__ ( \ | 211 | access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \ |
| 175 | "1:" insn " %1, %2, r0; \ | 212 | ? __get_user((x), (ptr)) : -EFAULT; \ |
| 176 | addk %0, r0, r0; \ | 213 | }) |
| 177 | 2: \ | 214 | |
| 178 | .section .fixup,\"ax\"; \ | 215 | #define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ |
| 179 | 3: brid 2b; \ | 216 | ({ \ |
| 180 | addik %0, r0, %3; \ | 217 | __asm__ __volatile__ ( \ |
| 181 | .previous; \ | 218 | "1:" insn " %1, %2, r0;" \ |
| 182 | .section __ex_table,\"a\"; \ | 219 | " addk %0, r0, r0;" \ |
| 183 | .word 1b,3b; \ | 220 | "2: " \ |
| 184 | .previous;" \ | 221 | __FIXUP_SECTION \ |
| 185 | : "=r"(__gu_err), "=r"(__gu_val) \ | 222 | "3: brid 2b;" \ |
| 186 | : "r"(__gu_ptr), "i"(-EFAULT) \ | 223 | " addik %0, r0, %3;" \ |
| 187 | ); \ | 224 | ".previous;" \ |
| 225 | __EX_TABLE_SECTION \ | ||
| 226 | ".word 1b,3b;" \ | ||
| 227 | ".previous;" \ | ||
| 228 | : "=&r"(__gu_err) \ | ||
| 229 | : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \ | ||
| 230 | ); \ | ||
| 188 | }) | 231 | }) |
| 189 | 232 | ||
| 233 | #define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err) \ | ||
| 234 | ({ \ | ||
| 235 | __asm__ __volatile__ (" lwi %0, %1, 0;" \ | ||
| 236 | "1: swi %0, %2, 0;" \ | ||
| 237 | " lwi %0, %1, 4;" \ | ||
| 238 | "2: swi %0, %2, 4;" \ | ||
| 239 | " addk %0, r0, r0;" \ | ||
| 240 | "3: " \ | ||
| 241 | __FIXUP_SECTION \ | ||
| 242 | "4: brid 3b;" \ | ||
| 243 | " addik %0, r0, %3;" \ | ||
| 244 | ".previous;" \ | ||
| 245 | __EX_TABLE_SECTION \ | ||
| 246 | ".word 1b,4b,2b,4b;" \ | ||
| 247 | ".previous;" \ | ||
| 248 | : "=&r"(__gu_err) \ | ||
| 249 | : "r"(&__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \ | ||
| 250 | ); \ | ||
| 251 | }) | ||
| 252 | |||
| 253 | /** | ||
| 254 | * put_user: - Write a simple value into user space. | ||
| 255 | * @x: Value to copy to user space. | ||
| 256 | * @ptr: Destination address, in user space. | ||
| 257 | * | ||
| 258 | * Context: User context only. This function may sleep. | ||
| 259 | * | ||
| 260 | * This macro copies a single simple value from kernel space to user | ||
| 261 | * space. It supports simple types like char and int, but not larger | ||
| 262 | * data types like structures or arrays. | ||
| 263 | * | ||
| 264 | * @ptr must have pointer-to-simple-variable type, and @x must be assignable | ||
| 265 | * to the result of dereferencing @ptr. | ||
| 266 | * | ||
| 267 | * Returns zero on success, or -EFAULT on error. | ||
| 268 | */ | ||
| 269 | |||
| 190 | #define __put_user(x, ptr) \ | 270 | #define __put_user(x, ptr) \ |
| 191 | ({ \ | 271 | ({ \ |
| 192 | __typeof__(*(ptr)) volatile __gu_val = (x); \ | 272 | __typeof__(*(ptr)) volatile __gu_val = (x); \ |
| @@ -195,7 +275,7 @@ extern long strnlen_user(const char *src, long count); | |||
| 195 | case 1: \ | 275 | case 1: \ |
| 196 | __put_user_asm("sb", (ptr), __gu_val, __gu_err); \ | 276 | __put_user_asm("sb", (ptr), __gu_val, __gu_err); \ |
| 197 | break; \ | 277 | break; \ |
| 198 | case 2: \ | 278 | case 2: \ |
| 199 | __put_user_asm("sh", (ptr), __gu_val, __gu_err); \ | 279 | __put_user_asm("sh", (ptr), __gu_val, __gu_err); \ |
| 200 | break; \ | 280 | break; \ |
| 201 | case 4: \ | 281 | case 4: \ |
| @@ -205,121 +285,82 @@ extern long strnlen_user(const char *src, long count); | |||
| 205 | __put_user_asm_8((ptr), __gu_val, __gu_err); \ | 285 | __put_user_asm_8((ptr), __gu_val, __gu_err); \ |
| 206 | break; \ | 286 | break; \ |
| 207 | default: \ | 287 | default: \ |
| 208 | __gu_err = -EINVAL; \ | 288 | /*__gu_err = -EINVAL;*/ __gu_err = __user_bad(); \ |
| 209 | } \ | 289 | } \ |
| 210 | __gu_err; \ | 290 | __gu_err; \ |
| 211 | }) | 291 | }) |
| 212 | 292 | ||
| 213 | #define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err) \ | 293 | #ifndef CONFIG_MMU |
| 214 | ({ \ | ||
| 215 | __asm__ __volatile__ (" lwi %0, %1, 0; \ | ||
| 216 | 1: swi %0, %2, 0; \ | ||
| 217 | lwi %0, %1, 4; \ | ||
| 218 | 2: swi %0, %2, 4; \ | ||
| 219 | addk %0,r0,r0; \ | ||
| 220 | 3: \ | ||
| 221 | .section .fixup,\"ax\"; \ | ||
| 222 | 4: brid 3b; \ | ||
| 223 | addik %0, r0, %3; \ | ||
| 224 | .previous; \ | ||
| 225 | .section __ex_table,\"a\"; \ | ||
| 226 | .word 1b,4b,2b,4b; \ | ||
| 227 | .previous;" \ | ||
| 228 | : "=&r"(__gu_err) \ | ||
| 229 | : "r"(&__gu_val), \ | ||
| 230 | "r"(__gu_ptr), "i"(-EFAULT) \ | ||
| 231 | ); \ | ||
| 232 | }) | ||
| 233 | 294 | ||
| 234 | #define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ | 295 | #define put_user(x, ptr) __put_user((x), (ptr)) |
| 235 | ({ \ | ||
| 236 | __asm__ __volatile__ ( \ | ||
| 237 | "1:" insn " %1, %2, r0; \ | ||
| 238 | addk %0, r0, r0; \ | ||
| 239 | 2: \ | ||
| 240 | .section .fixup,\"ax\"; \ | ||
| 241 | 3: brid 2b; \ | ||
| 242 | addik %0, r0, %3; \ | ||
| 243 | .previous; \ | ||
| 244 | .section __ex_table,\"a\"; \ | ||
| 245 | .word 1b,3b; \ | ||
| 246 | .previous;" \ | ||
| 247 | : "=r"(__gu_err) \ | ||
| 248 | : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT) \ | ||
| 249 | ); \ | ||
| 250 | }) | ||
| 251 | 296 | ||
| 252 | /* | 297 | #else /* CONFIG_MMU */ |
| 253 | * Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. | ||
| 254 | */ | ||
| 255 | static inline int clear_user(char *to, int size) | ||
| 256 | { | ||
| 257 | if (size && access_ok(VERIFY_WRITE, to, size)) { | ||
| 258 | __asm__ __volatile__ (" \ | ||
| 259 | 1: \ | ||
| 260 | sb r0, %2, r0; \ | ||
| 261 | addik %0, %0, -1; \ | ||
| 262 | bneid %0, 1b; \ | ||
| 263 | addik %2, %2, 1; \ | ||
| 264 | 2: \ | ||
| 265 | .section __ex_table,\"a\"; \ | ||
| 266 | .word 1b,2b; \ | ||
| 267 | .section .text;" \ | ||
| 268 | : "=r"(size) \ | ||
| 269 | : "0"(size), "r"(to) | ||
| 270 | ); | ||
| 271 | } | ||
| 272 | return size; | ||
| 273 | } | ||
| 274 | 298 | ||
| 275 | #define __copy_from_user(to, from, n) copy_from_user((to), (from), (n)) | 299 | #define put_user(x, ptr) \ |
| 300 | ({ \ | ||
| 301 | access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) \ | ||
| 302 | ? __put_user((x), (ptr)) : -EFAULT; \ | ||
| 303 | }) | ||
| 304 | #endif /* CONFIG_MMU */ | ||
| 305 | |||
| 306 | /* copy_to_from_user */ | ||
| 307 | #define __copy_from_user(to, from, n) \ | ||
| 308 | __copy_tofrom_user((__force void __user *)(to), \ | ||
| 309 | (void __user *)(from), (n)) | ||
| 276 | #define __copy_from_user_inatomic(to, from, n) \ | 310 | #define __copy_from_user_inatomic(to, from, n) \ |
| 277 | copy_from_user((to), (from), (n)) | 311 | copy_from_user((to), (from), (n)) |
| 278 | 312 | ||
| 279 | #define copy_to_user(to, from, n) \ | 313 | static inline long copy_from_user(void *to, |
| 280 | (access_ok(VERIFY_WRITE, (to), (n)) ? \ | 314 | const void __user *from, unsigned long n) |
| 281 | __copy_tofrom_user((void __user *)(to), \ | 315 | { |
| 282 | (__force const void __user *)(from), (n)) \ | 316 | might_sleep(); |
| 283 | : -EFAULT) | 317 | if (access_ok(VERIFY_READ, from, n)) |
| 318 | return __copy_from_user(to, from, n); | ||
| 319 | return n; | ||
| 320 | } | ||
| 284 | 321 | ||
| 285 | #define __copy_to_user(to, from, n) copy_to_user((to), (from), (n)) | 322 | #define __copy_to_user(to, from, n) \ |
| 323 | __copy_tofrom_user((void __user *)(to), \ | ||
| 324 | (__force const void __user *)(from), (n)) | ||
| 286 | #define __copy_to_user_inatomic(to, from, n) copy_to_user((to), (from), (n)) | 325 | #define __copy_to_user_inatomic(to, from, n) copy_to_user((to), (from), (n)) |
| 287 | 326 | ||
| 288 | #define copy_from_user(to, from, n) \ | 327 | static inline long copy_to_user(void __user *to, |
| 289 | (access_ok(VERIFY_READ, (from), (n)) ? \ | 328 | const void *from, unsigned long n) |
| 290 | __copy_tofrom_user((__force void __user *)(to), \ | 329 | { |
| 291 | (void __user *)(from), (n)) \ | 330 | might_sleep(); |
| 292 | : -EFAULT) | 331 | if (access_ok(VERIFY_WRITE, to, n)) |
| 332 | return __copy_to_user(to, from, n); | ||
| 333 | return n; | ||
| 334 | } | ||
| 293 | 335 | ||
| 336 | /* | ||
| 337 | * Copy a null terminated string from userspace. | ||
| 338 | */ | ||
| 294 | extern int __strncpy_user(char *to, const char __user *from, int len); | 339 | extern int __strncpy_user(char *to, const char __user *from, int len); |
| 295 | extern int __strnlen_user(const char __user *sstr, int len); | ||
| 296 | 340 | ||
| 297 | #define strncpy_from_user(to, from, len) \ | 341 | #define __strncpy_from_user __strncpy_user |
| 298 | (access_ok(VERIFY_READ, from, 1) ? \ | ||
| 299 | __strncpy_user(to, from, len) : -EFAULT) | ||
| 300 | #define strnlen_user(str, len) \ | ||
| 301 | (access_ok(VERIFY_READ, str, 1) ? __strnlen_user(str, len) : 0) | ||
| 302 | 342 | ||
| 303 | #endif /* CONFIG_MMU */ | 343 | static inline long |
| 304 | 344 | strncpy_from_user(char *dst, const char __user *src, long count) | |
| 305 | extern unsigned long __copy_tofrom_user(void __user *to, | 345 | { |
| 306 | const void __user *from, unsigned long size); | 346 | if (!access_ok(VERIFY_READ, src, 1)) |
| 347 | return -EFAULT; | ||
| 348 | return __strncpy_from_user(dst, src, count); | ||
| 349 | } | ||
| 307 | 350 | ||
| 308 | /* | 351 | /* |
| 309 | * The exception table consists of pairs of addresses: the first is the | 352 | * Return the size of a string (including the ending 0) |
| 310 | * address of an instruction that is allowed to fault, and the second is | ||
| 311 | * the address at which the program should continue. No registers are | ||
| 312 | * modified, so it is entirely up to the continuation code to figure out | ||
| 313 | * what to do. | ||
| 314 | * | 353 | * |
| 315 | * All the routines below use bits of fixup code that are out of line | 354 | * Return 0 on exception, a value greater than N if too long |
| 316 | * with the main instruction path. This means when everything is well, | ||
| 317 | * we don't even have to jump over them. Further, they do not intrude | ||
| 318 | * on our cache or tlb entries. | ||
| 319 | */ | 355 | */ |
| 320 | struct exception_table_entry { | 356 | extern int __strnlen_user(const char __user *sstr, int len); |
| 321 | unsigned long insn, fixup; | 357 | |
| 322 | }; | 358 | static inline long strnlen_user(const char __user *src, long n) |
| 359 | { | ||
| 360 | if (!access_ok(VERIFY_READ, src, 1)) | ||
| 361 | return 0; | ||
| 362 | return __strnlen_user(src, n); | ||
| 363 | } | ||
| 323 | 364 | ||
| 324 | #endif /* __ASSEMBLY__ */ | 365 | #endif /* __ASSEMBLY__ */ |
| 325 | #endif /* __KERNEL__ */ | 366 | #endif /* __KERNEL__ */ |
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index b1084974fccd..4d5b0311601b 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c | |||
| @@ -37,7 +37,7 @@ static inline void __dma_sync_page(unsigned long paddr, unsigned long offset, | |||
| 37 | 37 | ||
| 38 | static unsigned long get_dma_direct_offset(struct device *dev) | 38 | static unsigned long get_dma_direct_offset(struct device *dev) |
| 39 | { | 39 | { |
| 40 | if (dev) | 40 | if (likely(dev)) |
| 41 | return (unsigned long)dev->archdata.dma_data; | 41 | return (unsigned long)dev->archdata.dma_data; |
| 42 | 42 | ||
| 43 | return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */ | 43 | return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */ |
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index cb7815cfe5ab..da6a5f5dc766 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S | |||
| @@ -51,6 +51,12 @@ swapper_pg_dir: | |||
| 51 | 51 | ||
| 52 | .text | 52 | .text |
| 53 | ENTRY(_start) | 53 | ENTRY(_start) |
| 54 | #if CONFIG_KERNEL_BASE_ADDR == 0 | ||
| 55 | brai TOPHYS(real_start) | ||
| 56 | .org 0x100 | ||
| 57 | real_start: | ||
| 58 | #endif | ||
| 59 | |||
| 54 | mfs r1, rmsr | 60 | mfs r1, rmsr |
| 55 | andi r1, r1, ~2 | 61 | andi r1, r1, ~2 |
| 56 | mts rmsr, r1 | 62 | mts rmsr, r1 |
| @@ -99,8 +105,8 @@ no_fdt_arg: | |||
| 99 | tophys(r4,r4) /* convert to phys address */ | 105 | tophys(r4,r4) /* convert to phys address */ |
| 100 | ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */ | 106 | ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */ |
| 101 | _copy_command_line: | 107 | _copy_command_line: |
| 102 | lbu r2, r5, r6 /* r7=r5+r6 - r5 contain pointer to command line */ | 108 | lbu r2, r5, r6 /* r2=r5+r6 - r5 contain pointer to command line */ |
| 103 | sb r2, r4, r6 /* addr[r4+r6]= r7*/ | 109 | sb r2, r4, r6 /* addr[r4+r6]= r2*/ |
| 104 | addik r6, r6, 1 /* increment counting */ | 110 | addik r6, r6, 1 /* increment counting */ |
| 105 | bgtid r3, _copy_command_line /* loop for all entries */ | 111 | bgtid r3, _copy_command_line /* loop for all entries */ |
| 106 | addik r3, r3, -1 /* descrement loop */ | 112 | addik r3, r3, -1 /* descrement loop */ |
| @@ -128,7 +134,7 @@ _copy_bram: | |||
| 128 | * virtual to physical. | 134 | * virtual to physical. |
| 129 | */ | 135 | */ |
| 130 | nop | 136 | nop |
| 131 | addik r3, r0, 63 /* Invalidate all TLB entries */ | 137 | addik r3, r0, MICROBLAZE_TLB_SIZE -1 /* Invalidate all TLB entries */ |
| 132 | _invalidate: | 138 | _invalidate: |
| 133 | mts rtlbx, r3 | 139 | mts rtlbx, r3 |
| 134 | mts rtlbhi, r0 /* flush: ensure V is clear */ | 140 | mts rtlbhi, r0 /* flush: ensure V is clear */ |
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 2b86c03aa841..995a2123635b 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S | |||
| @@ -313,13 +313,13 @@ _hw_exception_handler: | |||
| 313 | mfs r5, rmsr; | 313 | mfs r5, rmsr; |
| 314 | nop | 314 | nop |
| 315 | swi r5, r1, 0; | 315 | swi r5, r1, 0; |
| 316 | mfs r3, resr | 316 | mfs r4, resr |
| 317 | nop | 317 | nop |
| 318 | mfs r4, rear; | 318 | mfs r3, rear; |
| 319 | nop | 319 | nop |
| 320 | 320 | ||
| 321 | #ifndef CONFIG_MMU | 321 | #ifndef CONFIG_MMU |
| 322 | andi r5, r3, 0x1000; /* Check ESR[DS] */ | 322 | andi r5, r4, 0x1000; /* Check ESR[DS] */ |
| 323 | beqi r5, not_in_delay_slot; /* Branch if ESR[DS] not set */ | 323 | beqi r5, not_in_delay_slot; /* Branch if ESR[DS] not set */ |
| 324 | mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ | 324 | mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ |
| 325 | nop | 325 | nop |
| @@ -327,13 +327,14 @@ not_in_delay_slot: | |||
| 327 | swi r17, r1, PT_R17 | 327 | swi r17, r1, PT_R17 |
| 328 | #endif | 328 | #endif |
| 329 | 329 | ||
| 330 | andi r5, r3, 0x1F; /* Extract ESR[EXC] */ | 330 | andi r5, r4, 0x1F; /* Extract ESR[EXC] */ |
| 331 | 331 | ||
| 332 | #ifdef CONFIG_MMU | 332 | #ifdef CONFIG_MMU |
| 333 | /* Calculate exception vector offset = r5 << 2 */ | 333 | /* Calculate exception vector offset = r5 << 2 */ |
| 334 | addk r6, r5, r5; /* << 1 */ | 334 | addk r6, r5, r5; /* << 1 */ |
| 335 | addk r6, r6, r6; /* << 2 */ | 335 | addk r6, r6, r6; /* << 2 */ |
| 336 | 336 | ||
| 337 | #ifdef DEBUG | ||
| 337 | /* counting which exception happen */ | 338 | /* counting which exception happen */ |
| 338 | lwi r5, r0, 0x200 + TOPHYS(r0_ram) | 339 | lwi r5, r0, 0x200 + TOPHYS(r0_ram) |
| 339 | addi r5, r5, 1 | 340 | addi r5, r5, 1 |
| @@ -341,6 +342,7 @@ not_in_delay_slot: | |||
| 341 | lwi r5, r6, 0x200 + TOPHYS(r0_ram) | 342 | lwi r5, r6, 0x200 + TOPHYS(r0_ram) |
| 342 | addi r5, r5, 1 | 343 | addi r5, r5, 1 |
| 343 | swi r5, r6, 0x200 + TOPHYS(r0_ram) | 344 | swi r5, r6, 0x200 + TOPHYS(r0_ram) |
| 345 | #endif | ||
| 344 | /* end */ | 346 | /* end */ |
| 345 | /* Load the HW Exception vector */ | 347 | /* Load the HW Exception vector */ |
| 346 | lwi r6, r6, TOPHYS(_MB_HW_ExceptionVectorTable) | 348 | lwi r6, r6, TOPHYS(_MB_HW_ExceptionVectorTable) |
| @@ -376,7 +378,7 @@ handle_other_ex: /* Handle Other exceptions here */ | |||
| 376 | swi r18, r1, PT_R18 | 378 | swi r18, r1, PT_R18 |
| 377 | 379 | ||
| 378 | or r5, r1, r0 | 380 | or r5, r1, r0 |
| 379 | andi r6, r3, 0x1F; /* Load ESR[EC] */ | 381 | andi r6, r4, 0x1F; /* Load ESR[EC] */ |
| 380 | lwi r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */ | 382 | lwi r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */ |
| 381 | swi r7, r1, PT_MODE | 383 | swi r7, r1, PT_MODE |
| 382 | mfs r7, rfsr | 384 | mfs r7, rfsr |
| @@ -426,11 +428,11 @@ handle_other_ex: /* Handle Other exceptions here */ | |||
| 426 | */ | 428 | */ |
| 427 | handle_unaligned_ex: | 429 | handle_unaligned_ex: |
| 428 | /* Working registers already saved: R3, R4, R5, R6 | 430 | /* Working registers already saved: R3, R4, R5, R6 |
| 429 | * R3 = ESR | 431 | * R4 = ESR |
| 430 | * R4 = EAR | 432 | * R3 = EAR |
| 431 | */ | 433 | */ |
| 432 | #ifdef CONFIG_MMU | 434 | #ifdef CONFIG_MMU |
| 433 | andi r6, r3, 0x1000 /* Check ESR[DS] */ | 435 | andi r6, r4, 0x1000 /* Check ESR[DS] */ |
| 434 | beqi r6, _no_delayslot /* Branch if ESR[DS] not set */ | 436 | beqi r6, _no_delayslot /* Branch if ESR[DS] not set */ |
| 435 | mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ | 437 | mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ |
| 436 | nop | 438 | nop |
| @@ -439,7 +441,7 @@ _no_delayslot: | |||
| 439 | RESTORE_STATE; | 441 | RESTORE_STATE; |
| 440 | bri unaligned_data_trap | 442 | bri unaligned_data_trap |
| 441 | #endif | 443 | #endif |
| 442 | andi r6, r3, 0x3E0; /* Mask and extract the register operand */ | 444 | andi r6, r4, 0x3E0; /* Mask and extract the register operand */ |
| 443 | srl r6, r6; /* r6 >> 5 */ | 445 | srl r6, r6; /* r6 >> 5 */ |
| 444 | srl r6, r6; | 446 | srl r6, r6; |
| 445 | srl r6, r6; | 447 | srl r6, r6; |
| @@ -448,33 +450,33 @@ _no_delayslot: | |||
| 448 | /* Store the register operand in a temporary location */ | 450 | /* Store the register operand in a temporary location */ |
| 449 | sbi r6, r0, TOPHYS(ex_reg_op); | 451 | sbi r6, r0, TOPHYS(ex_reg_op); |
| 450 | 452 | ||
| 451 | andi r6, r3, 0x400; /* Extract ESR[S] */ | 453 | andi r6, r4, 0x400; /* Extract ESR[S] */ |
| 452 | bnei r6, ex_sw; | 454 | bnei r6, ex_sw; |
| 453 | ex_lw: | 455 | ex_lw: |
| 454 | andi r6, r3, 0x800; /* Extract ESR[W] */ | 456 | andi r6, r4, 0x800; /* Extract ESR[W] */ |
| 455 | beqi r6, ex_lhw; | 457 | beqi r6, ex_lhw; |
| 456 | lbui r5, r4, 0; /* Exception address in r4 */ | 458 | lbui r5, r3, 0; /* Exception address in r3 */ |
| 457 | /* Load a word, byte-by-byte from destination address | 459 | /* Load a word, byte-by-byte from destination address |
| 458 | and save it in tmp space */ | 460 | and save it in tmp space */ |
| 459 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); | 461 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); |
| 460 | lbui r5, r4, 1; | 462 | lbui r5, r3, 1; |
| 461 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); | 463 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); |
| 462 | lbui r5, r4, 2; | 464 | lbui r5, r3, 2; |
| 463 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_2); | 465 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_2); |
| 464 | lbui r5, r4, 3; | 466 | lbui r5, r3, 3; |
| 465 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_3); | 467 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_3); |
| 466 | /* Get the destination register value into r3 */ | 468 | /* Get the destination register value into r4 */ |
| 467 | lwi r3, r0, TOPHYS(ex_tmp_data_loc_0); | 469 | lwi r4, r0, TOPHYS(ex_tmp_data_loc_0); |
| 468 | bri ex_lw_tail; | 470 | bri ex_lw_tail; |
| 469 | ex_lhw: | 471 | ex_lhw: |
| 470 | lbui r5, r4, 0; /* Exception address in r4 */ | 472 | lbui r5, r3, 0; /* Exception address in r3 */ |
| 471 | /* Load a half-word, byte-by-byte from destination | 473 | /* Load a half-word, byte-by-byte from destination |
| 472 | address and save it in tmp space */ | 474 | address and save it in tmp space */ |
| 473 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); | 475 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); |
| 474 | lbui r5, r4, 1; | 476 | lbui r5, r3, 1; |
| 475 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); | 477 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); |
| 476 | /* Get the destination register value into r3 */ | 478 | /* Get the destination register value into r4 */ |
| 477 | lhui r3, r0, TOPHYS(ex_tmp_data_loc_0); | 479 | lhui r4, r0, TOPHYS(ex_tmp_data_loc_0); |
| 478 | ex_lw_tail: | 480 | ex_lw_tail: |
| 479 | /* Get the destination register number into r5 */ | 481 | /* Get the destination register number into r5 */ |
| 480 | lbui r5, r0, TOPHYS(ex_reg_op); | 482 | lbui r5, r0, TOPHYS(ex_reg_op); |
| @@ -502,25 +504,25 @@ ex_sw_tail: | |||
| 502 | andi r6, r6, 0x800; /* Extract ESR[W] */ | 504 | andi r6, r6, 0x800; /* Extract ESR[W] */ |
| 503 | beqi r6, ex_shw; | 505 | beqi r6, ex_shw; |
| 504 | /* Get the word - delay slot */ | 506 | /* Get the word - delay slot */ |
| 505 | swi r3, r0, TOPHYS(ex_tmp_data_loc_0); | 507 | swi r4, r0, TOPHYS(ex_tmp_data_loc_0); |
| 506 | /* Store the word, byte-by-byte into destination address */ | 508 | /* Store the word, byte-by-byte into destination address */ |
| 507 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_0); | 509 | lbui r4, r0, TOPHYS(ex_tmp_data_loc_0); |
| 508 | sbi r3, r4, 0; | 510 | sbi r4, r3, 0; |
| 509 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_1); | 511 | lbui r4, r0, TOPHYS(ex_tmp_data_loc_1); |
| 510 | sbi r3, r4, 1; | 512 | sbi r4, r3, 1; |
| 511 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_2); | 513 | lbui r4, r0, TOPHYS(ex_tmp_data_loc_2); |
| 512 | sbi r3, r4, 2; | 514 | sbi r4, r3, 2; |
| 513 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_3); | 515 | lbui r4, r0, TOPHYS(ex_tmp_data_loc_3); |
| 514 | sbi r3, r4, 3; | 516 | sbi r4, r3, 3; |
| 515 | bri ex_handler_done; | 517 | bri ex_handler_done; |
| 516 | 518 | ||
| 517 | ex_shw: | 519 | ex_shw: |
| 518 | /* Store the lower half-word, byte-by-byte into destination address */ | 520 | /* Store the lower half-word, byte-by-byte into destination address */ |
| 519 | swi r3, r0, TOPHYS(ex_tmp_data_loc_0); | 521 | swi r4, r0, TOPHYS(ex_tmp_data_loc_0); |
| 520 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_2); | 522 | lbui r4, r0, TOPHYS(ex_tmp_data_loc_2); |
| 521 | sbi r3, r4, 0; | 523 | sbi r4, r3, 0; |
| 522 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_3); | 524 | lbui r4, r0, TOPHYS(ex_tmp_data_loc_3); |
| 523 | sbi r3, r4, 1; | 525 | sbi r4, r3, 1; |
| 524 | ex_sw_end: /* Exception handling of store word, ends. */ | 526 | ex_sw_end: /* Exception handling of store word, ends. */ |
| 525 | 527 | ||
| 526 | ex_handler_done: | 528 | ex_handler_done: |
| @@ -560,21 +562,16 @@ ex_handler_done: | |||
| 560 | */ | 562 | */ |
| 561 | mfs r11, rpid | 563 | mfs r11, rpid |
| 562 | nop | 564 | nop |
| 563 | bri 4 | ||
| 564 | mfs r3, rear /* Get faulting address */ | ||
| 565 | nop | ||
| 566 | /* If we are faulting a kernel address, we have to use the | 565 | /* If we are faulting a kernel address, we have to use the |
| 567 | * kernel page tables. | 566 | * kernel page tables. |
| 568 | */ | 567 | */ |
| 569 | ori r4, r0, CONFIG_KERNEL_START | 568 | ori r5, r0, CONFIG_KERNEL_START |
| 570 | cmpu r4, r3, r4 | 569 | cmpu r5, r3, r5 |
| 571 | bgti r4, ex3 | 570 | bgti r5, ex3 |
| 572 | /* First, check if it was a zone fault (which means a user | 571 | /* First, check if it was a zone fault (which means a user |
| 573 | * tried to access a kernel or read-protected page - always | 572 | * tried to access a kernel or read-protected page - always |
| 574 | * a SEGV). All other faults here must be stores, so no | 573 | * a SEGV). All other faults here must be stores, so no |
| 575 | * need to check ESR_S as well. */ | 574 | * need to check ESR_S as well. */ |
| 576 | mfs r4, resr | ||
| 577 | nop | ||
| 578 | andi r4, r4, 0x800 /* ESR_Z - zone protection */ | 575 | andi r4, r4, 0x800 /* ESR_Z - zone protection */ |
| 579 | bnei r4, ex2 | 576 | bnei r4, ex2 |
| 580 | 577 | ||
| @@ -589,8 +586,6 @@ ex_handler_done: | |||
| 589 | * tried to access a kernel or read-protected page - always | 586 | * tried to access a kernel or read-protected page - always |
| 590 | * a SEGV). All other faults here must be stores, so no | 587 | * a SEGV). All other faults here must be stores, so no |
| 591 | * need to check ESR_S as well. */ | 588 | * need to check ESR_S as well. */ |
| 592 | mfs r4, resr | ||
| 593 | nop | ||
| 594 | andi r4, r4, 0x800 /* ESR_Z */ | 589 | andi r4, r4, 0x800 /* ESR_Z */ |
| 595 | bnei r4, ex2 | 590 | bnei r4, ex2 |
| 596 | /* get current task address */ | 591 | /* get current task address */ |
| @@ -665,8 +660,6 @@ ex_handler_done: | |||
| 665 | * R3 = ESR | 660 | * R3 = ESR |
| 666 | */ | 661 | */ |
| 667 | 662 | ||
| 668 | mfs r3, rear /* Get faulting address */ | ||
| 669 | nop | ||
| 670 | RESTORE_STATE; | 663 | RESTORE_STATE; |
| 671 | bri page_fault_instr_trap | 664 | bri page_fault_instr_trap |
| 672 | 665 | ||
| @@ -677,18 +670,15 @@ ex_handler_done: | |||
| 677 | */ | 670 | */ |
| 678 | handle_data_tlb_miss_exception: | 671 | handle_data_tlb_miss_exception: |
| 679 | /* Working registers already saved: R3, R4, R5, R6 | 672 | /* Working registers already saved: R3, R4, R5, R6 |
| 680 | * R3 = ESR | 673 | * R3 = EAR, R4 = ESR |
| 681 | */ | 674 | */ |
| 682 | mfs r11, rpid | 675 | mfs r11, rpid |
| 683 | nop | 676 | nop |
| 684 | bri 4 | ||
| 685 | mfs r3, rear /* Get faulting address */ | ||
| 686 | nop | ||
| 687 | 677 | ||
| 688 | /* If we are faulting a kernel address, we have to use the | 678 | /* If we are faulting a kernel address, we have to use the |
| 689 | * kernel page tables. */ | 679 | * kernel page tables. */ |
| 690 | ori r4, r0, CONFIG_KERNEL_START | 680 | ori r6, r0, CONFIG_KERNEL_START |
| 691 | cmpu r4, r3, r4 | 681 | cmpu r4, r3, r6 |
| 692 | bgti r4, ex5 | 682 | bgti r4, ex5 |
| 693 | ori r4, r0, swapper_pg_dir | 683 | ori r4, r0, swapper_pg_dir |
| 694 | mts rpid, r0 /* TLB will have 0 TID */ | 684 | mts rpid, r0 /* TLB will have 0 TID */ |
| @@ -731,9 +721,8 @@ ex_handler_done: | |||
| 731 | * Many of these bits are software only. Bits we don't set | 721 | * Many of these bits are software only. Bits we don't set |
| 732 | * here we (properly should) assume have the appropriate value. | 722 | * here we (properly should) assume have the appropriate value. |
| 733 | */ | 723 | */ |
| 724 | brid finish_tlb_load | ||
| 734 | andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */ | 725 | andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */ |
| 735 | |||
| 736 | bri finish_tlb_load | ||
| 737 | ex7: | 726 | ex7: |
| 738 | /* The bailout. Restore registers to pre-exception conditions | 727 | /* The bailout. Restore registers to pre-exception conditions |
| 739 | * and call the heavyweights to help us out. | 728 | * and call the heavyweights to help us out. |
| @@ -754,9 +743,6 @@ ex_handler_done: | |||
| 754 | */ | 743 | */ |
| 755 | mfs r11, rpid | 744 | mfs r11, rpid |
| 756 | nop | 745 | nop |
| 757 | bri 4 | ||
| 758 | mfs r3, rear /* Get faulting address */ | ||
| 759 | nop | ||
| 760 | 746 | ||
| 761 | /* If we are faulting a kernel address, we have to use the | 747 | /* If we are faulting a kernel address, we have to use the |
| 762 | * kernel page tables. | 748 | * kernel page tables. |
| @@ -792,7 +778,7 @@ ex_handler_done: | |||
| 792 | lwi r4, r5, 0 /* Get Linux PTE */ | 778 | lwi r4, r5, 0 /* Get Linux PTE */ |
| 793 | 779 | ||
| 794 | andi r6, r4, _PAGE_PRESENT | 780 | andi r6, r4, _PAGE_PRESENT |
| 795 | beqi r6, ex7 | 781 | beqi r6, ex10 |
| 796 | 782 | ||
| 797 | ori r4, r4, _PAGE_ACCESSED | 783 | ori r4, r4, _PAGE_ACCESSED |
| 798 | swi r4, r5, 0 | 784 | swi r4, r5, 0 |
| @@ -805,9 +791,8 @@ ex_handler_done: | |||
| 805 | * Many of these bits are software only. Bits we don't set | 791 | * Many of these bits are software only. Bits we don't set |
| 806 | * here we (properly should) assume have the appropriate value. | 792 | * here we (properly should) assume have the appropriate value. |
| 807 | */ | 793 | */ |
| 794 | brid finish_tlb_load | ||
| 808 | andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */ | 795 | andni r4, r4, 0x0ce2 /* Make sure 20, 21 are zero */ |
| 809 | |||
| 810 | bri finish_tlb_load | ||
| 811 | ex10: | 796 | ex10: |
| 812 | /* The bailout. Restore registers to pre-exception conditions | 797 | /* The bailout. Restore registers to pre-exception conditions |
| 813 | * and call the heavyweights to help us out. | 798 | * and call the heavyweights to help us out. |
| @@ -837,9 +822,9 @@ ex_handler_done: | |||
| 837 | andi r5, r5, (MICROBLAZE_TLB_SIZE-1) | 822 | andi r5, r5, (MICROBLAZE_TLB_SIZE-1) |
| 838 | ori r6, r0, 1 | 823 | ori r6, r0, 1 |
| 839 | cmp r31, r5, r6 | 824 | cmp r31, r5, r6 |
| 840 | blti r31, sem | 825 | blti r31, ex12 |
| 841 | addik r5, r6, 1 | 826 | addik r5, r6, 1 |
| 842 | sem: | 827 | ex12: |
| 843 | /* MS: save back current TLB index */ | 828 | /* MS: save back current TLB index */ |
| 844 | swi r5, r0, TOPHYS(tlb_index) | 829 | swi r5, r0, TOPHYS(tlb_index) |
| 845 | 830 | ||
| @@ -859,7 +844,6 @@ ex_handler_done: | |||
| 859 | nop | 844 | nop |
| 860 | 845 | ||
| 861 | /* Done...restore registers and get out of here. */ | 846 | /* Done...restore registers and get out of here. */ |
| 862 | ex12: | ||
| 863 | mts rpid, r11 | 847 | mts rpid, r11 |
| 864 | nop | 848 | nop |
| 865 | bri 4 | 849 | bri 4 |
diff --git a/arch/microblaze/kernel/misc.S b/arch/microblaze/kernel/misc.S index df16c6287a8e..7cf86498326c 100644 --- a/arch/microblaze/kernel/misc.S +++ b/arch/microblaze/kernel/misc.S | |||
| @@ -26,9 +26,10 @@ | |||
| 26 | * We avoid flushing the pinned 0, 1 and possibly 2 entries. | 26 | * We avoid flushing the pinned 0, 1 and possibly 2 entries. |
| 27 | */ | 27 | */ |
| 28 | .globl _tlbia; | 28 | .globl _tlbia; |
| 29 | .type _tlbia, @function | ||
| 29 | .align 4; | 30 | .align 4; |
| 30 | _tlbia: | 31 | _tlbia: |
| 31 | addik r12, r0, 63 /* flush all entries (63 - 3) */ | 32 | addik r12, r0, MICROBLAZE_TLB_SIZE - 1 /* flush all entries (63 - 3) */ |
| 32 | /* isync */ | 33 | /* isync */ |
| 33 | _tlbia_1: | 34 | _tlbia_1: |
| 34 | mts rtlbx, r12 | 35 | mts rtlbx, r12 |
| @@ -41,11 +42,13 @@ _tlbia_1: | |||
| 41 | /* sync */ | 42 | /* sync */ |
| 42 | rtsd r15, 8 | 43 | rtsd r15, 8 |
| 43 | nop | 44 | nop |
| 45 | .size _tlbia, . - _tlbia | ||
| 44 | 46 | ||
| 45 | /* | 47 | /* |
| 46 | * Flush MMU TLB for a particular address (in r5) | 48 | * Flush MMU TLB for a particular address (in r5) |
| 47 | */ | 49 | */ |
| 48 | .globl _tlbie; | 50 | .globl _tlbie; |
| 51 | .type _tlbie, @function | ||
| 49 | .align 4; | 52 | .align 4; |
| 50 | _tlbie: | 53 | _tlbie: |
| 51 | mts rtlbsx, r5 /* look up the address in TLB */ | 54 | mts rtlbsx, r5 /* look up the address in TLB */ |
| @@ -59,17 +62,20 @@ _tlbie_1: | |||
| 59 | rtsd r15, 8 | 62 | rtsd r15, 8 |
| 60 | nop | 63 | nop |
| 61 | 64 | ||
| 65 | .size _tlbie, . - _tlbie | ||
| 66 | |||
| 62 | /* | 67 | /* |
| 63 | * Allocate TLB entry for early console | 68 | * Allocate TLB entry for early console |
| 64 | */ | 69 | */ |
| 65 | .globl early_console_reg_tlb_alloc; | 70 | .globl early_console_reg_tlb_alloc; |
| 71 | .type early_console_reg_tlb_alloc, @function | ||
| 66 | .align 4; | 72 | .align 4; |
| 67 | early_console_reg_tlb_alloc: | 73 | early_console_reg_tlb_alloc: |
| 68 | /* | 74 | /* |
| 69 | * Load a TLB entry for the UART, so that microblaze_progress() can use | 75 | * Load a TLB entry for the UART, so that microblaze_progress() can use |
| 70 | * the UARTs nice and early. We use a 4k real==virtual mapping. | 76 | * the UARTs nice and early. We use a 4k real==virtual mapping. |
| 71 | */ | 77 | */ |
| 72 | ori r4, r0, 63 | 78 | ori r4, r0, MICROBLAZE_TLB_SIZE - 1 |
| 73 | mts rtlbx, r4 /* TLB slot 2 */ | 79 | mts rtlbx, r4 /* TLB slot 2 */ |
| 74 | 80 | ||
| 75 | or r4,r5,r0 | 81 | or r4,r5,r0 |
| @@ -86,6 +92,8 @@ early_console_reg_tlb_alloc: | |||
| 86 | rtsd r15, 8 | 92 | rtsd r15, 8 |
| 87 | nop | 93 | nop |
| 88 | 94 | ||
| 95 | .size early_console_reg_tlb_alloc, . - early_console_reg_tlb_alloc | ||
| 96 | |||
| 89 | /* | 97 | /* |
| 90 | * Copy a whole page (4096 bytes). | 98 | * Copy a whole page (4096 bytes). |
| 91 | */ | 99 | */ |
| @@ -104,6 +112,7 @@ early_console_reg_tlb_alloc: | |||
| 104 | #define DCACHE_LINE_BYTES (4 * 4) | 112 | #define DCACHE_LINE_BYTES (4 * 4) |
| 105 | 113 | ||
| 106 | .globl copy_page; | 114 | .globl copy_page; |
| 115 | .type copy_page, @function | ||
| 107 | .align 4; | 116 | .align 4; |
| 108 | copy_page: | 117 | copy_page: |
| 109 | ori r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1 | 118 | ori r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1 |
| @@ -118,3 +127,5 @@ _copy_page_loop: | |||
| 118 | addik r11, r11, -1 | 127 | addik r11, r11, -1 |
| 119 | rtsd r15, 8 | 128 | rtsd r15, 8 |
| 120 | nop | 129 | nop |
| 130 | |||
| 131 | .size copy_page, . - copy_page | ||
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c index 812f1bf06c9e..09bed44dfcd3 100644 --- a/arch/microblaze/kernel/process.c +++ b/arch/microblaze/kernel/process.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
| 16 | #include <asm/system.h> | 16 | #include <asm/system.h> |
| 17 | #include <asm/pgalloc.h> | 17 | #include <asm/pgalloc.h> |
| 18 | #include <asm/uaccess.h> /* for USER_DS macros */ | ||
| 18 | #include <asm/cacheflush.h> | 19 | #include <asm/cacheflush.h> |
| 19 | 20 | ||
| 20 | void show_regs(struct pt_regs *regs) | 21 | void show_regs(struct pt_regs *regs) |
| @@ -74,7 +75,10 @@ __setup("hlt", hlt_setup); | |||
| 74 | 75 | ||
| 75 | void default_idle(void) | 76 | void default_idle(void) |
| 76 | { | 77 | { |
| 77 | if (!hlt_counter) { | 78 | if (likely(hlt_counter)) { |
| 79 | while (!need_resched()) | ||
| 80 | cpu_relax(); | ||
| 81 | } else { | ||
| 78 | clear_thread_flag(TIF_POLLING_NRFLAG); | 82 | clear_thread_flag(TIF_POLLING_NRFLAG); |
| 79 | smp_mb__after_clear_bit(); | 83 | smp_mb__after_clear_bit(); |
| 80 | local_irq_disable(); | 84 | local_irq_disable(); |
| @@ -82,9 +86,7 @@ void default_idle(void) | |||
| 82 | cpu_sleep(); | 86 | cpu_sleep(); |
| 83 | local_irq_enable(); | 87 | local_irq_enable(); |
| 84 | set_thread_flag(TIF_POLLING_NRFLAG); | 88 | set_thread_flag(TIF_POLLING_NRFLAG); |
| 85 | } else | 89 | } |
| 86 | while (!need_resched()) | ||
| 87 | cpu_relax(); | ||
| 88 | } | 90 | } |
| 89 | 91 | ||
| 90 | void cpu_idle(void) | 92 | void cpu_idle(void) |
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index f974ec7aa357..17c98dbcec88 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c | |||
| @@ -92,6 +92,12 @@ inline unsigned get_romfs_len(unsigned *addr) | |||
| 92 | } | 92 | } |
| 93 | #endif /* CONFIG_MTD_UCLINUX_EBSS */ | 93 | #endif /* CONFIG_MTD_UCLINUX_EBSS */ |
| 94 | 94 | ||
| 95 | #if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE) | ||
| 96 | #define eprintk early_printk | ||
| 97 | #else | ||
| 98 | #define eprintk printk | ||
| 99 | #endif | ||
| 100 | |||
| 95 | void __init machine_early_init(const char *cmdline, unsigned int ram, | 101 | void __init machine_early_init(const char *cmdline, unsigned int ram, |
| 96 | unsigned int fdt, unsigned int msr) | 102 | unsigned int fdt, unsigned int msr) |
| 97 | { | 103 | { |
| @@ -139,32 +145,32 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, | |||
| 139 | setup_early_printk(NULL); | 145 | setup_early_printk(NULL); |
| 140 | #endif | 146 | #endif |
| 141 | 147 | ||
| 142 | early_printk("Ramdisk addr 0x%08x, ", ram); | 148 | eprintk("Ramdisk addr 0x%08x, ", ram); |
| 143 | if (fdt) | 149 | if (fdt) |
| 144 | early_printk("FDT at 0x%08x\n", fdt); | 150 | eprintk("FDT at 0x%08x\n", fdt); |
| 145 | else | 151 | else |
| 146 | early_printk("Compiled-in FDT at 0x%08x\n", | 152 | eprintk("Compiled-in FDT at 0x%08x\n", |
| 147 | (unsigned int)_fdt_start); | 153 | (unsigned int)_fdt_start); |
| 148 | 154 | ||
| 149 | #ifdef CONFIG_MTD_UCLINUX | 155 | #ifdef CONFIG_MTD_UCLINUX |
| 150 | early_printk("Found romfs @ 0x%08x (0x%08x)\n", | 156 | eprintk("Found romfs @ 0x%08x (0x%08x)\n", |
| 151 | romfs_base, romfs_size); | 157 | romfs_base, romfs_size); |
| 152 | early_printk("#### klimit %p ####\n", old_klimit); | 158 | eprintk("#### klimit %p ####\n", old_klimit); |
| 153 | BUG_ON(romfs_size < 0); /* What else can we do? */ | 159 | BUG_ON(romfs_size < 0); /* What else can we do? */ |
| 154 | 160 | ||
| 155 | early_printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n", | 161 | eprintk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n", |
| 156 | romfs_size, romfs_base, (unsigned)&_ebss); | 162 | romfs_size, romfs_base, (unsigned)&_ebss); |
| 157 | 163 | ||
| 158 | early_printk("New klimit: 0x%08x\n", (unsigned)klimit); | 164 | eprintk("New klimit: 0x%08x\n", (unsigned)klimit); |
| 159 | #endif | 165 | #endif |
| 160 | 166 | ||
| 161 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | 167 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR |
| 162 | if (msr) | 168 | if (msr) |
| 163 | early_printk("!!!Your kernel has setup MSR instruction but " | 169 | eprintk("!!!Your kernel has setup MSR instruction but " |
| 164 | "CPU don't have it %d\n", msr); | 170 | "CPU don't have it %d\n", msr); |
| 165 | #else | 171 | #else |
| 166 | if (!msr) | 172 | if (!msr) |
| 167 | early_printk("!!!Your kernel not setup MSR instruction but " | 173 | eprintk("!!!Your kernel not setup MSR instruction but " |
| 168 | "CPU have it %d\n", msr); | 174 | "CPU have it %d\n", msr); |
| 169 | #endif | 175 | #endif |
| 170 | 176 | ||
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c index eaaaf805f31b..5e4570ef515c 100644 --- a/arch/microblaze/kernel/traps.c +++ b/arch/microblaze/kernel/traps.c | |||
| @@ -22,13 +22,11 @@ void trap_init(void) | |||
| 22 | __enable_hw_exceptions(); | 22 | __enable_hw_exceptions(); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | static int kstack_depth_to_print = 24; | 25 | static unsigned long kstack_depth_to_print = 24; |
| 26 | 26 | ||
| 27 | static int __init kstack_setup(char *s) | 27 | static int __init kstack_setup(char *s) |
| 28 | { | 28 | { |
| 29 | kstack_depth_to_print = strict_strtoul(s, 0, NULL); | 29 | return !strict_strtoul(s, 0, &kstack_depth_to_print); |
| 30 | |||
| 31 | return 1; | ||
| 32 | } | 30 | } |
| 33 | __setup("kstack=", kstack_setup); | 31 | __setup("kstack=", kstack_setup); |
| 34 | 32 | ||
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index b579db068c06..4dfe47d3cd91 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile | |||
| @@ -10,5 +10,4 @@ else | |||
| 10 | lib-y += memcpy.o memmove.o | 10 | lib-y += memcpy.o memmove.o |
| 11 | endif | 11 | endif |
| 12 | 12 | ||
| 13 | lib-$(CONFIG_NO_MMU) += uaccess.o | 13 | lib-y += uaccess_old.o |
| 14 | lib-$(CONFIG_MMU) += uaccess_old.o | ||
diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S index 02e3ab4eddf3..fdc48bb065d8 100644 --- a/arch/microblaze/lib/fastcopy.S +++ b/arch/microblaze/lib/fastcopy.S | |||
| @@ -30,8 +30,9 @@ | |||
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #include <linux/linkage.h> | 32 | #include <linux/linkage.h> |
| 33 | 33 | .text | |
| 34 | .globl memcpy | 34 | .globl memcpy |
| 35 | .type memcpy, @function | ||
| 35 | .ent memcpy | 36 | .ent memcpy |
| 36 | 37 | ||
| 37 | memcpy: | 38 | memcpy: |
| @@ -345,9 +346,11 @@ a_done: | |||
| 345 | rtsd r15, 8 | 346 | rtsd r15, 8 |
| 346 | nop | 347 | nop |
| 347 | 348 | ||
| 349 | .size memcpy, . - memcpy | ||
| 348 | .end memcpy | 350 | .end memcpy |
| 349 | /*----------------------------------------------------------------------------*/ | 351 | /*----------------------------------------------------------------------------*/ |
| 350 | .globl memmove | 352 | .globl memmove |
| 353 | .type memmove, @function | ||
| 351 | .ent memmove | 354 | .ent memmove |
| 352 | 355 | ||
| 353 | memmove: | 356 | memmove: |
| @@ -659,4 +662,5 @@ d_done: | |||
| 659 | rtsd r15, 8 | 662 | rtsd r15, 8 |
| 660 | nop | 663 | nop |
| 661 | 664 | ||
| 665 | .size memmove, . - memmove | ||
| 662 | .end memmove | 666 | .end memmove |
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c index cc2108b6b260..014bac92bdff 100644 --- a/arch/microblaze/lib/memcpy.c +++ b/arch/microblaze/lib/memcpy.c | |||
| @@ -53,7 +53,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) | |||
| 53 | const uint32_t *i_src; | 53 | const uint32_t *i_src; |
| 54 | uint32_t *i_dst; | 54 | uint32_t *i_dst; |
| 55 | 55 | ||
| 56 | if (c >= 4) { | 56 | if (likely(c >= 4)) { |
| 57 | unsigned value, buf_hold; | 57 | unsigned value, buf_hold; |
| 58 | 58 | ||
| 59 | /* Align the dstination to a word boundry. */ | 59 | /* Align the dstination to a word boundry. */ |
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c index 4df851d41a29..ecfb663e1fc1 100644 --- a/arch/microblaze/lib/memset.c +++ b/arch/microblaze/lib/memset.c | |||
| @@ -33,22 +33,23 @@ | |||
| 33 | #ifdef __HAVE_ARCH_MEMSET | 33 | #ifdef __HAVE_ARCH_MEMSET |
| 34 | void *memset(void *v_src, int c, __kernel_size_t n) | 34 | void *memset(void *v_src, int c, __kernel_size_t n) |
| 35 | { | 35 | { |
| 36 | |||
| 37 | char *src = v_src; | 36 | char *src = v_src; |
| 38 | #ifdef CONFIG_OPT_LIB_FUNCTION | 37 | #ifdef CONFIG_OPT_LIB_FUNCTION |
| 39 | uint32_t *i_src; | 38 | uint32_t *i_src; |
| 40 | uint32_t w32; | 39 | uint32_t w32 = 0; |
| 41 | #endif | 40 | #endif |
| 42 | /* Truncate c to 8 bits */ | 41 | /* Truncate c to 8 bits */ |
| 43 | c = (c & 0xFF); | 42 | c = (c & 0xFF); |
| 44 | 43 | ||
| 45 | #ifdef CONFIG_OPT_LIB_FUNCTION | 44 | #ifdef CONFIG_OPT_LIB_FUNCTION |
| 46 | /* Make a repeating word out of it */ | 45 | if (unlikely(c)) { |
| 47 | w32 = c; | 46 | /* Make a repeating word out of it */ |
| 48 | w32 |= w32 << 8; | 47 | w32 = c; |
| 49 | w32 |= w32 << 16; | 48 | w32 |= w32 << 8; |
| 49 | w32 |= w32 << 16; | ||
| 50 | } | ||
| 50 | 51 | ||
| 51 | if (n >= 4) { | 52 | if (likely(n >= 4)) { |
| 52 | /* Align the destination to a word boundary */ | 53 | /* Align the destination to a word boundary */ |
| 53 | /* This is done in an endian independant manner */ | 54 | /* This is done in an endian independant manner */ |
| 54 | switch ((unsigned) src & 3) { | 55 | switch ((unsigned) src & 3) { |
diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c deleted file mode 100644 index a853fe089c44..000000000000 --- a/arch/microblaze/lib/uaccess.c +++ /dev/null | |||
| @@ -1,48 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/string.h> | ||
| 10 | #include <asm/uaccess.h> | ||
| 11 | |||
| 12 | #include <asm/bug.h> | ||
| 13 | |||
| 14 | long strnlen_user(const char __user *src, long count) | ||
| 15 | { | ||
| 16 | return strlen(src) + 1; | ||
| 17 | } | ||
| 18 | |||
| 19 | #define __do_strncpy_from_user(dst, src, count, res) \ | ||
| 20 | do { \ | ||
| 21 | char *tmp; \ | ||
| 22 | strncpy(dst, src, count); \ | ||
| 23 | for (tmp = dst; *tmp && count > 0; tmp++, count--) \ | ||
| 24 | ; \ | ||
| 25 | res = (tmp - dst); \ | ||
| 26 | } while (0) | ||
| 27 | |||
| 28 | long __strncpy_from_user(char *dst, const char __user *src, long count) | ||
| 29 | { | ||
| 30 | long res; | ||
| 31 | __do_strncpy_from_user(dst, src, count, res); | ||
| 32 | return res; | ||
| 33 | } | ||
| 34 | |||
| 35 | long strncpy_from_user(char *dst, const char __user *src, long count) | ||
| 36 | { | ||
| 37 | long res = -EFAULT; | ||
| 38 | if (access_ok(VERIFY_READ, src, 1)) | ||
| 39 | __do_strncpy_from_user(dst, src, count, res); | ||
| 40 | return res; | ||
| 41 | } | ||
| 42 | |||
| 43 | unsigned long __copy_tofrom_user(void __user *to, | ||
| 44 | const void __user *from, unsigned long size) | ||
| 45 | { | ||
| 46 | memcpy(to, from, size); | ||
| 47 | return 0; | ||
| 48 | } | ||
diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S index 67f991c14b8a..5810cec54a7a 100644 --- a/arch/microblaze/lib/uaccess_old.S +++ b/arch/microblaze/lib/uaccess_old.S | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | .text | 23 | .text |
| 24 | .globl __strncpy_user; | 24 | .globl __strncpy_user; |
| 25 | .type __strncpy_user, @function | ||
| 25 | .align 4; | 26 | .align 4; |
| 26 | __strncpy_user: | 27 | __strncpy_user: |
| 27 | 28 | ||
| @@ -50,7 +51,7 @@ __strncpy_user: | |||
| 50 | 3: | 51 | 3: |
| 51 | rtsd r15,8 | 52 | rtsd r15,8 |
| 52 | nop | 53 | nop |
| 53 | 54 | .size __strncpy_user, . - __strncpy_user | |
| 54 | 55 | ||
| 55 | .section .fixup, "ax" | 56 | .section .fixup, "ax" |
| 56 | .align 2 | 57 | .align 2 |
| @@ -72,6 +73,7 @@ __strncpy_user: | |||
| 72 | 73 | ||
| 73 | .text | 74 | .text |
| 74 | .globl __strnlen_user; | 75 | .globl __strnlen_user; |
| 76 | .type __strnlen_user, @function | ||
| 75 | .align 4; | 77 | .align 4; |
| 76 | __strnlen_user: | 78 | __strnlen_user: |
| 77 | addik r3,r6,0 | 79 | addik r3,r6,0 |
| @@ -90,7 +92,7 @@ __strnlen_user: | |||
| 90 | 3: | 92 | 3: |
| 91 | rtsd r15,8 | 93 | rtsd r15,8 |
| 92 | nop | 94 | nop |
| 93 | 95 | .size __strnlen_user, . - __strnlen_user | |
| 94 | 96 | ||
| 95 | .section .fixup,"ax" | 97 | .section .fixup,"ax" |
| 96 | 4: | 98 | 4: |
| @@ -108,6 +110,7 @@ __strnlen_user: | |||
| 108 | */ | 110 | */ |
| 109 | .text | 111 | .text |
| 110 | .globl __copy_tofrom_user; | 112 | .globl __copy_tofrom_user; |
| 113 | .type __copy_tofrom_user, @function | ||
| 111 | .align 4; | 114 | .align 4; |
| 112 | __copy_tofrom_user: | 115 | __copy_tofrom_user: |
| 113 | /* | 116 | /* |
| @@ -116,20 +119,34 @@ __copy_tofrom_user: | |||
| 116 | * r7, r3 - count | 119 | * r7, r3 - count |
| 117 | * r4 - tempval | 120 | * r4 - tempval |
| 118 | */ | 121 | */ |
| 119 | addik r3,r7,0 | 122 | beqid r7, 3f /* zero size is not likely */ |
| 120 | beqi r3,3f | 123 | andi r3, r7, 0x3 /* filter add count */ |
| 121 | 1: | 124 | bneid r3, 4f /* if is odd value then byte copying */ |
| 122 | lbu r4,r6,r0 | 125 | or r3, r5, r6 /* find if is any to/from unaligned */ |
| 123 | addik r6,r6,1 | 126 | andi r3, r3, 0x3 /* mask unaligned */ |
| 124 | 2: | 127 | bneid r3, 1f /* it is unaligned -> then jump */ |
| 125 | sb r4,r5,r0 | 128 | or r3, r0, r0 |
| 126 | addik r3,r3,-1 | 129 | |
| 127 | bneid r3,1b | 130 | /* at least one 4 byte copy */ |
| 128 | addik r5,r5,1 /* delay slot */ | 131 | 5: lw r4, r6, r3 |
| 132 | 6: sw r4, r5, r3 | ||
| 133 | addik r7, r7, -4 | ||
| 134 | bneid r7, 5b | ||
| 135 | addik r3, r3, 4 | ||
| 136 | addik r3, r7, 0 | ||
| 137 | rtsd r15, 8 | ||
| 138 | nop | ||
| 139 | 4: or r3, r0, r0 | ||
| 140 | 1: lbu r4,r6,r3 | ||
| 141 | 2: sb r4,r5,r3 | ||
| 142 | addik r7,r7,-1 | ||
| 143 | bneid r7,1b | ||
| 144 | addik r3,r3,1 /* delay slot */ | ||
| 129 | 3: | 145 | 3: |
| 146 | addik r3,r7,0 | ||
| 130 | rtsd r15,8 | 147 | rtsd r15,8 |
| 131 | nop | 148 | nop |
| 132 | 149 | .size __copy_tofrom_user, . - __copy_tofrom_user | |
| 133 | 150 | ||
| 134 | .section __ex_table,"a" | 151 | .section __ex_table,"a" |
| 135 | .word 1b,3b,2b,3b | 152 | .word 1b,3b,2b,3b,5b,3b,6b,3b |
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c index d9d249a66ff2..7af87f4b2c2c 100644 --- a/arch/microblaze/mm/fault.c +++ b/arch/microblaze/mm/fault.c | |||
| @@ -106,7 +106,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, | |||
| 106 | regs->esr = error_code; | 106 | regs->esr = error_code; |
| 107 | 107 | ||
| 108 | /* On a kernel SLB miss we can only check for a valid exception entry */ | 108 | /* On a kernel SLB miss we can only check for a valid exception entry */ |
| 109 | if (kernel_mode(regs) && (address >= TASK_SIZE)) { | 109 | if (unlikely(kernel_mode(regs) && (address >= TASK_SIZE))) { |
| 110 | printk(KERN_WARNING "kernel task_size exceed"); | 110 | printk(KERN_WARNING "kernel task_size exceed"); |
| 111 | _exception(SIGSEGV, regs, code, address); | 111 | _exception(SIGSEGV, regs, code, address); |
| 112 | } | 112 | } |
| @@ -122,7 +122,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, | |||
| 122 | } | 122 | } |
| 123 | #endif /* CONFIG_KGDB */ | 123 | #endif /* CONFIG_KGDB */ |
| 124 | 124 | ||
| 125 | if (in_atomic() || !mm) { | 125 | if (unlikely(in_atomic() || !mm)) { |
| 126 | if (kernel_mode(regs)) | 126 | if (kernel_mode(regs)) |
| 127 | goto bad_area_nosemaphore; | 127 | goto bad_area_nosemaphore; |
| 128 | 128 | ||
| @@ -150,7 +150,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, | |||
| 150 | * source. If this is invalid we can skip the address space check, | 150 | * source. If this is invalid we can skip the address space check, |
| 151 | * thus avoiding the deadlock. | 151 | * thus avoiding the deadlock. |
| 152 | */ | 152 | */ |
| 153 | if (!down_read_trylock(&mm->mmap_sem)) { | 153 | if (unlikely(!down_read_trylock(&mm->mmap_sem))) { |
| 154 | if (kernel_mode(regs) && !search_exception_tables(regs->pc)) | 154 | if (kernel_mode(regs) && !search_exception_tables(regs->pc)) |
| 155 | goto bad_area_nosemaphore; | 155 | goto bad_area_nosemaphore; |
| 156 | 156 | ||
| @@ -158,16 +158,16 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, | |||
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | vma = find_vma(mm, address); | 160 | vma = find_vma(mm, address); |
| 161 | if (!vma) | 161 | if (unlikely(!vma)) |
| 162 | goto bad_area; | 162 | goto bad_area; |
| 163 | 163 | ||
| 164 | if (vma->vm_start <= address) | 164 | if (vma->vm_start <= address) |
| 165 | goto good_area; | 165 | goto good_area; |
| 166 | 166 | ||
| 167 | if (!(vma->vm_flags & VM_GROWSDOWN)) | 167 | if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) |
| 168 | goto bad_area; | 168 | goto bad_area; |
| 169 | 169 | ||
| 170 | if (!is_write) | 170 | if (unlikely(!is_write)) |
| 171 | goto bad_area; | 171 | goto bad_area; |
| 172 | 172 | ||
| 173 | /* | 173 | /* |
| @@ -179,7 +179,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, | |||
| 179 | * before setting the user r1. Thus we allow the stack to | 179 | * before setting the user r1. Thus we allow the stack to |
| 180 | * expand to 1MB without further checks. | 180 | * expand to 1MB without further checks. |
| 181 | */ | 181 | */ |
| 182 | if (address + 0x100000 < vma->vm_end) { | 182 | if (unlikely(address + 0x100000 < vma->vm_end)) { |
| 183 | 183 | ||
| 184 | /* get user regs even if this fault is in kernel mode */ | 184 | /* get user regs even if this fault is in kernel mode */ |
| 185 | struct pt_regs *uregs = current->thread.regs; | 185 | struct pt_regs *uregs = current->thread.regs; |
| @@ -209,15 +209,15 @@ good_area: | |||
| 209 | code = SEGV_ACCERR; | 209 | code = SEGV_ACCERR; |
| 210 | 210 | ||
| 211 | /* a write */ | 211 | /* a write */ |
| 212 | if (is_write) { | 212 | if (unlikely(is_write)) { |
| 213 | if (!(vma->vm_flags & VM_WRITE)) | 213 | if (unlikely(!(vma->vm_flags & VM_WRITE))) |
| 214 | goto bad_area; | 214 | goto bad_area; |
| 215 | /* a read */ | 215 | /* a read */ |
| 216 | } else { | 216 | } else { |
| 217 | /* protection fault */ | 217 | /* protection fault */ |
| 218 | if (error_code & 0x08000000) | 218 | if (unlikely(error_code & 0x08000000)) |
| 219 | goto bad_area; | 219 | goto bad_area; |
| 220 | if (!(vma->vm_flags & (VM_READ | VM_EXEC))) | 220 | if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC)))) |
| 221 | goto bad_area; | 221 | goto bad_area; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| @@ -235,7 +235,7 @@ survive: | |||
| 235 | goto do_sigbus; | 235 | goto do_sigbus; |
| 236 | BUG(); | 236 | BUG(); |
| 237 | } | 237 | } |
| 238 | if (fault & VM_FAULT_MAJOR) | 238 | if (unlikely(fault & VM_FAULT_MAJOR)) |
| 239 | current->maj_flt++; | 239 | current->maj_flt++; |
| 240 | else | 240 | else |
| 241 | current->min_flt++; | 241 | current->min_flt++; |
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index 1608e2e1a44a..40bc10ede097 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c | |||
| @@ -165,7 +165,6 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
| 165 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | 165 | for (addr = begin; addr < end; addr += PAGE_SIZE) { |
| 166 | ClearPageReserved(virt_to_page(addr)); | 166 | ClearPageReserved(virt_to_page(addr)); |
| 167 | init_page_count(virt_to_page(addr)); | 167 | init_page_count(virt_to_page(addr)); |
| 168 | memset((void *)addr, 0xcc, PAGE_SIZE); | ||
| 169 | free_page(addr); | 168 | free_page(addr); |
| 170 | totalram_pages++; | 169 | totalram_pages++; |
| 171 | } | 170 | } |
| @@ -208,14 +207,6 @@ void __init mem_init(void) | |||
| 208 | } | 207 | } |
| 209 | 208 | ||
| 210 | #ifndef CONFIG_MMU | 209 | #ifndef CONFIG_MMU |
| 211 | /* Check against bounds of physical memory */ | ||
| 212 | int ___range_ok(unsigned long addr, unsigned long size) | ||
| 213 | { | ||
| 214 | return ((addr < memory_start) || | ||
| 215 | ((addr + size) > memory_end)); | ||
| 216 | } | ||
| 217 | EXPORT_SYMBOL(___range_ok); | ||
| 218 | |||
| 219 | int page_is_ram(unsigned long pfn) | 210 | int page_is_ram(unsigned long pfn) |
| 220 | { | 211 | { |
| 221 | return __range_ok(pfn, 0); | 212 | return __range_ok(pfn, 0); |
diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c index 63a6fd07c48f..d31312cde6ea 100644 --- a/arch/microblaze/mm/pgtable.c +++ b/arch/microblaze/mm/pgtable.c | |||
| @@ -154,7 +154,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) | |||
| 154 | err = 0; | 154 | err = 0; |
| 155 | set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, | 155 | set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, |
| 156 | __pgprot(flags))); | 156 | __pgprot(flags))); |
| 157 | if (mem_init_done) | 157 | if (unlikely(mem_init_done)) |
| 158 | flush_HPTE(0, va, pmd_val(*pd)); | 158 | flush_HPTE(0, va, pmd_val(*pd)); |
| 159 | /* flush_HPTE(0, va, pg); */ | 159 | /* flush_HPTE(0, va, pg); */ |
| 160 | } | 160 | } |
