aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/process_32.c31
-rw-r--r--arch/x86/kernel/ptrace_32.c29
-rw-r--r--arch/x86/kernel/signal_32.c4
-rw-r--r--arch/x86/kernel/traps_32.c4
-rw-r--r--arch/x86/power/cpu.c14
-rw-r--r--include/asm-x86/processor_32.h7
6 files changed, 61 insertions, 28 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 53406461074f..3744cf63682c 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -445,7 +445,12 @@ void flush_thread(void)
445{ 445{
446 struct task_struct *tsk = current; 446 struct task_struct *tsk = current;
447 447
448 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); 448 tsk->thread.debugreg0 = 0;
449 tsk->thread.debugreg1 = 0;
450 tsk->thread.debugreg2 = 0;
451 tsk->thread.debugreg3 = 0;
452 tsk->thread.debugreg6 = 0;
453 tsk->thread.debugreg7 = 0;
449 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 454 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
450 clear_tsk_thread_flag(tsk, TIF_DEBUG); 455 clear_tsk_thread_flag(tsk, TIF_DEBUG);
451 /* 456 /*
@@ -522,7 +527,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
522 */ 527 */
523void dump_thread(struct pt_regs * regs, struct user * dump) 528void dump_thread(struct pt_regs * regs, struct user * dump)
524{ 529{
525 int i;
526 u16 gs; 530 u16 gs;
527 531
528/* changed the size calculations - should hopefully work better. lbt */ 532/* changed the size calculations - should hopefully work better. lbt */
@@ -533,8 +537,14 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
533 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; 537 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
534 dump->u_dsize -= dump->u_tsize; 538 dump->u_dsize -= dump->u_tsize;
535 dump->u_ssize = 0; 539 dump->u_ssize = 0;
536 for (i = 0; i < 8; i++) 540 dump->u_debugreg[0] = current->thread.debugreg0;
537 dump->u_debugreg[i] = current->thread.debugreg[i]; 541 dump->u_debugreg[1] = current->thread.debugreg1;
542 dump->u_debugreg[2] = current->thread.debugreg2;
543 dump->u_debugreg[3] = current->thread.debugreg3;
544 dump->u_debugreg[4] = 0;
545 dump->u_debugreg[5] = 0;
546 dump->u_debugreg[6] = current->thread.debugreg6;
547 dump->u_debugreg[7] = current->thread.debugreg7;
538 548
539 if (dump->start_stack < TASK_SIZE) 549 if (dump->start_stack < TASK_SIZE)
540 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; 550 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
@@ -612,13 +622,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
612 wrmsr(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr, 0); 622 wrmsr(MSR_IA32_DEBUGCTLMSR, next->debugctlmsr, 0);
613 623
614 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { 624 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
615 set_debugreg(next->debugreg[0], 0); 625 set_debugreg(next->debugreg0, 0);
616 set_debugreg(next->debugreg[1], 1); 626 set_debugreg(next->debugreg1, 1);
617 set_debugreg(next->debugreg[2], 2); 627 set_debugreg(next->debugreg2, 2);
618 set_debugreg(next->debugreg[3], 3); 628 set_debugreg(next->debugreg3, 3);
619 /* no 4 and 5 */ 629 /* no 4 and 5 */
620 set_debugreg(next->debugreg[6], 6); 630 set_debugreg(next->debugreg6, 6);
621 set_debugreg(next->debugreg[7], 7); 631 set_debugreg(next->debugreg7, 7);
622 } 632 }
623 633
624#ifdef CONFIG_SECCOMP 634#ifdef CONFIG_SECCOMP
@@ -869,4 +879,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
869 unsigned long range_end = mm->brk + 0x02000000; 879 unsigned long range_end = mm->brk + 0x02000000;
870 return randomize_range(mm->brk, range_end, 0) ? : mm->brk; 880 return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
871} 881}
872
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
index 26071305de2c..fed83d066135 100644
--- a/arch/x86/kernel/ptrace_32.c
+++ b/arch/x86/kernel/ptrace_32.c
@@ -133,19 +133,39 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
133 */ 133 */
134static unsigned long ptrace_get_debugreg(struct task_struct *child, int n) 134static unsigned long ptrace_get_debugreg(struct task_struct *child, int n)
135{ 135{
136 return child->thread.debugreg[n]; 136 switch (n) {
137 case 0: return child->thread.debugreg0;
138 case 1: return child->thread.debugreg1;
139 case 2: return child->thread.debugreg2;
140 case 3: return child->thread.debugreg3;
141 case 6: return child->thread.debugreg6;
142 case 7: return child->thread.debugreg7;
143 }
144 return 0;
137} 145}
138 146
139static int ptrace_set_debugreg(struct task_struct *child, 147static int ptrace_set_debugreg(struct task_struct *child,
140 int n, unsigned long data) 148 int n, unsigned long data)
141{ 149{
150 int i;
151
142 if (unlikely(n == 4 || n == 5)) 152 if (unlikely(n == 4 || n == 5))
143 return -EIO; 153 return -EIO;
144 154
145 if (n < 4 && unlikely(data >= TASK_SIZE - 3)) 155 if (n < 4 && unlikely(data >= TASK_SIZE - 3))
146 return -EIO; 156 return -EIO;
147 157
148 if (n == 7) { 158 switch (n) {
159 case 0: child->thread.debugreg0 = data; break;
160 case 1: child->thread.debugreg1 = data; break;
161 case 2: child->thread.debugreg2 = data; break;
162 case 3: child->thread.debugreg3 = data; break;
163
164 case 6:
165 child->thread.debugreg6 = data;
166 break;
167
168 case 7:
149 /* 169 /*
150 * Sanity-check data. Take one half-byte at once with 170 * Sanity-check data. Take one half-byte at once with
151 * check = (val >> (16 + 4*i)) & 0xf. It contains the 171 * check = (val >> (16 + 4*i)) & 0xf. It contains the
@@ -176,19 +196,18 @@ static int ptrace_set_debugreg(struct task_struct *child,
176 * 64-bit kernel), so the x86_64 mask value is 0x5454. 196 * 64-bit kernel), so the x86_64 mask value is 0x5454.
177 * See the AMD manual no. 24593 (AMD64 System Programming) 197 * See the AMD manual no. 24593 (AMD64 System Programming)
178 */ 198 */
179 int i;
180 data &= ~DR_CONTROL_RESERVED; 199 data &= ~DR_CONTROL_RESERVED;
181 for (i = 0; i < 4; i++) 200 for (i = 0; i < 4; i++)
182 if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1) 201 if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
183 return -EIO; 202 return -EIO;
203 child->thread.debugreg7 = data;
184 if (data) 204 if (data)
185 set_tsk_thread_flag(child, TIF_DEBUG); 205 set_tsk_thread_flag(child, TIF_DEBUG);
186 else 206 else
187 clear_tsk_thread_flag(child, TIF_DEBUG); 207 clear_tsk_thread_flag(child, TIF_DEBUG);
208 break;
188 } 209 }
189 210
190 child->thread.debugreg[n] = data;
191
192 return 0; 211 return 0;
193} 212}
194 213
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 64cb3c05de69..2bf5c9aed106 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -605,8 +605,8 @@ static void fastcall do_signal(struct pt_regs *regs)
605 * have been cleared if the watchpoint triggered 605 * have been cleared if the watchpoint triggered
606 * inside the kernel. 606 * inside the kernel.
607 */ 607 */
608 if (unlikely(current->thread.debugreg[7])) 608 if (unlikely(current->thread.debugreg7))
609 set_debugreg(current->thread.debugreg[7], 7); 609 set_debugreg(current->thread.debugreg7, 7);
610 610
611 /* Whee! Actually deliver the signal. */ 611 /* Whee! Actually deliver the signal. */
612 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 612 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 931ef10960ee..27713553cc59 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -852,7 +852,7 @@ fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
852 852
853 /* Mask out spurious debug traps due to lazy DR7 setting */ 853 /* Mask out spurious debug traps due to lazy DR7 setting */
854 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { 854 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
855 if (!tsk->thread.debugreg[7]) 855 if (!tsk->thread.debugreg7)
856 goto clear_dr7; 856 goto clear_dr7;
857 } 857 }
858 858
@@ -860,7 +860,7 @@ fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
860 goto debug_vm86; 860 goto debug_vm86;
861 861
862 /* Save debug status register where ptrace can see it */ 862 /* Save debug status register where ptrace can see it */
863 tsk->thread.debugreg[6] = condition; 863 tsk->thread.debugreg6 = condition;
864 864
865 /* 865 /*
866 * Single-stepping through TF: make sure we ignore any events in 866 * Single-stepping through TF: make sure we ignore any events in
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 998fd3ec0d68..5a98dc35addf 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -74,14 +74,14 @@ static void fix_processor_context(void)
74 /* 74 /*
75 * Now maybe reload the debug registers 75 * Now maybe reload the debug registers
76 */ 76 */
77 if (current->thread.debugreg[7]){ 77 if (current->thread.debugreg7) {
78 set_debugreg(current->thread.debugreg[0], 0); 78 set_debugreg(current->thread.debugreg0, 0);
79 set_debugreg(current->thread.debugreg[1], 1); 79 set_debugreg(current->thread.debugreg1, 1);
80 set_debugreg(current->thread.debugreg[2], 2); 80 set_debugreg(current->thread.debugreg2, 2);
81 set_debugreg(current->thread.debugreg[3], 3); 81 set_debugreg(current->thread.debugreg3, 3);
82 /* no 4 and 5 */ 82 /* no 4 and 5 */
83 set_debugreg(current->thread.debugreg[6], 6); 83 set_debugreg(current->thread.debugreg6, 6);
84 set_debugreg(current->thread.debugreg[7], 7); 84 set_debugreg(current->thread.debugreg7, 7);
85 } 85 }
86 86
87} 87}
diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h
index c85400fe58c4..d50a4b48d441 100644
--- a/include/asm-x86/processor_32.h
+++ b/include/asm-x86/processor_32.h
@@ -353,7 +353,12 @@ struct thread_struct {
353 unsigned long fs; 353 unsigned long fs;
354 unsigned long gs; 354 unsigned long gs;
355/* Hardware debugging registers */ 355/* Hardware debugging registers */
356 unsigned long debugreg[8]; /* %%db0-7 debug registers */ 356 unsigned long debugreg0;
357 unsigned long debugreg1;
358 unsigned long debugreg2;
359 unsigned long debugreg3;
360 unsigned long debugreg6;
361 unsigned long debugreg7;
357/* fault info */ 362/* fault info */
358 unsigned long cr2, trap_no, error_code; 363 unsigned long cr2, trap_no, error_code;
359/* floating point info */ 364/* floating point info */