summaryrefslogtreecommitdiffstats
path: root/arch/x86/events/intel/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/events/intel/pt.c')
-rw-r--r--arch/x86/events/intel/pt.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index c87d163c2917..1db7a51d9792 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -606,6 +606,7 @@ static inline phys_addr_t topa_pfn(struct topa *topa)
static void pt_config_buffer(struct pt_buffer *buf)
{
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
u64 reg, mask;
void *base;
@@ -617,11 +618,17 @@ static void pt_config_buffer(struct pt_buffer *buf)
mask = (u64)buf->cur_idx;
}
- wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, virt_to_phys(base));
+ reg = virt_to_phys(base);
+ if (pt->output_base != reg) {
+ pt->output_base = reg;
+ wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, reg);
+ }
reg = 0x7f | (mask << 7) | ((u64)buf->output_off << 32);
-
- wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
+ if (pt->output_mask != reg) {
+ pt->output_mask = reg;
+ wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
+ }
}
/**
@@ -930,21 +937,21 @@ static void pt_handle_status(struct pt *pt)
*/
static void pt_read_offset(struct pt_buffer *buf)
{
- u64 offset, base;
+ struct pt *pt = this_cpu_ptr(&pt_ctx);
struct topa_page *tp;
if (!buf->single) {
- rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, base);
- tp = phys_to_virt(base);
+ rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, pt->output_base);
+ tp = phys_to_virt(pt->output_base);
buf->cur = &tp->topa;
}
- rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, offset);
+ rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, pt->output_mask);
/* offset within current output region */
- buf->output_off = offset >> 32;
+ buf->output_off = pt->output_mask >> 32;
/* index of current output region within this table */
if (!buf->single)
- buf->cur_idx = (offset & 0xffffff80) >> 7;
+ buf->cur_idx = (pt->output_mask & 0xffffff80) >> 7;
}
static struct topa_entry *