diff options
author | Chuck Ebbert <76306.1226@compuserve.com> | 2006-09-26 04:52:33 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:33 -0400 |
commit | 2ade2920dcefdf5595c6380ebed131c964190855 (patch) | |
tree | 053542af977e5c402633771bb737f3d8a0efef33 /arch/x86_64 | |
parent | 91cd444e56ebe0c2acd9576a045d77490b26f607 (diff) |
[PATCH] i386/x86-64: rename is_at_popf(), add iret to tests and fix
is_at_popf() needs to test for the iret instruction as well as
popf. So add that test and rename it to is_setting_trap_flag().
Also change max insn length from 16 to 15 to match reality.
LAHF / SAHF can't affect TF, so the comment in x86_64 is removed.
Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/ptrace.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index 412c6a8bf906..addc14af0c56 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c | |||
@@ -116,17 +116,17 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r | |||
116 | return addr; | 116 | return addr; |
117 | } | 117 | } |
118 | 118 | ||
119 | static int is_at_popf(struct task_struct *child, struct pt_regs *regs) | 119 | static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) |
120 | { | 120 | { |
121 | int i, copied; | 121 | int i, copied; |
122 | unsigned char opcode[16]; | 122 | unsigned char opcode[15]; |
123 | unsigned long addr = convert_rip_to_linear(child, regs); | 123 | unsigned long addr = convert_rip_to_linear(child, regs); |
124 | 124 | ||
125 | copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); | 125 | copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); |
126 | for (i = 0; i < copied; i++) { | 126 | for (i = 0; i < copied; i++) { |
127 | switch (opcode[i]) { | 127 | switch (opcode[i]) { |
128 | /* popf */ | 128 | /* popf and iret */ |
129 | case 0x9d: | 129 | case 0x9d: case 0xcf: |
130 | return 1; | 130 | return 1; |
131 | 131 | ||
132 | /* CHECKME: 64 65 */ | 132 | /* CHECKME: 64 65 */ |
@@ -189,10 +189,8 @@ static void set_singlestep(struct task_struct *child) | |||
189 | * ..but if TF is changed by the instruction we will trace, | 189 | * ..but if TF is changed by the instruction we will trace, |
190 | * don't mark it as being "us" that set it, so that we | 190 | * don't mark it as being "us" that set it, so that we |
191 | * won't clear it by hand later. | 191 | * won't clear it by hand later. |
192 | * | ||
193 | * AK: this is not enough, LAHF and IRET can change TF in user space too. | ||
194 | */ | 192 | */ |
195 | if (is_at_popf(child, regs)) | 193 | if (is_setting_trap_flag(child, regs)) |
196 | return; | 194 | return; |
197 | 195 | ||
198 | child->ptrace |= PT_DTRACE; | 196 | child->ptrace |= PT_DTRACE; |