aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ds.c
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2008-01-30 07:31:20 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:31:20 -0500
commita95d67f87e1a5f1b4429be3ba3bf7b4051657908 (patch)
tree4a67994b901c5dfbf3c2ee752efd53dbce938c36 /arch/x86/kernel/ds.c
parente4811f2568c55e595a7bf15a3b9aba863b31fb94 (diff)
x86, ptrace: new ptrace BTS API
Here's the new ptrace BTS API that supports two different overflow handling mechanisms (wrap-around and buffer-full-signal) to support two different use cases (debugging and profiling). It further combines buffer allocation and configuration. Opens: - memory rlimit - overflow signal What would be the right signal to use? Signed-off-by: Markus Metzger <markus.t.metzger@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/ds.c')
-rw-r--r--arch/x86/kernel/ds.c56
1 files changed, 51 insertions, 5 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index e7855def97c3..6eb5d49a36bb 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -177,18 +177,20 @@ static inline void set_info_data(char *base, unsigned long value)
177} 177}
178 178
179 179
180int ds_allocate(void **dsp, size_t bts_size_in_records) 180int ds_allocate(void **dsp, size_t bts_size_in_bytes)
181{ 181{
182 size_t bts_size_in_bytes = 0; 182 size_t bts_size_in_records;
183 void *bts = 0; 183 void *bts;
184 void *ds = 0; 184 void *ds;
185 185
186 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) 186 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
187 return -EOPNOTSUPP; 187 return -EOPNOTSUPP;
188 188
189 if (bts_size_in_records < 0) 189 if (bts_size_in_bytes < 0)
190 return -EINVAL; 190 return -EINVAL;
191 191
192 bts_size_in_records =
193 bts_size_in_bytes / ds_cfg.sizeof_bts;
192 bts_size_in_bytes = 194 bts_size_in_bytes =
193 bts_size_in_records * ds_cfg.sizeof_bts; 195 bts_size_in_records * ds_cfg.sizeof_bts;
194 196
@@ -233,9 +235,21 @@ int ds_get_bts_size(void *ds)
233 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts) 235 if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
234 return -EOPNOTSUPP; 236 return -EOPNOTSUPP;
235 237
238 if (!ds)
239 return 0;
240
236 size_in_bytes = 241 size_in_bytes =
237 get_bts_absolute_maximum(ds) - 242 get_bts_absolute_maximum(ds) -
238 get_bts_buffer_base(ds); 243 get_bts_buffer_base(ds);
244 return size_in_bytes;
245}
246
247int ds_get_bts_end(void *ds)
248{
249 size_t size_in_bytes = ds_get_bts_size(ds);
250
251 if (size_in_bytes <= 0)
252 return size_in_bytes;
239 253
240 return size_in_bytes / ds_cfg.sizeof_bts; 254 return size_in_bytes / ds_cfg.sizeof_bts;
241} 255}
@@ -254,6 +268,38 @@ int ds_get_bts_index(void *ds)
254 return index_offset_in_bytes / ds_cfg.sizeof_bts; 268 return index_offset_in_bytes / ds_cfg.sizeof_bts;
255} 269}
256 270
271int ds_set_overflow(void *ds, int method)
272{
273 switch (method) {
274 case DS_O_SIGNAL:
275 return -EOPNOTSUPP;
276 case DS_O_WRAP:
277 return 0;
278 default:
279 return -EINVAL;
280 }
281}
282
283int ds_get_overflow(void *ds)
284{
285 return DS_O_WRAP;
286}
287
288int ds_clear(void *ds)
289{
290 int bts_size = ds_get_bts_size(ds);
291 void *bts_base;
292
293 if (bts_size <= 0)
294 return bts_size;
295
296 bts_base = get_bts_buffer_base(ds);
297 memset(bts_base, 0, bts_size);
298
299 set_bts_index(ds, bts_base);
300 return 0;
301}
302
257int ds_read_bts(void *ds, size_t index, struct bts_struct *out) 303int ds_read_bts(void *ds, size_t index, struct bts_struct *out)
258{ 304{
259 void *bts; 305 void *bts;