| 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__ */ }