All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] xtf/vpmu VPMU tests
@ 2017-04-28 18:25 Mohit Gambhir
  2017-04-28 18:26 ` [PATCH v2 1/2] xtf/vpmu: Add Intel PMU MSR addresses Mohit Gambhir
  2017-04-28 18:26 ` [PATCH v2 2/2] xtf/vpmu: MSR read/write tests for VPMU Mohit Gambhir
  0 siblings, 2 replies; 3+ messages in thread
From: Mohit Gambhir @ 2017-04-28 18:25 UTC (permalink / raw)
  To: andrew.cooper3, xen-devel; +Cc: boris.ostrovsky, mgambhir, Mohit Gambhir

v2: 

Incorporated review comments received on patch v1. 

+ Changed test type from utility to functional
+ Test is now defined only for hvm64 and hvm32 instead of ALL_ENVIRONMENTS
+ Several code styling and formatting changes
+ Expanded test description for doxygen
+ Added max_leaf check before cpuid_count
+ Addded PDCM bit check before reading MSR_PERF_CAPABILTIES

v1: 

This patch series adds tests to validate VPMU functionality on x86. The tests
write and read PMU MSRs to make sure that that they have been exposed
correctly.

The ultimate goal is to address security vulnerabilities, if any, that are
vaguely mentioned in XSA-163 and make VPMU available to guests with reasonable
caveats.

Further testing is required to validate the MSR state save/restore functionality
of the VPMU, concurrent usage of the counters by a number of guests and analyze
if any other non-PMU MSRs have been exposed incorrectly.

Mohit Gambhir (2):
  xtf/vpmu: Add Intel PMU MSR addresses
  xtf/vpmu: MSR read/write tests for VPMU

 arch/x86/include/arch/msr-index.h |  12 ++
 tests/vpmu/Makefile               |   9 +
 tests/vpmu/main.c                 | 433 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 454 insertions(+)
 create mode 100644 tests/vpmu/Makefile
 create mode 100644 tests/vpmu/main.c

-- 
2.9.3


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2 1/2] xtf/vpmu: Add Intel PMU MSR addresses
  2017-04-28 18:25 [PATCH v2 0/2] xtf/vpmu VPMU tests Mohit Gambhir
@ 2017-04-28 18:26 ` Mohit Gambhir
  2017-04-28 18:26 ` [PATCH v2 2/2] xtf/vpmu: MSR read/write tests for VPMU Mohit Gambhir
  1 sibling, 0 replies; 3+ messages in thread
From: Mohit Gambhir @ 2017-04-28 18:26 UTC (permalink / raw)
  To: andrew.cooper3, xen-devel; +Cc: boris.ostrovsky, mgambhir, Mohit Gambhir

This patch adds Intel PMU MSR addresses as macros for VPMU testing

Signed-off-by: Mohit Gambhir <mohit.gambhir@oracle.com>
---
 arch/x86/include/arch/msr-index.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/x86/include/arch/msr-index.h b/arch/x86/include/arch/msr-index.h
index 72373c6..911d7f9 100644
--- a/arch/x86/include/arch/msr-index.h
+++ b/arch/x86/include/arch/msr-index.h
@@ -3,6 +3,8 @@
 
 #include <xtf/numbers.h>
 
+#define MSR_PMC(n)                      (0x000000c1 + (n))
+
 #define MSR_INTEL_PLATFORM_INFO         0x000000ce
 #define _MSR_PLATFORM_INFO_CPUID_FAULTING       31
 #define MSR_PLATFORM_INFO_CPUID_FAULTING        (1ULL << _MSR_PLATFORM_INFO_CPUID_FAULTING)
@@ -11,10 +13,20 @@
 #define _MSR_MISC_FEATURES_CPUID_FAULTING        0
 #define MSR_MISC_FEATURES_CPUID_FAULTING         (1ULL << _MSR_MISC_FEATURES_CPUID_FAULTING)
 
