]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Martin Hicks <mort@sgi.com> |
2 | Subject: KDB Backtrace Fixes | |
3 | References: bnc#501114 | |
4 | ||
5 | This patch fixes a failure in bb_all. | |
6 | ||
7 | Acked-by: Jeff Mahoney <jeffm@suse.com> | |
8 | --- | |
9 | ||
10 | arch/x86/kdb/kdba_bt.c | 61 ++++++++++++++++++++++++++++++++++++++++--------- | |
11 | 1 file changed, 51 insertions(+), 10 deletions(-) | |
12 | --- a/arch/x86/kdb/kdba_bt.c | |
13 | +++ b/arch/x86/kdb/kdba_bt.c | |
14 | @@ -416,34 +416,29 @@ static struct bb_name_state bb_special_c | |
15 | NS_MEM("ia32_ptregs_common", partial_pt_regs_plus_1, 0), | |
16 | NS_MEM("ia32_sysret", partial_pt_regs, 0), | |
17 | NS_MEM("int_careful", partial_pt_regs, 0), | |
18 | + NS_MEM("ia32_badarg", partial_pt_regs, 0), | |
19 | NS_MEM("int_restore_rest", full_pt_regs, 0), | |
20 | NS_MEM("int_signal", full_pt_regs, 0), | |
21 | NS_MEM("int_very_careful", partial_pt_regs, 0), | |
22 | - NS_MEM("int_with_check", partial_pt_regs, 0), | |
23 | #ifdef CONFIG_TRACE_IRQFLAGS | |
24 | NS_MEM("paranoid_exit0", full_pt_regs, 0), | |
25 | #endif /* CONFIG_TRACE_IRQFLAGS */ | |
26 | NS_MEM("paranoid_exit1", full_pt_regs, 0), | |
27 | NS_MEM("ptregscall_common", partial_pt_regs_plus_1, 0), | |
28 | - NS_MEM("restore_norax", partial_pt_regs, 0), | |
29 | - NS_MEM("restore", partial_pt_regs, 0), | |
30 | NS_MEM("ret_from_intr", partial_pt_regs_plus_2, 0), | |
31 | NS_MEM("stub32_clone", partial_pt_regs_plus_1, 0), | |
32 | NS_MEM("stub32_execve", partial_pt_regs_plus_1, 0), | |
33 | NS_MEM("stub32_fork", partial_pt_regs_plus_1, 0), | |
34 | NS_MEM("stub32_iopl", partial_pt_regs_plus_1, 0), | |
35 | NS_MEM("stub32_rt_sigreturn", partial_pt_regs_plus_1, 0), | |
36 | - NS_MEM("stub32_rt_sigsuspend", partial_pt_regs_plus_1, 0), | |
37 | NS_MEM("stub32_sigaltstack", partial_pt_regs_plus_1, 0), | |
38 | NS_MEM("stub32_sigreturn", partial_pt_regs_plus_1, 0), | |
39 | - NS_MEM("stub32_sigsuspend", partial_pt_regs_plus_1, 0), | |
40 | NS_MEM("stub32_vfork", partial_pt_regs_plus_1, 0), | |
41 | NS_MEM("stub_clone", partial_pt_regs_plus_1, 0), | |
42 | NS_MEM("stub_execve", partial_pt_regs_plus_1, 0), | |
43 | NS_MEM("stub_fork", partial_pt_regs_plus_1, 0), | |
44 | NS_MEM("stub_iopl", partial_pt_regs_plus_1, 0), | |
45 | NS_MEM("stub_rt_sigreturn", partial_pt_regs_plus_1, 0), | |
46 | - NS_MEM("stub_rt_sigsuspend", partial_pt_regs_plus_1, 0), | |
47 | NS_MEM("stub_sigaltstack", partial_pt_regs_plus_1, 0), | |
48 | NS_MEM("stub_vfork", partial_pt_regs_plus_1, 0), | |
49 | ||
50 | @@ -464,6 +459,17 @@ static struct bb_name_state bb_special_c | |
51 | BB_SKIP(RAX) | BB_SKIP(RCX)), | |
52 | NS_MEM("ia32_badsys", partial_pt_regs, 0), | |
53 | ||
54 | +#ifdef CONFIG_AUDITSYSCALL | |
55 | + NS_MEM_FROM("int_with_check", "sysexit_audit", partial_pt_regs, | |
56 | + BB_SKIP(R8) | BB_SKIP(R9) | BB_SKIP(R10) | BB_SKIP(R11) | | |
57 | + BB_SKIP(RAX)), | |
58 | + NS_MEM_FROM("int_with_check", "ia32_cstar_target", partial_pt_regs, | |
59 | + BB_SKIP(R8) | BB_SKIP(R9) | BB_SKIP(R10) | BB_SKIP(R11) | | |
60 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
61 | +#endif | |
62 | + NS_MEM("int_with_check", no_memory, 0), | |
63 | + | |
64 | + | |
65 | /* Various bits of code branch to int_ret_from_sys_call, with slightly | |
66 | * different missing values in pt_regs. | |
67 | */ | |
68 | @@ -540,11 +546,11 @@ static struct bb_name_state bb_special_c | |
69 | ||
70 | NS_REG("bad_put_user", | |
71 | all_regs, | |
72 | - BB_SKIP(RAX) | BB_SKIP(RCX) | BB_SKIP(R8)), | |
73 | + BB_SKIP(RBX)), | |
74 | ||
75 | NS_REG("bad_get_user", | |
76 | all_regs, | |
77 | - BB_SKIP(RAX) | BB_SKIP(RCX) | BB_SKIP(R8)), | |
78 | + BB_SKIP(RAX) | BB_SKIP(RDX)), | |
79 | ||
80 | NS_REG("bad_to_user", | |
81 | all_regs, | |
82 | @@ -585,11 +591,17 @@ static const char *bb_spurious[] = { | |
83 | "rff_action", | |
84 | "rff_trace", | |
85 | /* system_call */ | |
86 | + "system_call_after_swapgs", | |
87 | + "system_call_fastpath", | |
88 | "ret_from_sys_call", | |
89 | "sysret_check", | |
90 | "sysret_careful", | |
91 | "sysret_signal", | |
92 | "badsys", | |
93 | +#ifdef CONFIG_AUDITSYSCALL | |
94 | + "auditsys", | |
95 | + "sysret_audit", | |
96 | +#endif | |
97 | "tracesys", | |
98 | "int_ret_from_sys_call", | |
99 | "int_with_check", | |
100 | @@ -635,11 +647,22 @@ static const char *bb_spurious[] = { | |
101 | "bad_gs", | |
102 | /* ia32_sysenter_target */ | |
103 | "sysenter_do_call", | |
104 | + "sysenter_dispatch", | |
105 | + "sysexit_from_sys_call", | |
106 | +#ifdef CONFIG_AUDITSYSCALL | |
107 | + "sysenter_auditsys", | |
108 | + "sysexit_audit", | |
109 | +#endif | |
110 | "sysenter_tracesys", | |
111 | /* ia32_cstar_target */ | |
112 | "cstar_do_call", | |
113 | + "cstar_dispatch", | |
114 | + "sysretl_from_sys_call", | |
115 | +#ifdef CONFIG_AUDITSYSCALL | |
116 | + "cstar_auditsys", | |
117 | + "sysretl_audit", | |
118 | +#endif | |
119 | "cstar_tracesys", | |
120 | - "ia32_badarg", | |
121 | /* ia32_syscall */ | |
122 | "ia32_do_syscall", | |
123 | "ia32_sysret", | |
124 | @@ -1805,6 +1828,7 @@ enum bb_operand_usage { | |
125 | BBOU_RSRDWSWD, /* 15 */ | |
126 | /* opcode specific entries */ | |
127 | BBOU_ADD, | |
128 | + BBOU_AND, | |
129 | BBOU_CALL, | |
130 | BBOU_CBW, | |
131 | BBOU_CMOV, | |
132 | @@ -1896,7 +1920,7 @@ static const struct bb_opcode_usage | |
133 | bb_opcode_usage_all[] = { | |
134 | {3, BBOU_RSRDWD, "adc"}, | |
135 | {3, BBOU_ADD, "add"}, | |
136 | - {3, BBOU_RSRDWD, "and"}, | |
137 | + {3, BBOU_AND, "and"}, | |
138 | {3, BBOU_RSWD, "bsf"}, | |
139 | {3, BBOU_RSWD, "bsr"}, | |
140 | {5, BBOU_RSWS, "bswap"}, | |
141 | @@ -2952,6 +2976,12 @@ bb_sanity_check(int type) | |
142 | (strcmp(bb_func_name, "ptregscall_common") == 0 || | |
143 | strcmp(bb_func_name, "ia32_ptregs_common") == 0)))) | |
144 | continue; | |
145 | + /* The put_user and save_paranoid functions are special. | |
146 | + * %rbx gets clobbered */ | |
147 | + if (expect == BBRG_RBX && | |
148 | + (strncmp(bb_func_name, "__put_user_", 11) == 0 || | |
149 | + strcmp(bb_func_name, "save_paranoid") == 0)) | |
150 | + continue; | |
151 | kdb_printf("%s: Expected %s, got %s", | |
152 | __FUNCTION__, | |
153 | bbrg_name[expect], bbrg_name[actual]); | |
154 | @@ -3445,6 +3475,17 @@ bb_usage(void) | |
155 | } else { | |
156 | usage = BBOU_RSRDWD; | |
157 | } | |
158 | + break; | |
159 | + case BBOU_AND: | |
160 | + /* Special case when trying to round the stack pointer | |
161 | + * to achieve byte alignment | |
162 | + */ | |
163 | + if (dst->reg && dst->base_rc == BBRG_RSP && | |
164 | + src->immediate && strncmp(bb_func_name, "efi_call", 8) == 0) { | |
165 | + usage = BBOU_NOP; | |
166 | + } else { | |
167 | + usage = BBOU_RSRDWD; | |
168 | + } | |
169 | break; | |
170 | case BBOU_CALL: | |
171 | /* Invalidate the scratch registers. Functions sync_regs and |