diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/ia32/sys_ia32.c | 10 | ||||
-rw-r--r-- | arch/ia64/kernel/efi.c | 36 | ||||
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 11 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 30 | ||||
-rw-r--r-- | arch/ia64/lib/Makefile | 3 | ||||
-rw-r--r-- | arch/ia64/mm/contig.c | 5 | ||||
-rw-r--r-- | arch/ia64/mm/discontig.c | 6 |
7 files changed, 81 insertions, 20 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index d430d36ae49..0afb4fe7c35 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 struct getdents32_callback buf; int error; + error = -EFAULT; + if (!access_ok(VERIFY_WRITE, dirent, count)) + goto out; + error = -EBADF; file = fget(fd); if (!file) @@ -1283,10 +1287,10 @@ sys32_getdents (unsigned int fd, struct compat_dirent __user *dirent, unsigned i error = buf.error; lastdirent = buf.previous; if (lastdirent) { - error = -EINVAL; if (put_user(file->f_pos, &lastdirent->d_off)) - goto out_putf; - error = count - buf.count; + error = -EFAULT; + else + error = count - buf.count; } out_putf: diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 772ba6fe110..4061593e5b1 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -21,6 +21,7 @@ * Skip non-WB memory and ignore empty memory ranges. */ #include <linux/module.h> +#include <linux/bootmem.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/types.h> @@ -1009,6 +1010,11 @@ efi_memmap_init(unsigned long *s, unsigned long *e) } else ae = efi_md_end(md); +#ifdef CONFIG_CRASH_DUMP + /* saved_max_pfn should ignore max_addr= command line arg */ + if (saved_max_pfn < (ae >> PAGE_SHIFT)) + saved_max_pfn = (ae >> PAGE_SHIFT); +#endif /* keep within max_addr= and min_addr= command line arg */ as = max(as, min_addr); ae = min(ae, max_addr); @@ -1177,3 +1183,33 @@ kdump_find_rsvd_region (unsigned long size, return ~0UL; } #endif + +#ifdef CONFIG_PROC_VMCORE +/* locate the size find a the descriptor at a certain address */ +unsigned long +vmcore_find_descriptor_size (unsigned long address) +{ + void *efi_map_start, *efi_map_end, *p; + efi_memory_desc_t *md; + u64 efi_desc_size; + unsigned long ret = 0; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + md = p; + if (efi_wb(md) && md->type == EFI_LOADER_DATA + && md->phys_addr == address) { + ret = efi_md_size(md); + break; + } + } + + if (ret == 0) + printk(KERN_WARNING "Cannot locate EFI vmcore descriptor\n"); + + return ret; +} +#endif diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 9ddf896a137..abc7ad03588 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 * allocate a sampling buffer and remaps it into the user address space of the task */ static int -pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned long rsize, void **user_vaddr) +pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned long rsize, void **user_vaddr) { struct mm_struct *mm = task->mm; struct vm_area_struct *vma = NULL; @@ -2349,6 +2349,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon * partially initialize the vma for the sampling buffer */ vma->vm_mm = mm; + vma->vm_file = filp; vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED; vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */ @@ -2387,6 +2388,8 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon goto error; } + get_file(filp); + /* * now insert the vma in the vm list for the process, must be * done with mmap lock held @@ -2464,7 +2467,7 @@ pfarg_is_sane(struct task_struct *task, pfarg_context_t *pfx) } static int -pfm_setup_buffer_fmt(struct task_struct *task, pfm_context_t *ctx, unsigned int ctx_flags, +pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t *ctx, unsigned int ctx_flags, unsigned int cpu, pfarg_context_t *arg) { pfm_buffer_fmt_t *fmt = NULL; @@ -2505,7 +2508,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, pfm_context_t *ctx, unsigned int /* * buffer is always remapped into the caller's address space */ - ret = pfm_smpl_buffer_alloc(current, ctx, size, &uaddr); + ret = pfm_smpl_buffer_alloc(current, filp, ctx, size, &uaddr); if (ret) goto error; /* 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 * does the user want to sample? */ if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) { - ret = pfm_setup_buffer_fmt(current, ctx, ctx_flags, 0, req); + ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req); if (ret) goto buffer_error; } diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5fa09d141ab..7d6fe65c93f 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -251,6 +251,12 @@ reserve_memory (void) } #endif +#ifdef CONFIG_PROC_VMCORE + if (reserve_elfcorehdr(&rsvd_region[n].start, + &rsvd_region[n].end) == 0) + n++; +#endif + efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); n++; @@ -453,6 +459,30 @@ static int __init parse_elfcorehdr(char *arg) return 0; } early_param("elfcorehdr", parse_elfcorehdr); + +int __init reserve_elfcorehdr(unsigned long *start, unsigned long *end) +{ + unsigned long length; + + /* We get the address using the kernel command line, + * but the size is extracted from the EFI tables. + * Both address and size are required for reservation + * to work properly. + */ + + if (elfcorehdr_addr >= ELFCORE_ADDR_MAX) + return -EINVAL; + + if ((length = vmcore_find_descriptor_size(elfcorehdr_addr)) == 0) { + elfcorehdr_addr = ELFCORE_ADDR_MAX; + return -EINVAL; + } + + *start = (unsigned long)__va(elfcorehdr_addr); + *end = *start + length; + return 0; +} + #endif /* CONFIG_PROC_VMCORE */ void __init diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 38fa6e49e79..46edf8444c7 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 \ checksum.o clear_page.o csum_partial_copy.o \ clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ flush.o ip_fast_csum.o do_csum.o \ - memset.o strlen.o + memset.o strlen.o xor.o lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o lib-$(CONFIG_PERFMON) += carta_random.o -lib-$(CONFIG_MD_RAID456) += xor.o AFLAGS___divdi3.o = AFLAGS___udivdi3.o = -DUNSIGNED diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index ca4d41e5f17..fb0f4698f5d 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -197,11 +197,6 @@ find_memory (void) find_initrd(); -#ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we still need to know the real mem - * size before original memory map is reset. */ - saved_max_pfn = max_pfn; -#endif } #ifdef CONFIG_SMP diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 16835108bb5..11a2d8825d8 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -480,12 +480,6 @@ void __init find_memory(void) max_pfn = max_low_pfn; find_initrd(); - -#ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we still need to know the real mem - * size before original memory map is reset. */ - saved_max_pfn = max_pfn; -#endif } #ifdef CONFIG_SMP |