+#define MSR_PERFEVTSEL(n)               (0x00000186 + (n))
+
 #define MSR_DEBUGCTL                    0x000001d9
 #define _MSR_DEBUGCTL_LBR               0 /* Last Branch Record. */
 #define MSR_DEBUGCTL_LBR                (_AC(1, L) << _MSR_DEBUGCTL_LBR)
 
+#define MSR_FIXED_CTR(n)                (0x00000309 + (n))
+#define MSR_PERF_CAPABILITIES           0x00000345
+#define MSR_FIXED_CTR_CTRL              0x0000038d
+#define MSR_PERF_GLOBAL_STATUS          0x0000038e
+#define MSR_PERF_GLOBAL_CTRL            0x0000038f
+#define MSR_PERF_GLOBAL_OVF_CTRL        0x00000390
+#define MSR_A_PMC(n)                    (0x000004c1 + (n))
+
 #define MSR_EFER                        0xc0000080 /* Extended Feature register. */
 #define _EFER_SCE                       0  /* SYSCALL Enable. */
 #define EFER_SCE                        (_AC(1, L) << _EFER_SCE)
-- 
2.9.3


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/2] xtf/vpmu: MSR read/write tests for VPMU
  2017-04-28 18:25 [PATCH v2 0/2] xtf/vpmu VPMU tests Mohit Gambhir
  2017-04-28 18:26 ` [PATCH v2 1/2] xtf/vpmu: Add Intel PMU MSR addresses Mohit Gambhir
@ 2017-04-28 18:26 ` Mohit Gambhir
  1 sibling, 0 replies; 3+ messages in thread
From: Mohit Gambhir @ 2017-04-28 18:26 UTC (permalink / raw)
  To: andrew.cooper3, xen-devel; +Cc: boris.ostrovsky, mgambhir, Mohit Gambhir

This patch tests VPMU functionality in the hypervisor on Intel machines.
The tests write to all valid bits in the MSRs that get exposed to the guests
when VPMU is enabled. The tests also write invalid values to the bits
that should be masked and expect the wrmsr call to fault.

The tests are currently unsupported for AMD machines and PV guests.

Signed-off-by: Mohit Gambhir <mohit.gambhir@oracle.com>
---
 tests/vpmu/Makefile |   9 ++
 tests/vpmu/main.c   | 442 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 451 insertions(+)
 create mode 100644 tests/vpmu/Makefile
 create mode 100644 tests/vpmu/main.c

