1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/compiler.h> 4 #include <linux/bits.h> 5 #include <string.h> 6 #include <cpuid.h> 7 #include <sched.h> 8 9 #include "intel-pt-decoder/intel-pt-pkt-decoder.h" 10 11 #include "debug.h" 12 #include "tests/tests.h" 13 #include "arch-tests.h" 14 #include "cpumap.h" 15 16 /** 17 * struct test_data - Test data. 18 * @len: number of bytes to decode 19 * @bytes: bytes to decode 20 * @ctx: packet context to decode 21 * @packet: expected packet 22 * @new_ctx: expected new packet context 23 * @ctx_unchanged: the packet context must not change 24 */ 25 static const struct test_data { 26 int len; 27 u8 bytes[INTEL_PT_PKT_MAX_SZ]; 28 enum intel_pt_pkt_ctx ctx; 29 struct intel_pt_pkt packet; 30 enum intel_pt_pkt_ctx new_ctx; 31 int ctx_unchanged; 32 } data[] = { 33 /* Padding Packet */ 34 {1, {0}, 0, {INTEL_PT_PAD, 0, 0}, 0, 1 }, 35 /* Short Taken/Not Taken Packet */ 36 {1, {4}, 0, {INTEL_PT_TNT, 1, 0}, 0, 0 }, 37 {1, {6}, 0, {INTEL_PT_TNT, 1, 0x20ULL << 58}, 0, 0 }, 38 {1, {0x80}, 0, {INTEL_PT_TNT, 6, 0}, 0, 0 }, 39 {1, {0xfe}, 0, {INTEL_PT_TNT, 6, 0x3fULL << 58}, 0, 0 }, 40 /* Long Taken/Not Taken Packet */ 41 {8, {0x02, 0xa3, 2}, 0, {INTEL_PT_TNT, 1, 0xa302ULL << 47}, 0, 0 }, 42 {8, {0x02, 0xa3, 3}, 0, {INTEL_PT_TNT, 1, 0x1a302ULL << 47}, 0, 0 }, 43 {8, {0x02, 0xa3, 0, 0, 0, 0, 0, 0x80}, 0, {INTEL_PT_TNT, 47, 0xa302ULL << 1}, 0, 0 }, 44 {8, {0x02, 0xa3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, {INTEL_PT_TNT, 47, 0xffffffffffffa302ULL << 1}, 0, 0 }, 45 /* Target IP Packet */ 46 {1, {0x0d}, 0, {INTEL_PT_TIP, 0, 0}, 0, 0 }, 47 {3, {0x2d, 1, 2}, 0, {INTEL_PT_TIP, 1, 0x201}, 0, 0 }, 48 {5, {0x4d, 1, 2, 3, 4}, 0, {INTEL_PT_TIP, 2, 0x4030201}, 0, 0 }, 49 {7, {0x6d, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_TIP, 3, 0x60504030201}, 0, 0 }, 50 {7, {0x8d, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_TIP, 4, 0x60504030201}, 0, 0 }, 51 {9, {0xcd, 1, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_TIP, 6, 0x807060504030201}, 0, 0 }, 52 /* Packet Generation Enable */ 53 {1, {0x11}, 0, {INTEL_PT_TIP_PGE, 0, 0}, 0, 0 }, 54 {3, {0x31, 1, 2}, 0, {INTEL_PT_TIP_PGE, 1, 0x201}, 0, 0 }, 55 {5, {0x51, 1, 2, 3, 4}, 0, {INTEL_PT_TIP_PGE, 2, 0x4030201}, 0, 0 }, 56 {7, {0x71, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_TIP_PGE, 3, 0x60504030201}, 0, 0 }, 57 {7, {0x91, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_TIP_PGE, 4, 0x60504030201}, 0, 0 }, 58 {9, {0xd1, 1, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_TIP_PGE, 6, 0x807060504030201}, 0, 0 }, 59 /* Packet Generation Disable */ 60 {1, {0x01}, 0, {INTEL_PT_TIP_PGD, 0, 0}, 0, 0 }, 61 {3, {0x21, 1, 2}, 0, {INTEL_PT_TIP_PGD, 1, 0x201}, 0, 0 }, 62 {5, {0x41, 1, 2, 3, 4}, 0, {INTEL_PT_TIP_PGD, 2, 0x4030201}, 0, 0 }, 63 {7, {0x61, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_TIP_PGD, 3, 0x60504030201}, 0, 0 }, 64 {7, {0x81, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_TIP_PGD, 4, 0x60504030201}, 0, 0 }, 65 {9, {0xc1, 1, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_TIP_PGD, 6, 0x807060504030201}, 0, 0 }, 66 /* Flow Update Packet */ 67 {1, {0x1d}, 0, {INTEL_PT_FUP, 0, 0}, 0, 0 }, 68 {3, {0x3d, 1, 2}, 0, {INTEL_PT_FUP, 1, 0x201}, 0, 0 }, 69 {5, {0x5d, 1, 2, 3, 4}, 0, {INTEL_PT_FUP, 2, 0x4030201}, 0, 0 }, 70 {7, {0x7d, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_FUP, 3, 0x60504030201}, 0, 0 }, 71 {7, {0x9d, 1, 2, 3, 4, 5, 6}, 0, {INTEL_PT_FUP, 4, 0x60504030201}, 0, 0 }, 72 {9, {0xdd, 1, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_FUP, 6, 0x807060504030201}, 0, 0 }, 73 /* Paging Information Packet */ 74 {8, {0x02, 0x43, 2, 4, 6, 8, 10, 12}, 0, {INTEL_PT_PIP, 0, 0xC0A08060402}, 0, 0 }, 75 {8, {0x02, 0x43, 3, 4, 6, 8, 10, 12}, 0, {INTEL_PT_PIP, 0, 0xC0A08060403}, 0, 0 }, 76 /* Mode Exec Packet */ 77 {2, {0x99, 0x00}, 0, {INTEL_PT_MODE_EXEC, 0, 16}, 0, 0 }, 78 {2, {0x99, 0x01}, 0, {INTEL_PT_MODE_EXEC, 1, 64}, 0, 0 }, 79 {2, {0x99, 0x02}, 0, {INTEL_PT_MODE_EXEC, 2, 32}, 0, 0 }, 80 {2, {0x99, 0x04}, 0, {INTEL_PT_MODE_EXEC, 4, 16}, 0, 0 }, 81 {2, {0x99, 0x05}, 0, {INTEL_PT_MODE_EXEC, 5, 64}, 0, 0 }, 82 {2, {0x99, 0x06}, 0, {INTEL_PT_MODE_EXEC, 6, 32}, 0, 0 }, 83 /* Mode TSX Packet */ 84 {2, {0x99, 0x20}, 0, {INTEL_PT_MODE_TSX, 0, 0}, 0, 0 }, 85 {2, {0x99, 0x21}, 0, {INTEL_PT_MODE_TSX, 0, 1}, 0, 0 }, 86 {2, {0x99, 0x22}, 0, {INTEL_PT_MODE_TSX, 0, 2}, 0, 0 }, 87 /* Trace Stop Packet */ 88 {2, {0x02, 0x83}, 0, {INTEL_PT_TRACESTOP, 0, 0}, 0, 0 }, 89 /* Core:Bus Ratio Packet */ 90 {4, {0x02, 0x03, 0x12, 0}, 0, {INTEL_PT_CBR, 0, 0x12}, 0, 1 }, 91 /* Timestamp Counter Packet */ 92 {8, {0x19, 1, 2, 3, 4, 5, 6, 7}, 0, {INTEL_PT_TSC, 0, 0x7060504030201}, 0, 1 }, 93 /* Mini Time Counter Packet */ 94 {2, {0x59, 0x12}, 0, {INTEL_PT_MTC, 0, 0x12}, 0, 1 }, 95 /* TSC / MTC Alignment Packet */ 96 {7, {0x02, 0x73}, 0, {INTEL_PT_TMA, 0, 0}, 0, 1 }, 97 {7, {0x02, 0x73, 1, 2}, 0, {INTEL_PT_TMA, 0, 0x201}, 0, 1 }, 98 {7, {0x02, 0x73, 0, 0, 0, 0xff, 1}, 0, {INTEL_PT_TMA, 0x1ff, 0}, 0, 1 }, 99 {7, {0x02, 0x73, 0x80, 0xc0, 0, 0xff, 1}, 0, {INTEL_PT_TMA, 0x1ff, 0xc080}, 0, 1 }, 100 /* Cycle Count Packet */ 101 {1, {0x03}, 0, {INTEL_PT_CYC, 0, 0}, 0, 1 }, 102 {1, {0x0b}, 0, {INTEL_PT_CYC, 0, 1}, 0, 1 }, 103 {1, {0xfb}, 0, {INTEL_PT_CYC, 0, 0x1f}, 0, 1 }, 104 {2, {0x07, 2}, 0, {INTEL_PT_CYC, 0, 0x20}, 0, 1 }, 105 {2, {0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0xfff}, 0, 1 }, 106 {3, {0x07, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x1000}, 0, 1 }, 107 {3, {0xff, 0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0x7ffff}, 0, 1 }, 108 {4, {0x07, 1, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x80000}, 0, 1 }, 109 {4, {0xff, 0xff, 0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0x3ffffff}, 0, 1 }, 110 {5, {0x07, 1, 1, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x4000000}, 0, 1 }, 111 {5, {0xff, 0xff, 0xff, 0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0x1ffffffff}, 0, 1 }, 112 {6, {0x07, 1, 1, 1, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x200000000}, 0, 1 }, 113 {6, {0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0xffffffffff}, 0, 1 }, 114 {7, {0x07, 1, 1, 1, 1, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x10000000000}, 0, 1 }, 115 {7, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0x7fffffffffff}, 0, 1 }, 116 {8, {0x07, 1, 1, 1, 1, 1, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x800000000000}, 0, 1 }, 117 {8, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0x3fffffffffffff}, 0, 1 }, 118 {9, {0x07, 1, 1, 1, 1, 1, 1, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x40000000000000}, 0, 1 }, 119 {9, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}, 0, {INTEL_PT_CYC, 0, 0x1fffffffffffffff}, 0, 1 }, 120 {10, {0x07, 1, 1, 1, 1, 1, 1, 1, 1, 2}, 0, {INTEL_PT_CYC, 0, 0x2000000000000000}, 0, 1 }, 121 {10, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe}, 0, {INTEL_PT_CYC, 0, 0xffffffffffffffff}, 0, 1 }, 122 /* Virtual-Machine Control Structure Packet */ 123 {7, {0x02, 0xc8, 1, 2, 3, 4, 5}, 0, {INTEL_PT_VMCS, 5, 0x504030201}, 0, 0 }, 124 /* Overflow Packet */ 125 {2, {0x02, 0xf3}, 0, {INTEL_PT_OVF, 0, 0}, 0, 0 }, 126 {2, {0x02, 0xf3}, INTEL_PT_BLK_4_CTX, {INTEL_PT_OVF, 0, 0}, 0, 0 }, 127 {2, {0x02, 0xf3}, INTEL_PT_BLK_8_CTX, {INTEL_PT_OVF, 0, 0}, 0, 0 }, 128 /* Packet Stream Boundary*/ 129 {16, {0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82}, 0, {INTEL_PT_PSB, 0, 0}, 0, 0 }, 130 {16, {0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82}, INTEL_PT_BLK_4_CTX, {INTEL_PT_PSB, 0, 0}, 0, 0 }, 131 {16, {0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82}, INTEL_PT_BLK_8_CTX, {INTEL_PT_PSB, 0, 0}, 0, 0 }, 132 /* PSB End Packet */ 133 {2, {0x02, 0x23}, 0, {INTEL_PT_PSBEND, 0, 0}, 0, 0 }, 134 /* Maintenance Packet */ 135 {11, {0x02, 0xc3, 0x88, 1, 2, 3, 4, 5, 6, 7}, 0, {INTEL_PT_MNT, 0, 0x7060504030201}, 0, 1 }, 136 /* Write Data to PT Packet */ 137 {6, {0x02, 0x12, 1, 2, 3, 4}, 0, {INTEL_PT_PTWRITE, 0, 0x4030201}, 0, 0 }, 138 {10, {0x02, 0x32, 1, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_PTWRITE, 1, 0x807060504030201}, 0, 0 }, 139 {6, {0x02, 0x92, 1, 2, 3, 4}, 0, {INTEL_PT_PTWRITE_IP, 0, 0x4030201}, 0, 0 }, 140 {10, {0x02, 0xb2, 1, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_PTWRITE_IP, 1, 0x807060504030201}, 0, 0 }, 141 /* Execution Stop Packet */ 142 {2, {0x02, 0x62}, 0, {INTEL_PT_EXSTOP, 0, 0}, 0, 1 }, 143 {2, {0x02, 0xe2}, 0, {INTEL_PT_EXSTOP_IP, 0, 0}, 0, 1 }, 144 /* Monitor Wait Packet */ 145 {10, {0x02, 0xc2}, 0, {INTEL_PT_MWAIT, 0, 0}, 0, 0 }, 146 {10, {0x02, 0xc2, 1, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_MWAIT, 0, 0x807060504030201}, 0, 0 }, 147 {10, {0x02, 0xc2, 0xff, 2, 3, 4, 7, 6, 7, 8}, 0, {INTEL_PT_MWAIT, 0, 0x8070607040302ff}, 0, 0 }, 148 /* Power Entry Packet */ 149 {4, {0x02, 0x22}, 0, {INTEL_PT_PWRE, 0, 0}, 0, 1 }, 150 {4, {0x02, 0x22, 1, 2}, 0, {INTEL_PT_PWRE, 0, 0x0201}, 0, 1 }, 151 {4, {0x02, 0x22, 0x80, 0x34}, 0, {INTEL_PT_PWRE, 0, 0x3480}, 0, 1 }, 152 {4, {0x02, 0x22, 0x00, 0x56}, 0, {INTEL_PT_PWRE, 0, 0x5600}, 0, 1 }, 153 /* Power Exit Packet */ 154 {7, {0x02, 0xa2}, 0, {INTEL_PT_PWRX, 0, 0}, 0, 1 }, 155 {7, {0x02, 0xa2, 1, 2, 3, 4, 5}, 0, {INTEL_PT_PWRX, 0, 0x504030201}, 0, 1 }, 156 {7, {0x02, 0xa2, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, {INTEL_PT_PWRX, 0, 0xffffffffff}, 0, 1 }, 157 /* Block Begin Packet */ 158 {3, {0x02, 0x63, 0x00}, 0, {INTEL_PT_BBP, 0, 0}, INTEL_PT_BLK_8_CTX, 0 }, 159 {3, {0x02, 0x63, 0x80}, 0, {INTEL_PT_BBP, 1, 0}, INTEL_PT_BLK_4_CTX, 0 }, 160 {3, {0x02, 0x63, 0x1f}, 0, {INTEL_PT_BBP, 0, 0x1f}, INTEL_PT_BLK_8_CTX, 0 }, 161 {3, {0x02, 0x63, 0x9f}, 0, {INTEL_PT_BBP, 1, 0x1f}, INTEL_PT_BLK_4_CTX, 0 }, 162 /* 4-byte Block Item Packet */ 163 {5, {0x04}, INTEL_PT_BLK_4_CTX, {INTEL_PT_BIP, 0, 0}, INTEL_PT_BLK_4_CTX, 0 }, 164 {5, {0xfc}, INTEL_PT_BLK_4_CTX, {INTEL_PT_BIP, 0x1f, 0}, INTEL_PT_BLK_4_CTX, 0 }, 165 {5, {0x04, 1, 2, 3, 4}, INTEL_PT_BLK_4_CTX, {INTEL_PT_BIP, 0, 0x04030201}, INTEL_PT_BLK_4_CTX, 0 }, 166 {5, {0xfc, 1, 2, 3, 4}, INTEL_PT_BLK_4_CTX, {INTEL_PT_BIP, 0x1f, 0x04030201}, INTEL_PT_BLK_4_CTX, 0 }, 167 /* 8-byte Block Item Packet */ 168 {9, {0x04}, INTEL_PT_BLK_8_CTX, {INTEL_PT_BIP, 0, 0}, INTEL_PT_BLK_8_CTX, 0 }, 169 {9, {0xfc}, INTEL_PT_BLK_8_CTX, {INTEL_PT_BIP, 0x1f, 0}, INTEL_PT_BLK_8_CTX, 0 }, 170 {9, {0x04, 1, 2, 3, 4, 5, 6, 7, 8}, INTEL_PT_BLK_8_CTX, {INTEL_PT_BIP, 0, 0x0807060504030201}, INTEL_PT_BLK_8_CTX, 0 }, 171 {9, {0xfc, 1, 2, 3, 4, 5, 6, 7, 8}, INTEL_PT_BLK_8_CTX, {INTEL_PT_BIP, 0x1f, 0x0807060504030201}, INTEL_PT_BLK_8_CTX, 0 }, 172 /* Block End Packet */ 173 {2, {0x02, 0x33}, INTEL_PT_BLK_4_CTX, {INTEL_PT_BEP, 0, 0}, 0, 0 }, 174 {2, {0x02, 0xb3}, INTEL_PT_BLK_4_CTX, {INTEL_PT_BEP_IP, 0, 0}, 0, 0 }, 175 {2, {0x02, 0x33}, INTEL_PT_BLK_8_CTX, {INTEL_PT_BEP, 0, 0}, 0, 0 }, 176 {2, {0x02, 0xb3}, INTEL_PT_BLK_8_CTX, {INTEL_PT_BEP_IP, 0, 0}, 0, 0 }, 177 /* Control Flow Event Packet */ 178 {4, {0x02, 0x13, 0x01, 0x03}, 0, {INTEL_PT_CFE, 1, 3}, 0, 0 }, 179 {4, {0x02, 0x13, 0x81, 0x03}, 0, {INTEL_PT_CFE_IP, 1, 3}, 0, 0 }, 180 {4, {0x02, 0x13, 0x1f, 0x00}, 0, {INTEL_PT_CFE, 0x1f, 0}, 0, 0 }, 181 {4, {0x02, 0x13, 0x9f, 0xff}, 0, {INTEL_PT_CFE_IP, 0x1f, 0xff}, 0, 0 }, 182 /* */ 183 {11, {0x02, 0x53, 0x09, 1, 2, 3, 4, 5, 6, 7}, 0, {INTEL_PT_EVD, 0x09, 0x7060504030201}, 0, 0 }, 184 {11, {0x02, 0x53, 0x3f, 2, 3, 4, 5, 6, 7, 8}, 0, {INTEL_PT_EVD, 0x3f, 0x8070605040302}, 0, 0 }, 185 /* Terminator */ 186 {0, {0}, 0, {0, 0, 0}, 0, 0 }, 187 }; 188 189 static int dump_packet(const struct intel_pt_pkt *packet, const u8 *bytes, int len) 190 { 191 char desc[INTEL_PT_PKT_DESC_MAX]; 192 int ret, i; 193 194 for (i = 0; i < len; i++) 195 pr_debug(" %02x", bytes[i]); 196 for (; i < INTEL_PT_PKT_MAX_SZ; i++) 197 pr_debug(" "); 198 pr_debug(" "); 199 ret = intel_pt_pkt_desc(packet, desc, INTEL_PT_PKT_DESC_MAX); 200 if (ret < 0) { 201 pr_debug("intel_pt_pkt_desc failed!\n"); 202 return TEST_FAIL; 203 } 204 pr_debug("%s\n", desc); 205 206 return TEST_OK; 207 } 208 209 static void decoding_failed(const struct test_data *d) 210 { 211 pr_debug("Decoding failed!\n"); 212 pr_debug("Decoding: "); 213 dump_packet(&d->packet, d->bytes, d->len); 214 } 215 216 static int fail(const struct test_data *d, struct intel_pt_pkt *packet, int len, 217 enum intel_pt_pkt_ctx new_ctx) 218 { 219 decoding_failed(d); 220 221 if (len != d->len) 222 pr_debug("Expected length: %d Decoded length %d\n", 223 d->len, len); 224 225 if (packet->type != d->packet.type) 226 pr_debug("Expected type: %d Decoded type %d\n", 227 d->packet.type, packet->type); 228 229 if (packet->count != d->packet.count) 230 pr_debug("Expected count: %d Decoded count %d\n", 231 d->packet.count, packet->count); 232 233 if (packet->payload != d->packet.payload) 234 pr_debug("Expected payload: 0x%llx Decoded payload 0x%llx\n", 235 (unsigned long long)d->packet.payload, 236 (unsigned long long)packet->payload); 237 238 if (new_ctx != d->new_ctx) 239 pr_debug("Expected packet context: %d Decoded packet context %d\n", 240 d->new_ctx, new_ctx); 241 242 return TEST_FAIL; 243 } 244 245 static int test_ctx_unchanged(const struct test_data *d, struct intel_pt_pkt *packet, 246 enum intel_pt_pkt_ctx ctx) 247 { 248 enum intel_pt_pkt_ctx old_ctx = ctx; 249 250 intel_pt_upd_pkt_ctx(packet, &ctx); 251 252 if (ctx != old_ctx) { 253 decoding_failed(d); 254 pr_debug("Packet context changed!\n"); 255 return TEST_FAIL; 256 } 257 258 return TEST_OK; 259 } 260 261 static int test_one(const struct test_data *d) 262 { 263 struct intel_pt_pkt packet; 264 enum intel_pt_pkt_ctx ctx = d->ctx; 265 int ret; 266 267 memset(&packet, 0xff, sizeof(packet)); 268 269 /* Decode a packet */ 270 ret = intel_pt_get_packet(d->bytes, d->len, &packet, &ctx); 271 if (ret < 0 || ret > INTEL_PT_PKT_MAX_SZ) { 272 decoding_failed(d); 273 pr_debug("intel_pt_get_packet returned %d\n", ret); 274 return TEST_FAIL; 275 } 276 277 /* Some packets must always leave the packet context unchanged */ 278 if (d->ctx_unchanged) { 279 int err; 280 281 err = test_ctx_unchanged(d, &packet, INTEL_PT_NO_CTX); 282 if (err) 283 return err; 284 err = test_ctx_unchanged(d, &packet, INTEL_PT_BLK_4_CTX); 285 if (err) 286 return err; 287 err = test_ctx_unchanged(d, &packet, INTEL_PT_BLK_8_CTX); 288 if (err) 289 return err; 290 } 291 292 /* Compare to the expected values */ 293 if (ret != d->len || packet.type != d->packet.type || 294 packet.count != d->packet.count || 295 packet.payload != d->packet.payload || ctx != d->new_ctx) 296 return fail(d, &packet, ret, ctx); 297 298 pr_debug("Decoded ok:"); 299 ret = dump_packet(&d->packet, d->bytes, d->len); 300 301 return ret; 302 } 303 304 /* 305 * This test feeds byte sequences to the Intel PT packet decoder and checks the 306 * results. Changes to the packet context are also checked. 307 */ 308 int test__intel_pt_pkt_decoder(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 309 { 310 const struct test_data *d = data; 311 int ret; 312 313 for (d = data; d->len; d++) { 314 ret = test_one(d); 315 if (ret) 316 return ret; 317 } 318 319 return TEST_OK; 320 } 321 322 static int setaffinity(int cpu) 323 { 324 cpu_set_t cpu_set; 325 326 CPU_ZERO(&cpu_set); 327 CPU_SET(cpu, &cpu_set); 328 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set)) { 329 pr_debug("sched_setaffinity() failed for CPU %d\n", cpu); 330 return -1; 331 } 332 return 0; 333 } 334 335 #define INTEL_PT_ADDR_FILT_CNT_MASK GENMASK(2, 0) 336 #define INTEL_PT_SUBLEAF_CNT 2 337 #define CPUID_REG_CNT 4 338 339 struct cpuid_result { 340 union { 341 struct { 342 unsigned int eax; 343 unsigned int ebx; 344 unsigned int ecx; 345 unsigned int edx; 346 }; 347 unsigned int reg[CPUID_REG_CNT]; 348 }; 349 }; 350 351 struct pt_caps { 352 struct cpuid_result subleaf[INTEL_PT_SUBLEAF_CNT]; 353 }; 354 355 static int get_pt_caps(int cpu, struct pt_caps *caps) 356 { 357 struct cpuid_result r; 358 int i; 359 360 if (setaffinity(cpu)) 361 return -1; 362 363 memset(caps, 0, sizeof(*caps)); 364 365 for (i = 0; i < INTEL_PT_SUBLEAF_CNT; i++) { 366 __get_cpuid_count(20, i, &r.eax, &r.ebx, &r.ecx, &r.edx); 367 pr_debug("CPU %d CPUID leaf 20 subleaf %d\n", cpu, i); 368 pr_debug("eax = 0x%08x\n", r.eax); 369 pr_debug("ebx = 0x%08x\n", r.ebx); 370 pr_debug("ecx = 0x%08x\n", r.ecx); 371 pr_debug("edx = 0x%08x\n", r.edx); 372 caps->subleaf[i] = r; 373 } 374 375 return 0; 376 } 377 378 static bool is_hydrid(void) 379 { 380 unsigned int eax, ebx, ecx, edx = 0; 381 bool result; 382 383 __get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx); 384 result = edx & BIT(15); 385 pr_debug("Is %shybrid : CPUID leaf 7 subleaf 0 edx %#x (bit-15 indicates hybrid)\n", 386 result ? "" : "not ", edx); 387 return result; 388 } 389 390 static int compare_caps(int cpu, struct pt_caps *caps, struct pt_caps *caps0) 391 { 392 struct pt_caps mask = { /* Mask of bits to check*/ 393 .subleaf = { 394 [0] = { 395 .ebx = GENMASK(8, 0), 396 .ecx = GENMASK(3, 0), 397 }, 398 [1] = { 399 .eax = GENMASK(31, 16), 400 .ebx = GENMASK(31, 0), 401 } 402 } 403 }; 404 unsigned int m, reg, reg0; 405 int ret = 0; 406 int i, j; 407 408 for (i = 0; i < INTEL_PT_SUBLEAF_CNT; i++) { 409 for (j = 0; j < CPUID_REG_CNT; j++) { 410 m = mask.subleaf[i].reg[j]; 411 reg = m & caps->subleaf[i].reg[j]; 412 reg0 = m & caps0->subleaf[i].reg[j]; 413 if ((reg & reg0) != reg0) { 414 pr_debug("CPU %d subleaf %d reg %d FAIL %#x vs %#x\n", 415 cpu, i, j, reg, reg0); 416 ret = -1; 417 } 418 } 419 } 420 421 m = INTEL_PT_ADDR_FILT_CNT_MASK; 422 reg = m & caps->subleaf[1].eax; 423 reg0 = m & caps0->subleaf[1].eax; 424 if (reg < reg0) { 425 pr_debug("CPU %d subleaf 1 reg 0 FAIL address filter count %#x vs %#x\n", 426 cpu, reg, reg0); 427 ret = -1; 428 } 429 430 if (!ret) 431 pr_debug("CPU %d OK\n", cpu); 432 433 return ret; 434 } 435 436 int test__intel_pt_hybrid_compat(struct test_suite *test, int subtest) 437 { 438 int max_cpu = cpu__max_cpu().cpu; 439 struct pt_caps last_caps; 440 struct pt_caps caps0; 441 int ret = TEST_OK; 442 int cpu; 443 444 if (!is_hydrid()) { 445 test->test_cases[subtest].skip_reason = "not hybrid"; 446 return TEST_SKIP; 447 } 448 449 if (get_pt_caps(0, &caps0)) 450 return TEST_FAIL; 451 452 for (cpu = 1, last_caps = caps0; cpu < max_cpu; cpu++) { 453 struct pt_caps caps; 454 455 if (get_pt_caps(cpu, &caps)) { 456 pr_debug("CPU %d not found\n", cpu); 457 continue; 458 } 459 if (!memcmp(&caps, &last_caps, sizeof(caps))) { 460 pr_debug("CPU %d same caps as previous CPU\n", cpu); 461 continue; 462 } 463 if (compare_caps(cpu, &caps, &caps0)) 464 ret = TEST_FAIL; 465 last_caps = caps; 466 } 467 468 return ret; 469 } 470
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.