diff options
Diffstat (limited to 'arch/microblaze/include')
-rw-r--r-- | arch/microblaze/include/asm/cache.h | 2 | ||||
-rw-r--r-- | arch/microblaze/include/asm/dma.h | 6 | ||||
-rw-r--r-- | arch/microblaze/include/asm/exceptions.h | 6 | ||||
-rw-r--r-- | arch/microblaze/include/asm/futex.h | 2 | ||||
-rw-r--r-- | arch/microblaze/include/asm/io.h | 7 | ||||
-rw-r--r-- | arch/microblaze/include/asm/page.h | 12 | ||||
-rw-r--r-- | arch/microblaze/include/asm/pci.h | 8 | ||||
-rw-r--r-- | arch/microblaze/include/asm/pgalloc.h | 16 | ||||
-rw-r--r-- | arch/microblaze/include/asm/pgtable.h | 35 | ||||
-rw-r--r-- | arch/microblaze/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/microblaze/include/asm/segment.h | 49 | ||||
-rw-r--r-- | arch/microblaze/include/asm/thread_info.h | 5 | ||||
-rw-r--r-- | arch/microblaze/include/asm/tlbflush.h | 3 | ||||
-rw-r--r-- | arch/microblaze/include/asm/uaccess.h | 447 |
14 files changed, 269 insertions, 330 deletions
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h index e52210891d78..4efe96a036f7 100644 --- a/arch/microblaze/include/asm/cache.h +++ b/arch/microblaze/include/asm/cache.h | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #include <asm/registers.h> | 16 | #include <asm/registers.h> |
17 | 17 | ||
18 | #define L1_CACHE_SHIFT 2 | 18 | #define L1_CACHE_SHIFT 5 |
19 | /* word-granular cache in microblaze */ | 19 | /* word-granular cache in microblaze */ |
20 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | 20 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) |
21 | 21 | ||
diff --git a/arch/microblaze/include/asm/dma.h b/arch/microblaze/include/asm/dma.h index 08c073badf19..0d73d0c6de37 100644 --- a/arch/microblaze/include/asm/dma.h +++ b/arch/microblaze/include/asm/dma.h | |||
@@ -18,4 +18,10 @@ | |||
18 | #define MAX_DMA_ADDRESS (CONFIG_KERNEL_START + memory_size - 1) | 18 | #define MAX_DMA_ADDRESS (CONFIG_KERNEL_START + memory_size - 1) |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #ifdef CONFIG_PCI | ||
22 | extern int isa_dma_bridge_buggy; | ||
23 | #else | ||
24 | #define isa_dma_bridge_buggy (0) | ||
25 | #endif | ||
26 | |||
21 | #endif /* _ASM_MICROBLAZE_DMA_H */ | 27 | #endif /* _ASM_MICROBLAZE_DMA_H */ |
diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h index 90731df9e574..4c7b5d037c88 100644 --- a/arch/microblaze/include/asm/exceptions.h +++ b/arch/microblaze/include/asm/exceptions.h | |||
@@ -64,12 +64,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, | |||
64 | void die(const char *str, struct pt_regs *fp, long err); | 64 | void die(const char *str, struct pt_regs *fp, long err); |
65 | void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr); | 65 | void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr); |
66 | 66 | ||
67 | #ifdef CONFIG_MMU | ||
68 | void __bug(const char *file, int line, void *data); | ||
69 | int bad_trap(int trap_num, struct pt_regs *regs); | ||
70 | int debug_trap(struct pt_regs *regs); | ||
71 | #endif /* CONFIG_MMU */ | ||
72 | |||
73 | #if defined(CONFIG_KGDB) | 67 | #if defined(CONFIG_KGDB) |
74 | void (*debugger)(struct pt_regs *regs); | 68 | void (*debugger)(struct pt_regs *regs); |
75 | int (*debugger_bpt)(struct pt_regs *regs); | 69 | int (*debugger_bpt)(struct pt_regs *regs); |
diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h index 8dbb6e7a03a2..ad3fd61b2fe7 100644 --- a/arch/microblaze/include/asm/futex.h +++ b/arch/microblaze/include/asm/futex.h | |||
@@ -55,7 +55,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | |||
55 | __futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg); | 55 | __futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg); |
56 | break; | 56 | break; |
57 | case FUTEX_OP_ANDN: | 57 | case FUTEX_OP_ANDN: |
58 | __futex_atomic_op("and %1,%0,%4;", ret, oldval, uaddr, oparg); | 58 | __futex_atomic_op("andn %1,%0,%4;", ret, oldval, uaddr, oparg); |
59 | break; | 59 | break; |
60 | case FUTEX_OP_XOR: | 60 | case FUTEX_OP_XOR: |
61 | __futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg); | 61 | __futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg); |
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 32d621a56aee..00b5398d08c7 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h | |||
@@ -108,6 +108,11 @@ static inline void writel(unsigned int v, volatile void __iomem *addr) | |||
108 | #define iowrite16(v, addr) __raw_writew((u16)(v), (u16 *)(addr)) | 108 | #define iowrite16(v, addr) __raw_writew((u16)(v), (u16 *)(addr)) |
109 | #define iowrite32(v, addr) __raw_writel((u32)(v), (u32 *)(addr)) | 109 | #define iowrite32(v, addr) __raw_writel((u32)(v), (u32 *)(addr)) |
110 | 110 | ||
111 | #define ioread16be(addr) __raw_readw((u16 *)(addr)) | ||
112 | #define ioread32be(addr) __raw_readl((u32 *)(addr)) | ||
113 | #define iowrite16be(v, addr) __raw_writew((u16)(v), (u16 *)(addr)) | ||
114 | #define iowrite32be(v, addr) __raw_writel((u32)(v), (u32 *)(addr)) | ||
115 | |||
111 | /* These are the definitions for the x86 IO instructions | 116 | /* These are the definitions for the x86 IO instructions |
112 | * inb/inw/inl/outb/outw/outl, the "string" versions | 117 | * inb/inw/inl/outb/outw/outl, the "string" versions |
113 | * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions | 118 | * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions |
@@ -134,8 +139,6 @@ static inline void writel(unsigned int v, volatile void __iomem *addr) | |||
134 | 139 | ||
135 | #ifdef CONFIG_MMU | 140 | #ifdef CONFIG_MMU |
136 | 141 | ||
137 | #define mm_ptov(addr) ((void *)__phys_to_virt(addr)) | ||
138 | #define mm_vtop(addr) ((unsigned long)__virt_to_phys(addr)) | ||
139 | #define phys_to_virt(addr) ((void *)__phys_to_virt(addr)) | 142 | #define phys_to_virt(addr) ((void *)__phys_to_virt(addr)) |
140 | #define virt_to_phys(addr) ((unsigned long)__virt_to_phys(addr)) | 143 | #define virt_to_phys(addr) ((unsigned long)__virt_to_phys(addr)) |
141 | #define virt_to_bus(addr) ((unsigned long)__virt_to_phys(addr)) | 144 | #define virt_to_bus(addr) ((unsigned long)__virt_to_phys(addr)) |
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index 2dd1d04129e0..de493f86d28f 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h | |||
@@ -31,6 +31,9 @@ | |||
31 | 31 | ||
32 | #ifndef __ASSEMBLY__ | 32 | #ifndef __ASSEMBLY__ |
33 | 33 | ||
34 | /* MS be sure that SLAB allocates aligned objects */ | ||
35 | #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES | ||
36 | |||
34 | #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) | 37 | #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) |
35 | #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) | 38 | #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) |
36 | 39 | ||
@@ -70,14 +73,7 @@ typedef unsigned long pte_basic_t; | |||
70 | 73 | ||
71 | #endif /* CONFIG_MMU */ | 74 | #endif /* CONFIG_MMU */ |
72 | 75 | ||
73 | # ifndef CONFIG_MMU | 76 | # define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) |
74 | # define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) | ||
75 | # define get_user_page(vaddr) __get_free_page(GFP_KERNEL) | ||
76 | # define free_user_page(page, addr) free_page(addr) | ||
77 | # else /* CONFIG_MMU */ | ||
78 | extern void copy_page(void *to, void *from); | ||
79 | # endif /* CONFIG_MMU */ | ||
80 | |||
81 | # define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) | 77 | # define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) |
82 | 78 | ||
83 | # define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE) | 79 | # define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE) |
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index bdd65aaee30d..5a388eeeb28f 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h | |||
@@ -94,14 +94,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus, | |||
94 | 94 | ||
95 | #define HAVE_PCI_LEGACY 1 | 95 | #define HAVE_PCI_LEGACY 1 |
96 | 96 | ||
97 | /* pci_unmap_{page,single} is a nop so... */ | ||
98 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) | ||
99 | #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) | ||
100 | #define pci_unmap_addr(PTR, ADDR_NAME) (0) | ||
101 | #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) | ||
102 | #define pci_unmap_len(PTR, LEN_NAME) (0) | ||
103 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) | ||
104 | |||
105 | /* The PCI address space does equal the physical memory | 97 | /* The PCI address space does equal the physical memory |
106 | * address space (no IOMMU). The IDE and SCSI device layers use | 98 | * address space (no IOMMU). The IDE and SCSI device layers use |
107 | * this boolean for bounce buffer decisions. | 99 | * this boolean for bounce buffer decisions. |
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h index f44b0d696fe2..c614a893f8a3 100644 --- a/arch/microblaze/include/asm/pgalloc.h +++ b/arch/microblaze/include/asm/pgalloc.h | |||
@@ -108,21 +108,7 @@ extern inline void free_pgd_slow(pgd_t *pgd) | |||
108 | #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); }) | 108 | #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); }) |
109 | #define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); }) | 109 | #define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); }) |
110 | 110 | ||
111 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 111 | extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); |
112 | unsigned long address) | ||
113 | { | ||
114 | pte_t *pte; | ||
115 | extern void *early_get_page(void); | ||
116 | if (mem_init_done) { | ||
117 | pte = (pte_t *)__get_free_page(GFP_KERNEL | | ||
118 | __GFP_REPEAT | __GFP_ZERO); | ||
119 | } else { | ||
120 | pte = (pte_t *)early_get_page(); | ||
121 | if (pte) | ||
122 | clear_page(pte); | ||
123 | } | ||
124 | return pte; | ||
125 | } | ||
126 | 112 | ||
127 | static inline struct page *pte_alloc_one(struct mm_struct *mm, | 113 | static inline struct page *pte_alloc_one(struct mm_struct *mm, |
128 | unsigned long address) | 114 | unsigned long address) |
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index dd2bb60651c7..ca2d92871545 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h | |||
@@ -512,15 +512,6 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) | |||
512 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | 512 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
513 | 513 | ||
514 | /* | 514 | /* |
515 | * When flushing the tlb entry for a page, we also need to flush the hash | ||
516 | * table entry. flush_hash_page is assembler (for speed) in hashtable.S. | ||
517 | */ | ||
518 | extern int flush_hash_page(unsigned context, unsigned long va, pte_t *ptep); | ||
519 | |||
520 | /* Add an HPTE to the hash table */ | ||
521 | extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep); | ||
522 | |||
523 | /* | ||
524 | * Encode and decode a swap entry. | 515 | * Encode and decode a swap entry. |
525 | * Note that the bits we use in a PTE for representing a swap entry | 516 | * Note that the bits we use in a PTE for representing a swap entry |
526 | * must not include the _PAGE_PRESENT bit, or the _PAGE_HASHPTE bit | 517 | * must not include the _PAGE_PRESENT bit, or the _PAGE_HASHPTE bit |
@@ -533,15 +524,7 @@ extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep); | |||
533 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 2 }) | 524 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 2 }) |
534 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val << 2 }) | 525 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val << 2 }) |
535 | 526 | ||
536 | |||
537 | /* CONFIG_APUS */ | ||
538 | /* For virtual address to physical address conversion */ | ||
539 | extern void cache_clear(__u32 addr, int length); | ||
540 | extern void cache_push(__u32 addr, int length); | ||
541 | extern int mm_end_of_chunk(unsigned long addr, int len); | ||
542 | extern unsigned long iopa(unsigned long addr); | 527 | extern unsigned long iopa(unsigned long addr); |
543 | /* extern unsigned long mm_ptov(unsigned long addr) \ | ||
544 | __attribute__ ((const)); TBD */ | ||
545 | 528 | ||
546 | /* Values for nocacheflag and cmode */ | 529 | /* Values for nocacheflag and cmode */ |
547 | /* These are not used by the APUS kernel_map, but prevents | 530 | /* These are not used by the APUS kernel_map, but prevents |
@@ -552,18 +535,6 @@ extern unsigned long iopa(unsigned long addr); | |||
552 | #define IOMAP_NOCACHE_NONSER 2 | 535 | #define IOMAP_NOCACHE_NONSER 2 |
553 | #define IOMAP_NO_COPYBACK 3 | 536 | #define IOMAP_NO_COPYBACK 3 |
554 | 537 | ||
555 | /* | ||
556 | * Map some physical address range into the kernel address space. | ||
557 | */ | ||
558 | extern unsigned long kernel_map(unsigned long paddr, unsigned long size, | ||
559 | int nocacheflag, unsigned long *memavailp); | ||
560 | |||
561 | /* | ||
562 | * Set cache mode of (kernel space) address range. | ||
563 | */ | ||
564 | extern void kernel_set_cachemode(unsigned long address, unsigned long size, | ||
565 | unsigned int cmode); | ||
566 | |||
567 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | 538 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ |
568 | #define kern_addr_valid(addr) (1) | 539 | #define kern_addr_valid(addr) (1) |
569 | 540 | ||
@@ -577,10 +548,6 @@ extern void kernel_set_cachemode(unsigned long address, unsigned long size, | |||
577 | void do_page_fault(struct pt_regs *regs, unsigned long address, | 548 | void do_page_fault(struct pt_regs *regs, unsigned long address, |
578 | unsigned long error_code); | 549 | unsigned long error_code); |
579 | 550 | ||
580 | void __init io_block_mapping(unsigned long virt, phys_addr_t phys, | ||
581 | unsigned int size, int flags); | ||
582 | |||
583 | void __init adjust_total_lowmem(void); | ||
584 | void mapin_ram(void); | 551 | void mapin_ram(void); |
585 | int map_page(unsigned long va, phys_addr_t pa, int flags); | 552 | int map_page(unsigned long va, phys_addr_t pa, int flags); |
586 | 553 | ||
@@ -601,7 +568,7 @@ void __init *early_get_page(void); | |||
601 | extern unsigned long ioremap_bot, ioremap_base; | 568 | extern unsigned long ioremap_bot, ioremap_base; |
602 | 569 | ||
603 | void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle); | 570 | void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle); |
604 | void consistent_free(void *vaddr); | 571 | void consistent_free(size_t size, void *vaddr); |
605 | void consistent_sync(void *vaddr, size_t size, int direction); | 572 | void consistent_sync(void *vaddr, size_t size, int direction); |
606 | void consistent_sync_page(struct page *page, unsigned long offset, | 573 | void consistent_sync_page(struct page *page, unsigned long offset, |
607 | size_t size, int direction); | 574 | size_t size, int direction); |
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__ */ |