diff --git a/tests/vpmu/Makefile b/tests/vpmu/Makefile
new file mode 100644
index 0000000..57eb29d
--- /dev/null
+++ b/tests/vpmu/Makefile
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := vpmu
+CATEGORY  := functional
+TEST-ENVS := hvm64 hvm32
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/vpmu/main.c b/tests/vpmu/main.c
new file mode 100644
index 0000000..b7f9398
--- /dev/null
+++ b/tests/vpmu/main.c
@@ -0,0 +1,442 @@
+/**
+ * @file tests/vpmu/main.c
+ * @ref test-vpmu
+ *
+ * @page test-vpmu vpmu
+ *
+ * Test Virtual Performance Monitoring Unit implementation, which allows guests 
+ * to program fixed and general purpose performance counters to measure hardware
+ * performance. 
+ *
+ * The tests read and write MSRs that are  exposed by VPMU for various versions
+ * of Architectural Performance Monitoring
+ *
+ * @see tests/vpmu/main.c
+ */
+
+#include <xtf.h>
+#include <arch/msr-index.h>
+#include <arch/mm.h>
+
+#define EVENT_UOPS_RETIRED                   0x004101c2
+#define EVENT_UOPS_RETIRED_ANYTHREAD         0x006101c2
+#define FIXED_CTR_CTL_BITS                   4
+#define FIXED_CTR_ENABLE                     0x0000000A
+#define FIXED_CTR_ENABLE_ANYTHREAD           0x0000000E
+#define PERFEVENTSELx_ENABLE_ANYTHREAD       (1ull << 21)
+#define PERFEVENTSELx_ENABLE_PCB             (1ull << 19)
+#define DEBUGCTL_Freeze_LBR_ON_PMI           (1ull << 11)
+#define DEBUGCTL_Freeze_PerfMon_On_PMI       (1ull << 12)
+#define PERF_CAPABILITIES_Full_Width         (1ull << 13)
+
+const char test_title[] = "Test vpmu";
+
+static void test_valid_msr_write(uint32_t idx, uint64_t wval)
+{
+    uint64_t rval = 0;
+
+    if( wrmsr_safe(idx, wval) )
+        xtf_failure("Fail: wrmsr(0x%08x, 0x%016"PRIx64") got unexpected fault"
+                    "\n", idx, wval);
+
+    /* check to see if the values were written correctly */
+    if ( rdmsr_safe(idx, &rval) )
+        xtf_failure("Fail: rdmsr(0x%08x, 0x016%"PRIxPTR") got unexpected fault"
+                    "\n", idx, (uintptr_t) &rval);
+
+    if ( rval != wval )
+        xtf_failure("Fail: rdmsr mismatch idx 0x%08x, wval 0x%016"PRIx64
+                ", rval 0x%016"PRIx64"\n", idx, wval, rval);
+}
+
+static void test_invalid_msr_write(uint32_t idx, uint64_t wval)
+{
+    /* wrmsr_safe must return false after faulting */
+    if( !wrmsr_safe(idx, wval) )
+        xtf_failure("Fail: wrmsr(0x%08x, 0x%016"PRIx64") did not fault.\n", 
+                idx, wval);
+}
+
+static void test_transparent_msr_write(uint32_t idx, uint64_t wval)
+{
+    uint64_t rval1 = 0, rval2 = 0;
+
+    /* read current value */
+    if ( rdmsr_safe(idx, &rval1) )
+        xtf_failure("Fail: rdmsr(0x%08x, 0x016%"PRIxPTR") got unexpected fault"
+                    "\n", idx, (uintptr_t)&rval1);
+
+    /* wrmsr should not fault but should not write anything either */
+    if  ( wrmsr_safe(idx, wval) )
+        xtf_failure("Fail: wrmsr(0x%08x, 0x%016"PRIx64") got unexpected fault"
+                    "\n", idx, wval);
+
+    /* read new value */
+    if ( rdmsr_safe(idx, &rval2) )
+        xtf_failure("Fail: rdmsr(0x%08x, 0x016%"PRIxPTR") got unexpected fault"
+                    "\n", idx, (uintptr_t) &rval2);
+
+    /* Check if the new value is the same as the one before wrmsr */
+    if ( rval1 != rval2 )
+        xtf_failure("Fail: rdmsr mismatch idx 0x%08x, wval 0x%016"PRIx64
+                ", rval 0x%016"PRIx64"\n", idx, rval1, rval2);
+}
+
+static void test_intel_pmu_ver1(uint8_t ng)
+{
+    /* 
+     * Intel Sofwtare Development Manual Vol. 3B,
+     * Section 18.2.1 - Architectural Performance Monitoring Version 1
+     *
+     * MSRs made available by the VPMU
+     *
+     * PMCx (start at address 0xc1)
+     * PERFEVENTSELx (start at address 0x186)
+     */
+
+    uint32_t idx;
+    uint64_t wval = 0;
+    unsigned i;
+
+    printk("Testing version 1\n");
+
+    /* for all general purpose counters */
+    for ( i = 0; i < ng; i++ )
+    {
+        /* test writing to PMCx */
+        idx = MSR_PMC(i);
+
+        /* 
+         * test we can write to all valid bits in the counters
+         * don't set bit 31 since that gets sign-extended
+         */
+        wval = ((1ull << 31) - 1) ;
+
+        test_valid_msr_write(idx, wval);
+
+        /* set all valid bits in MSR_EVENTSELx */
+        idx = MSR_PERFEVTSEL(i);
+        wval = ((1ull << 32) - 1) ^ (PERFEVENTSELx_ENABLE_ANYTHREAD |
+                PERFEVENTSELx_ENABLE_PCB);
+
+        test_valid_msr_write(idx, wval);
+
+        /* test writing an invalid value and assert that it faults */
+        wval = ~((1ull << 32) - 1);
+
+        test_invalid_msr_write(idx, wval);
+    }
+}
+
+static void test_intel_pmu_ver2(uint8_t ng, uint8_t nf)
+{
+    /* 
+     * Intel Sofwtare Development Manual Vol. 3B,
+     * Section 18.2.2 - Architectural Performance Monitoring Version 2
+     *
+     * MSRs made available by the VPMU -
+     *
+     * FIXED_CTRx (start at address 0x309)
+     * FIXED_CTR_CTRL
+     * PERF_GLOBAL_CTRL
+     * PERF_GLOBAL_STATUS (read-only)
+     * PERF_GLOBAL_OVF_CTRL
+     * DEBUGCTL_Freeze_LBR_ON_PMI
+     * DEBUGCTL_Freeze_PerfMon_On_PMI
+     */
+
+    uint32_t idx;
+    uint64_t wval;
+    uint64_t rval;
+    unsigned i;
+
+    printk("Testing version 2\n");
+
+    for ( i = 0; i < nf; i++ )
+    {
+        /* test writing to FIXED_CTRx */
+        idx = MSR_FIXED_CTR(i);
+
+        wval = (1ull << 32) - 1;
+
+        test_valid_msr_write(idx, wval);
+
+        /* test invalid write to FIXED_CTRx */
+        wval = ~wval;
+
+        test_invalid_msr_write(idx, wval);
+    }
+
+    /* test FIXED_CTR_CTRL */
+    idx = MSR_FIXED_CTR_CTRL;
+
+    /* enable all fixed counters */
+    wval = 0;
+
+    for ( i = 0; i < nf; i++ )
+        wval |= (FIXED_CTR_ENABLE << (FIXED_CTR_CTL_BITS * i));
+
+    test_valid_msr_write(idx, wval);
+    
+    /* invert wval to test writing an invalid value */
+    wval = ~wval;
+
+    test_invalid_msr_write(idx, wval);
+
+    /* test PERF_GLOBAL_CTRL */
+    idx = MSR_PERF_GLOBAL_CTRL;
+
+    wval = 0;
+
+    /* set all fixed function counters enable bits */
+    for ( i=0; i < nf; i ++ )
+        wval |= ((uint64_t)1 << (32 + i));
+
+    /* set all general purpose counters enable bits*/
+    for ( i = 0; i < ng; i++ )
+        wval |= (1 << i);
+
+    test_valid_msr_write(idx, wval);
+
+    /* invert wval to test invalid write to MSR_PERF_GLOBAL_CTRL*/
+    wval = ~wval;
+
+    test_invalid_msr_write(idx, wval);
+
+    /* test PERF_GLOBAL_OVF_CTRL */
+    idx = MSR_PERF_GLOBAL_OVF_CTRL;
+
+    /* set all valid bits in MSR_PERF_GLOBAL_OVF_CTRL */
+    wval = 0xC000000000000000 | (((1ULL << nf) - 1) << 32) | ((1ULL << ng) - 1);
+
+    /* 
+     * Writing to MSR_PERF_GLOBAL_OVF_CTRL clears
+     * MSR_PERF_GLOBAL_STATUS but but always returns 0 when read so
+     * it is tested as a transparent write 
+     */
+
+    test_transparent_msr_write(idx, wval);
+
+    /* invert wval to test invalid write to MSR_PERF_GLOBAL_OVF_CTRL*/
+    wval = ~wval;
+
+    test_invalid_msr_write(idx, wval);
+
+    /* test PERF_GLOBAL_STATUS (read-only) */
+    idx = MSR_PERF_GLOBAL_STATUS;
+
+    if ( rdmsr_safe(idx, &rval) )
+    {
+        xtf_failure("Error: test_intel_pmu_ver2: "
+                  "rdmsr_safe for MSR 0x%x resulted in a fault!\n", idx);
+    }
+
+    /* try to write the PERF_GLOBAL_STATUS register and expect it to fail*/
+    test_invalid_msr_write(idx, wval);
+
+    /* test DEBUGCTL */
+    idx = MSR_DEBUGCTL;
+
+    /* Test DEBUGCTL facilities enabled by v2 */
+    wval = DEBUGCTL_Freeze_LBR_ON_PMI | DEBUGCTL_Freeze_PerfMon_On_PMI;
+
+    /* 
+     * XENBUG: This test currently fails and needs to be fixed in Xen. Once 
+     * fixed, call test_valid_msr_write(idx, wval) to fully test MSR write
+     */
+    if( wrmsr_safe(idx, wval) )
+        xtf_error("Fail: wrmsr(0x%08x, 0x%016"PRIx64") got unexpected fault"
+                    "\n", idx, wval);
+}
+
+static void test_intel_pmu_ver3(uint8_t ng, uint8_t nf)
+{
+    /* 
+     * Intel Sofwtare Development Manual Vol. 3B
+     * Section 18.2.3 Architectural Performance Monitoring Version 3
+     *
+     * MSRs made available by the VPMU
+     *
+     * PERFEVENTSELx.ANYTHREAD (Bit 21)
+     * FIXED_CTR_CTRL.ANYTHREADx (Bit 2, 6, 11)
+     *
+     * Version 3 introduces ANYTHREAD bit but VPMU does not support it to
+     * ensure that a VCPU isn't able to read values from physical resources that
+     * are not allocated to it. This test case validates that we are unable to
+     * write to .ANYTHREAD bit in PERFEVENTSELx and FIXED_CTR_CTRL
+     */
+
+    uint64_t wval;
+    uint32_t idx;
+    unsigned i;
+
+    printk("Testing version 3\n");
+
+    /* test PERFEVENTSELx.ANYTHREAD is disabled */
+    for ( i = 0; i < ng; i++ )
+    {
+        idx = MSR_PERFEVTSEL(i);
+
+        wval = EVENT_UOPS_RETIRED_ANYTHREAD;
+
+        test_invalid_msr_write(idx, wval);
+    }
+
+    /* test FIXED_CTR_CTL.ANYTHREAD is disabled */
+    idx = MSR_FIXED_CTR_CTRL;
+
+    wval = 0;
+
+    for ( i = 0; i < nf; i++ )
+        wval |= (FIXED_CTR_ENABLE_ANYTHREAD << (4 * i)) ;
+
+    test_invalid_msr_write(idx, wval);
+}
+
+static void test_full_width_cnts(uint8_t ng, uint8_t ngb, uint8_t pdcm)
+{
+    uint64_t caps, wval;
+    uint32_t idx;
+    unsigned i;
+
+    if ( rdmsr_safe(MSR_PERF_CAPABILITIES, &caps) )
+    {
+        if (pdcm) {
+            xtf_failure("Fail: Fault while reading MSR_PERF_CAPABILITIES\n");
+        }
+        return;
+    }
+    else if ( !pdcm ) 
+    {
+        /* 
+         * XENBUG: MSR_PERF_CAPABILITIES should nto be readable without PDCM 
+         * bit set in CPUID.
+         */
+        xtf_error("Error: MSR_PERF_CAPABILITIES readable while PDCM is 0\n");
+    }
+
+
+    if ( !(caps & PERF_CAPABILITIES_Full_Width) )
+    {
+        printk("Info: Full width counters not supported\n");
+        return;
+    }
+
+    /* test writes to full width counters */
+    for ( i = 0; i < ng; i++)
+    {
+        idx = MSR_A_PMC(i);
+
+        wval = ((1ull << ngb) - 1) ;
+
+        test_valid_msr_write(idx, wval);
+
+        /* invert wval to test invalid write to MSR_PERF_GLOBAL_OVF_CTRL */
+        wval = ~wval;
+
+        test_invalid_msr_write(idx, wval);
+    }
+}
+
+void test_main(void)
+{
+    /* Architectural Performance Monitoring Version */
+    uint8_t ver;
+    /* Number of general purpose counter registers */
+    uint8_t ngregs;
+    /* Number of fixed function counter registers */
+    uint8_t nfregs;
+    /* Bit width of general-purpose, performance monitoring counter */
+    uint8_t ngbits;
+    /* Performance and debug capabilties MSR*/
+    uint8_t pdcm;
+
+    /* cpuid variables */
+    uint32_t leaf = 0x0a, subleaf = 0;
+    uint32_t eax, ebx, ecx, edx;
+
+    if ( vendor_is_amd )
+        return xtf_skip("Skip: VPMU testing for AMD currently unsupported\n");
+
+    if (max_leaf < leaf) 
+        return xtf_skip("Skip: Unable to retrieve PMU information from cpuid\n");
+
+    /* 
+     * Inter Software Development Manual Vol 2A
+     * Table 3-8  Information Returned by CPUID Instruction 
+     */
+
+    cpuid_count(leaf, subleaf, &eax, &ebx, &ecx, &edx);
+
+    /* Extract the version ID - EAX 7:0 */
+    ver =  (eax & 0xff);
+
+    /* Extract number of general purpose counter regs - EAX 15:8 */
+    ngregs = (eax >> 8) & 0xff;
+
+    /* Extract number of fixed function counter regs - EDX 4:0 */
+    nfregs = edx & 0x1f;
+
+    /* Extract number of bits in general purpose counter registers bits */
+    ngbits = (eax >> 16)  & 0xff;
+
+    /* Retrieve Perf & Debug Capabilties MSR availability*/
+    leaf = 0x01;
+    
+    printk("Info: PMU Version %u, Genereal purpose counters %u, Fixed function "
+            "counters %u, Counter width %u\n", ver, ngregs, nfregs, ngbits);
+
+    cpuid_count(leaf, subleaf, &eax, &ebx, &ecx, &edx);
+
+    /* Extract Performance & Debug Capabilties MSR from ECX bit 15 */
+    pdcm = (ecx >> 15) & 0x01;
+
+    printk("Info: Perf & Debug Capability MSR %u\n", pdcm);
+    
+    switch (ver)
+    {
+
+        default:
+                /* 
+                 * Version 4 facilities are not supported by Xen. 
+                 * VPMU  emulates version 3. Fall through 
+                 */
+                 xtf_warning("Test doesn't support version %u\n", ver);
+
+        case 3:
+                /* test version 3 facilities */
+                test_intel_pmu_ver3( ngregs, nfregs);
+           
+                /* fall through */
+
+        case 2:
+                /* test version 2 facilities */
+                test_intel_pmu_ver2(ngregs, nfregs);
+
+                /* test version 1 facilities */
+                test_intel_pmu_ver1(ngregs);
+
+                /* test full width counters */
+                test_full_width_cnts(ngregs, ngbits, pdcm);
+
+                break;
+
+        case 1:
+                return xtf_skip("Skip: VPMU version 1 unsupported in Xen\n");
+
+        case 0: 
+                return xtf_skip("Skip: VPMU not enabled in Xen\n");
+    }
+
+    return xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.9.3


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-04-28 18:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-28 18:25 [PATCH v2 0/2] xtf/vpmu VPMU tests Mohit Gambhir
2017-04-28 18:26 ` [PATCH v2 1/2] xtf/vpmu: Add Intel PMU MSR addresses Mohit Gambhir
2017-04-28 18:26 ` [PATCH v2 2/2] xtf/vpmu: MSR read/write tests for VPMU Mohit Gambhir

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.