Message ID | 20200406080936.7180-21-jniethe5@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Initial Prefixed Instruction support | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/merge (2c0ce4ff35994a7b12cc9879ced52c9e7c2e6667) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch powerpc/next (6ba4a2d3591039aea1cb45c7c42262d26351a2fa) |
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch linus/master (a10c9c710f9ecea87b9f4bbb837467893b4bef01) |
snowpatch_ozlabs/apply_patch | success | Successfully applied on branch powerpc/fixes (1d0c32ec3b860a32df593a22bad0d1dbc5546a59) |
snowpatch_ozlabs/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 192 lines checked |
snowpatch_ozlabs/needsstable | success | Patch has no Fixes tags |
Hi Jordan, Thank you for the patch! Yet something to improve: [auto build test ERROR on v5.6] [cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215 base: 7111951b8d4973bda27ff663f2cf18b663d15b48 config: powerpc-allnoconfig (attached as .config) compiler: powerpc-linux-gcc (GCC) 9.3.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=9.3.0 make.cross ARCH=powerpc If you fix the issue, kindly add following tag as appropriate Reported-by: kbuild test robot <lkp@intel.com> All errors (new ones prefixed by >>): In file included from arch/powerpc/include/asm/code-patching.h:14, from arch/powerpc/include/asm/kprobes.h:24, from include/linux/kprobes.h:30, from arch/powerpc/lib/sstep.c:8: arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst' 69 | static inline bool ppc_inst_prefixed(ppc_inst x) | ^~~~~~~~ arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val' 79 | static inline u32 ppc_inst_val(struct ppc_inst x) | ^~~~~~~~~~~~ arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here 21 | static inline u32 ppc_inst_val(struct ppc_inst x) | ^~~~~~~~~~~~ arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len': arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration] 103 | return (ppc_inst_prefixed(x)) ? 8 : 4; | ^~~~~~~~~~~~~~~~~ | ppc_inst_write arch/powerpc/lib/sstep.c: In function 'analyse_instr': arch/powerpc/lib/sstep.c:1215:11: error: implicit declaration of function 'ppc_inst_suffix'; did you mean 'ppc_inst_swab'? [-Werror=implicit-function-declaration] 1215 | suffix = ppc_inst_suffix(instr); | ^~~~~~~~~~~~~~~ | ppc_inst_swab >> arch/powerpc/lib/sstep.c:1207:41: error: unused variable 'prefix_r' [-Werror=unused-variable] 1207 | unsigned int suffixopcode, prefixtype, prefix_r; | ^~~~~~~~ >> arch/powerpc/lib/sstep.c:1207:29: error: unused variable 'prefixtype' [-Werror=unused-variable] 1207 | unsigned int suffixopcode, prefixtype, prefix_r; | ^~~~~~~~~~ >> arch/powerpc/lib/sstep.c:1207:15: error: unused variable 'suffixopcode' [-Werror=unused-variable] 1207 | unsigned int suffixopcode, prefixtype, prefix_r; | ^~~~~~~~~~~~ cc1: all warnings being treated as errors vim +/prefix_r +1207 arch/powerpc/lib/sstep.c 1191 1192 /* 1193 * Decode an instruction, and return information about it in *op 1194 * without changing *regs. 1195 * Integer arithmetic and logical instructions, branches, and barrier 1196 * instructions can be emulated just using the information in *op. 1197 * 1198 * Return value is 1 if the instruction can be emulated just by 1199 * updating *regs with the information in *op, -1 if we need the 1200 * GPRs but *regs doesn't contain the full register set, or 0 1201 * otherwise. 1202 */ 1203 int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, 1204 struct ppc_inst instr) 1205 { 1206 unsigned int opcode, ra, rb, rc, rd, spr, u; > 1207 unsigned int suffixopcode, prefixtype, prefix_r; 1208 unsigned long int imm; 1209 unsigned long int val, val2; 1210 unsigned int mb, me, sh; 1211 unsigned int word, suffix; 1212 long ival; 1213 1214 word = ppc_inst_val(instr); 1215 suffix = ppc_inst_suffix(instr); 1216 1217 op->type = COMPUTE; 1218 1219 opcode = word >> 26; 1220 switch (opcode) { 1221 case 16: /* bc */ 1222 op->type = BRANCH; 1223 imm = (signed short)(word & 0xfffc); 1224 if ((word & 2) == 0) 1225 imm += regs->nip; 1226 op->val = truncate_if_32bit(regs->msr, imm); 1227 if (word & 1) 1228 op->type |= SETLK; 1229 if (branch_taken(word, regs, op)) 1230 op->type |= BRTAKEN; 1231 return 1; 1232 #ifdef CONFIG_PPC64 1233 case 17: /* sc */ 1234 if ((word & 0xfe2) == 2) 1235 op->type = SYSCALL; 1236 else 1237 op->type = UNKNOWN; 1238 return 0; 1239 #endif 1240 case 18: /* b */ 1241 op->type = BRANCH | BRTAKEN; 1242 imm = word & 0x03fffffc; 1243 if (imm & 0x02000000) 1244 imm -= 0x04000000; 1245 if ((word & 2) == 0) 1246 imm += regs->nip; 1247 op->val = truncate_if_32bit(regs->msr, imm); 1248 if (word & 1) 1249 op->type |= SETLK; 1250 return 1; 1251 case 19: 1252 switch ((word >> 1) & 0x3ff) { 1253 case 0: /* mcrf */ 1254 op->type = COMPUTE + SETCC; 1255 rd = 7 - ((word >> 23) & 0x7); 1256 ra = 7 - ((word >> 18) & 0x7); 1257 rd *= 4; 1258 ra *= 4; 1259 val = (regs->ccr >> ra) & 0xf; 1260 op->ccval = (regs->ccr & ~(0xfUL << rd)) | (val << rd); 1261 return 1; 1262 1263 case 16: /* bclr */ 1264 case 528: /* bcctr */ 1265 op->type = BRANCH; 1266 imm = (word & 0x400)? regs->ctr: regs->link; 1267 op->val = truncate_if_32bit(regs->msr, imm); 1268 if (word & 1) 1269 op->type |= SETLK; 1270 if (branch_taken(word, regs, op)) 1271 op->type |= BRTAKEN; 1272 return 1; 1273 1274 case 18: /* rfid, scary */ 1275 if (regs->msr & MSR_PR) 1276 goto priv; 1277 op->type = RFI; 1278 return 0; 1279 1280 case 150: /* isync */ 1281 op->type = BARRIER | BARRIER_ISYNC; 1282 return 1; 1283 1284 case 33: /* crnor */ 1285 case 129: /* crandc */ 1286 case 193: /* crxor */ 1287 case 225: /* crnand */ 1288 case 257: /* crand */ 1289 case 289: /* creqv */ 1290 case 417: /* crorc */ 1291 case 449: /* cror */ 1292 op->type = COMPUTE + SETCC; 1293 ra = (word >> 16) & 0x1f; 1294 rb = (word >> 11) & 0x1f; 1295 rd = (word >> 21) & 0x1f; 1296 ra = (regs->ccr >> (31 - ra)) & 1; 1297 rb = (regs->ccr >> (31 - rb)) & 1; 1298 val = (word >> (6 + ra * 2 + rb)) & 1; 1299 op->ccval = (regs->ccr & ~(1UL << (31 - rd))) | 1300 (val << (31 - rd)); 1301 return 1; 1302 } 1303 break; 1304 case 31: 1305 switch ((word >> 1) & 0x3ff) { 1306 case 598: /* sync */ 1307 op->type = BARRIER + BARRIER_SYNC; 1308 #ifdef __powerpc64__ 1309 switch ((word >> 21) & 3) { 1310 case 1: /* lwsync */ 1311 op->type = BARRIER + BARRIER_LWSYNC; 1312 break; 1313 case 2: /* ptesync */ 1314 op->type = BARRIER + BARRIER_PTESYNC; 1315 break; 1316 } 1317 #endif 1318 return 1; 1319 1320 case 854: /* eieio */ 1321 op->type = BARRIER + BARRIER_EIEIO; 1322 return 1; 1323 } 1324 break; 1325 } 1326 1327 /* Following cases refer to regs->gpr[], so we need all regs */ 1328 if (!FULL_REGS(regs)) 1329 return -1; 1330 1331 rd = (word >> 21) & 0x1f; 1332 ra = (word >> 16) & 0x1f; 1333 rb = (word >> 11) & 0x1f; 1334 rc = (word >> 6) & 0x1f; 1335 1336 switch (opcode) { 1337 #ifdef __powerpc64__ 1338 case 2: /* tdi */ 1339 if (rd & trap_compare(regs->gpr[ra], (short) word)) 1340 goto trap; 1341 return 1; 1342 #endif 1343 case 3: /* twi */ 1344 if (rd & trap_compare((int)regs->gpr[ra], (short) word)) 1345 goto trap; 1346 return 1; 1347 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index c3ce903ac488..9b200a5f8794 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -90,11 +90,15 @@ enum instruction_type { #define VSX_LDLEFT 4 /* load VSX register from left */ #define VSX_CHECK_VEC 8 /* check MSR_VEC not MSR_VSX for reg >= 32 */ +/* Prefixed flag, ORed in with type */ +#define PREFIXED 0x800 + /* Size field in type word */ #define SIZE(n) ((n) << 12) #define GETSIZE(w) ((w) >> 12) #define GETTYPE(t) ((t) & INSTR_TYPE_MASK) +#define GETLENGTH(t) (((t) & PREFIXED) ? 8 : 4) #define MKOP(t, f, s) ((t) | (f) | SIZE(s)) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 8b285bf11218..8b6aee0ee636 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -187,6 +187,44 @@ static nokprobe_inline unsigned long xform_ea(unsigned int instr, return ea; } +/* + * Calculate effective address for a MLS:D-form / 8LS:D-form + * prefixed instruction + */ +static nokprobe_inline unsigned long mlsd_8lsd_ea(unsigned int instr, + unsigned int suffix, + const struct pt_regs *regs) +{ + int ra, prefix_r; + unsigned int dd; + unsigned long ea, d0, d1, d; + + prefix_r = instr & (1ul << 20); + ra = (suffix >> 16) & 0x1f; + + d0 = instr & 0x3ffff; + d1 = suffix & 0xffff; + d = (d0 << 16) | d1; + + /* + * sign extend a 34 bit number + */ + dd = (unsigned int)(d >> 2); + ea = (signed int)dd; + ea = (ea << 2) | (d & 0x3); + + if (!prefix_r && ra) + ea += regs->gpr[ra]; + else if (!prefix_r && !ra) + ; /* Leave ea as is */ + else if (prefix_r && !ra) + ea += regs->nip; + else if (prefix_r && ra) + ; /* Invalid form. Should already be checked for by caller! */ + + return ea; +} + /* * Return the largest power of 2, not greater than sizeof(unsigned long), * such that x is a multiple of it. @@ -1166,6 +1204,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, struct ppc_inst instr) { unsigned int opcode, ra, rb, rc, rd, spr, u; + unsigned int suffixopcode, prefixtype, prefix_r; unsigned long int imm; unsigned long int val, val2; unsigned int mb, me, sh; @@ -2652,6 +2691,126 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; } break; + case 1: /* Prefixed instructions */ + prefix_r = word & (1ul << 20); + ra = (suffix >> 16) & 0x1f; + op->update_reg = ra; + rd = (suffix >> 21) & 0x1f; + op->reg = rd; + op->val = regs->gpr[rd]; + + suffixopcode = suffix >> 26; + prefixtype = (word >> 24) & 0x3; + switch (prefixtype) { + case 0: /* Type 00 Eight-Byte Load/Store */ + if (prefix_r && ra) + break; + op->ea = mlsd_8lsd_ea(word, suffix, regs); + switch (suffixopcode) { + case 41: /* plwa */ + op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 4); + break; + case 42: /* plxsd */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, PREFIXED, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 43: /* plxssp */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, PREFIXED, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + case 46: /* pstxsd */ + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, PREFIXED, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 47: /* pstxssp */ + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, PREFIXED, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + case 51: /* plxv1 */ + op->reg += 32; + + /* fallthru */ + case 50: /* plxv0 */ + op->type = MKOP(LOAD_VSX, PREFIXED, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 55: /* pstxv1 */ + op->reg = rd + 32; + + /* fallthru */ + case 54: /* pstxv0 */ + op->type = MKOP(STORE_VSX, PREFIXED, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 56: /* plq */ + op->type = MKOP(LOAD, PREFIXED, 16); + break; + case 57: /* pld */ + op->type = MKOP(LOAD, PREFIXED, 8); + break; + case 60: /* stq */ + op->type = MKOP(STORE, PREFIXED, 16); + break; + case 61: /* pstd */ + op->type = MKOP(STORE, PREFIXED, 8); + break; + } + break; + case 1: /* Type 01 Eight-Byte Register-to-Register */ + break; + case 2: /* Type 10 Modified Load/Store */ + if (prefix_r && ra) + break; + op->ea = mlsd_8lsd_ea(word, suffix, regs); + switch (suffixopcode) { + case 32: /* plwz */ + op->type = MKOP(LOAD, PREFIXED, 4); + break; + case 34: /* plbz */ + op->type = MKOP(LOAD, PREFIXED, 1); + break; + case 36: /* pstw */ + op->type = MKOP(STORE, PREFIXED, 4); + break; + case 38: /* pstb */ + op->type = MKOP(STORE, PREFIXED, 1); + break; + case 40: /* plhz */ + op->type = MKOP(LOAD, PREFIXED, 2); + break; + case 42: /* plha */ + op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 2); + break; + case 44: /* psth */ + op->type = MKOP(STORE, PREFIXED, 2); + break; + case 48: /* plfs */ + op->type = MKOP(LOAD_FP, PREFIXED | FPCONV, 4); + break; + case 50: /* plfd */ + op->type = MKOP(LOAD_FP, PREFIXED, 8); + break; + case 52: /* pstfs */ + op->type = MKOP(STORE_FP, PREFIXED | FPCONV, 4); + break; + case 54: /* pstfd */ + op->type = MKOP(STORE_FP, PREFIXED, 8); + break; + } + break; + case 3: /* Type 11 Modified Register-to-Register */ + break; + } #endif /* __powerpc64__ */ }