aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-06 21:05:10 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-06 21:05:10 -0500
commit1ba73b99c34c31ea18b44dcf161c6e1f2838e0fa (patch)
treeb0ce77589bdf5a860418181cf1704ba75d7fd415
parent185d84b4e1f6febebbe30d785fe31310dcf9632a (diff)
parentcee87af2a5f75713b98d3e65e43872e547122cd5 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6: [IA64] kexec: Use EFI_LOADER_DATA for ELF core header [IA64] permon use-after-free fix [IA64] sync compat getdents [IA64] always build arch/ia64/lib/xor.o [IA64] Remove stack hard limit on ia64 [IA64] point saved_max_pfn to the max_pfn of the entire system Revert "[IA64] swiotlb abstraction (e.g. for Xen)"
-rw-r--r--arch/ia64/ia32/sys_ia32.c10
-rw-r--r--arch/ia64/kernel/efi.c36
-rw-r--r--arch/ia64/kernel/perfmon.c11
-rw-r--r--arch/ia64/kernel/setup.c30
-rw-r--r--arch/ia64/lib/Makefile3
-rw-r--r--arch/ia64/mm/contig.c5
-rw-r--r--arch/ia64/mm/discontig.c6
-rw-r--r--include/asm-ia64/meminit.h6
-rw-r--r--include/asm-ia64/resource.h1
-rw-r--r--include/asm-ia64/swiotlb.h9
-rw-r--r--include/asm-x86_64/swiotlb.h1
-rw-r--r--lib/swiotlb.c184
12 files changed, 121 insertions, 181 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index d430d36ae49d..0afb4fe7c35b 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1267,6 +1267,10 @@ sys32_getdents (unsigned int fd, struct compat_dirent __user *dirent, unsigned i
1267 struct getdents32_callback buf; 1267 struct getdents32_callback buf;
1268 int error; 1268 int error;
1269 1269
1270 error = -EFAULT;
1271 if (!access_ok(VERIFY_WRITE, dirent, count))
1272 goto out;
1273
1270 error = -EBADF; 1274 error = -EBADF;
1271 file = fget(fd); 1275 file = fget(fd);
1272 if (!file) 1276 if (!file)
@@ -1283,10 +1287,10 @@ sys32_getdents (unsigned int fd, struct compat_dirent __user *dirent, unsigned i
1283 error = buf.error; 1287 error = buf.error;
1284 lastdirent = buf.previous; 1288 lastdirent = buf.previous;
1285 if (lastdirent) { 1289 if (lastdirent) {
1286 error = -EINVAL;
1287 if (put_user(file->f_pos, &lastdirent->d_off)) 1290 if (put_user(file->f_pos, &lastdirent->d_off))
1288 goto out_putf; 1291 error = -EFAULT;
1289 error = count - buf.count; 1292 else
1293 error = count - buf.count;
1290 } 1294 }
1291 1295
1292out_putf: 1296out_putf:
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 772ba6fe110f..4061593e5b17 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -21,6 +21,7 @@
21 * Skip non-WB memory and ignore empty memory ranges. 21 * Skip non-WB memory and ignore empty memory ranges.
22 */ 22 */
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/bootmem.h>
24#include <linux/kernel.h> 25#include <linux/kernel.h>
25#include <linux/init.h> 26#include <linux/init.h>
26#include <linux/types.h> 27#include <linux/types.h>
@@ -1009,6 +1010,11 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
1009 } else 1010 } else
1010 ae = efi_md_end(md); 1011 ae = efi_md_end(md);
1011 1012
1013#ifdef CONFIG_CRASH_DUMP
1014 /* saved_max_pfn should ignore max_addr= command line arg */
1015 if (saved_max_pfn < (ae >> PAGE_SHIFT))
1016 saved_max_pfn = (ae >> PAGE_SHIFT);
1017#endif
1012 /* keep within max_addr= and min_addr= command line arg */ 1018 /* keep within max_addr= and min_addr= command line arg */
1013 as = max(as, min_addr); 1019 as = max(as, min_addr);
1014 ae = min(ae, max_addr); 1020 ae = min(ae, max_addr);
@@ -1177,3 +1183,33 @@ kdump_find_rsvd_region (unsigned long size,
1177 return ~0UL; 1183 return ~0UL;
1178} 1184}
1179#endif 1185#endif
1186
1187#ifdef CONFIG_PROC_VMCORE
1188/* locate the size find a the descriptor at a certain address */
1189unsigned long
1190vmcore_find_descriptor_size (unsigned long address)
1191{
1192 void *efi_map_start, *efi_map_end, *p;
1193 efi_memory_desc_t *md;
1194 u64 efi_desc_size;
1195 unsigned long ret = 0;
1196
1197 efi_map_start = __va(ia64_boot_param->efi_memmap);
1198 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
1199 efi_desc_size = ia64_boot_param->efi_memdesc_size;
1200
1201 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
1202 md = p;
1203 if (efi_wb(md) && md->type == EFI_LOADER_DATA
1204 && md->phys_addr == address) {
1205 ret = efi_md_size(md);
1206 break;
1207 }
1208 }
1209
1210 if (ret == 0)
1211 printk(KERN_WARNING "Cannot locate EFI vmcore descriptor\n");
1212
1213 return ret;
1214}
1215#endif
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 9ddf896a137a..abc7ad035886 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2299,7 +2299,7 @@ pfm_remap_buffer(struct vm_area_struct *vma, unsigned long buf, unsigned long ad
2299 * allocate a sampling buffer and remaps it into the user address space of the task 2299 * allocate a sampling buffer and remaps it into the user address space of the task
2300 */ 2300 */
2301static int 2301static int
2302pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned long rsize, void **user_vaddr) 2302pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned long rsize, void **user_vaddr)
2303{ 2303{
2304 struct mm_struct *mm = task->mm; 2304 struct mm_struct *mm = task->mm;
2305 struct vm_area_struct *vma = NULL; 2305 struct vm_area_struct *vma = NULL;
@@ -2349,6 +2349,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon
2349 * partially initialize the vma for the sampling buffer 2349 * partially initialize the vma for the sampling buffer
2350 */ 2350 */
2351 vma->vm_mm = mm; 2351 vma->vm_mm = mm;
2352 vma->vm_file = filp;
2352 vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED; 2353 vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED;
2353 vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */ 2354 vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */
2354 2355
@@ -2387,6 +2388,8 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon
2387 goto error; 2388 goto error;
2388 } 2389 }
2389 2390
2391 get_file(filp);
2392
2390 /* 2393 /*
2391 * now insert the vma in the vm list for the process, must be 2394 * now insert the vma in the vm list for the process, must be
2392 * done with mmap lock held 2395 * done with mmap lock held
@@ -2464,7 +2467,7 @@ pfarg_is_sane(struct task_struct *task, pfarg_context_t *pfx)
2464} 2467}
2465 2468
2466static int 2469static int
2467pfm_setup_buffer_fmt(struct task_struct *task, pfm_context_t *ctx, unsigned int ctx_flags, 2470pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned int ctx_flags,
2468 unsigned int cpu, pfarg_context_t *arg) 2471 unsigned int cpu, pfarg_context_t *arg)
2469{ 2472{
2470 pfm_buffer_fmt_t *fmt = NULL; 2473 pfm_buffer_fmt_t *fmt = NULL;
@@ -2505,7 +2508,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, pfm_context_t *ctx, unsigned int
2505 /* 2508 /*
2506 * buffer is always remapped into the caller's address space 2509 * buffer is always remapped into the caller's address space
2507 */ 2510 */
2508 ret = pfm_smpl_buffer_alloc(current, ctx, size, &uaddr); 2511 ret = pfm_smpl_buffer_alloc(current, filp, ctx, size, &uaddr);
2509 if (ret) goto error; 2512 if (ret) goto error;
2510 2513
2511 /* keep track of user address of buffer */ 2514 /* keep track of user address of buffer */
@@ -2716,7 +2719,7 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
2716 * does the user want to sample? 2719 * does the user want to sample?
2717 */ 2720 */
2718 if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) { 2721 if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) {
2719 ret = pfm_setup_buffer_fmt(current, ctx, ctx_flags, 0, req); 2722 ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req);
2720 if (ret) goto buffer_error; 2723 if (ret) goto buffer_error;
2721 } 2724 }
2722 2725
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 5fa09d141ab7..7d6fe65c93f4 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -251,6 +251,12 @@ reserve_memory (void)
251 } 251 }
252#endif 252#endif
253 253
254#ifdef CONFIG_PROC_VMCORE
255 if (reserve_elfcorehdr(&rsvd_region[n].start,
256 &rsvd_region[n].end) == 0)
257 n++;
258#endif
259
254 efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); 260 efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
255 n++; 261 n++;
256 262
@@ -453,6 +459,30 @@ static int __init parse_elfcorehdr(char *arg)
453 return 0; 459 return 0;
454} 460}
455early_param("elfcorehdr", parse_elfcorehdr); 461early_param("elfcorehdr", parse_elfcorehdr);
462
463int __init reserve_elfcorehdr(unsigned long *start, unsigned long *end)
464{
465 unsigned long length;
466
467 /* We get the address using the kernel command line,
468 * but the size is extracted from the EFI tables.
469 * Both address and size are required for reservation
470 * to work properly.
471 */
472
473 if (elfcorehdr_addr >= ELFCORE_ADDR_MAX)
474 return -EINVAL;
475
476 if ((length = vmcore_find_descriptor_size(elfcorehdr_addr)) == 0) {
477 elfcorehdr_addr = ELFCORE_ADDR_MAX;
478 return -EINVAL;
479 }
480
481 *start = (unsigned long)__va(elfcorehdr_addr);
482 *end = *start + length;
483 return 0;
484}
485
456#endif /* CONFIG_PROC_VMCORE */ 486#endif /* CONFIG_PROC_VMCORE */
457 487
458void __init 488void __init
diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
index 38fa6e49e791..46edf8444c7e 100644
--- a/arch/ia64/lib/Makefile
+++ b/arch/ia64/lib/Makefile
@@ -9,12 +9,11 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
9 checksum.o clear_page.o csum_partial_copy.o \ 9 checksum.o clear_page.o csum_partial_copy.o \
10 clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ 10 clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \
11 flush.o ip_fast_csum.o do_csum.o \ 11 flush.o ip_fast_csum.o do_csum.o \
12 memset.o strlen.o 12 memset.o strlen.o xor.o
13 13
14lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o 14lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
15lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o 15lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
16lib-$(CONFIG_PERFMON) += carta_random.o 16lib-$(CONFIG_PERFMON) += carta_random.o
17lib-$(CONFIG_MD_RAID456) += xor.o
18 17
19AFLAGS___divdi3.o = 18AFLAGS___divdi3.o =
20AFLAGS___udivdi3.o = -DUNSIGNED 19AFLAGS___udivdi3.o = -DUNSIGNED
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index ca4d41e5f177..fb0f4698f5d0 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -197,11 +197,6 @@ find_memory (void)
197 197
198 find_initrd(); 198 find_initrd();
199 199
200#ifdef CONFIG_CRASH_DUMP
201 /* If we are doing a crash dump, we still need to know the real mem
202 * size before original memory map is reset. */
203 saved_max_pfn = max_pfn;
204#endif
205} 200}
206 201
207#ifdef CONFIG_SMP 202#ifdef CONFIG_SMP
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 16835108bb5b..11a2d8825d89 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -480,12 +480,6 @@ void __init find_memory(void)
480 max_pfn = max_low_pfn; 480 max_pfn = max_low_pfn;
481 481
482 find_initrd(); 482 find_initrd();
483
484#ifdef CONFIG_CRASH_DUMP
485 /* If we are doing a crash dump, we still need to know the real mem
486 * size before original memory map is reset. */
487 saved_max_pfn = max_pfn;
488#endif
489} 483}
490 484
491#ifdef CONFIG_SMP 485#ifdef CONFIG_SMP
diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
index 6dd476b652c6..21ec5f3d23de 100644
--- a/include/asm-ia64/meminit.h
+++ b/include/asm-ia64/meminit.h
@@ -17,10 +17,11 @@
17 * - kernel code & data 17 * - kernel code & data
18 * - crash dumping code reserved region 18 * - crash dumping code reserved region
19 * - Kernel memory map built from EFI memory map 19 * - Kernel memory map built from EFI memory map
20 * - ELF core header
20 * 21 *
21 * More could be added if necessary 22 * More could be added if necessary
22 */ 23 */
23#define IA64_MAX_RSVD_REGIONS 7 24#define IA64_MAX_RSVD_REGIONS 8
24 25
25struct rsvd_region { 26struct rsvd_region {
26 unsigned long start; /* virtual address of beginning of element */ 27 unsigned long start; /* virtual address of beginning of element */
@@ -36,6 +37,9 @@ extern void find_initrd (void);
36extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg); 37extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
37extern void efi_memmap_init(unsigned long *, unsigned long *); 38extern void efi_memmap_init(unsigned long *, unsigned long *);
38 39
40extern unsigned long vmcore_find_descriptor_size(unsigned long address);
41extern int reserve_elfcorehdr(unsigned long *start, unsigned long *end);
42
39/* 43/*
40 * For rounding an address to the next IA64_GRANULE_SIZE or order 44 * For rounding an address to the next IA64_GRANULE_SIZE or order
41 */ 45 */
diff --git a/include/asm-ia64/resource.h b/include/asm-ia64/resource.h
index 77b1eee01f30..ba2272a87fc7 100644
--- a/include/asm-ia64/resource.h
+++ b/include/asm-ia64/resource.h
@@ -2,7 +2,6 @@
2#define _ASM_IA64_RESOURCE_H 2#define _ASM_IA64_RESOURCE_H
3 3
4#include <asm/ustack.h> 4#include <asm/ustack.h>
5#define _STK_LIM_MAX DEFAULT_USER_STACK_SIZE
6#include <asm-generic/resource.h> 5#include <asm-generic/resource.h>
7 6
8#endif /* _ASM_IA64_RESOURCE_H */ 7#endif /* _ASM_IA64_RESOURCE_H */
diff --git a/include/asm-ia64/swiotlb.h b/include/asm-ia64/swiotlb.h
deleted file mode 100644
index 452c162dee4e..000000000000
--- a/include/asm-ia64/swiotlb.h
+++ /dev/null
@@ -1,9 +0,0 @@
1#ifndef _ASM_SWIOTLB_H
2#define _ASM_SWIOTLB_H 1
3
4#include <asm/machvec.h>
5
6#define SWIOTLB_ARCH_NEED_LATE_INIT
7#define SWIOTLB_ARCH_NEED_ALLOC
8
9#endif /* _ASM_SWIOTLB_H */
diff --git a/include/asm-x86_64/swiotlb.h b/include/asm-x86_64/swiotlb.h
index ab913ffcad56..f9c589539a82 100644
--- a/include/asm-x86_64/swiotlb.h
+++ b/include/asm-x86_64/swiotlb.h
@@ -44,7 +44,6 @@ extern void swiotlb_init(void);
44extern int swiotlb_force; 44extern int swiotlb_force;
45 45
46#ifdef CONFIG_SWIOTLB 46#ifdef CONFIG_SWIOTLB
47#define SWIOTLB_ARCH_NEED_ALLOC
48extern int swiotlb; 47extern int swiotlb;
49#else 48#else
50#define swiotlb 0 49#define swiotlb 0
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 623a68af8b18..9970e55c90bd 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -28,7 +28,6 @@
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/dma.h> 29#include <asm/dma.h>
30#include <asm/scatterlist.h> 30#include <asm/scatterlist.h>
31#include <asm/swiotlb.h>
32 31
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/bootmem.h> 33#include <linux/bootmem.h>
@@ -36,10 +35,8 @@
36#define OFFSET(val,align) ((unsigned long) \ 35#define OFFSET(val,align) ((unsigned long) \
37 ( (val) & ( (align) - 1))) 36 ( (val) & ( (align) - 1)))
38 37
39#ifndef SG_ENT_VIRT_ADDRESS
40#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset) 38#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset)
41#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) 39#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
42#endif
43 40
44/* 41/*
45 * Maximum allowable number of contiguous slabs to map, 42 * Maximum allowable number of contiguous slabs to map,
@@ -104,25 +101,13 @@ static unsigned int io_tlb_index;
104 * We need to save away the original address corresponding to a mapped entry 101 * We need to save away the original address corresponding to a mapped entry
105 * for the sync operations. 102 * for the sync operations.
106 */ 103 */
107#ifndef SWIOTLB_ARCH_HAS_IO_TLB_ADDR_T 104static unsigned char **io_tlb_orig_addr;
108typedef char *io_tlb_addr_t;
109#define swiotlb_orig_addr_null(buffer) (!(buffer))
110#define ptr_to_io_tlb_addr(ptr) (ptr)
111#define page_to_io_tlb_addr(pg, off) (page_address(pg) + (off))
112#define sg_to_io_tlb_addr(sg) SG_ENT_VIRT_ADDRESS(sg)
113#endif
114static io_tlb_addr_t *io_tlb_orig_addr;
115 105
116/* 106/*
117 * Protect the above data structures in the map and unmap calls 107 * Protect the above data structures in the map and unmap calls
118 */ 108 */
119static DEFINE_SPINLOCK(io_tlb_lock); 109static DEFINE_SPINLOCK(io_tlb_lock);
120 110
121#ifdef SWIOTLB_EXTRA_VARIABLES
122SWIOTLB_EXTRA_VARIABLES;
123#endif
124
125#ifndef SWIOTLB_ARCH_HAS_SETUP_IO_TLB_NPAGES
126static int __init 111static int __init
127setup_io_tlb_npages(char *str) 112setup_io_tlb_npages(char *str)
128{ 113{
@@ -137,25 +122,9 @@ setup_io_tlb_npages(char *str)
137 swiotlb_force = 1; 122 swiotlb_force = 1;
138 return 1; 123 return 1;
139} 124}
140#endif
141__setup("swiotlb=", setup_io_tlb_npages); 125__setup("swiotlb=", setup_io_tlb_npages);
142/* make io_tlb_overflow tunable too? */ 126/* make io_tlb_overflow tunable too? */
143 127
144#ifndef swiotlb_adjust_size
145#define swiotlb_adjust_size(size) ((void)0)
146#endif
147
148#ifndef swiotlb_adjust_seg
149#define swiotlb_adjust_seg(start, size) ((void)0)
150#endif
151
152#ifndef swiotlb_print_info
153#define swiotlb_print_info(bytes) \
154 printk(KERN_INFO "Placing %luMB software IO TLB between 0x%lx - " \
155 "0x%lx\n", bytes >> 20, \
156 virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end))
157#endif
158
159/* 128/*
160 * Statically reserve bounce buffer space and initialize bounce buffer data 129 * Statically reserve bounce buffer space and initialize bounce buffer data
161 * structures for the software IO TLB used to implement the DMA API. 130 * structures for the software IO TLB used to implement the DMA API.
@@ -169,8 +138,6 @@ swiotlb_init_with_default_size(size_t default_size)
169 io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); 138 io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
170 io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); 139 io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
171 } 140 }
172 swiotlb_adjust_size(io_tlb_nslabs);
173 swiotlb_adjust_size(io_tlb_overflow);
174 141
175 bytes = io_tlb_nslabs << IO_TLB_SHIFT; 142 bytes = io_tlb_nslabs << IO_TLB_SHIFT;
176 143
@@ -188,14 +155,10 @@ swiotlb_init_with_default_size(size_t default_size)
188 * between io_tlb_start and io_tlb_end. 155 * between io_tlb_start and io_tlb_end.
189 */ 156 */
190 io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); 157 io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int));
191 for (i = 0; i < io_tlb_nslabs; i++) { 158 for (i = 0; i < io_tlb_nslabs; i++)
192 if ( !(i % IO_TLB_SEGSIZE) )
193 swiotlb_adjust_seg(io_tlb_start + (i << IO_TLB_SHIFT),
194 IO_TLB_SEGSIZE << IO_TLB_SHIFT);
195 io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); 159 io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
196 }
197 io_tlb_index = 0; 160 io_tlb_index = 0;
198 io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(io_tlb_addr_t)); 161 io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
199 162
200 /* 163 /*
201 * Get the overflow emergency buffer 164 * Get the overflow emergency buffer
@@ -203,21 +166,17 @@ swiotlb_init_with_default_size(size_t default_size)
203 io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); 166 io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
204 if (!io_tlb_overflow_buffer) 167 if (!io_tlb_overflow_buffer)
205 panic("Cannot allocate SWIOTLB overflow buffer!\n"); 168 panic("Cannot allocate SWIOTLB overflow buffer!\n");
206 swiotlb_adjust_seg(io_tlb_overflow_buffer, io_tlb_overflow);
207 169
208 swiotlb_print_info(bytes); 170 printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n",
171 virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end));
209} 172}
210#ifndef __swiotlb_init_with_default_size
211#define __swiotlb_init_with_default_size swiotlb_init_with_default_size
212#endif
213 173
214void __init 174void __init
215swiotlb_init(void) 175swiotlb_init(void)
216{ 176{
217 __swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */ 177 swiotlb_init_with_default_size(64 * (1<<20)); /* default to 64MB */
218} 178}
219 179
220#ifdef SWIOTLB_ARCH_NEED_LATE_INIT
221/* 180/*
222 * Systems with larger DMA zones (those that don't support ISA) can 181 * Systems with larger DMA zones (those that don't support ISA) can
223 * initialize the swiotlb later using the slab allocator if needed. 182 * initialize the swiotlb later using the slab allocator if needed.
@@ -275,12 +234,12 @@ swiotlb_late_init_with_default_size(size_t default_size)
275 io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); 234 io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
276 io_tlb_index = 0; 235 io_tlb_index = 0;
277 236
278 io_tlb_orig_addr = (io_tlb_addr_t *)__get_free_pages(GFP_KERNEL, 237 io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL,
279 get_order(io_tlb_nslabs * sizeof(io_tlb_addr_t))); 238 get_order(io_tlb_nslabs * sizeof(char *)));
280 if (!io_tlb_orig_addr) 239 if (!io_tlb_orig_addr)
281 goto cleanup3; 240 goto cleanup3;
282 241
283 memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(io_tlb_addr_t)); 242 memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *));
284 243
285 /* 244 /*
286 * Get the overflow emergency buffer 245 * Get the overflow emergency buffer
@@ -290,17 +249,19 @@ swiotlb_late_init_with_default_size(size_t default_size)
290 if (!io_tlb_overflow_buffer) 249 if (!io_tlb_overflow_buffer)
291 goto cleanup4; 250 goto cleanup4;
292 251
293 swiotlb_print_info(bytes); 252 printk(KERN_INFO "Placing %luMB software IO TLB between 0x%lx - "
253 "0x%lx\n", bytes >> 20,
254 virt_to_bus(io_tlb_start), virt_to_bus(io_tlb_end));
294 255
295 return 0; 256 return 0;
296 257
297cleanup4: 258cleanup4:
298 free_pages((unsigned long)io_tlb_orig_addr, 259 free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs *
299 get_order(io_tlb_nslabs * sizeof(io_tlb_addr_t))); 260 sizeof(char *)));
300 io_tlb_orig_addr = NULL; 261 io_tlb_orig_addr = NULL;
301cleanup3: 262cleanup3:
302 free_pages((unsigned long)io_tlb_list, 263 free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
303 get_order(io_tlb_nslabs * sizeof(int))); 264 sizeof(int)));
304 io_tlb_list = NULL; 265 io_tlb_list = NULL;
305cleanup2: 266cleanup2:
306 io_tlb_end = NULL; 267 io_tlb_end = NULL;
@@ -310,9 +271,7 @@ cleanup1:
310 io_tlb_nslabs = req_nslabs; 271 io_tlb_nslabs = req_nslabs;
311 return -ENOMEM; 272 return -ENOMEM;
312} 273}
313#endif
314 274
315#ifndef SWIOTLB_ARCH_HAS_NEEDS_MAPPING
316static int 275static int
317address_needs_mapping(struct device *hwdev, dma_addr_t addr) 276address_needs_mapping(struct device *hwdev, dma_addr_t addr)
318{ 277{
@@ -323,35 +282,11 @@ address_needs_mapping(struct device *hwdev, dma_addr_t addr)
323 return (addr & ~mask) != 0; 282 return (addr & ~mask) != 0;
324} 283}
325 284
326static inline int range_needs_mapping(const void *ptr, size_t size)
327{
328 return swiotlb_force;
329}
330
331static inline int order_needs_mapping(unsigned int order)
332{
333 return 0;
334}
335#endif
336
337static void
338__sync_single(io_tlb_addr_t buffer, char *dma_addr, size_t size, int dir)
339{
340#ifndef SWIOTLB_ARCH_HAS_SYNC_SINGLE
341 if (dir == DMA_TO_DEVICE)
342 memcpy(dma_addr, buffer, size);
343 else
344 memcpy(buffer, dma_addr, size);
345#else
346 __swiotlb_arch_sync_single(buffer, dma_addr, size, dir);
347#endif
348}
349
350/* 285/*
351 * Allocates bounce buffer and returns its kernel virtual address. 286 * Allocates bounce buffer and returns its kernel virtual address.
352 */ 287 */
353static void * 288static void *
354map_single(struct device *hwdev, io_tlb_addr_t buffer, size_t size, int dir) 289map_single(struct device *hwdev, char *buffer, size_t size, int dir)
355{ 290{
356 unsigned long flags; 291 unsigned long flags;
357 char *dma_addr; 292 char *dma_addr;
@@ -424,7 +359,7 @@ map_single(struct device *hwdev, io_tlb_addr_t buffer, size_t size, int dir)
424 */ 359 */
425 io_tlb_orig_addr[index] = buffer; 360 io_tlb_orig_addr[index] = buffer;
426 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) 361 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
427 __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); 362 memcpy(dma_addr, buffer, size);
428 363
429 return dma_addr; 364 return dma_addr;
430} 365}
@@ -438,18 +373,17 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
438 unsigned long flags; 373 unsigned long flags;
439 int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; 374 int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
440 int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; 375 int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
441 io_tlb_addr_t buffer = io_tlb_orig_addr[index]; 376 char *buffer = io_tlb_orig_addr[index];
442 377
443 /* 378 /*
444 * First, sync the memory before unmapping the entry 379 * First, sync the memory before unmapping the entry
445 */ 380 */
446 if (!swiotlb_orig_addr_null(buffer) 381 if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
447 && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
448 /* 382 /*
449 * bounce... copy the data back into the original buffer * and 383 * bounce... copy the data back into the original buffer * and
450 * delete the bounce buffer. 384 * delete the bounce buffer.
451 */ 385 */
452 __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); 386 memcpy(buffer, dma_addr, size);
453 387
454 /* 388 /*
455 * Return the buffer to the free list by setting the corresponding 389 * Return the buffer to the free list by setting the corresponding
@@ -482,18 +416,18 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size,
482 int dir, int target) 416 int dir, int target)
483{ 417{
484 int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; 418 int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
485 io_tlb_addr_t buffer = io_tlb_orig_addr[index]; 419 char *buffer = io_tlb_orig_addr[index];
486 420
487 switch (target) { 421 switch (target) {
488 case SYNC_FOR_CPU: 422 case SYNC_FOR_CPU:
489 if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) 423 if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))
490 __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); 424 memcpy(buffer, dma_addr, size);
491 else 425 else
492 BUG_ON(dir != DMA_TO_DEVICE); 426 BUG_ON(dir != DMA_TO_DEVICE);
493 break; 427 break;
494 case SYNC_FOR_DEVICE: 428 case SYNC_FOR_DEVICE:
495 if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) 429 if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
496 __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); 430 memcpy(dma_addr, buffer, size);
497 else 431 else
498 BUG_ON(dir != DMA_FROM_DEVICE); 432 BUG_ON(dir != DMA_FROM_DEVICE);
499 break; 433 break;
@@ -502,8 +436,6 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size,
502 } 436 }
503} 437}
504 438
505#ifdef SWIOTLB_ARCH_NEED_ALLOC
506
507void * 439void *
508swiotlb_alloc_coherent(struct device *hwdev, size_t size, 440swiotlb_alloc_coherent(struct device *hwdev, size_t size,
509 dma_addr_t *dma_handle, gfp_t flags) 441 dma_addr_t *dma_handle, gfp_t flags)
@@ -519,10 +451,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
519 */ 451 */
520 flags |= GFP_DMA; 452 flags |= GFP_DMA;
521 453
522 if (!order_needs_mapping(order)) 454 ret = (void *)__get_free_pages(flags, order);
523 ret = (void *)__get_free_pages(flags, order);
524 else
525 ret = NULL;
526 if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) { 455 if (ret && address_needs_mapping(hwdev, virt_to_bus(ret))) {
527 /* 456 /*
528 * The allocated memory isn't reachable by the device. 457 * The allocated memory isn't reachable by the device.
@@ -560,7 +489,6 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
560 *dma_handle = dev_addr; 489 *dma_handle = dev_addr;
561 return ret; 490 return ret;
562} 491}
563EXPORT_SYMBOL(swiotlb_alloc_coherent);
564 492
565void 493void
566swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, 494swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
@@ -573,9 +501,6 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
573 /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ 501 /* DMA_TO_DEVICE to avoid memcpy in unmap_single */
574 swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE); 502 swiotlb_unmap_single (hwdev, dma_handle, size, DMA_TO_DEVICE);
575} 503}
576EXPORT_SYMBOL(swiotlb_free_coherent);
577
578#endif
579 504
580static void 505static void
581swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) 506swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
@@ -617,14 +542,13 @@ swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir)
617 * we can safely return the device addr and not worry about bounce 542 * we can safely return the device addr and not worry about bounce
618 * buffering it. 543 * buffering it.
619 */ 544 */
620 if (!range_needs_mapping(ptr, size) 545 if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force)
621 && !address_needs_mapping(hwdev, dev_addr))
622 return dev_addr; 546 return dev_addr;
623 547
624 /* 548 /*
625 * Oh well, have to allocate and map a bounce buffer. 549 * Oh well, have to allocate and map a bounce buffer.
626 */ 550 */
627 map = map_single(hwdev, ptr_to_io_tlb_addr(ptr), size, dir); 551 map = map_single(hwdev, ptr, size, dir);
628 if (!map) { 552 if (!map) {
629 swiotlb_full(hwdev, size, dir, 1); 553 swiotlb_full(hwdev, size, dir, 1);
630 map = io_tlb_overflow_buffer; 554 map = io_tlb_overflow_buffer;
@@ -752,16 +676,17 @@ int
752swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, 676swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
753 int dir) 677 int dir)
754{ 678{
679 void *addr;
755 dma_addr_t dev_addr; 680 dma_addr_t dev_addr;
756 int i; 681 int i;
757 682
758 BUG_ON(dir == DMA_NONE); 683 BUG_ON(dir == DMA_NONE);
759 684
760 for (i = 0; i < nelems; i++, sg++) { 685 for (i = 0; i < nelems; i++, sg++) {
761 dev_addr = SG_ENT_PHYS_ADDRESS(sg); 686 addr = SG_ENT_VIRT_ADDRESS(sg);
762 if (range_needs_mapping(SG_ENT_VIRT_ADDRESS(sg), sg->length) 687 dev_addr = virt_to_bus(addr);
763 || address_needs_mapping(hwdev, dev_addr)) { 688 if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
764 void *map = map_single(hwdev, sg_to_io_tlb_addr(sg), sg->length, dir); 689 void *map = map_single(hwdev, addr, sg->length, dir);
765 if (!map) { 690 if (!map) {
766 /* Don't panic here, we expect map_sg users 691 /* Don't panic here, we expect map_sg users
767 to do proper error handling. */ 692 to do proper error handling. */
@@ -835,44 +760,6 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
835 swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); 760 swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
836} 761}
837 762
838#ifdef SWIOTLB_ARCH_NEED_MAP_PAGE
839
840dma_addr_t
841swiotlb_map_page(struct device *hwdev, struct page *page,
842 unsigned long offset, size_t size,
843 enum dma_data_direction direction)
844{
845 dma_addr_t dev_addr;
846 char *map;
847
848 dev_addr = page_to_bus(page) + offset;
849 if (address_needs_mapping(hwdev, dev_addr)) {
850 map = map_single(hwdev, page_to_io_tlb_addr(page, offset), size, direction);
851 if (!map) {
852 swiotlb_full(hwdev, size, direction, 1);
853 map = io_tlb_overflow_buffer;
854 }
855 dev_addr = virt_to_bus(map);
856 }
857
858 return dev_addr;
859}
860
861void
862swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
863 size_t size, enum dma_data_direction direction)
864{
865 char *dma_addr = bus_to_virt(dev_addr);
866
867 BUG_ON(direction == DMA_NONE);
868 if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
869 unmap_single(hwdev, dma_addr, size, direction);
870 else if (direction == DMA_FROM_DEVICE)
871 dma_mark_clean(dma_addr, size);
872}
873
874#endif
875
876int 763int
877swiotlb_dma_mapping_error(dma_addr_t dma_addr) 764swiotlb_dma_mapping_error(dma_addr_t dma_addr)
878{ 765{
@@ -885,13 +772,10 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr)
885 * during bus mastering, then you would pass 0x00ffffff as the mask to 772 * during bus mastering, then you would pass 0x00ffffff as the mask to
886 * this function. 773 * this function.
887 */ 774 */
888#ifndef __swiotlb_dma_supported
889#define __swiotlb_dma_supported(hwdev, mask) (virt_to_bus(io_tlb_end - 1) <= (mask))
890#endif
891int 775int
892swiotlb_dma_supported(struct device *hwdev, u64 mask) 776swiotlb_dma_supported(struct device *hwdev, u64 mask)
893{ 777{
894 return __swiotlb_dma_supported(hwdev, mask); 778 return virt_to_bus(io_tlb_end - 1) <= mask;
895} 779}
896 780
897EXPORT_SYMBOL(swiotlb_init); 781EXPORT_SYMBOL(swiotlb_init);
@@ -906,4 +790,6 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device);
906EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu); 790EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
907EXPORT_SYMBOL(swiotlb_sync_sg_for_device); 791EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
908EXPORT_SYMBOL(swiotlb_dma_mapping_error); 792EXPORT_SYMBOL(swiotlb_dma_mapping_error);
793EXPORT_SYMBOL(swiotlb_alloc_coherent);
794EXPORT_SYMBOL(swiotlb_free_coherent);
909EXPORT_SYMBOL(swiotlb_dma_supported); 795EXPORT_SYMBOL(swiotlb_dma_supported);