summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ds.c
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2008-01-30 13:31:20 +0100
committerIngo Molnar <mingo@elte.hu>2008-01-30 13:31:20 +0100
commita95d67f87e1a5f1b4429be3ba3bf7b4051657908 (patch)
tree4a67994b901c5dfbf3c2ee752efd53dbce938c36 /arch/x86/kernel/ds.c
parente4811f2568c55e595a7bf15a3b9aba863b31fb94 (diff)
downloadlinux-a95d67f87e1a5f1b4429be3ba3bf7b4051657908.tar.bz2
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)
}
-int ds_allocate(void **dsp, size_t bts_size_in_records)
+int ds_allocate(void **dsp, size_t bts_size_in_bytes)
{
- size_t bts_size_in_bytes = 0;
- void *bts = 0;
- void *ds = 0;
+ size_t bts_size_in_records;
+ void *bts;
+ void *ds;
if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
return -EOPNOTSUPP;
- if (bts_size_in_records < 0)
+ if (bts_size_in_bytes < 0)
return -EINVAL;
+ bts_size_in_records =
+ bts_size_in_bytes / ds_cfg.sizeof_bts;
bts_size_in_bytes =
bts_size_in_records * ds_cfg.sizeof_bts;
@@ -233,9 +235,21 @@ int ds_get_bts_size(void *ds)
if (!ds_cfg.sizeof_ds || !ds_cfg.sizeof_bts)
return -EOPNOTSUPP;
+ if (!ds)
+ return 0;
+
size_in_bytes =
get_bts_absolute_maximum(ds) -
get_bts_buffer_base(ds);
+ return size_in_bytes;
+}
+
+int ds_get_bts_end(void *ds)
+{
+ size_t size_in_bytes = ds_get_bts_size(ds);
+
+ if (size_in_bytes <= 0)
+ return size_in_bytes;
return size_in_bytes / ds_cfg.sizeof_bts;
}
@@ -254,6 +268,38 @@ int ds_get_bts_index(void *ds)
return index_offset_in_bytes / ds_cfg.sizeof_bts;
}
+int ds_set_overflow(void *ds, int method)
+{
+ switch (method) {
+ case DS_O_SIGNAL:
+ return -EOPNOTSUPP;
+ case DS_O_WRAP:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+int ds_get_overflow(void *ds)
+{
+ return DS_O_WRAP;
+}
+
+int ds_clear(void *ds)
+{
+ int bts_size = ds_get_bts_size(ds);
+ void *bts_base;
+
+ if (bts_size <= 0)
+ return bts_size;
+
+ bts_base = get_bts_buffer_base(ds);
+ memset(bts_base, 0, bts_size);
+
+ set_bts_index(ds, bts_base);
+ return 0;
+}
+
int ds_read_bts(void *ds, size_t index, struct bts_struct *out)
{
void *bts;