diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/ia32/ia32_binfmt.c | 49 | ||||
-rw-r--r-- | arch/x86_64/ia32/syscall32.c | 15 | ||||
-rw-r--r-- | arch/x86_64/kernel/nmi.c | 2 |
3 files changed, 15 insertions, 51 deletions
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 543ef4f405e9..5ce0bd486bbf 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c | |||
@@ -64,55 +64,6 @@ typedef unsigned int elf_greg_t; | |||
64 | #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t)) | 64 | #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t)) |
65 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | 65 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
66 | 66 | ||
67 | /* | ||
68 | * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out | ||
69 | * extra segments containing the vsyscall DSO contents. Dumping its | ||
70 | * contents makes post-mortem fully interpretable later without matching up | ||
71 | * the same kernel and hardware config to see what PC values meant. | ||
72 | * Dumping its extra ELF program headers includes all the other information | ||
73 | * a debugger needs to easily find how the vsyscall DSO was being used. | ||
74 | */ | ||
75 | #define ELF_CORE_EXTRA_PHDRS (find_vma(current->mm, VSYSCALL32_BASE) ? \ | ||
76 | (VSYSCALL32_EHDR->e_phnum) : 0) | ||
77 | #define ELF_CORE_WRITE_EXTRA_PHDRS \ | ||
78 | do { \ | ||
79 | if (find_vma(current->mm, VSYSCALL32_BASE)) { \ | ||
80 | const struct elf32_phdr *const vsyscall_phdrs = \ | ||
81 | (const struct elf32_phdr *) (VSYSCALL32_BASE \ | ||
82 | + VSYSCALL32_EHDR->e_phoff);\ | ||
83 | int i; \ | ||
84 | Elf32_Off ofs = 0; \ | ||
85 | for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ | ||
86 | struct elf32_phdr phdr = vsyscall_phdrs[i]; \ | ||
87 | if (phdr.p_type == PT_LOAD) { \ | ||
88 | BUG_ON(ofs != 0); \ | ||
89 | ofs = phdr.p_offset = offset; \ | ||
90 | phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ | ||
91 | phdr.p_filesz = phdr.p_memsz; \ | ||
92 | offset += phdr.p_filesz; \ | ||
93 | } \ | ||
94 | else \ | ||
95 | phdr.p_offset += ofs; \ | ||
96 | phdr.p_paddr = 0; /* match other core phdrs */ \ | ||
97 | DUMP_WRITE(&phdr, sizeof(phdr)); \ | ||
98 | } \ | ||
99 | } \ | ||
100 | } while (0) | ||
101 | #define ELF_CORE_WRITE_EXTRA_DATA \ | ||
102 | do { \ | ||
103 | if (find_vma(current->mm, VSYSCALL32_BASE)) { \ | ||
104 | const struct elf32_phdr *const vsyscall_phdrs = \ | ||
105 | (const struct elf32_phdr *) (VSYSCALL32_BASE \ | ||
106 | + VSYSCALL32_EHDR->e_phoff); \ | ||
107 | int i; \ | ||
108 | for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ | ||
109 | if (vsyscall_phdrs[i].p_type == PT_LOAD) \ | ||
110 | DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\ | ||
111 | PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ | ||
112 | } \ | ||
113 | } \ | ||
114 | } while (0) | ||
115 | |||
116 | struct elf_siginfo | 67 | struct elf_siginfo |
117 | { | 68 | { |
118 | int si_signo; /* signal number */ | 69 | int si_signo; /* signal number */ |
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index 3e5ed20cba45..59f1fa155915 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c | |||
@@ -59,6 +59,13 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) | |||
59 | vma->vm_end = VSYSCALL32_END; | 59 | vma->vm_end = VSYSCALL32_END; |
60 | /* MAYWRITE to allow gdb to COW and set breakpoints */ | 60 | /* MAYWRITE to allow gdb to COW and set breakpoints */ |
61 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; | 61 | vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; |
62 | /* | ||
63 | * Make sure the vDSO gets into every core dump. | ||
64 | * Dumping its contents makes post-mortem fully interpretable later | ||
65 | * without matching up the same kernel and hardware config to see | ||
66 | * what PC values meant. | ||
67 | */ | ||
68 | vma->vm_flags |= VM_ALWAYSDUMP; | ||
62 | vma->vm_flags |= mm->def_flags; | 69 | vma->vm_flags |= mm->def_flags; |
63 | vma->vm_page_prot = protection_map[vma->vm_flags & 7]; | 70 | vma->vm_page_prot = protection_map[vma->vm_flags & 7]; |
64 | vma->vm_ops = &syscall32_vm_ops; | 71 | vma->vm_ops = &syscall32_vm_ops; |
@@ -75,6 +82,14 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) | |||
75 | return 0; | 82 | return 0; |
76 | } | 83 | } |
77 | 84 | ||
85 | const char *arch_vma_name(struct vm_area_struct *vma) | ||
86 | { | ||
87 | if (vma->vm_start == VSYSCALL32_BASE && | ||
88 | vma->vm_mm && vma->vm_mm->task_size == IA32_PAGE_OFFSET) | ||
89 | return "[vdso]"; | ||
90 | return NULL; | ||
91 | } | ||
92 | |||
78 | static int __init init_syscall32(void) | 93 | static int __init init_syscall32(void) |
79 | { | 94 | { |
80 | syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); | 95 | syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 186aebbae32d..9cb42ecb7f89 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -302,8 +302,6 @@ int __init setup_nmi_watchdog(char *str) | |||
302 | if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) | 302 | if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) |
303 | return 0; | 303 | return 0; |
304 | 304 | ||
305 | if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0)) | ||
306 | return 0; /* no lapic support */ | ||
307 | nmi_watchdog = nmi; | 305 | nmi_watchdog = nmi; |
308 | return 1; | 306 | return 1; |
309 | } | 307 | } |