linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andi Kleen <andi@firstfloor.org>
To: peterz@infradead.org
Cc: gleb@kernel.org, pbonzini@redhat.com, eranian@google.com,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	Andi Kleen <ak@linux.intel.com>
Subject: [PATCH 3/4] perf: Handle guest PEBS events with a fake event
Date: Thu, 29 May 2014 18:12:06 -0700	[thread overview]
Message-ID: <1401412327-14810-4-git-send-email-andi@firstfloor.org> (raw)
In-Reply-To: <1401412327-14810-1-git-send-email-andi@firstfloor.org>

From: Andi Kleen <ak@linux.intel.com>

With PEBS virtualization the PEBS record gets delivered to the guest,
but the host sees the PMI. This would normally result in a spurious
PEBS PMI that is ignored. But we need to inject the PMI into the guest,
so that the guest PMI handler can handle the PEBS record.

Check for this case in the perf PEBS handler.  When any guest PEBS
counters are active always check the counters explicitely for
overflow. If a guest PEBs counter overflowed trigger a fake event. The
fake event results in calling the KVM PMI callback, which injects
the PMI into the guest. The guest handler then retrieves the correct
information from its own PEBS record and the guest state.

Note: in very rare cases with exotic events this may lead to spurious PMIs
in the guest.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c | 49 +++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 29622a7..0267174 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -998,6 +998,53 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
 	__intel_pmu_pebs_event(event, iregs, at);
 }
 
+/*
+ * We may be running with virtualized PEBS, so the PEBS record
+ * was logged into the guest's DS and is invisible to us.
+ *
+ * For guest-owned counters we always have to check the counter
+ * and see if they are overflowed, because PEBS thresholds
+ * are not reported in the GLOBAL_STATUS.
+ *
+ * In this case just trigger a fake event for KVM to forward
+ * to the guest as PMI.  The guest will then see the real PEBS
+ * record and read the counter values.
+ *
+ * The contents of the event do not matter.
+ */
+static void intel_pmu_handle_guest_pebs(struct cpu_hw_events *cpuc,
+					struct pt_regs *iregs)
+{
+	int bit;
+	struct perf_event *event;
+
+	if (!cpuc->intel_ctrl_guest_owned)
+		return;
+
+	for_each_set_bit(bit, (unsigned long *)&cpuc->intel_ctrl_guest_owned,
+			 x86_pmu.max_pebs_events) {
+		struct perf_sample_data data;
+		s64 count;
+		int shift;
+
+		event = cpuc->events[bit];
+		if (!event->attr.precise_ip)
+			continue;
+		rdpmcl(event->hw.event_base_rdpmc, count);
+
+		/* sign extend */
+		shift = 64 - x86_pmu.cntval_bits;
+		count = ((s64)((u64)count << shift)) >> shift;
+
+		if (count < 0)
+			continue;
+
+		perf_sample_data_init(&data, 0, event->hw.last_period);
+		if (perf_event_overflow(event, &data, iregs))
+			x86_pmu_stop(event, 0);
+	}
+}
+
 static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -1010,6 +1057,8 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
 	if (!x86_pmu.pebs_active)
 		return;
 
+	intel_pmu_handle_guest_pebs(cpuc, iregs);
+
 	at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
 	top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
 
-- 
1.9.0


  parent reply	other threads:[~2014-05-30  1:13 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-30  1:12 Implement PEBS virtualization for Silvermont Andi Kleen
2014-05-30  1:12 ` [PATCH 1/4] perf: Add PEBS virtualization enable " Andi Kleen
2014-05-30  1:12 ` [PATCH 2/4] perf: Allow guest PEBS for KVM owned counters Andi Kleen
2014-05-30  7:31   ` Peter Zijlstra
2014-05-30 16:03     ` Andi Kleen
2014-05-30 16:17       ` Peter Zijlstra
2014-05-30  1:12 ` Andi Kleen [this message]
2014-05-30  7:34   ` [PATCH 3/4] perf: Handle guest PEBS events with a fake event Peter Zijlstra
2014-05-30 16:29     ` Andi Kleen
2014-05-30  1:12 ` [PATCH 4/4] kvm: Implement PEBS virtualization Andi Kleen
2014-05-30  8:21   ` Gleb Natapov
2014-05-30 16:24     ` Andi Kleen
2014-06-02 16:45       ` Gleb Natapov
2014-06-02 16:52         ` Andi Kleen
2014-06-02 19:09         ` Marcelo Tosatti
2014-06-02 19:05   ` Eric Northup
2014-06-02 19:57     ` Andi Kleen
2014-06-19 14:39       ` Paolo Bonzini
2014-06-10 18:04   ` Marcelo Tosatti
2014-06-10 19:22     ` Andi Kleen
2014-06-10 21:06       ` Marcelo Tosatti
2014-06-19 14:42         ` Paolo Bonzini
2014-06-19 17:33           ` Andi Kleen
2014-06-19 20:33             ` Paolo Bonzini
2014-06-22 13:57   ` Avi Kivity
2014-06-22 19:02     ` Andi Kleen
2014-06-24 16:45       ` Marcelo Tosatti
2014-06-25  7:04         ` Avi Kivity
2014-05-30  7:39 ` Implement PEBS virtualization for Silvermont Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1401412327-14810-4-git-send-email-andi@firstfloor.org \
    --to=andi@firstfloor.org \
    --cc=ak@linux.intel.com \
    --cc=eranian@google.com \
    --cc=gleb@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).