xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Jacob Shin <jacob.shin@amd.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH 3/3] hvm: vpmu: Add support for AMD Family 15h processors
Date: Wed, 4 May 2011 20:09:18 -0500	[thread overview]
Message-ID: <4DC1F8BE.3060707@amd.com> (raw)
In-Reply-To: <4DC1F53B.4050201@amd.com>

# HG changeset patch
# User Jacob Shin <jacob.shin@amd.com>
# Date 1304554679 18000
# Node ID 43a81a05dbf7bbb6e29b283e0cd5f80d8ac04aab
# Parent  349a9e537940f8bc340a2055cb5068b58809042f
hvm: vpmu: Add support for AMD Family 15h processors

AMD Family 15h CPU mirrors legacy K7 performance monitor counters to
a new location, and adds 2 new counters. This patch updates HVM VPMU
to take advantage of the new counters.

Signed-off-by: Jacob Shin <jacob.shin@amd.com>

diff -r 349a9e537940 -r 43a81a05dbf7 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c	Wed May 04 10:56:36 2011 -0500
+++ b/xen/arch/x86/hvm/svm/svm.c	Wed May 04 19:17:59 2011 -0500
@@ -1235,6 +1235,18 @@ static int svm_msr_read_intercept(unsign
     case MSR_K7_EVNTSEL1:
     case MSR_K7_EVNTSEL2:
     case MSR_K7_EVNTSEL3:
+    case MSR_FAM15H_PERFCTR0:
+    case MSR_FAM15H_PERFCTR1:
+    case MSR_FAM15H_PERFCTR2:
+    case MSR_FAM15H_PERFCTR3:
+    case MSR_FAM15H_PERFCTR4:
+    case MSR_FAM15H_PERFCTR5:
+    case MSR_FAM15H_EVNTSEL0:
+    case MSR_FAM15H_EVNTSEL1:
+    case MSR_FAM15H_EVNTSEL2:
+    case MSR_FAM15H_EVNTSEL3:
+    case MSR_FAM15H_EVNTSEL4:
+    case MSR_FAM15H_EVNTSEL5:
         vpmu_do_rdmsr(msr, msr_content);
         break;
 
@@ -1333,6 +1345,18 @@ static int svm_msr_write_intercept(unsig
     case MSR_K7_EVNTSEL1:
     case MSR_K7_EVNTSEL2:
     case MSR_K7_EVNTSEL3:
+    case MSR_FAM15H_PERFCTR0:
+    case MSR_FAM15H_PERFCTR1:
+    case MSR_FAM15H_PERFCTR2:
+    case MSR_FAM15H_PERFCTR3:
+    case MSR_FAM15H_PERFCTR4:
+    case MSR_FAM15H_PERFCTR5:
+    case MSR_FAM15H_EVNTSEL0:
+    case MSR_FAM15H_EVNTSEL1:
+    case MSR_FAM15H_EVNTSEL2:
+    case MSR_FAM15H_EVNTSEL3:
+    case MSR_FAM15H_EVNTSEL4:
+    case MSR_FAM15H_EVNTSEL5:
         vpmu_do_wrmsr(msr, msr_content);
         break;
 
diff -r 349a9e537940 -r 43a81a05dbf7 xen/arch/x86/hvm/svm/vpmu.c
--- a/xen/arch/x86/hvm/svm/vpmu.c	Wed May 04 10:56:36 2011 -0500
+++ b/xen/arch/x86/hvm/svm/vpmu.c	Wed May 04 19:17:59 2011 -0500
@@ -36,7 +36,9 @@
 #include <public/hvm/save.h>
 #include <asm/hvm/vpmu.h>
 
-#define NUM_COUNTERS 4
+#define F10H_NUM_COUNTERS 4
+#define F15H_NUM_COUNTERS 6
+#define MAX_NUM_COUNTERS F15H_NUM_COUNTERS
 
 #define MSR_F10H_EVNTSEL_GO_SHIFT   40
 #define MSR_F10H_EVNTSEL_EN_SHIFT   22
@@ -46,6 +48,11 @@
 #define is_pmu_enabled(msr) ((msr) & (1ULL << MSR_F10H_EVNTSEL_EN_SHIFT))
 #define set_guest_mode(msr) (msr |= (1ULL << MSR_F10H_EVNTSEL_GO_SHIFT))
 #define is_overflowed(msr) (!((msr) & (1ULL << (MSR_F10H_COUNTER_LENGTH-1))))
+
+static int __read_mostly num_counters = 0;
+static u32 __read_mostly *counters = NULL;
+static u32 __read_mostly *ctrls = NULL;
+static bool_t __read_mostly k7_counters_mirrored = 0;
 
 /* PMU Counter MSRs. */
 u32 AMD_F10H_COUNTERS[] = {
@@ -63,10 +70,28 @@ u32 AMD_F10H_CTRLS[] = {
     MSR_K7_EVNTSEL3
 };
 
+u32 AMD_F15H_COUNTERS[] = {
+    MSR_FAM15H_PERFCTR0,
+    MSR_FAM15H_PERFCTR1,
+    MSR_FAM15H_PERFCTR2,
+    MSR_FAM15H_PERFCTR3,
+    MSR_FAM15H_PERFCTR4,
+    MSR_FAM15H_PERFCTR5
+};
+
+u32 AMD_F15H_CTRLS[] = {
+    MSR_FAM15H_EVNTSEL0,
+    MSR_FAM15H_EVNTSEL1,
+    MSR_FAM15H_EVNTSEL2,
+    MSR_FAM15H_EVNTSEL3,
+    MSR_FAM15H_EVNTSEL4,
+    MSR_FAM15H_EVNTSEL5
+};
+
 /* storage for context switching */
 struct amd_vpmu_context {
-    u64 counters[NUM_COUNTERS];
-    u64 ctrls[NUM_COUNTERS];
+    u64 counters[MAX_NUM_COUNTERS];
+    u64 ctrls[MAX_NUM_COUNTERS];
     u32 hw_lapic_lvtpc;
 };
 
@@ -78,10 +103,44 @@ static inline int get_pmu_reg_type(u32 a
     if ( (addr >= MSR_K7_PERFCTR0) && (addr <= MSR_K7_PERFCTR3) )
         return MSR_TYPE_COUNTER;
 
+    if ( (addr >= MSR_FAM15H_EVNTSEL0) && (addr <= MSR_FAM15H_PERFCTR5 ) )
+    {
+        if (addr & 1)
+            return MSR_TYPE_COUNTER;
+        else
+            return MSR_TYPE_CTRL;
+    }
+
     /* unsupported registers */
     return -1;
 }
 
+static inline u32 get_fam15h_addr(u32 addr)
+{
+    switch ( addr )
+    {
+    case MSR_K7_PERFCTR0:
+        return MSR_FAM15H_PERFCTR0;
+    case MSR_K7_PERFCTR1:
+        return MSR_FAM15H_PERFCTR1;
+    case MSR_K7_PERFCTR2:
+        return MSR_FAM15H_PERFCTR2;
+    case MSR_K7_PERFCTR3:
+        return MSR_FAM15H_PERFCTR3;
+    case MSR_K7_EVNTSEL0:
+        return MSR_FAM15H_EVNTSEL0;
+    case MSR_K7_EVNTSEL1:
+        return MSR_FAM15H_EVNTSEL1;
+    case MSR_K7_EVNTSEL2:
+        return MSR_FAM15H_EVNTSEL2;
+    case MSR_K7_EVNTSEL3:
+        return MSR_FAM15H_EVNTSEL3;
+    default:
+        break;
+    }
+
+    return addr;
+}
 
 static int amd_vpmu_do_interrupt(struct cpu_user_regs *regs)
 {
@@ -110,12 +169,12 @@ static inline void context_restore(struc
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
     struct amd_vpmu_context *ctxt = vpmu->context;
 
-    for ( i = 0; i < NUM_COUNTERS; i++ )
-        wrmsrl(AMD_F10H_CTRLS[i], ctxt->ctrls[i]);
+    for ( i = 0; i < num_counters; i++ )
+        wrmsrl(ctrls[i], ctxt->ctrls[i]);
 
-    for ( i = 0; i < NUM_COUNTERS; i++ )
+    for ( i = 0; i < num_counters; i++ )
     {
-        wrmsrl(AMD_F10H_COUNTERS[i], ctxt->counters[i]);
+        wrmsrl(counters[i], ctxt->counters[i]);
 
         /* Force an interrupt to allow guest reset the counter,
         if the value is positive */
@@ -147,11 +206,11 @@ static inline void context_save(struct v
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
     struct amd_vpmu_context *ctxt = vpmu->context;
 
-    for ( i = 0; i < NUM_COUNTERS; i++ )
-        rdmsrl(AMD_F10H_COUNTERS[i], ctxt->counters[i]);
+    for ( i = 0; i < num_counters; i++ )
+        rdmsrl(counters[i], ctxt->counters[i]);
 
-    for ( i = 0; i < NUM_COUNTERS; i++ )
-        rdmsrl(AMD_F10H_CTRLS[i], ctxt->ctrls[i]);
+    for ( i = 0; i < num_counters; i++ )
+        rdmsrl(ctrls[i], ctxt->ctrls[i]);
 }
 
 static void amd_vpmu_save(struct vcpu *v)
@@ -175,12 +234,18 @@ static void context_update(unsigned int 
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
     struct amd_vpmu_context *ctxt = vpmu->context;
 
-    for ( i = 0; i < NUM_COUNTERS; i++ )
-        if ( msr == AMD_F10H_COUNTERS[i] )
+    if ( k7_counters_mirrored &&
+        ((msr >= MSR_K7_EVNTSEL0) && (msr <= MSR_K7_PERFCTR3)) )
+    {
+        msr = get_fam15h_addr(msr);
+    }
+
+    for ( i = 0; i < num_counters; i++ )
+        if ( msr == counters[i] )
             ctxt->counters[i] = msr_content;
 
-    for ( i = 0; i < NUM_COUNTERS; i++ )
-        if ( msr == AMD_F10H_CTRLS[i] )
+    for ( i = 0; i < num_counters; i++ )
+        if ( msr == ctrls[i] )
             ctxt->ctrls[i] = msr_content;
 
     ctxt->hw_lapic_lvtpc = apic_read(APIC_LVTPC);
@@ -235,9 +300,30 @@ static void amd_vpmu_initialise(struct v
 {
     struct amd_vpmu_context *ctxt = NULL;
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
+    __u8 family = current_cpu_data.x86;
 
     if ( vpmu->flags & VPMU_CONTEXT_ALLOCATED )
         return;
+
+    if ( counters == NULL )
+    {
+         switch ( family )
+	 {
+	 case 0x15:
+	     num_counters = F15H_NUM_COUNTERS;
+	     counters = AMD_F15H_COUNTERS;
+	     ctrls = AMD_F15H_CTRLS;
+	     k7_counters_mirrored = 1;
+	     break;
+	 case 0x10:
+	 default:
+	     num_counters = F10H_NUM_COUNTERS;
+	     counters = AMD_F10H_COUNTERS;
+	     ctrls = AMD_F10H_CTRLS;
+	     k7_counters_mirrored = 0;
+	     break;
+	 }
+    }
 
     ctxt = xmalloc_bytes(sizeof(struct amd_vpmu_context));
 
diff -r 349a9e537940 -r 43a81a05dbf7 xen/arch/x86/hvm/vpmu.c
--- a/xen/arch/x86/hvm/vpmu.c	Wed May 04 10:56:36 2011 -0500
+++ b/xen/arch/x86/hvm/vpmu.c	Wed May 04 19:17:59 2011 -0500
@@ -101,6 +101,7 @@ void vpmu_initialise(struct vcpu *v)
         switch ( family )
         {
         case 0x10:
+        case 0x15:
             vpmu->arch_vpmu_ops = &amd_vpmu_ops;
             break;
         default:

  parent reply	other threads:[~2011-05-05  1:09 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-05  0:54 [PATCH 0/3] AMD Family 15h Performance Monitor Counters patches Jacob Shin
2011-05-05  1:09 ` [PATCH 1/3] xenoprof: Update cpu_type to sync with upstream oprofile Jacob Shin
2011-05-05  1:09 ` [PATCH 2/3] xenoprof: Add support for AMD Family 15h processors Jacob Shin
2011-05-05  7:38   ` Jan Beulich
2011-05-05  1:09 ` Jacob Shin [this message]
2011-05-05  7:43   ` [PATCH 3/3] hvm: vpmu: " Jan Beulich
2011-05-10 17:00     ` Jacob Shin
2011-05-10 17:20       ` Keir Fraser

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=4DC1F8BE.3060707@amd.com \
    --to=jacob.shin@amd.com \
    --cc=xen-devel@lists.xensource.com \
    /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).