xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Dietmar Hahn <dietmar.hahn@ts.fujitsu.com>
To: "xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>
Cc: "Shan, Haitao" <haitao.shan@intel.com>
Subject: [PATCH 2 of 2]  vpmu:  Add the BTS extension
Date: Mon, 13 Feb 2012 14:01:40 +0100	[thread overview]
Message-ID: <6587132.0KbvunDmjW@amur> (raw)


Add the BTS functionality to the existing vpmu implementation for Intel cpus.

Signed-off-by: Dietmar Hahn <dietmar.hahn@ts.fujitsu.com>

 xen/arch/x86/hvm/vmx/vmx.c               |   12 +-
 xen/arch/x86/hvm/vmx/vpmu_core2.c        |  156 +++++++++++++++++++++++++-----
 xen/include/asm-x86/hvm/vmx/vpmu_core2.h |    1 +
 xen/include/asm-x86/hvm/vpmu.h           |    3 +
 xen/include/asm-x86/msr-index.h          |    5 +
 5 files changed, 148 insertions(+), 29 deletions(-)



diff -r 6c666c08cf0d xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Feb 13 12:36:09 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Feb 13 13:51:51 2012 +0100
@@ -1823,6 +1823,9 @@ static int vmx_msr_read_intercept(unsign
         /* Debug Trace Store is not supported. */
         *msr_content |= MSR_IA32_MISC_ENABLE_BTS_UNAVAIL |
                        MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL;
+        /* Perhaps vpmu will change some bits. */
+        if ( vpmu_do_rdmsr(msr, msr_content) )
+            goto done;
         break;
     default:
         if ( vpmu_do_rdmsr(msr, msr_content) )
@@ -1950,9 +1953,14 @@ static int vmx_msr_write_intercept(unsig
         int i, rc = 0;
         uint64_t supported = IA32_DEBUGCTLMSR_LBR | IA32_DEBUGCTLMSR_BTF;
 
-        if ( !msr_content || (msr_content & ~supported) )
+        if ( !msr_content )
             break;
-
+        if ( msr_content & ~supported )
+        {
+            /* Perhaps some other bits are supported in vpmu. */
+            if ( !vpmu_do_wrmsr(msr, msr_content) )
+                break;
+        }
         if ( msr_content & IA32_DEBUGCTLMSR_LBR )
         {
             const struct lbr_info *lbr = last_branch_msr_get();
diff -r 6c666c08cf0d xen/arch/x86/hvm/vmx/vpmu_core2.c
--- a/xen/arch/x86/hvm/vmx/vpmu_core2.c	Mon Feb 13 12:36:09 2012 +0100
+++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c	Mon Feb 13 13:51:51 2012 +0100
@@ -401,7 +401,31 @@ static int core2_vpmu_do_wrmsr(unsigned 
     struct core2_vpmu_context *core2_vpmu_cxt = NULL;
 
     if ( !core2_vpmu_msr_common_check(msr, &type, &index) )
+    {
+        /* Special handling for BTS */
+        if ( msr == MSR_IA32_DEBUGCTLMSR )
+        {
+            uint64_t supported = IA32_DEBUGCTLMSR_TR | IA32_DEBUGCTLMSR_BTS |
+                                 IA32_DEBUGCTLMSR_BTINT;
+
+            if ( cpu_has(&current_cpu_data, X86_FEATURE_DSCPL) )
+            {
+                supported |= IA32_DEBUGCTLMSR_BTS_OFF_OS |
+                                 IA32_DEBUGCTLMSR_BTS_OFF_USR;
+            }
+            if ( msr_content & supported  )
+            {
+                if ( !vpmu_is_set(vpmu, VPMU_CPU_HAS_BTS) )
+                {
+                    gdprintk(XENLOG_WARNING, "Debug Store is not supported on this cpu\n");
+                    vmx_inject_hw_exception(TRAP_gp_fault, 0);
+                    return 0;
+                }
+                return 1;
+            }
+        }
         return 0;
+    }
 
     core2_vpmu_cxt = vpmu->context;
     switch ( msr )
@@ -420,8 +444,26 @@ static int core2_vpmu_do_wrmsr(unsigned 
                      "which is not supported.\n");
         return 1;
     case MSR_IA32_DS_AREA:
-        gdprintk(XENLOG_WARNING, "Guest setting of DTS is ignored.\n");
-        return 1;
+        if ( vpmu_is_set(vpmu, VPMU_CPU_HAS_DS) )
+        {
+            if (!msr_content || !is_canonical_address(msr_content))
+            {
+                gdprintk(XENLOG_WARNING, "Illegal address for IA32_DS_AREA: 0x%lx\n",
+                                                            msr_content);
+                vmx_inject_hw_exception(TRAP_gp_fault, 0);
+                return 1;
+            }
+            else
+            {
+                core2_vpmu_cxt->pmu_enable->ds_area_enable = msr_content ? 1 : 0;
+                break;
+            }
+        }
+        else
+        {
+            gdprintk(XENLOG_WARNING, "Guest setting of DTS is ignored.\n");
+            return 1;
+        }
     case MSR_CORE_PERF_GLOBAL_CTRL:
         global_ctrl = msr_content;
         for ( i = 0; i < core2_get_pmc_count(); i++ )
@@ -466,6 +508,7 @@ static int core2_vpmu_do_wrmsr(unsigned 
         pmu_enable |= core2_vpmu_cxt->pmu_enable->fixed_ctr_enable[i];
     for ( i = 0; i < core2_get_pmc_count(); i++ )
         pmu_enable |= core2_vpmu_cxt->pmu_enable->arch_pmc_enable[i];
+    pmu_enable |= core2_vpmu_cxt->pmu_enable->ds_area_enable;
     if ( pmu_enable )
         vpmu_set(vpmu, VPMU_RUNNING);
     else
@@ -491,6 +534,8 @@ static int core2_vpmu_do_wrmsr(unsigned 
                 inject_gp = 1;
             break;
         case MSR_TYPE_CTRL:           /* IA32_FIXED_CTR_CTRL */
+            if  ( msr == MSR_IA32_DS_AREA )
+                break;
             /* 4 bits per counter, currently 3 fixed counters implemented. */
             mask = ~((1ull << (3 * 4)) - 1);
             if (msr_content & mask)
@@ -520,25 +565,35 @@ static int core2_vpmu_do_rdmsr(unsigned 
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
     struct core2_vpmu_context *core2_vpmu_cxt = NULL;
 
-    if ( !core2_vpmu_msr_common_check(msr, &type, &index) )
-        return 0;
-
-    core2_vpmu_cxt = vpmu->context;
-    switch ( msr )
+    if ( core2_vpmu_msr_common_check(msr, &type, &index) )
     {
-    case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
-        *msr_content = 0;
-        break;
-    case MSR_CORE_PERF_GLOBAL_STATUS:
-        *msr_content = core2_vpmu_cxt->global_ovf_status;
-        break;
-    case MSR_CORE_PERF_GLOBAL_CTRL:
-        vmx_read_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL, msr_content);
-        break;
-    default:
-        rdmsrl(msr, *msr_content);
+        core2_vpmu_cxt = vpmu->context;
+        switch ( msr )
+        {
+        case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
+            *msr_content = 0;
+            break;
+        case MSR_CORE_PERF_GLOBAL_STATUS:
+            *msr_content = core2_vpmu_cxt->global_ovf_status;
+            break;
+        case MSR_CORE_PERF_GLOBAL_CTRL:
+            vmx_read_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL, msr_content);
+            break;
+        default:
+            rdmsrl(msr, *msr_content);
+        }
     }
-
+    else
+    {
+        /* Extension for BTS */
+        if ( msr == MSR_IA32_MISC_ENABLE)
+        {
+            if ( vpmu_is_set(vpmu, VPMU_CPU_HAS_BTS) )
+                *msr_content &= ~MSR_IA32_MISC_ENABLE_BTS_UNAVAIL;
+        }
+        else
+            return 0;
+    }
     return 1;
 }
 
@@ -553,15 +608,24 @@ static int core2_vpmu_do_interrupt(struc
     struct vlapic *vlapic = vcpu_vlapic(v);
 
     rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, msr_content);
-    if ( !msr_content )
-        return 0;
+    if ( msr_content )
+    {
+        if ( is_pmc_quirk )
+            handle_pmc_quirk(msr_content);
 
-    if ( is_pmc_quirk )
-        handle_pmc_quirk(msr_content);
-
-    core2_vpmu_cxt->global_ovf_status |= msr_content;
-    msr_content = 0xC000000700000000 | ((1 << core2_get_pmc_count()) - 1);
-    wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, msr_content);
+        core2_vpmu_cxt->global_ovf_status |= msr_content;
+        msr_content = 0xC000000700000000 | ((1 << core2_get_pmc_count()) - 1);
+        wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, msr_content);
+    }
+    else
+    {
+        /* No PMC overflow but perhaps a Trace Message interrupt. */
+        msr_content = __vmread(GUEST_IA32_DEBUGCTL);
+        if ( !(msr_content & IA32_DEBUGCTLMSR_TR) )
+        {
+            return 0;
+        }
+    }
 
     apic_write_around(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
 
@@ -582,10 +646,48 @@ static void core2_vpmu_do_cpuid(unsigned
                                 unsigned int *eax, unsigned int *ebx,
                                 unsigned int *ecx, unsigned int *edx)
 {
+    if (input == 0x1)
+    {
+        struct vpmu_struct *vpmu = vcpu_vpmu(current);
+
+        if ( vpmu_is_set(vpmu, VPMU_CPU_HAS_DS) )
+        {
+            /* Switch on the 'Debug Store' feature in CPUID.EAX[1]:EDX[21] */
+            *edx |= cpufeat_mask(X86_FEATURE_DS);
+        }
+    }
 }
 
 static void core2_vpmu_initialise(struct vcpu *v)
 {
+    struct vpmu_struct *vpmu = vcpu_vpmu(v);
+    u64 msr_content;
+    struct cpuinfo_x86 *c = &current_cpu_data;
+
+    /* Check the 'Debug Store' feature in the CPUID.EAX[1]:EDX[21] */
+    if ( cpu_has(c, X86_FEATURE_DS) )
+    {
+        if ( !cpu_has(c, X86_FEATURE_DTES64) )
+        {
+            gdprintk(XENLOG_WARNING, "CPU doesn't support 64-bit DS Area - Debug Store disabled\n");
+            goto func_out;
+        }
+        vpmu_set(vpmu, VPMU_CPU_HAS_DS);
+        rdmsrl(MSR_IA32_MISC_ENABLE, msr_content);
+        if ( msr_content & MSR_IA32_MISC_ENABLE_BTS_UNAVAIL )
+        {
+            /* If BTS_UNAVAIL is set reset the DS feature. */
+            vpmu_reset(vpmu, VPMU_CPU_HAS_DS);
+            gdprintk(XENLOG_WARNING, "CPU has set BTS_UNAVAIL - Debug Store disabled\n");
+        }
+        else
+            vpmu_set(vpmu, VPMU_CPU_HAS_BTS);
+            if ( !cpu_has(c, X86_FEATURE_DSCPL) )
+            {
+                gdprintk(XENLOG_WARNING, "vpmu: cpu doesn't support CPL-Qualified BTS\n");
+            }
+    }
+func_out:
     check_pmc_quirk();
 }
 
diff -r 6c666c08cf0d xen/include/asm-x86/hvm/vmx/vpmu_core2.h
--- a/xen/include/asm-x86/hvm/vmx/vpmu_core2.h	Mon Feb 13 12:36:09 2012 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vpmu_core2.h	Mon Feb 13 13:51:51 2012 +0100
@@ -29,6 +29,7 @@ struct arch_msr_pair {
 };
 
 struct core2_pmu_enable {
+    char ds_area_enable;
     char fixed_ctr_enable[3];
     char arch_pmc_enable[1];
 };
diff -r 6c666c08cf0d xen/include/asm-x86/hvm/vpmu.h
--- a/xen/include/asm-x86/hvm/vpmu.h	Mon Feb 13 12:36:09 2012 +0100
+++ b/xen/include/asm-x86/hvm/vpmu.h	Mon Feb 13 13:51:51 2012 +0100
@@ -72,6 +72,9 @@ struct vpmu_struct {
 #define VPMU_CONTEXT_LOADED                 0x2
 #define VPMU_RUNNING                        0x4
 #define VPMU_PASSIVE_DOMAIN_ALLOCATED       0x8
+#define VPMU_CPU_HAS_DS                     0x10 /* Has Debug Store */
+#define VPMU_CPU_HAS_BTS                    0x20 /* Has Branche Trace Store */
+
 
 #define vpmu_set(_vpmu, _x)    ((_vpmu)->flags |= (_x))
 #define vpmu_reset(_vpmu, _x)  ((_vpmu)->flags &= ~(_x))
diff -r 6c666c08cf0d xen/include/asm-x86/msr-index.h
--- a/xen/include/asm-x86/msr-index.h	Mon Feb 13 12:36:09 2012 +0100
+++ b/xen/include/asm-x86/msr-index.h	Mon Feb 13 13:51:51 2012 +0100
@@ -67,6 +67,11 @@
 #define MSR_IA32_DEBUGCTLMSR		0x000001d9
 #define IA32_DEBUGCTLMSR_LBR		(1<<0) /* Last Branch Record */
 #define IA32_DEBUGCTLMSR_BTF		(1<<1) /* Single Step on Branches */
+#define IA32_DEBUGCTLMSR_TR		(1<<6) /* Trace Message Enable */
+#define IA32_DEBUGCTLMSR_BTS		(1<<7) /* Branch Trace Store */
+#define IA32_DEBUGCTLMSR_BTINT		(1<<8) /* Branch Trace Interrupt */
+#define IA32_DEBUGCTLMSR_BTS_OFF_OS	(1<<9)  /* BTS off if CPL 0 */
+#define IA32_DEBUGCTLMSR_BTS_OFF_USR	(1<<10) /* BTS off if CPL > 0 */
 
 #define MSR_IA32_LASTBRANCHFROMIP	0x000001db
 #define MSR_IA32_LASTBRANCHTOIP		0x000001dc

-- 
Company details: http://ts.fujitsu.com/imprint.html

             reply	other threads:[~2012-02-13 13:01 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-13 13:01 Dietmar Hahn [this message]
2012-02-14 11:51 ` [PATCH 2 of 2] vpmu: Add the BTS extension Jan Beulich
2012-02-14 12:59   ` Dietmar Hahn
2012-02-14 13:27     ` Jan Beulich
2012-02-14 14:30       ` Dietmar Hahn
2012-02-14 14:50         ` Jan Beulich
2012-02-15 10:18           ` Dietmar Hahn
2012-02-15 10:29             ` Jan Beulich

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=6587132.0KbvunDmjW@amur \
    --to=dietmar.hahn@ts.fujitsu.com \
    --cc=haitao.shan@intel.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).