summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2009-06-03 20:54:56 +0200
committerRobert Richter <robert.richter@amd.com>2009-06-11 20:16:00 +0200
commit51563a0e5650d0d76539625388d72d62b34c726e (patch)
tree17148f56578af8f7d7d67491f8b7eb05d99acdd9
parentc572ae4efd1b0a5cc76c5e6aae05c1b182b6a69c (diff)
downloadlinux-51563a0e5650d0d76539625388d72d62b34c726e.tar.bz2
x86/oprofile: introduce oprofile_add_data64()
The IBS implemention writes 64 bit register values to the cpu buffer by writing two 32 values using oprofile_add_data(). This patch introduces oprofile_add_data64() to write a single 64 bit value to the buffer. Signed-off-by: Robert Richter <robert.richter@amd.com>
-rw-r--r--arch/x86/oprofile/op_model_amd.c27
-rw-r--r--drivers/oprofile/cpu_buffer.c15
-rw-r--r--include/linux/oprofile.h1
3 files changed, 25 insertions, 18 deletions
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 6493ef7ae9ad..cc930467575d 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -140,13 +140,10 @@ op_amd_handle_ibs(struct pt_regs * const regs,
rdmsrl(MSR_AMD64_IBSFETCHLINAD, val);
oprofile_write_reserve(&entry, regs, val,
IBS_FETCH_CODE, IBS_FETCH_SIZE);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
- oprofile_add_data(&entry, (u32)ctl);
- oprofile_add_data(&entry, (u32)(ctl >> 32));
+ oprofile_add_data64(&entry, val);
+ oprofile_add_data64(&entry, ctl);
rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, val);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
+ oprofile_add_data64(&entry, val);
oprofile_write_commit(&entry);
/* reenable the IRQ */
@@ -162,23 +159,17 @@ op_amd_handle_ibs(struct pt_regs * const regs,
rdmsrl(MSR_AMD64_IBSOPRIP, val);
oprofile_write_reserve(&entry, regs, val,
IBS_OP_CODE, IBS_OP_SIZE);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
+ oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSOPDATA, val);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
+ oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSOPDATA2, val);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
+ oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSOPDATA3, val);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
+ oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSDCLINAD, val);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
+ oprofile_add_data64(&entry, val);
rdmsrl(MSR_AMD64_IBSDCPHYSAD, val);
- oprofile_add_data(&entry, (u32)val);
- oprofile_add_data(&entry, (u32)(val >> 32));
+ oprofile_add_data64(&entry, val);
oprofile_write_commit(&entry);
/* reenable the IRQ */
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 50640cc5eef2..a7aae24f2889 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -406,6 +406,21 @@ int oprofile_add_data(struct op_entry *entry, unsigned long val)
return op_cpu_buffer_add_data(entry, val);
}
+int oprofile_add_data64(struct op_entry *entry, u64 val)
+{
+ if (!entry->event)
+ return 0;
+ if (op_cpu_buffer_get_size(entry) < 2)
+ /*
+ * the function returns 0 to indicate a too small
+ * buffer, even if there is some space left
+ */
+ return 0;
+ if (!op_cpu_buffer_add_data(entry, (u32)val))
+ return 0;
+ return op_cpu_buffer_add_data(entry, (u32)(val >> 32));
+}
+
int oprofile_write_commit(struct op_entry *entry)
{
if (!entry->event)
diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h
index dbbe2dbc4418..d68d2ed94f15 100644
--- a/include/linux/oprofile.h
+++ b/include/linux/oprofile.h
@@ -179,6 +179,7 @@ void oprofile_write_reserve(struct op_entry *entry,
struct pt_regs * const regs,
unsigned long pc, int code, int size);
int oprofile_add_data(struct op_entry *entry, unsigned long val);
+int oprofile_add_data64(struct op_entry *entry, u64 val);
int oprofile_write_commit(struct op_entry *entry);
#endif /* OPROFILE_H */